Odd negative scale: OptimizeGraph
OptimizeGraph postprocessing now reverses face order when node scale is mirroring. Fixes flip to backfacing in models that mirrored some nodes. (Odd count of negative scale components, negative determinant)pull/2818/head
parent
463573c771
commit
193b02cdac
|
@ -137,8 +137,9 @@ public:
|
|||
// -------------------------------------------------------------------
|
||||
void Execute( aiScene* pScene);
|
||||
|
||||
protected:
|
||||
void ProcessMesh( aiMesh* pMesh);
|
||||
public:
|
||||
/** Some other types of post-processing require winding order flips */
|
||||
static void ProcessMesh( aiMesh* pMesh);
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "OptimizeGraph.h"
|
||||
#include "ProcessHelper.h"
|
||||
#include "ConvertToLHProcess.h"
|
||||
#include <assimp/Exceptional.h>
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include <stdio.h>
|
||||
|
@ -135,7 +136,7 @@ void OptimizeGraphProcess::CollectNewChildren(aiNode *nd, std::list<aiNode *> &n
|
|||
nodes.push_back(nd);
|
||||
|
||||
// Now check for possible optimizations in our list of child nodes. join as many as possible
|
||||
aiNode *join_master = NULL;
|
||||
aiNode *join_master = nullptr;
|
||||
aiMatrix4x4 inv;
|
||||
|
||||
const LockedSetType::const_iterator end = locked.end();
|
||||
|
@ -172,7 +173,7 @@ void OptimizeGraphProcess::CollectNewChildren(aiNode *nd, std::list<aiNode *> &n
|
|||
join_master->mName.length = ::ai_snprintf(join_master->mName.data, MAXLEN, "$MergedNode_%i", count_merged++);
|
||||
|
||||
unsigned int out_meshes = 0;
|
||||
for (std::list<aiNode *>::iterator it = join.begin(); it != join.end(); ++it) {
|
||||
for (std::list<aiNode *>::const_iterator it = join.cbegin(); it != join.cend(); ++it) {
|
||||
out_meshes += (*it)->mNumMeshes;
|
||||
}
|
||||
|
||||
|
@ -183,17 +184,26 @@ void OptimizeGraphProcess::CollectNewChildren(aiNode *nd, std::list<aiNode *> &n
|
|||
*tmp++ = join_master->mMeshes[n];
|
||||
}
|
||||
|
||||
for (std::list<aiNode *>::iterator it = join.begin(); it != join.end(); ++it) {
|
||||
for (unsigned int n = 0; n < (*it)->mNumMeshes; ++n) {
|
||||
for (const aiNode *join_node : join) {
|
||||
for (unsigned int n = 0; n < join_node->mNumMeshes; ++n) {
|
||||
|
||||
*tmp = (*it)->mMeshes[n];
|
||||
*tmp = join_node->mMeshes[n];
|
||||
aiMesh *mesh = mScene->mMeshes[*tmp++];
|
||||
|
||||
// Assume the transformation is affine
|
||||
// manually move the mesh into the right coordinate system
|
||||
const aiMatrix3x3 IT = aiMatrix3x3((*it)->mTransformation).Inverse().Transpose();
|
||||
|
||||
// Check for odd negative scale (mirror)
|
||||
if (join_node->mTransformation.Determinant() < 0) {
|
||||
// Reverse the mesh face winding order
|
||||
FlipWindingOrderProcess::ProcessMesh(mesh);
|
||||
}
|
||||
|
||||
// Update positions, normals and tangents
|
||||
const aiMatrix3x3 IT = aiMatrix3x3(join_node->mTransformation).Inverse().Transpose();
|
||||
for (unsigned int a = 0; a < mesh->mNumVertices; ++a) {
|
||||
|
||||
mesh->mVertices[a] *= (*it)->mTransformation;
|
||||
mesh->mVertices[a] *= join_node->mTransformation;
|
||||
|
||||
if (mesh->HasNormals())
|
||||
mesh->mNormals[a] *= IT;
|
||||
|
@ -204,7 +214,7 @@ void OptimizeGraphProcess::CollectNewChildren(aiNode *nd, std::list<aiNode *> &n
|
|||
}
|
||||
}
|
||||
}
|
||||
delete *it; // bye, node
|
||||
delete join_node; // bye, node
|
||||
}
|
||||
delete[] join_master->mMeshes;
|
||||
join_master->mMeshes = meshes;
|
||||
|
@ -304,7 +314,7 @@ void OptimizeGraphProcess::Execute(aiScene *pScene) {
|
|||
ai_assert(nodes.size() == 1);
|
||||
|
||||
if (dummy_root->mNumChildren == 0) {
|
||||
pScene->mRootNode = NULL;
|
||||
pScene->mRootNode = nullptr;
|
||||
throw DeadlyImportError("After optimizing the scene graph, no data remains");
|
||||
}
|
||||
|
||||
|
@ -318,11 +328,11 @@ void OptimizeGraphProcess::Execute(aiScene *pScene) {
|
|||
// Remove the dummy root node again.
|
||||
pScene->mRootNode = dummy_root->mChildren[0];
|
||||
|
||||
dummy_root->mChildren[0] = NULL;
|
||||
dummy_root->mChildren[0] = nullptr;
|
||||
delete dummy_root;
|
||||
}
|
||||
|
||||
pScene->mRootNode->mParent = NULL;
|
||||
pScene->mRootNode->mParent = nullptr;
|
||||
if (!DefaultLogger::isNullLogger()) {
|
||||
if (nodes_in != nodes_out) {
|
||||
ASSIMP_LOG_INFO_F("OptimizeGraphProcess finished; Input nodes: ", nodes_in, ", Output nodes: ", nodes_out);
|
||||
|
|
|
@ -75,13 +75,13 @@ public:
|
|||
~OptimizeGraphProcess();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
bool IsActive( unsigned int pFlags) const;
|
||||
bool IsActive( unsigned int pFlags) const override;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void Execute( aiScene* pScene);
|
||||
void Execute( aiScene* pScene) override;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void SetupProperties(const Importer* pImp);
|
||||
void SetupProperties(const Importer* pImp) override;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Add a list of node names to be locked and not modified.
|
||||
|
|
Loading…
Reference in New Issue