From 9159258b503f7970b0fa05dea0053c1a61eeefde Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 16 Oct 2019 17:42:36 -0700 Subject: [PATCH 1/3] clean ups --- .../render-utils/src/CauterizedModel.cpp | 145 +++--------------- libraries/render-utils/src/Model.cpp | 69 +-------- 2 files changed, 33 insertions(+), 181 deletions(-) diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index cbd608e092..717d3cada7 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -32,31 +32,9 @@ bool CauterizedModel::updateGeometry() { bool needsFullUpdate = Model::updateGeometry(); if (_isCauterized && needsFullUpdate) { assert(_cauterizeMeshStates.empty()); - /* const HFMModel& hfmModel = getHFMModel(); - const auto& hfmDynamicTransforms = hfmModel.skinDeformers; - for (int i = 0; i < hfmDynamicTransforms.size(); i++) { - const auto& dynT = hfmDynamicTransforms[i]; - MeshState state; - if (_useDualQuaternionSkinning) { - state.clusterDualQuaternions.resize(dynT.clusters.size()); - } else { - state.clusterMatrices.resize(dynT.clusters.size()); - } - _cauterizeMeshStates.append(state); - _meshStates.push_back(state); - }*/ const HFMModel& hfmModel = getHFMModel(); const auto& hfmDynamicTransforms = hfmModel.skinDeformers; - int i = 0; - /* for (const auto& mesh: hfmModel.meshes) { - MeshState state; - state.clusterDualQuaternions.resize(mesh.clusters.size()); - state.clusterMatrices.resize(mesh.clusters.size()); - _meshStates.push_back(state); - i++; - } - */ for (int i = 0; i < hfmDynamicTransforms.size(); i++) { const auto& dynT = hfmDynamicTransforms[i]; MeshState state; @@ -64,17 +42,6 @@ bool CauterizedModel::updateGeometry() { state.clusterMatrices.resize(dynT.clusters.size()); _cauterizeMeshStates.push_back(state); } - - /* foreach (const HFMMesh& mesh, hfmModel.meshes) { - Model::MeshState state; - if (_useDualQuaternionSkinning) { - state.clusterDualQuaternions.resize(mesh.clusters.size()); - _cauterizeMeshStates.append(state); - } else { - state.clusterMatrices.resize(mesh.clusters.size()); - _cauterizeMeshStates.append(state); - } - }*/ } return needsFullUpdate; } @@ -103,7 +70,6 @@ void CauterizedModel::createRenderItemSet() { Transform::mult(transform, transform, offset); // Run through all of the meshes, and place them into their segregated, but unsorted buckets - // Run through all of the meshes, and place them into their segregated, but unsorted buckets int shapeID = 0; const auto& shapes = _renderGeometry->getHFMModel().shapes; for (shapeID; shapeID < shapes.size(); shapeID++) { @@ -115,26 +81,6 @@ void CauterizedModel::createRenderItemSet() { _modelMeshMaterialNames.push_back(material ? material->getName() : ""); _modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)shape.mesh, shape.skinDeformer }); } - -/* int shapeID = 0; - uint32_t numMeshes = (uint32_t)meshes.size(); - for (uint32_t i = 0; i < numMeshes; i++) { - const auto& mesh = meshes.at(i); - if (!mesh) { - continue; - } - - // Create the render payloads - int numParts = (int)mesh->getNumParts(); - for (int partIndex = 0; partIndex < numParts; partIndex++) { - auto ptr = std::make_shared(shared_from_this(), i, partIndex, shapeID, transform); - _modelMeshRenderItems << std::static_pointer_cast(ptr); - auto material = getNetworkModel()->getShapeMaterial(shapeID); - _modelMeshMaterialNames.push_back(material ? material->getName() : ""); - _modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)i }); - shapeID++; - } - }*/ } else { Model::createRenderItemSet(); } @@ -153,17 +99,13 @@ void CauterizedModel::updateClusterMatrices() { const HFMModel& hfmModel = getHFMModel(); - const auto& hfmDynamicTransforms = hfmModel.skinDeformers; - for (int i = 0; i < (int)_meshStates.size(); i++) { - MeshState& state = _meshStates[i]; - const auto& deformer = hfmDynamicTransforms[i]; + const auto& hfmSkinDeformers = hfmModel.skinDeformers; + for (int meshIndex = 0; meshIndex < (int)_meshStates.size(); meshIndex++) { + MeshState& state = _meshStates[meshIndex]; + const auto& deformer = hfmSkinDeformers[meshIndex]; - int meshIndex = i; - int clusterIndex = 0; - - for (int d = 0; d < deformer.clusters.size(); d++) { - const auto& cluster = deformer.clusters[d]; - clusterIndex = d; + for (int clusterIndex = 0; clusterIndex < deformer.clusters.size(); clusterIndex++) { + const auto& cluster = deformer.clusters[clusterIndex]; const auto& cbmov = _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex); @@ -172,40 +114,14 @@ void CauterizedModel::updateClusterMatrices() { Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); Transform clusterTransform; Transform::mult(clusterTransform, jointTransform, cbmov.inverseBindTransform); - state.clusterDualQuaternions[d] = Model::TransformDualQuaternion(clusterTransform); - } - else { - auto jointMatrix = _rig.getJointTransform(cluster.jointIndex); - glm_mat4u_mul(jointMatrix, cbmov.inverseBindMatrix, state.clusterMatrices[d]); - } - - } - } -/* - const HFMModel& hfmModel = getHFMModel(); - for (int i = 0; i < (int)_meshStates.size(); i++) { - Model::MeshState& state = _meshStates[i]; - const HFMMesh& mesh = hfmModel.meshes.at(i); - int meshIndex = i; - - for (int j = 0; j < mesh.clusters.size(); j++) { - const HFMCluster& cluster = mesh.clusters.at(j); - int clusterIndex = j; - - if (_useDualQuaternionSkinning) { - auto jointPose = _rig.getJointPose(cluster.jointIndex); - Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); - Transform clusterTransform; - Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindTransform); - state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform); - state.clusterDualQuaternions[j].setCauterizationParameters(0.0f, jointPose.trans()); + state.clusterDualQuaternions[clusterIndex] = Model::TransformDualQuaternion(clusterTransform); } else { auto jointMatrix = _rig.getJointTransform(cluster.jointIndex); - glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]); + glm_mat4u_mul(jointMatrix, cbmov.inverseBindMatrix, state.clusterMatrices[clusterIndex]); } } } -*/ + // as an optimization, don't build cautrizedClusterMatrices if the boneSet is empty. if (!_cauterizeBoneSet.empty()) { @@ -219,32 +135,32 @@ void CauterizedModel::updateClusterMatrices() { glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); auto cauterizeMatrix = _rig.getJointTransform(_rig.indexOfJoint("Neck")) * zeroScale; - for (int i = 0; i < _cauterizeMeshStates.size(); i++) { - Model::MeshState& state = _cauterizeMeshStates[i]; - const HFMMesh& mesh = hfmModel.meshes.at(i); - int meshIndex = i; + for (int meshIndex = 0; meshIndex < _cauterizeMeshStates.size(); meshIndex++) { + Model::MeshState& state = _cauterizeMeshStates[meshIndex]; + const auto& deformer = hfmSkinDeformers[meshIndex]; - for (int j = 0; j < mesh.clusters.size(); j++) { - const HFMCluster& cluster = mesh.clusters.at(j); - int clusterIndex = j; + for (int clusterIndex = 0; clusterIndex < deformer.clusters.size(); clusterIndex++) { + const auto& cluster = deformer.clusters[clusterIndex]; + + const auto& cbmov = _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex); if (_useDualQuaternionSkinning) { if (_cauterizeBoneSet.find(cluster.jointIndex) == _cauterizeBoneSet.end()) { // not cauterized so just copy the value from the non-cauterized version. - state.clusterDualQuaternions[j] = _meshStates[i].clusterDualQuaternions[j]; + state.clusterDualQuaternions[clusterIndex] = _meshStates[meshIndex].clusterDualQuaternions[clusterIndex]; } else { Transform jointTransform(cauterizePose.rot(), cauterizePose.scale(), cauterizePose.trans()); Transform clusterTransform; - Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindTransform); - state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform); - state.clusterDualQuaternions[j].setCauterizationParameters(1.0f, cauterizePose.trans()); + Transform::mult(clusterTransform, jointTransform, cbmov.inverseBindTransform); + state.clusterDualQuaternions[clusterIndex] = Model::TransformDualQuaternion(clusterTransform); + state.clusterDualQuaternions[clusterIndex].setCauterizationParameters(1.0f, cauterizePose.trans()); } } else { if (_cauterizeBoneSet.find(cluster.jointIndex) == _cauterizeBoneSet.end()) { // not cauterized so just copy the value from the non-cauterized version. - state.clusterMatrices[j] = _meshStates[i].clusterMatrices[j]; + state.clusterMatrices[clusterIndex] = _meshStates[meshIndex].clusterMatrices[clusterIndex]; } else { - glm_mat4u_mul(cauterizeMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]); + glm_mat4u_mul(cauterizeMatrix, cbmov.inverseBindMatrix, state.clusterMatrices[clusterIndex]); } } } @@ -302,18 +218,9 @@ void CauterizedModel::updateRenderItems() { auto deformerIndex = self->_modelMeshRenderItemShapes[i].deformerIndex; bool isDeformed = (deformerIndex != hfm::UNDEFINED_KEY); - - // auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex; - // auto deformerIndex = self->_modelMeshRenderItemShapes[i].meshIndex; - - // const auto& shapeState = self->getShapeState(i); - - bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex); bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning(); - - if (isDeformed) { const auto& meshState = self->getMeshState(deformerIndex); @@ -324,12 +231,10 @@ void CauterizedModel::updateRenderItems() { primitiveMode, renderItemKeyGlobalFlags, enableCauterization](ModelMeshPartPayload& mmppData) { CauterizedMeshPartPayload& data = static_cast(mmppData); if (useDualQuaternionSkinning) { - data.updateClusterBuffer(meshState.clusterDualQuaternions, - cauterizedMeshState.clusterDualQuaternions); + data.updateClusterBuffer(meshState.clusterDualQuaternions, cauterizedMeshState.clusterDualQuaternions); } else { - data.updateClusterBuffer(meshState.clusterMatrices, - cauterizedMeshState.clusterMatrices); - } + data.updateClusterBuffer(meshState.clusterMatrices, cauterizedMeshState.clusterMatrices); + } Transform renderTransform = modelTransform; // if (meshState.clusterMatrices.size() <= 2) { diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index d3766fa65c..6df3c76a67 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -270,9 +270,7 @@ void Model::updateRenderItems() { transaction.updateItem(itemID, [modelTransform, shapeState, invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags](ModelMeshPartPayload& data) { Transform renderTransform = modelTransform; - // if (meshState.clusterMatrices.size() <= 1) { renderTransform = modelTransform.worldTransform(shapeState._rootFromJointTransform); - // } data.updateTransform(renderTransform); data.updateKey(renderItemKeyGlobalFlags); @@ -337,15 +335,6 @@ bool Model::updateGeometry() { const HFMModel& hfmModel = getHFMModel(); const auto& hfmSkinDeformers = hfmModel.skinDeformers; - int i = 0; - /* for (const auto& mesh: hfmModel.meshes) { - MeshState state; - state.clusterDualQuaternions.resize(mesh.clusters.size()); - state.clusterMatrices.resize(mesh.clusters.size()); - _meshStates.push_back(state); - i++; - } - */ for (int i = 0; i < hfmSkinDeformers.size(); i++) { const auto& dynT = hfmSkinDeformers[i]; MeshState state; @@ -1428,16 +1417,12 @@ void Model::updateClusterMatrices() { _needsUpdateClusterMatrices = false; const HFMModel& hfmModel = getHFMModel(); const auto& hfmSkinDeformers = hfmModel.skinDeformers; - for (int i = 0; i < (int) _meshStates.size(); i++) { - MeshState& state = _meshStates[i]; - const auto& deformer = hfmSkinDeformers[i]; + for (int meshIndex = 0; meshIndex < (int) _meshStates.size(); meshIndex++) { + MeshState& state = _meshStates[meshIndex]; + const auto& deformer = hfmSkinDeformers[meshIndex]; - int meshIndex = i; - int clusterIndex = 0; - - for (int d = 0; d < deformer.clusters.size(); d++) { - const auto& cluster = deformer.clusters[d]; - clusterIndex = d; + for (int clusterIndex = 0; clusterIndex < deformer.clusters.size(); clusterIndex++) { + const auto& cluster = deformer.clusters[clusterIndex]; const auto& cbmov = _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex); @@ -1446,32 +1431,12 @@ void Model::updateClusterMatrices() { Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); Transform clusterTransform; Transform::mult(clusterTransform, jointTransform, cbmov.inverseBindTransform); - state.clusterDualQuaternions[d] = Model::TransformDualQuaternion(clusterTransform); - } - else { - auto jointMatrix = _rig.getJointTransform(cluster.jointIndex); - glm_mat4u_mul(jointMatrix, cbmov.inverseBindMatrix, state.clusterMatrices[d]); - } - - } -/* - int meshIndex = i; - const HFMMesh& mesh = hfmModel.meshes.at(i); - for (int j = 0; j < mesh.clusters.size(); j++) { - const HFMCluster& cluster = mesh.clusters.at(j); - int clusterIndex = j; - - if (_useDualQuaternionSkinning) { - auto jointPose = _rig.getJointPose(cluster.jointIndex); - Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); - Transform clusterTransform; - Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindTransform); - state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform); + state.clusterDualQuaternions[clusterIndex] = Model::TransformDualQuaternion(clusterTransform); } else { auto jointMatrix = _rig.getJointTransform(cluster.jointIndex); - glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]); + glm_mat4u_mul(jointMatrix, cbmov.inverseBindMatrix, state.clusterMatrices[clusterIndex]); } - }*/ + } } // post the blender if we're not currently waiting for one to finish @@ -1547,24 +1512,6 @@ void Model::createRenderItemSet() { _modelMeshMaterialNames.push_back(material ? material->getName() : ""); _modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)shape.mesh, shape.skinDeformer }); } -/* - uint32_t numMeshes = (uint32_t)meshes.size(); - for (uint32_t i = 0; i < numMeshes; i++) { - const auto& mesh = meshes.at(i); - if (!mesh) { - continue; - } - - // Create the render payloads - int numParts = (int)mesh->getNumParts(); - for (int partIndex = 0; partIndex < numParts; partIndex++) { - _modelMeshRenderItems << std::make_shared(shared_from_this(), i, partIndex, shapeID, transform); - auto material = getNetworkModel()->getShapeMaterial(shapeID); - _modelMeshMaterialNames.push_back(material ? material->getName() : ""); - _modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)i }); - shapeID++; - } - }*/ } bool Model::isRenderable() const { From 55ed7d9a5312c4c2163528411d0e801b419b962e Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 17 Oct 2019 14:53:32 -0700 Subject: [PATCH 2/3] Add support for shape generation for obj serializer --- libraries/fbx/src/OBJSerializer.cpp | 43 ++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/libraries/fbx/src/OBJSerializer.cpp b/libraries/fbx/src/OBJSerializer.cpp index e1fc85ca2a..0c795d3a94 100644 --- a/libraries/fbx/src/OBJSerializer.cpp +++ b/libraries/fbx/src/OBJSerializer.cpp @@ -678,14 +678,17 @@ HFMModel::Pointer OBJSerializer::read(const hifi::ByteArray& data, const hifi::V hfmModel.meshExtents.reset(); hfmModel.meshes.push_back(HFMMesh()); + std::vector materialNamePerShape; try { // call parseOBJGroup as long as it's returning true. Each successful call will // add a new meshPart to the model's single mesh. while (parseOBJGroup(tokenizer, mapping, hfmModel, scaleGuess, combineParts)) {} - HFMMesh& mesh = hfmModel.meshes[0]; - mesh.meshIndex = 0; + uint32_t meshIndex = 0; + HFMMesh& mesh = hfmModel.meshes[meshIndex]; + mesh.meshIndex = meshIndex; + uint32_t jointIndex = 0; hfmModel.joints.resize(1); hfmModel.joints[0].parentIndex = -1; hfmModel.joints[0].distanceToParent = 0; @@ -697,14 +700,6 @@ HFMModel::Pointer OBJSerializer::read(const hifi::ByteArray& data, const hifi::V hfmModel.jointIndices["x"] = 1; - HFMCluster cluster; - cluster.jointIndex = 0; - cluster.inverseBindMatrix = glm::mat4(1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1); - mesh.clusters.append(cluster); - QMap materialMeshIdMap; std::vector hfmMeshParts; for (uint32_t i = 0, meshPartCount = 0; i < (uint32_t)mesh.parts.size(); i++, meshPartCount++) { @@ -718,12 +713,13 @@ HFMModel::Pointer OBJSerializer::read(const hifi::ByteArray& data, const hifi::V // Create a new HFMMesh for this material mapping. materialMeshIdMap.insert(face.materialName, materialMeshIdMap.count()); + uint32_t partIndex = (int)hfmMeshParts.size(); hfmMeshParts.push_back(HFMMeshPart()); HFMMeshPart& meshPartNew = hfmMeshParts.back(); meshPartNew.quadIndices = QVector(meshPart.quadIndices); // Copy over quad indices [NOTE (trent/mittens, 4/3/17): Likely unnecessary since they go unused anyway]. meshPartNew.quadTrianglesIndices = QVector(meshPart.quadTrianglesIndices); // Copy over quad triangulated indices [NOTE (trent/mittens, 4/3/17): Likely unnecessary since they go unused anyway]. meshPartNew.triangleIndices = QVector(meshPart.triangleIndices); // Copy over triangle indices. - + // Do some of the material logic (which previously lived below) now. // All the faces in the same group will have the same name and material. QString groupMaterialName = face.materialName; @@ -745,8 +741,15 @@ HFMModel::Pointer OBJSerializer::read(const hifi::ByteArray& data, const hifi::V needsMaterialLibrary = groupMaterialName != SMART_DEFAULT_MATERIAL_NAME; } materials[groupMaterialName] = material; - meshPartNew.materialID = groupMaterialName; + materialNamePerShape.push_back(groupMaterialName); } + + + hfm::Shape shape; + shape.mesh = meshIndex; + shape.joint = jointIndex; + shape.meshPart = partIndex; + hfmModel.shapes.push_back(shape); } } } @@ -829,12 +832,15 @@ HFMModel::Pointer OBJSerializer::read(const hifi::ByteArray& data, const hifi::V mesh.meshExtents.addPoint(vertex); hfmModel.meshExtents.addPoint(vertex); } - + // hfmDebugDump(hfmModel); } catch(const std::exception& e) { qCDebug(modelformat) << "OBJSerializer fail: " << e.what(); } + // At this point, the hfmModel joint, mesh, parts and shpaes have been defined + // only no material assigned + QString queryPart = _url.query(); bool suppressMaterialsHack = queryPart.contains("hifiusemat"); // If this appears in query string, don't fetch mtl even if used. OBJMaterial& preDefinedMaterial = materials[SMART_DEFAULT_MATERIAL_NAME]; @@ -886,6 +892,8 @@ HFMModel::Pointer OBJSerializer::read(const hifi::ByteArray& data, const hifi::V } } + // As we are populating the material list in the hfmModel, let s also create the reverse map (from materialName to index) + QMap materialNameToIndex; foreach (QString materialID, materials.keys()) { OBJMaterial& objMaterial = materials[materialID]; if (!objMaterial.used) { @@ -898,6 +906,7 @@ HFMModel::Pointer OBJSerializer::read(const hifi::ByteArray& data, const hifi::V objMaterial.shininess, objMaterial.opacity); HFMMaterial& hfmMaterial = hfmModel.materials.back(); + materialNameToIndex[materialID] = hfmModel.materials.size(); hfmMaterial.name = materialID; hfmMaterial.materialID = materialID; @@ -997,6 +1006,14 @@ HFMModel::Pointer OBJSerializer::read(const hifi::ByteArray& data, const hifi::V modelMaterial->setOpacity(hfmMaterial.opacity); } + // GO over the shapes once more to assign hte material index correctly + for (int i = 0; i < hfmModel.shapes.size(); ++i) { + auto foundMaterialIndex = materialNameToIndex.find(materialNamePerShape[i]); + if (foundMaterialIndex != materialNameToIndex.end()) { + hfmModel.shapes[i].material = foundMaterialIndex.value(); + } + } + return hfmModelPtr; } From bd57cc7b1499c0541fa057f649a6fec057503ce4 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 17 Oct 2019 15:56:41 -0700 Subject: [PATCH 3/3] Fixing bad indexing --- libraries/fbx/src/OBJSerializer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/fbx/src/OBJSerializer.cpp b/libraries/fbx/src/OBJSerializer.cpp index 0c795d3a94..8384a3e4b8 100644 --- a/libraries/fbx/src/OBJSerializer.cpp +++ b/libraries/fbx/src/OBJSerializer.cpp @@ -899,6 +899,10 @@ HFMModel::Pointer OBJSerializer::read(const hifi::ByteArray& data, const hifi::V if (!objMaterial.used) { continue; } + qCDebug(modelformat) << "OBJSerializer Material Name:" << materialID; + + // capture the name to index map + materialNameToIndex[materialID] = hfmModel.materials.size(); hfmModel.materials.emplace_back(objMaterial.diffuseColor, objMaterial.specularColor, @@ -906,7 +910,6 @@ HFMModel::Pointer OBJSerializer::read(const hifi::ByteArray& data, const hifi::V objMaterial.shininess, objMaterial.opacity); HFMMaterial& hfmMaterial = hfmModel.materials.back(); - materialNameToIndex[materialID] = hfmModel.materials.size(); hfmMaterial.name = materialID; hfmMaterial.materialID = materialID;