workaround bad FBXMesh data rather than assert

This commit is contained in:
Andrew Meadows 2016-08-18 11:09:48 -07:00
parent 54a5bf3b23
commit cb9a5466d5

View file

@ -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<const model::Mesh::Part> partItr = parts.cbegin<const model::Mesh::Part>();
while (partItr != parts.cend<const model::Mesh::Part>()) {
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<const gpu::BufferView::Index>() + 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<const gpu::BufferView::Index>() + 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<const model::Mesh::Part>()) {
// collect unique list of indices for this part
std::set<int32_t> 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<const gpu::BufferView::Index>() + 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<const gpu::BufferView::Index>() + 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));
}