diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 2e96cdb4ac..b713a882cb 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -595,6 +595,9 @@ bool RenderableModelEntityItem::isReadyToComputeShape() { } void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { + const uint32_t TRIANGLE_STRIDE = 3; + const uint32_t QUAD_STRIDE = 4; + ShapeType type = getShapeType(); glm::vec3 dimensions = getDimensions(); if (type == SHAPE_TYPE_COMPOUND) { @@ -611,8 +614,6 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { // the way OBJ files get read, each section under a "g" line is its own meshPart. We only expect // to find one actual "mesh" (with one or more meshParts in it), but we loop over the meshes, just in case. - const uint32_t TRIANGLE_STRIDE = 3; - const uint32_t QUAD_STRIDE = 4; foreach (const FBXMesh& mesh, collisionGeometry.meshes) { // each meshPart is a convex hull foreach (const FBXMeshPart &meshPart, mesh.parts) { @@ -621,7 +622,10 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { // run through all the triangles and (uniquely) add each point to the hull uint32_t numIndices = (uint32_t)meshPart.triangleIndices.size(); - assert(numIndices % TRIANGLE_STRIDE == 0); + // TODO: assert rather than workaround after we start sanitizing FBXMesh higher up + //assert(numIndices % TRIANGLE_STRIDE == 0); + numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader + for (uint32_t j = 0; j < numIndices; j += TRIANGLE_STRIDE) { glm::vec3 p0 = mesh.vertices[meshPart.triangleIndices[j]]; glm::vec3 p1 = mesh.vertices[meshPart.triangleIndices[j + 1]]; @@ -639,7 +643,10 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { // run through all the quads and (uniquely) add each point to the hull numIndices = (uint32_t)meshPart.quadIndices.size(); - assert(numIndices % QUAD_STRIDE == 0); + // TODO: assert rather than workaround after we start sanitizing FBXMesh higher up + //assert(numIndices % QUAD_STRIDE == 0); + numIndices -= numIndices % QUAD_STRIDE; // WORKAROUND lack of sanity checking in FBXReader + for (uint32_t j = 0; j < numIndices; j += QUAD_STRIDE) { glm::vec3 p0 = mesh.vertices[meshPart.quadIndices[j]]; glm::vec3 p1 = mesh.vertices[meshPart.quadIndices[j + 1]]; @@ -768,24 +775,30 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { triangleIndices.reserve((int32_t)((gpu::Size)(triangleIndices.size()) + indices.getNumElements())); gpu::BufferView::Iterator partItr = parts.cbegin(); while (partItr != parts.cend()) { + auto numIndices = partItr->_numIndices; if (partItr->_topology == model::Mesh::TRIANGLES) { - assert(partItr->_numIndices % 3 == 0); + // TODO: assert rather than workaround after we start sanitizing FBXMesh higher up + //assert(numIndices % TRIANGLE_STRIDE == 0); + numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader + auto indexItr = indices.cbegin() + partItr->_startIndex; - auto indexEnd = indexItr + partItr->_numIndices; - while (indexItr != indexEnd) { + auto indexEnd = indexItr + numIndices; + while (indexItr < indexEnd) { triangleIndices.push_back(*indexItr + meshIndexOffset); ++indexItr; } } else if (partItr->_topology == model::Mesh::TRIANGLE_STRIP) { - assert(partItr->_numIndices > 2); - uint32_t approxNumIndices = 3 * partItr->_numIndices; + // TODO: resurrect assert after we start sanitizing FBXMesh higher up + //assert(numIndices > 2); + + uint32_t approxNumIndices = TRIANGLE_STRIDE * numIndices; if (approxNumIndices > (uint32_t)(triangleIndices.capacity() - triangleIndices.size())) { // we underestimated the final size of triangleIndices so we pre-emptively expand it triangleIndices.reserve(triangleIndices.size() + approxNumIndices); } auto indexItr = indices.cbegin() + partItr->_startIndex; - auto indexEnd = indexItr + (partItr->_numIndices - 2); + auto indexEnd = indexItr + (numIndices - 2); // first triangle uses the first three indices triangleIndices.push_back(*(indexItr++) + meshIndexOffset); @@ -794,7 +807,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { // the rest use previous and next index uint32_t triangleCount = 1; - while (indexItr != indexEnd) { + while (indexItr < indexEnd) { if ((*indexItr) != model::Mesh::PRIMITIVE_RESTART_INDEX) { if (triangleCount % 2 == 0) { // even triangles use first two indices in order @@ -819,18 +832,24 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { while (partItr != parts.cend()) { // collect unique list of indices for this part std::set uniqueIndices; + auto numIndices = partItr->_numIndices; if (partItr->_topology == model::Mesh::TRIANGLES) { - assert(partItr->_numIndices % 3 == 0); + // TODO: assert rather than workaround after we start sanitizing FBXMesh higher up + //assert(numIndices% TRIANGLE_STRIDE == 0); + numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader + auto indexItr = indices.cbegin() + partItr->_startIndex; - auto indexEnd = indexItr + partItr->_numIndices; - while (indexItr != indexEnd) { + auto indexEnd = indexItr + numIndices; + while (indexItr < indexEnd) { uniqueIndices.insert(*indexItr); ++indexItr; } } else if (partItr->_topology == model::Mesh::TRIANGLE_STRIP) { - assert(partItr->_numIndices > 2); + // TODO: resurrect assert after we start sanitizing FBXMesh higher up + //assert(numIndices > TRIANGLE_STRIDE - 1); + auto indexItr = indices.cbegin() + partItr->_startIndex; - auto indexEnd = indexItr + (partItr->_numIndices - 2); + auto indexEnd = indexItr + (numIndices - 2); // first triangle uses the first three indices uniqueIndices.insert(*(indexItr++)); @@ -839,14 +858,14 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { // the rest use previous and next index uint32_t triangleCount = 1; - while (indexItr != indexEnd) { + while (indexItr < indexEnd) { if ((*indexItr) != model::Mesh::PRIMITIVE_RESTART_INDEX) { if (triangleCount % 2 == 0) { - // even triangles use first two indices in order + // EVEN triangles use first two indices in order uniqueIndices.insert(*(indexItr - 2)); uniqueIndices.insert(*(indexItr - 1)); } else { - // odd triangles swap order of first two indices + // ODD triangles swap order of first two indices uniqueIndices.insert(*(indexItr - 1)); uniqueIndices.insert(*(indexItr - 2)); }