gltfio: FilamentInstance owner is now const.

In the future, we will allow instances to be constructed from
immutable assets (this is a Google feature request) so this PR
prepares for that.
This commit is contained in:
Philip Rideout
2022-09-16 15:16:18 -07:00
parent b0fb52c5f4
commit 034aaff56c
7 changed files with 31 additions and 33 deletions

View File

@@ -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()

View File

@@ -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;

View File

@@ -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

View File

@@ -70,7 +70,7 @@ struct Animation {
struct AnimatorImpl {
vector<Animation> 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;

View File

@@ -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;

View File

@@ -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<utils::Entity> entities;
utils::FixedCapacityVector<Variant> variants;

View File

@@ -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;
}