Merge branch 'master' into develop_kimkulling

pull/1805/head
Kim Kulling 2018-02-23 17:54:58 +01:00 committed by GitHub
commit 606a28dbe8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 127 additions and 22 deletions

View File

@ -142,6 +142,7 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
nodes.reserve( conns.size() ); nodes.reserve( conns.size() );
std::vector<aiNode*> nodes_chain; std::vector<aiNode*> nodes_chain;
std::vector<aiNode*> post_nodes_chain;
try { try {
for( const Connection* con : conns ) { for( const Connection* con : conns ) {
@ -161,6 +162,7 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
if ( model ) { if ( model ) {
nodes_chain.clear(); nodes_chain.clear();
post_nodes_chain.clear();
aiMatrix4x4 new_abs_transform = parent_transform; aiMatrix4x4 new_abs_transform = parent_transform;
@ -168,7 +170,7 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
// assimp (or rather: the complicated transformation chain that // assimp (or rather: the complicated transformation chain that
// is employed by fbx) means that we may need multiple aiNode's // is employed by fbx) means that we may need multiple aiNode's
// to represent a fbx node's transformation. // to represent a fbx node's transformation.
GenerateTransformationNodeChain( *model, nodes_chain ); GenerateTransformationNodeChain( *model, nodes_chain, post_nodes_chain );
ai_assert( nodes_chain.size() ); ai_assert( nodes_chain.size() );
@ -213,8 +215,25 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
// attach geometry // attach geometry
ConvertModel( *model, *nodes_chain.back(), new_abs_transform ); ConvertModel( *model, *nodes_chain.back(), new_abs_transform );
// now link the geometric transform inverse nodes,
// before we attach any child nodes
for( aiNode* postnode : post_nodes_chain ) {
ai_assert( postnode );
if ( last_parent != &parent ) {
last_parent->mNumChildren = 1;
last_parent->mChildren = new aiNode*[ 1 ];
last_parent->mChildren[ 0 ] = postnode;
}
postnode->mParent = last_parent;
last_parent = postnode;
new_abs_transform *= postnode->mTransformation;
}
// attach sub-nodes // attach sub-nodes
ConvertNodes( model->ID(), *nodes_chain.back(), new_abs_transform ); ConvertNodes( model->ID(), *last_parent, new_abs_transform );
if ( doc.Settings().readLights ) { if ( doc.Settings().readLights ) {
ConvertLights( *model ); ConvertLights( *model );
@ -396,6 +415,12 @@ const char* Converter::NameTransformationComp( TransformationComp comp )
return "GeometricRotation"; return "GeometricRotation";
case TransformationComp_GeometricTranslation: case TransformationComp_GeometricTranslation:
return "GeometricTranslation"; return "GeometricTranslation";
case TransformationComp_GeometricScalingInverse:
return "GeometricScalingInverse";
case TransformationComp_GeometricRotationInverse:
return "GeometricRotationInverse";
case TransformationComp_GeometricTranslationInverse:
return "GeometricTranslationInverse";
case TransformationComp_MAXIMUM: // this is to silence compiler warnings case TransformationComp_MAXIMUM: // this is to silence compiler warnings
default: default:
break; break;
@ -437,6 +462,12 @@ const char* Converter::NameTransformationCompProperty( TransformationComp comp )
return "GeometricRotation"; return "GeometricRotation";
case TransformationComp_GeometricTranslation: case TransformationComp_GeometricTranslation:
return "GeometricTranslation"; return "GeometricTranslation";
case TransformationComp_GeometricScalingInverse:
return "GeometricScalingInverse";
case TransformationComp_GeometricRotationInverse:
return "GeometricRotationInverse";
case TransformationComp_GeometricTranslationInverse:
return "GeometricTranslationInverse";
case TransformationComp_MAXIMUM: // this is to silence compiler warnings case TransformationComp_MAXIMUM: // this is to silence compiler warnings
break; break;
} }
@ -548,17 +579,25 @@ bool Converter::NeedsComplexTransformationChain( const Model& model )
bool ok; bool ok;
const float zero_epsilon = 1e-6f; const float zero_epsilon = 1e-6f;
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
for ( size_t i = 0; i < TransformationComp_MAXIMUM; ++i ) { for ( size_t i = 0; i < TransformationComp_MAXIMUM; ++i ) {
const TransformationComp comp = static_cast< TransformationComp >( i ); const TransformationComp comp = static_cast< TransformationComp >( i );
if ( comp == TransformationComp_Rotation || comp == TransformationComp_Scaling || comp == TransformationComp_Translation || if ( comp == TransformationComp_Rotation || comp == TransformationComp_Scaling || comp == TransformationComp_Translation ) {
comp == TransformationComp_GeometricScaling || comp == TransformationComp_GeometricRotation || comp == TransformationComp_GeometricTranslation ) {
continue; continue;
} }
bool scale_compare = ( comp == TransformationComp_GeometricScaling || comp == TransformationComp_Scaling );
const aiVector3D& v = PropertyGet<aiVector3D>( props, NameTransformationCompProperty( comp ), ok ); const aiVector3D& v = PropertyGet<aiVector3D>( props, NameTransformationCompProperty( comp ), ok );
if ( ok && v.SquareLength() > zero_epsilon ) { if ( ok && scale_compare ) {
return true; if ( (v - all_ones).SquareLength() > zero_epsilon ) {
return true;
}
} else if ( ok ) {
if ( v.SquareLength() > zero_epsilon ) {
return true;
}
} }
} }
@ -570,7 +609,7 @@ std::string Converter::NameTransformationChainNode( const std::string& name, Tra
return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp ); return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp );
} }
void Converter::GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes ) void Converter::GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes, std::vector<aiNode*>& post_output_nodes )
{ {
const PropertyTable& props = model.Props(); const PropertyTable& props = model.Props();
const Model::RotOrder rot = model.RotationOrder(); const Model::RotOrder rot = model.RotationOrder();
@ -582,6 +621,7 @@ void Converter::GenerateTransformationNodeChain( const Model& model, std::vector
// generate transformation matrices for all the different transformation components // generate transformation matrices for all the different transformation components
const float zero_epsilon = 1e-6f; const float zero_epsilon = 1e-6f;
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
bool is_complex = false; bool is_complex = false;
const aiVector3D& PreRotation = PropertyGet<aiVector3D>( props, "PreRotation", ok ); const aiVector3D& PreRotation = PropertyGet<aiVector3D>( props, "PreRotation", ok );
@ -634,7 +674,7 @@ void Converter::GenerateTransformationNodeChain( const Model& model, std::vector
} }
const aiVector3D& Scaling = PropertyGet<aiVector3D>( props, "Lcl Scaling", ok ); const aiVector3D& Scaling = PropertyGet<aiVector3D>( props, "Lcl Scaling", ok );
if ( ok && std::fabs( Scaling.SquareLength() - 1.0f ) > zero_epsilon ) { if ( ok && (Scaling - all_ones).SquareLength() > zero_epsilon ) {
aiMatrix4x4::Scaling( Scaling, chain[ TransformationComp_Scaling ] ); aiMatrix4x4::Scaling( Scaling, chain[ TransformationComp_Scaling ] );
} }
@ -644,18 +684,38 @@ void Converter::GenerateTransformationNodeChain( const Model& model, std::vector
} }
const aiVector3D& GeometricScaling = PropertyGet<aiVector3D>( props, "GeometricScaling", ok ); const aiVector3D& GeometricScaling = PropertyGet<aiVector3D>( props, "GeometricScaling", ok );
if ( ok && std::fabs( GeometricScaling.SquareLength() - 1.0f ) > zero_epsilon ) { if ( ok && (GeometricScaling - all_ones).SquareLength() > zero_epsilon ) {
is_complex = true;
aiMatrix4x4::Scaling( GeometricScaling, chain[ TransformationComp_GeometricScaling ] ); aiMatrix4x4::Scaling( GeometricScaling, chain[ TransformationComp_GeometricScaling ] );
aiVector3D GeometricScalingInverse = GeometricScaling;
bool canscale = true;
for (size_t i = 0; i < 3; ++i) {
if ( std::fabs( GeometricScalingInverse[i] ) > zero_epsilon ) {
GeometricScalingInverse[i] = 1.0f / GeometricScaling[i];
} else {
FBXImporter::LogError( "cannot invert geometric scaling matrix with a 0.0 scale component" );
canscale = false;
break;
}
}
if (canscale) {
aiMatrix4x4::Scaling( GeometricScalingInverse, chain[ TransformationComp_GeometricScalingInverse ] );
}
} }
const aiVector3D& GeometricRotation = PropertyGet<aiVector3D>( props, "GeometricRotation", ok ); const aiVector3D& GeometricRotation = PropertyGet<aiVector3D>( props, "GeometricRotation", ok );
if ( ok && GeometricRotation.SquareLength() > zero_epsilon ) { if ( ok && GeometricRotation.SquareLength() > zero_epsilon ) {
is_complex = true;
GetRotationMatrix( rot, GeometricRotation, chain[ TransformationComp_GeometricRotation ] ); GetRotationMatrix( rot, GeometricRotation, chain[ TransformationComp_GeometricRotation ] );
GetRotationMatrix( rot, GeometricRotation, chain[ TransformationComp_GeometricRotationInverse ] );
chain[ TransformationComp_GeometricRotationInverse ].Inverse();
} }
const aiVector3D& GeometricTranslation = PropertyGet<aiVector3D>( props, "GeometricTranslation", ok ); const aiVector3D& GeometricTranslation = PropertyGet<aiVector3D>( props, "GeometricTranslation", ok );
if ( ok && GeometricTranslation.SquareLength() > zero_epsilon ) { if ( ok && GeometricTranslation.SquareLength() > zero_epsilon ) {
is_complex = true;
aiMatrix4x4::Translation( GeometricTranslation, chain[ TransformationComp_GeometricTranslation ] ); aiMatrix4x4::Translation( GeometricTranslation, chain[ TransformationComp_GeometricTranslation ] );
aiMatrix4x4::Translation( -GeometricTranslation, chain[ TransformationComp_GeometricTranslationInverse ] );
} }
// is_complex needs to be consistent with NeedsComplexTransformationChain() // is_complex needs to be consistent with NeedsComplexTransformationChain()
@ -690,10 +750,18 @@ void Converter::GenerateTransformationNodeChain( const Model& model, std::vector
} }
aiNode* nd = new aiNode(); aiNode* nd = new aiNode();
output_nodes.push_back( nd );
nd->mName.Set( NameTransformationChainNode( name, comp ) ); nd->mName.Set( NameTransformationChainNode( name, comp ) );
nd->mTransformation = chain[ i ]; nd->mTransformation = chain[ i ];
// geometric inverses go in a post-node chain
if ( comp == TransformationComp_GeometricScalingInverse ||
comp == TransformationComp_GeometricRotationInverse ||
comp == TransformationComp_GeometricTranslationInverse
) {
post_output_nodes.push_back( nd );
} else {
output_nodes.push_back( nd );
}
} }
ai_assert( output_nodes.size() ); ai_assert( output_nodes.size() );
@ -2209,8 +2277,7 @@ void Converter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
has_any = true; has_any = true;
if ( comp != TransformationComp_Rotation && comp != TransformationComp_Scaling && comp != TransformationComp_Translation && if ( comp != TransformationComp_Rotation && comp != TransformationComp_Scaling && comp != TransformationComp_Translation )
comp != TransformationComp_GeometricScaling && comp != TransformationComp_GeometricRotation && comp != TransformationComp_GeometricTranslation )
{ {
has_complex = true; has_complex = true;
} }

View File

@ -82,7 +82,10 @@ public:
* The different parts that make up the final local transformation of a fbx-node * The different parts that make up the final local transformation of a fbx-node
*/ */
enum TransformationComp { enum TransformationComp {
TransformationComp_Translation = 0, TransformationComp_GeometricScalingInverse = 0,
TransformationComp_GeometricRotationInverse,
TransformationComp_GeometricTranslationInverse,
TransformationComp_Translation,
TransformationComp_RotationOffset, TransformationComp_RotationOffset,
TransformationComp_RotationPivot, TransformationComp_RotationPivot,
TransformationComp_PreRotation, TransformationComp_PreRotation,
@ -153,7 +156,7 @@ private:
/** /**
* note: memory for output_nodes will be managed by the caller * note: memory for output_nodes will be managed by the caller
*/ */
void GenerateTransformationNodeChain(const Model& model, std::vector<aiNode*>& output_nodes); void GenerateTransformationNodeChain(const Model& model, std::vector<aiNode*>& output_nodes, std::vector<aiNode*>& post_output_nodes);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void SetupNodeMetadata(const Model& model, aiNode& nd); void SetupNodeMetadata(const Model& model, aiNode& nd);

View File

@ -47,9 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Main.h" #include "Main.h"
const char* AICMD_MSG_INFO_HELP_E = const char* AICMD_MSG_INFO_HELP_E =
"assimp info <file> [-r]\n" "assimp info <file> [-r] [-v]\n"
"\tPrint basic structure of a 3D model\n" "\tPrint basic structure of a 3D model\n"
"\t-r,--raw: No postprocessing, do a raw import\n"; "\t-r,--raw: No postprocessing, do a raw import\n"
"\t-v,--verbose: Print verbose info such as node transform data\n";
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
@ -184,7 +185,7 @@ std::string FindPTypes(const aiScene* scene)
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void PrintHierarchy(const aiNode* root, unsigned int maxnest, unsigned int maxline, void PrintHierarchy(const aiNode* root, unsigned int maxnest, unsigned int maxline,
unsigned int cline, unsigned int cnest=0) unsigned int cline, bool verbose, unsigned int cnest=0)
{ {
if (cline++ >= maxline || cnest >= maxnest) { if (cline++ >= maxline || cnest >= maxnest) {
return; return;
@ -194,8 +195,29 @@ void PrintHierarchy(const aiNode* root, unsigned int maxnest, unsigned int maxli
printf("-- "); printf("-- ");
} }
printf("\'%s\', meshes: %u\n",root->mName.data,root->mNumMeshes); printf("\'%s\', meshes: %u\n",root->mName.data,root->mNumMeshes);
if (verbose) {
// print the actual transform
//printf(",");
aiVector3D s, r, t;
root->mTransformation.Decompose(s, r, t);
if (s.x != 1.0 || s.y != 1.0 || s.z != 1.0) {
for(unsigned int i = 0; i < cnest; ++i) { printf(" "); }
printf(" S:[%f %f %f]\n", s.x, s.y, s.z);
}
if (r.x || r.y || r.z) {
for(unsigned int i = 0; i < cnest; ++i) { printf(" "); }
printf(" R:[%f %f %f]\n", r.x, r.y, r.z);
}
if (t.x || t.y || t.z) {
for(unsigned int i = 0; i < cnest; ++i) { printf(" "); }
printf(" T:[%f %f %f]\n", t.x, t.y, t.z);
}
}
//printf("\n");
for (unsigned int i = 0; i < root->mNumChildren; ++i ) { for (unsigned int i = 0; i < root->mNumChildren; ++i ) {
PrintHierarchy(root->mChildren[i],maxnest,maxline,cline,cnest+1); PrintHierarchy(root->mChildren[i],maxnest,maxline,cline,verbose,cnest+1);
if(i == root->mNumChildren-1) { if(i == root->mNumChildren-1) {
for(unsigned int i = 0; i < cnest; ++i) { for(unsigned int i = 0; i < cnest; ++i) {
printf(" "); printf(" ");
@ -230,10 +252,23 @@ int Assimp_Info (const char* const* params, unsigned int num)
const std::string in = std::string(params[0]); const std::string in = std::string(params[0]);
// get -r and -v arguments
bool raw = false;
bool verbose = false;
for(unsigned int i = 1; i < num; ++i) {
if (!strcmp(params[i],"--raw")||!strcmp(params[i],"-r")) {
raw = true;
}
if (!strcmp(params[i],"--verbose")||!strcmp(params[i],"-v")) {
verbose = true;
}
}
// do maximum post-processing unless -r was specified // do maximum post-processing unless -r was specified
ImportData import; ImportData import;
import.ppFlags = num>1&&(!strcmp(params[1],"--raw")||!strcmp(params[1],"-r")) ? 0 if (!raw) {
: aiProcessPreset_TargetRealtime_MaxQuality; import.ppFlags = aiProcessPreset_TargetRealtime_MaxQuality;
}
// import the main model // import the main model
const aiScene* scene = ImportModel(import,in); const aiScene* scene = ImportModel(import,in);
@ -346,7 +381,7 @@ int Assimp_Info (const char* const* params, unsigned int num)
printf("\nNode hierarchy:\n"); printf("\nNode hierarchy:\n");
unsigned int cline=0; unsigned int cline=0;
PrintHierarchy(scene->mRootNode,20,1000,cline); PrintHierarchy(scene->mRootNode,20,1000,cline,verbose);
printf("\n"); printf("\n");
return 0; return 0;