forked from Mirrorlandia_minetest/minetest
Recalculate mesh normals for CAOs (#10000)
This commit is contained in:
parent
8fc9e7eb11
commit
fe1f72ab0a
@ -726,6 +726,14 @@ void GenericCAO::addToScene(ITextureSource *tsrc)
|
||||
addAnimatedMeshSceneNode(mesh, m_matrixnode);
|
||||
m_animated_meshnode->grab();
|
||||
mesh->drop(); // The scene node took hold of it
|
||||
|
||||
if (!checkMeshNormals(mesh)) {
|
||||
infostream << "GenericCAO: recalculating normals for mesh "
|
||||
<< m_prop.mesh << std::endl;
|
||||
m_smgr->getMeshManipulator()->
|
||||
recalculateNormals(mesh, true, false);
|
||||
}
|
||||
|
||||
m_animated_meshnode->animateJoints(); // Needed for some animations
|
||||
m_animated_meshnode->setScale(m_prop.visual_size);
|
||||
|
||||
|
@ -328,6 +328,26 @@ void recalculateBoundingBox(scene::IMesh *src_mesh)
|
||||
src_mesh->setBoundingBox(bbox);
|
||||
}
|
||||
|
||||
bool checkMeshNormals(scene::IMesh *mesh)
|
||||
{
|
||||
u32 buffer_count = mesh->getMeshBufferCount();
|
||||
|
||||
for (u32 i = 0; i < buffer_count; i++) {
|
||||
scene::IMeshBuffer *buffer = mesh->getMeshBuffer(i);
|
||||
|
||||
// Here we intentionally check only first normal, assuming that if buffer
|
||||
// has it valid, then most likely all other ones are fine too. We can
|
||||
// check all of the normals to have length, but it seems like an overkill
|
||||
// hurting the performance and covering only really weird broken models.
|
||||
f32 length = buffer->getNormal(0).getLength();
|
||||
|
||||
if (!isfinite(length) || fabs(length) < 1e-10)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
scene::IMeshBuffer* cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer)
|
||||
{
|
||||
switch (mesh_buffer->getVertexType()) {
|
||||
|
@ -121,6 +121,12 @@ scene::IMesh* convertNodeboxesToMesh(const std::vector<aabb3f> &boxes,
|
||||
*/
|
||||
void recalculateBoundingBox(scene::IMesh *src_mesh);
|
||||
|
||||
/*
|
||||
Check if mesh has valid normals and return true if it does.
|
||||
We assume normal to be valid when it's 0 < length < Inf. and not NaN
|
||||
*/
|
||||
bool checkMeshNormals(scene::IMesh *mesh);
|
||||
|
||||
/*
|
||||
Vertex cache optimization according to the Forsyth paper:
|
||||
http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html
|
||||
|
Loading…
Reference in New Issue
Block a user