summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan "Geenz" Goodman <geenz@geenzo.com>2025-04-08 13:51:21 -0400
committerJonathan "Geenz" Goodman <geenz@geenzo.com>2025-04-08 13:51:21 -0400
commitc8499b7f01ac3f46f0764ea8195c30a4a2ec27a8 (patch)
treef1175d186cbdd87c0afe13498ba01d46ae56bf92
parent3c9bb9bfe5aa178141c381cfac066fd31a7252b4 (diff)
GLTF WIP. Still working on getting transforms working proper and need to figure out our indices.
-rw-r--r--indra/llprimitive/CMakeLists.txt2
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/gltf/asset.cpp20
-rw-r--r--indra/newview/gltf/asset.h3
-rw-r--r--indra/newview/gltf/llgltfloader.cpp (renamed from indra/llprimitive/llgltfloader.cpp)135
-rw-r--r--indra/newview/gltf/llgltfloader.h (renamed from indra/llprimitive/llgltfloader.h)5
-rw-r--r--indra/newview/llfilepicker.cpp2
-rw-r--r--indra/newview/llmodelpreview.cpp2
8 files changed, 105 insertions, 66 deletions
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index 3d8e02cb16..e13f0bbd96 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -12,7 +12,6 @@ include(TinyGLTF)
set(llprimitive_SOURCE_FILES
lldaeloader.cpp
- llgltfloader.cpp
llgltfmaterial.cpp
llmaterialid.cpp
llmaterial.cpp
@@ -32,7 +31,6 @@ set(llprimitive_SOURCE_FILES
set(llprimitive_HEADER_FILES
CMakeLists.txt
lldaeloader.h
- llgltfloader.h
llgltfmaterial.h
llgltfmaterial_templates.h
legacy_object_types.h
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index ed29911a43..7dfe01898a 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -76,6 +76,7 @@ set(viewer_SOURCE_FILES
gltf/accessor.cpp
gltf/primitive.cpp
gltf/animation.cpp
+ gltf/llgltfloader.cpp
groupchatlistener.cpp
llaccountingcostmanager.cpp
llaisapi.cpp
@@ -744,6 +745,7 @@ set(viewer_HEADER_FILES
gltf/buffer_util.h
gltf/primitive.h
gltf/animation.h
+ gltf/llgltfloader.h
llaccountingcost.h
llaccountingcostmanager.h
llaisapi.h
diff --git a/indra/newview/gltf/asset.cpp b/indra/newview/gltf/asset.cpp
index c210b9c61d..beccb02bd4 100644
--- a/indra/newview/gltf/asset.cpp
+++ b/indra/newview/gltf/asset.cpp
@@ -472,11 +472,14 @@ void Asset::update()
for (auto& image : mImages)
{
- if (image.mTexture.notNull())
- { // HACK - force texture to be loaded full rez
- // TODO: calculate actual vsize
- image.mTexture->addTextureStats(2048.f * 2048.f);
- image.mTexture->setBoostLevel(LLViewerTexture::BOOST_HIGH);
+ if (image.mLoadIntoTexturePipe)
+ {
+ if (image.mTexture.notNull())
+ { // HACK - force texture to be loaded full rez
+ // TODO: calculate actual vsize
+ image.mTexture->addTextureStats(2048.f * 2048.f);
+ image.mTexture->setBoostLevel(LLViewerTexture::BOOST_HIGH);
+ }
}
}
}
@@ -603,6 +606,7 @@ bool Asset::prep()
if (vertex_count[variant] > 0)
{
U32 mat_idx = mat_id + 1;
+ #if 0
LLVertexBuffer* vb = new LLVertexBuffer(attribute_mask);
rd.mBatches[variant][mat_idx].mVertexBuffer = vb;
@@ -624,6 +628,7 @@ bool Asset::prep()
vb->unmapBuffer();
vb->unbind();
+ #endif
}
}
}
@@ -634,10 +639,10 @@ bool Asset::prep()
{
for (auto& primitive : mesh.mPrimitives)
{
- llassert(primitive.mVertexBuffer.notNull());
+ //llassert(primitive.mVertexBuffer.notNull());
}
}
-
+ #if 0
// build render batches
for (S32 node_id = 0; node_id < mNodes.size(); ++node_id)
{
@@ -664,6 +669,7 @@ bool Asset::prep()
}
}
}
+ #endif
return true;
}
diff --git a/indra/newview/gltf/asset.h b/indra/newview/gltf/asset.h
index 27821659db..e70fffa986 100644
--- a/indra/newview/gltf/asset.h
+++ b/indra/newview/gltf/asset.h
@@ -286,6 +286,7 @@ namespace LL
void serialize(boost::json::object& dst) const;
};
+ // Image is for images that we want to load for the given asset. This acts as an interface into the viewer's texture pipe.
class Image
{
public:
@@ -301,6 +302,8 @@ namespace LL
S32 mBits = -1;
S32 mPixelType = -1;
+ bool mLoadIntoTexturePipe = false;
+
LLPointer<LLViewerFetchedTexture> mTexture;
const Image& operator=(const Value& src);
diff --git a/indra/llprimitive/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp
index 480012699a..106c20d4d3 100644
--- a/indra/llprimitive/llgltfloader.cpp
+++ b/indra/newview/gltf/llgltfloader.cpp
@@ -106,16 +106,7 @@ bool LLGLTFLoader::OpenFile(const std::string &filename)
std::string filename_lc(filename);
LLStringUtil::toLower(filename_lc);
- // Load a tinygltf model fom a file. Assumes that the input filename has already been
- // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish.
- if (std::string::npos == filename_lc.rfind(".gltf"))
- { // file is binary
- mGltfLoaded = loader.LoadBinaryFromFile(&mGltfModel, &error_msg, &warn_msg, filename);
- }
- else
- { // file is ascii
- mGltfLoaded = loader.LoadASCIIFromFile(&mGltfModel, &error_msg, &warn_msg, filename);
- }
+ mGltfLoaded = mGLTFAsset.load(filename);
if (!mGltfLoaded)
{
@@ -129,10 +120,14 @@ bool LLGLTFLoader::OpenFile(const std::string &filename)
mMeshesLoaded = parseMeshes();
if (mMeshesLoaded) uploadMeshes();
+ /*
mMaterialsLoaded = parseMaterials();
if (mMaterialsLoaded) uploadMaterials();
+ */
- return (mMeshesLoaded || mMaterialsLoaded);
+ setLoadState(DONE);
+
+ return (mMeshesLoaded);
}
bool LLGLTFLoader::parseMeshes()
@@ -143,71 +138,102 @@ bool LLGLTFLoader::parseMeshes()
LLVolumeParams volume_params;
volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
- for (tinygltf::Mesh mesh : mGltfModel.meshes)
+ for (auto node : mGLTFAsset.mNodes)
{
- LLModel *pModel = new LLModel(volume_params, 0.f);
+ LLMatrix4 transform;
+ material_map mats;
+ auto meshidx = node.mMesh;
- if (populateModelFromMesh(pModel, mesh) &&
- (LLModel::NO_ERRORS == pModel->getStatus()) &&
- validate_model(pModel))
+ if (meshidx >= 0)
{
- mModelList.push_back(pModel);
- }
- else
- {
- setLoadState(ERROR_MODEL + pModel->getStatus());
- delete(pModel);
- return false;
+ LLModel* pModel = new LLModel(volume_params, 0.f);
+ auto mesh = mGLTFAsset.mMeshes[meshidx];
+
+ if (populateModelFromMesh(pModel, mesh, mats) && (LLModel::NO_ERRORS == pModel->getStatus()) && validate_model(pModel))
+ {
+ mModelList.push_back(pModel);
+ LLVector3 mesh_scale_vector;
+ LLVector3 mesh_translation_vector;
+ pModel->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector);
+
+ LLMatrix4 mesh_translation;
+ mesh_translation.setTranslation(mesh_translation_vector);
+ mesh_translation *= transform;
+ transform = mesh_translation;
+
+ LLMatrix4 mesh_scale;
+ mesh_scale.initScale(mesh_scale_vector);
+ mesh_scale *= transform;
+ transform = mesh_scale;
+
+
+ mScene[transform].push_back(LLModelInstance(pModel, node.mName, transform, mats));
+ }
+ else
+ {
+ setLoadState(ERROR_MODEL + pModel->getStatus());
+ delete (pModel);
+ return false;
+ }
}
}
+
return true;
}
-
-bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh)
+
+bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, material_map &mats)
{
- pModel->mLabel = mesh.name;
- int pos_idx;
- tinygltf::Accessor indices_a, positions_a, normals_a, uv0_a, color0_a;
+ pModel->mLabel = mesh.mName;
+ pModel->ClearFacesAndMaterials();
- auto prims = mesh.primitives;
+ auto prims = mesh.mPrimitives;
for (auto prim : prims)
{
- if (prim.indices >= 0) indices_a = mGltfModel.accessors[prim.indices];
+ // So primitives already have all of the data we need for a given face in SL land.
+ // Primitives may only ever have a single material assigned to them - as the relation is 1:1 in terms of intended draw call count.
+ // Just go ahead and populate faces direct from the GLTF primitives here.
+ // -Geenz 2025-04-07
+ LLVolumeFace face;
+ LLVolumeFace::VertexMapData::PointMap point_map;
+
+ std::vector<LLVolumeFace::VertexData> vertices;
+ std::vector<U16> indices;
+
+ LLImportMaterial impMat;
+
+ auto material = mGLTFAsset.mMaterials[prim.mMaterial];
- pos_idx = (prim.attributes.count("POSITION") > 0) ? prim.attributes.at("POSITION") : -1;
- if (pos_idx >= 0)
+ impMat.mDiffuseColor = LLColor4::white;
+
+
+ for (U32 i = 0; i < prim.getVertexCount(); i++)
{
- positions_a = mGltfModel.accessors[pos_idx];
- if (TINYGLTF_COMPONENT_TYPE_FLOAT != positions_a.componentType)
- continue;
- auto positions_bv = mGltfModel.bufferViews[positions_a.bufferView];
- auto positions_buf = mGltfModel.buffers[positions_bv.buffer];
- //auto type = positions_vb.
- //if (positions_buf.name
+ LLVolumeFace::VertexData vert;
+ vert.setPosition(prim.mPositions[i]);
+ vert.setNormal(prim.mNormals[i]);
+ vert.mTexCoord = prim.mTexCoords0[i];
+ vertices.push_back(vert);
}
-#if 0
- int norm_idx, tan_idx, uv0_idx, uv1_idx, color0_idx, color1_idx;
- norm_idx = (prim.attributes.count("NORMAL") > 0) ? prim.attributes.at("NORMAL") : -1;
- tan_idx = (prim.attributes.count("TANGENT") > 0) ? prim.attributes.at("TANGENT") : -1;
- uv0_idx = (prim.attributes.count("TEXCOORDS_0") > 0) ? prim.attributes.at("TEXCOORDS_0") : -1;
- uv1_idx = (prim.attributes.count("TEXCOORDS_1") > 0) ? prim.attributes.at("TEXCOORDS_1") : -1;
- color0_idx = (prim.attributes.count("COLOR_0") > 0) ? prim.attributes.at("COLOR_0") : -1;
- color1_idx = (prim.attributes.count("COLOR_1") > 0) ? prim.attributes.at("COLOR_1") : -1;
-#endif
-
- if (prim.mode == TINYGLTF_MODE_TRIANGLES)
+ for (S32 i = 0; i < prim.mIndexArray.size(); i++)
{
- //auto pos = mesh. TODO resume here DJH 2022-04
+ indices.push_back(prim.mIndexArray[i]);
}
+
+ face.fillFromLegacyData(vertices, indices);
+
+ pModel->getVolumeFaces().push_back(face);
+ pModel->getMaterialList().push_back("mat" + std::to_string(prim.mMaterial));
+ mats["mat" + std::to_string(prim.mMaterial)] = impMat;
}
- //pModel->addFace()
- return false;
+ return true;
}
bool LLGLTFLoader::parseMaterials()
{
+ return true;
+ /*
if (!mGltfLoaded) return false;
// fill local texture data structures
@@ -329,12 +355,13 @@ bool LLGLTFLoader::parseMaterials()
}
return true;
+ */
}
// TODO: convert raw vertex buffers to UUIDs
void LLGLTFLoader::uploadMeshes()
{
- llassert(0);
+ //llassert(0);
}
// convert raw image buffers to texture UUIDs & assemble into a render material
diff --git a/indra/llprimitive/llgltfloader.h b/indra/newview/gltf/llgltfloader.h
index 66671d1c5a..3b7147f588 100644
--- a/indra/llprimitive/llgltfloader.h
+++ b/indra/newview/gltf/llgltfloader.h
@@ -29,6 +29,8 @@
#include "tinygltf/tiny_gltf.h"
+#include "asset.h"
+
#include "llglheaders.h"
#include "llmodelloader.h"
@@ -138,6 +140,7 @@ class LLGLTFLoader : public LLModelLoader
virtual bool OpenFile(const std::string &filename);
protected:
+ LL::GLTF::Asset mGLTFAsset;
tinygltf::Model mGltfModel;
bool mGltfLoaded;
bool mMeshesLoaded;
@@ -155,7 +158,7 @@ private:
void uploadMeshes();
bool parseMaterials();
void uploadMaterials();
- bool populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh);
+ bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, material_map& mats);
LLUUID imageBufferToTextureUUID(const gltf_texture& tex);
// bool mPreprocessGLTF;
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 716e6cd9e3..09a2206cd7 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -59,7 +59,7 @@ LLFilePicker LLFilePicker::sInstance;
#define XML_FILTER L"XML files (*.xml)\0*.xml\0"
#define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0"
#define RAW_FILTER L"RAW files (*.raw)\0*.raw\0"
-#define MODEL_FILTER L"Model files (*.dae)\0*.dae\0"
+#define MODEL_FILTER L"Model files (*.dae, *.gltf, *.glb)\0*.dae;*.gltf;*.glb\0"
#define MATERIAL_FILTER L"GLTF Files (*.gltf; *.glb)\0*.gltf;*.glb\0"
#define HDRI_FILTER L"HDRI Files (*.exr)\0*.exr\0"
#define MATERIAL_TEXTURES_FILTER L"GLTF Import (*.gltf; *.glb; *.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.gltf;*.glb;*.tga;*.bmp;*.jpg;*.jpeg;*.png\0"
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 5a8fd299bf..14d23b73c9 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -30,7 +30,7 @@
#include "llmodelloader.h"
#include "lldaeloader.h"
-#include "llgltfloader.h"
+#include "gltf/llgltfloader.h"
#include "llfloatermodelpreview.h"
#include "llagent.h"