diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 48ff2f3218..8f5cf7244f 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -6,6 +6,7 @@ A new header is inserted each time a *tag* is created. ## main branch - gltfio: punctual lights are now duplicated when adding new asset instances +- gltfio: FilamentInstance getAsset method now returns an immutable asset - gltfio: allow zero-instance assets - gltfio: fix regression with meshes that have no material - gltfio: fix regression with recomputeBoundingBoxes() diff --git a/libs/gltfio/include/gltfio/Animator.h b/libs/gltfio/include/gltfio/Animator.h index c8d3803f5f..199555a40d 100644 --- a/libs/gltfio/include/gltfio/Animator.h +++ b/libs/gltfio/include/gltfio/Animator.h @@ -105,7 +105,7 @@ private: /*! \endcond */ // If "instance" is null, then this is the primary animator. - Animator(FFilamentAsset* asset, FFilamentInstance* instance); + Animator(FFilamentAsset const* asset, FFilamentInstance* instance); ~Animator(); Animator(const Animator& animator) = delete; diff --git a/libs/gltfio/include/gltfio/FilamentInstance.h b/libs/gltfio/include/gltfio/FilamentInstance.h index ceed2fc5d5..bd3605e0e0 100644 --- a/libs/gltfio/include/gltfio/FilamentInstance.h +++ b/libs/gltfio/include/gltfio/FilamentInstance.h @@ -41,7 +41,7 @@ public: /** * Gets the owner of this instance. */ - FilamentAsset* getAsset() const noexcept; + FilamentAsset const* getAsset() const noexcept; /** * Gets the list of entities in this instance, one for each glTF node. All of these have a diff --git a/libs/gltfio/src/Animator.cpp b/libs/gltfio/src/Animator.cpp index e7a71d77ea..bb774561c1 100644 --- a/libs/gltfio/src/Animator.cpp +++ b/libs/gltfio/src/Animator.cpp @@ -70,7 +70,7 @@ struct Animation { struct AnimatorImpl { vector animations; BoneVector boneMatrices; - FFilamentAsset* asset = nullptr; + FFilamentAsset const* asset = nullptr; FFilamentInstance* instance = nullptr; RenderableManager* renderableManager; TransformManager* transformManager; @@ -176,7 +176,7 @@ static bool validateAnimation(const cgltf_animation& anim) { return true; } -Animator::Animator(FFilamentAsset* asset, FFilamentInstance* instance) { +Animator::Animator(FFilamentAsset const* asset, FFilamentInstance* instance) { assert(asset->mResourcesLoaded && asset->mSourceAsset); mImpl = new AnimatorImpl(); mImpl->asset = asset; diff --git a/libs/gltfio/src/AssetLoader.cpp b/libs/gltfio/src/AssetLoader.cpp index 28fd3975b5..9ebce2d88a 100644 --- a/libs/gltfio/src/AssetLoader.cpp +++ b/libs/gltfio/src/AssetLoader.cpp @@ -106,9 +106,9 @@ static const char* getNodeName(const cgltf_node* node, const char* defaultNodeNa return defaultNodeName; } -static bool primitiveHasVertexColor(const cgltf_primitive* inPrim) { - for (int slot = 0; slot < inPrim->attributes_count; slot++) { - const cgltf_attribute& inputAttribute = inPrim->attributes[slot]; +static bool primitiveHasVertexColor(const cgltf_primitive& inPrim) { + for (int slot = 0; slot < inPrim.attributes_count; slot++) { + const cgltf_attribute& inputAttribute = inPrim.attributes[slot]; if (inputAttribute.type == cgltf_attribute_type_color) { return true; } @@ -223,7 +223,7 @@ private: void createRootAsset(const cgltf_data* srcAsset); void recursePrimitives(const cgltf_data* srcAsset, const cgltf_node* rootNode); void createPrimitives(const cgltf_data* srcAsset, const cgltf_node* node, const char* name); - bool createPrimitive(const cgltf_primitive* inPrim, Primitive* outPrim, const char* name); + bool createPrimitive(const cgltf_primitive& inPrim, Primitive* outPrim, const char* name); // Methods used during subsequent traverals (creation of entities, renderables, etc) void createInstances(const cgltf_data* srcAsset, size_t numInstances); @@ -448,6 +448,7 @@ void FAssetLoader::recursePrimitives(const cgltf_data* srcAsset, const cgltf_nod if (node->mesh) { createPrimitives(srcAsset, node, name); + mAsset->mRenderableCount++; } for (cgltf_size i = 0, len = node->children_count; i < len; ++i) { @@ -456,8 +457,6 @@ void FAssetLoader::recursePrimitives(const cgltf_data* srcAsset, const cgltf_nod } void FAssetLoader::createInstances(const cgltf_data* srcAsset, size_t numInstances) { - mAsset->mRenderableCount = 0; - // Create a separate entity hierarchy for each instance. Note that MeshCache (vertex // buffers and index buffers) and MaterialInstanceCache (materials and textures) help avoid // needless duplication of resources. @@ -605,7 +604,7 @@ void FAssetLoader::createPrimitives(const cgltf_data* srcAsset, const cgltf_node const cgltf_primitive& inputPrim = mesh->primitives[index]; // Create a Filament VertexBuffer and IndexBuffer for this prim if we haven't already. - if (!outputPrim.vertices && !createPrimitive(&inputPrim, &outputPrim, name)) { + if (!outputPrim.vertices && !createPrimitive(inputPrim, &outputPrim, name)) { mError = true; return; } @@ -660,7 +659,7 @@ void FAssetLoader::createRenderable(const cgltf_data* srcAsset, const cgltf_node // Create a material instance for this primitive or fetch one from the cache. UvMap uvmap {}; - bool hasVertexColor = primitiveHasVertexColor(inputPrim); + bool hasVertexColor = primitiveHasVertexColor(*inputPrim); MaterialInstance* mi = createMaterialInstance(srcAsset, inputPrim->material, &uvmap, hasVertexColor); assert_invariant(mi); @@ -731,18 +730,16 @@ void FAssetLoader::createRenderable(const cgltf_data* srcAsset, const cgltf_node } mRenderableManager.setMorphWeights(renderable, weights.data(), size); } - - ++mAsset->mRenderableCount; } void FAssetLoader::createMaterialVariants(const cgltf_data* srcAsset, const cgltf_mesh* mesh, Entity entity, FFilamentInstance* instance) { UvMap uvmap {}; for (cgltf_size prim = 0, n = mesh->primitives_count; prim < n; ++prim) { - const cgltf_primitive* srcPrim = &mesh->primitives[prim]; - for (size_t i = 0, m = srcPrim->mappings_count; i < m; i++) { - const size_t variantIndex = srcPrim->mappings[i].variant; - const cgltf_material* material = srcPrim->mappings[i].material; + const cgltf_primitive& srcPrim = mesh->primitives[prim]; + for (size_t i = 0, m = srcPrim.mappings_count; i < m; i++) { + const size_t variantIndex = srcPrim.mappings[i].variant; + const cgltf_material* material = srcPrim.mappings[i].material; assert_invariant(variantIndex < mAsset->mVariants.size()); if (variantIndex >= mAsset->mVariants.size()) { mError = true; @@ -763,10 +760,10 @@ void FAssetLoader::createMaterialVariants(const cgltf_data* srcAsset, const cglt } } -bool FAssetLoader::createPrimitive(const cgltf_primitive* inPrim, Primitive* outPrim, +bool FAssetLoader::createPrimitive(const cgltf_primitive& inPrim, Primitive* outPrim, const char* name) { Material* material = getMaterial(mAsset->mSourceAsset->hierarchy, - inPrim->material, &outPrim->uvmap, primitiveHasVertexColor(inPrim)); + inPrim.material, &outPrim->uvmap, primitiveHasVertexColor(inPrim)); AttributeBitset requiredAttributes = material->getRequiredAttributes(); // TODO: populate a mapping of Texture Index => [MaterialInstance, const char*] slots. @@ -782,7 +779,7 @@ bool FAssetLoader::createPrimitive(const cgltf_primitive* inPrim, Primitive* out // In glTF, each primitive may or may not have an index buffer. IndexBuffer* indices = nullptr; - const cgltf_accessor* accessor = inPrim->indices; + const cgltf_accessor* accessor = inPrim.indices; if (accessor) { IndexBuffer::IndexType indexType; if (!getIndexType(accessor->component_type, &indexType)) { @@ -798,9 +795,9 @@ bool FAssetLoader::createPrimitive(const cgltf_primitive* inPrim, Primitive* out BufferSlot slot = { accessor }; slot.indexBuffer = indices; addBufferSlot(slot); - } else if (inPrim->attributes_count > 0) { + } else if (inPrim.attributes_count > 0) { // If a primitive does not have an index buffer, generate a trivial one now. - const uint32_t vertexCount = inPrim->attributes[0].data->count; + const uint32_t vertexCount = inPrim.attributes[0].data->count; indices = IndexBuffer::Builder() .indexCount(vertexCount) @@ -826,8 +823,8 @@ bool FAssetLoader::createPrimitive(const cgltf_primitive* inPrim, Primitive* out const size_t firstSlot = mAsset->mBufferSlots.size(); int slot = 0; - for (cgltf_size aindex = 0; aindex < inPrim->attributes_count; aindex++) { - const cgltf_attribute& attribute = inPrim->attributes[aindex]; + for (cgltf_size aindex = 0; aindex < inPrim.attributes_count; aindex++) { + const cgltf_attribute& attribute = inPrim.attributes[aindex]; const int index = attribute.index; const cgltf_attribute_type atype = attribute.type; const cgltf_accessor* accessor = attribute.data; @@ -932,7 +929,7 @@ bool FAssetLoader::createPrimitive(const cgltf_primitive* inPrim, Primitive* out addBufferSlot({&mAsset->mGenerateNormals, atype, slot++}); } - cgltf_size targetsCount = inPrim->targets_count; + cgltf_size targetsCount = inPrim.targets_count; if (targetsCount > MAX_MORPH_TARGETS) { utils::slog.w << "WARNING: Exceeded max morph target count of " @@ -941,7 +938,7 @@ bool FAssetLoader::createPrimitive(const cgltf_primitive* inPrim, Primitive* out } for (cgltf_size targetIndex = 0; targetIndex < targetsCount; targetIndex++) { - const cgltf_morph_target& morphTarget = inPrim->targets[targetIndex]; + const cgltf_morph_target& morphTarget = inPrim.targets[targetIndex]; for (cgltf_size aindex = 0; aindex < morphTarget.attributes_count; aindex++) { const cgltf_attribute& attribute = morphTarget.attributes[aindex]; const cgltf_accessor* accessor = attribute.data; @@ -1025,7 +1022,7 @@ bool FAssetLoader::createPrimitive(const cgltf_primitive* inPrim, Primitive* out outPrim->indices = indices; outPrim->vertices = vertices; - mAsset->mPrimitives.push_back({inPrim, vertices}); + mAsset->mPrimitives.push_back({&inPrim, vertices}); mAsset->mVertexBuffers.push_back(vertices); for (size_t i = firstSlot; i < mAsset->mBufferSlots.size(); ++i) { @@ -1041,7 +1038,7 @@ bool FAssetLoader::createPrimitive(const cgltf_primitive* inPrim, Primitive* out mAsset->mMorphTargetBuffers.push_back(targets); const cgltf_accessor* previous = nullptr; for (int tindex = 0; tindex < targetsCount; ++tindex) { - const cgltf_morph_target& inTarget = inPrim->targets[tindex]; + const cgltf_morph_target& inTarget = inPrim.targets[tindex]; for (cgltf_size aindex = 0; aindex < inTarget.attributes_count; ++aindex) { const cgltf_attribute& attribute = inTarget.attributes[aindex]; const cgltf_accessor* accessor = attribute.data; diff --git a/libs/gltfio/src/FFilamentInstance.h b/libs/gltfio/src/FFilamentInstance.h index fc7960d878..13f7ade493 100644 --- a/libs/gltfio/src/FFilamentInstance.h +++ b/libs/gltfio/src/FFilamentInstance.h @@ -54,7 +54,7 @@ struct Variant { }; struct FFilamentInstance : public FilamentInstance { - FFilamentInstance(utils::Entity root, FFilamentAsset* owner); + FFilamentInstance(utils::Entity root, FFilamentAsset const* owner); // The per-instance skin structure caches information to allow animation to be applied // efficiently at run time. Note that shared immutable data, such as the skin name and inverse @@ -69,7 +69,7 @@ struct FFilamentInstance : public FilamentInstance { }; const utils::Entity root; - FFilamentAsset* const owner; + FFilamentAsset const* owner; std::vector entities; utils::FixedCapacityVector variants; diff --git a/libs/gltfio/src/FilamentInstance.cpp b/libs/gltfio/src/FilamentInstance.cpp index 08dff111d6..018c55812c 100644 --- a/libs/gltfio/src/FilamentInstance.cpp +++ b/libs/gltfio/src/FilamentInstance.cpp @@ -28,7 +28,7 @@ using namespace utils; namespace filament::gltfio { -FFilamentInstance::FFilamentInstance(Entity root, FFilamentAsset* owner) : +FFilamentInstance::FFilamentInstance(Entity root, FFilamentAsset const* owner) : root(root), owner(owner), nodeMap(owner->mSourceAsset->hierarchy->nodes_count, Entity()) {} @@ -285,7 +285,7 @@ void FFilamentInstance::recomputeBoundingBoxes() { boundingBox = assetBounds; } -FilamentAsset* FilamentInstance::getAsset() const noexcept { +FilamentAsset const* FilamentInstance::getAsset() const noexcept { return upcast(this)->owner; }