Skip to content

Commit 92d552d

Browse files
magical fix of the MitsubaLoader which fixes both slow render times and screw ups when a model is replicated as multiple shapes (Mesh018.obj in the bedroom scene)
1 parent e07e96c commit 92d552d

File tree

1 file changed

+32
-39
lines changed

1 file changed

+32
-39
lines changed

src/nbl/ext/MitsubaLoader/CMitsubaLoader.cpp

Lines changed: 32 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -709,18 +709,13 @@ SContext::shape_ass_type CMitsubaLoader::loadBasicShape(SContext& ctx, uint32_t
709709
auto asset = contentRange.begin()[actualIndex];
710710
if (!asset)
711711
return nullptr;
712-
// make a (shallow) copy because the mesh will get mutilated and abused for metadata NOT ANYMORE?
713-
auto mesh = core::smart_refctd_ptr_static_cast<asset::ICPUMesh>(asset);
714-
auto copy = core::make_smart_refctd_ptr<asset::ICPUMesh>();
715-
copy->getMeshBufferVector() = mesh->getMeshBufferVector();
716-
IMeshManipulator::recalculateBoundingBox(copy.get());
717-
return copy;
712+
return core::smart_refctd_ptr_static_cast<asset::ICPUMesh>(asset);
718713
}
719714
else
720715
return nullptr;
721716
};
722717

723-
core::smart_refctd_ptr<asset::ICPUMesh> mesh;
718+
core::smart_refctd_ptr<asset::ICPUMesh> mesh,newMesh;
724719
bool flipNormals = false;
725720
bool faceNormals = false;
726721
float maxSmoothAngle = NAN;
@@ -782,7 +777,8 @@ SContext::shape_ass_type CMitsubaLoader::loadBasicShape(SContext& ctx, uint32_t
782777
maxSmoothAngle = shape->obj.maxSmoothAngle;
783778
if (mesh && shape->obj.flipTexCoords)
784779
{
785-
for (auto meshbuffer : mesh->getMeshBuffers())
780+
newMesh = core::smart_refctd_ptr_static_cast<asset::ICPUMesh>(mesh->clone(~0u));//clone everything (for the texcoords)
781+
for (auto meshbuffer : newMesh->getMeshBuffers())
786782
{
787783
core::vectorSIMDf uv;
788784
for (uint32_t i=0u; meshbuffer->getAttribute(uv, UV_ATTRIB_ID, i); i++)
@@ -797,7 +793,6 @@ SContext::shape_ass_type CMitsubaLoader::loadBasicShape(SContext& ctx, uint32_t
797793
case CElementShape::Type::PLY:
798794
_NBL_DEBUG_BREAK_IF(true); // this code has never been tested
799795
mesh = loadModel(shape->ply.filename);
800-
mesh = core::smart_refctd_ptr_static_cast<asset::ICPUMesh>(mesh->clone(~0u));//clone everything
801796
flipNormals = flipNormals!=shape->ply.flipNormals;
802797
faceNormals = shape->ply.faceNormals;
803798
maxSmoothAngle = shape->ply.maxSmoothAngle;
@@ -811,7 +806,8 @@ SContext::shape_ass_type CMitsubaLoader::loadBasicShape(SContext& ctx, uint32_t
811806
constexpr uint32_t hidefRGBSize = 4u;
812807
auto newRGB = core::make_smart_refctd_ptr<asset::ICPUBuffer>(hidefRGBSize*totalVertexCount);
813808
uint32_t* it = reinterpret_cast<uint32_t*>(newRGB->getPointer());
814-
for (auto meshbuffer : mesh->getMeshBuffers())
809+
newMesh = core::smart_refctd_ptr_static_cast<asset::ICPUMesh>(mesh->clone(~0u));//clone everything
810+
for (auto meshbuffer : newMesh->getMeshBuffers())
815811
{
816812
uint32_t offset = reinterpret_cast<uint8_t*>(it)-reinterpret_cast<uint8_t*>(newRGB->getPointer());
817813
core::vectorSIMDf rgb;
@@ -855,38 +851,35 @@ SContext::shape_ass_type CMitsubaLoader::loadBasicShape(SContext& ctx, uint32_t
855851

856852
// flip normals if necessary
857853
if (flipNormals)
858-
for (auto meshbuffer : mesh->getMeshBuffers())
859-
ctx.manipulator->flipSurfaces(meshbuffer);
860-
861-
//turned off by default, it's too slow (works though)
862-
//#define OPTIMIZE_MESHES
854+
{
855+
if (!newMesh)
856+
newMesh = core::smart_refctd_ptr_static_cast<asset::ICPUMesh>(mesh->clone(~0u));//clone everything (for the index buffer)
857+
for (auto meshbuffer : mesh->getMeshBuffers())
858+
ctx.manipulator->flipSurfaces(meshbuffer);
859+
}
863860

864-
auto newMesh = core::make_smart_refctd_ptr<asset::ICPUMesh>();
865-
for (auto meshbuffer : mesh->getMeshBuffers())
861+
if (!newMesh)
866862
{
867-
#ifdef OPTIMIZE_MESHES // TODO
868-
asset::IMeshManipulator::SErrorMetric metrics[asset::ICPUMeshBuffer::MAX_ATTR_BUF_BINDING_COUNT];
869-
metrics[3].method = asset::IMeshManipulator::EEM_ANGLES;
870-
auto newMeshBuffer = ctx.manipulator->createOptimizedMeshBuffer(meshbuffer, metrics);
871-
#else
872-
auto newMeshBuffer = core::smart_refctd_ptr<asset::ICPUMeshBuffer>(meshbuffer);
873-
#endif
874-
if (faceNormals || !std::isnan(maxSmoothAngle))
875-
{
876-
const float smoothAngleCos = cos(core::radians(maxSmoothAngle));
863+
newMesh = core::make_smart_refctd_ptr<ICPUMesh>();
864+
newMesh->getMeshBufferVector() = mesh->getMeshBufferVector();
865+
}
866+
if (faceNormals || !std::isnan(maxSmoothAngle))
867+
for (auto& meshbuffer : mesh->getMeshBufferVector())
868+
{
869+
const float smoothAngleCos = cos(core::radians(maxSmoothAngle));
877870

878-
ctx.manipulator->filterInvalidTriangles(meshbuffer);
879-
newMeshBuffer = ctx.manipulator->createMeshBufferUniquePrimitives(meshbuffer);
880-
ctx.manipulator->calculateSmoothNormals(newMeshBuffer.get(), false, 0.f, newMeshBuffer->getNormalAttributeIx(),
881-
[&](const asset::IMeshManipulator::SSNGVertexData& a, const asset::IMeshManipulator::SSNGVertexData& b, asset::ICPUMeshBuffer* buffer)
882-
{
883-
if (faceNormals)
884-
return a.indexOffset == b.indexOffset;
885-
else
886-
return core::dot(a.parentTriangleFaceNormal, b.parentTriangleFaceNormal).x >= smoothAngleCos;
887-
});
888-
}
889-
newMesh->getMeshBufferVector().push_back(std::move(newMeshBuffer));
871+
// TODO: make these mesh manipulator functions const-correct
872+
auto newMeshBuffer = ctx.manipulator->createMeshBufferUniquePrimitives(meshbuffer.get());
873+
ctx.manipulator->filterInvalidTriangles(newMeshBuffer.get());
874+
ctx.manipulator->calculateSmoothNormals(newMeshBuffer.get(), false, 0.f, newMeshBuffer->getNormalAttributeIx(),
875+
[&](const asset::IMeshManipulator::SSNGVertexData& a, const asset::IMeshManipulator::SSNGVertexData& b, asset::ICPUMeshBuffer* buffer)
876+
{
877+
if (faceNormals)
878+
return a.indexOffset == b.indexOffset;
879+
else
880+
return core::dot(a.parentTriangleFaceNormal, b.parentTriangleFaceNormal).x >= smoothAngleCos;
881+
});
882+
meshbuffer = std::move(newMeshBuffer);
890883
}
891884
IMeshManipulator::recalculateBoundingBox(newMesh.get());
892885
mesh = std::move(newMesh);

0 commit comments

Comments
 (0)