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