Merge branch 'master' into 3mf_basematerial_support
commit
437ae0c839
|
@ -205,7 +205,7 @@ enum ErrorPolicy {
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** Represents a data structure in a BLEND file. A Structure defines n fields
|
/** Represents a data structure in a BLEND file. A Structure defines n fields
|
||||||
* and their locatios and encodings the input stream. Usually, every
|
* and their locations and encodings the input stream. Usually, every
|
||||||
* Structure instance pertains to one equally-named data structure in the
|
* Structure instance pertains to one equally-named data structure in the
|
||||||
* BlenderScene.h header. This class defines various utilities to map a
|
* BlenderScene.h header. This class defines various utilities to map a
|
||||||
* binary `blob` read from the file to such a structure instance with
|
* binary `blob` read from the file to such a structure instance with
|
||||||
|
|
|
@ -502,7 +502,7 @@ const FileBlockHead* Structure :: LocateFileBlockForAddress(const Pointer & ptrv
|
||||||
{
|
{
|
||||||
// the file blocks appear in list sorted by
|
// the file blocks appear in list sorted by
|
||||||
// with ascending base addresses so we can run a
|
// with ascending base addresses so we can run a
|
||||||
// binary search to locate the pointee quickly.
|
// binary search to locate the pointer quickly.
|
||||||
|
|
||||||
// NOTE: Blender seems to distinguish between side-by-side
|
// NOTE: Blender seems to distinguish between side-by-side
|
||||||
// data (stored in the same data block) and far pointers,
|
// data (stored in the same data block) and far pointers,
|
||||||
|
|
|
@ -116,7 +116,7 @@ template <> void Structure :: Convert<MTex> (
|
||||||
ReadField<ErrorPolicy_Igno>(temp,"projy",db);
|
ReadField<ErrorPolicy_Igno>(temp,"projy",db);
|
||||||
dest.projy = static_cast<Assimp::Blender::MTex::Projection>(temp);
|
dest.projy = static_cast<Assimp::Blender::MTex::Projection>(temp);
|
||||||
ReadField<ErrorPolicy_Igno>(temp,"projz",db);
|
ReadField<ErrorPolicy_Igno>(temp,"projz",db);
|
||||||
dest.projx = static_cast<Assimp::Blender::MTex::Projection>(temp);
|
dest.projz = static_cast<Assimp::Blender::MTex::Projection>(temp);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.mapping,"mapping",db);
|
ReadField<ErrorPolicy_Igno>(dest.mapping,"mapping",db);
|
||||||
ReadFieldArray<ErrorPolicy_Igno>(dest.ofs,"ofs",db);
|
ReadFieldArray<ErrorPolicy_Igno>(dest.ofs,"ofs",db);
|
||||||
ReadFieldArray<ErrorPolicy_Igno>(dest.size,"size",db);
|
ReadFieldArray<ErrorPolicy_Igno>(dest.size,"size",db);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -428,16 +428,19 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
|
||||||
const std::vector<unsigned int>& mapping_offsets,
|
const std::vector<unsigned int>& mapping_offsets,
|
||||||
const std::vector<unsigned int>& mappings)
|
const std::vector<unsigned int>& mappings)
|
||||||
{
|
{
|
||||||
|
bool isDirect = ReferenceInformationType == "Direct";
|
||||||
|
bool isIndexToDirect = ReferenceInformationType == "IndexToDirect";
|
||||||
|
|
||||||
|
// fallback to direct data if there is no index data element
|
||||||
|
if ( isIndexToDirect && !HasElement( source, indexDataElementName ) ) {
|
||||||
|
isDirect = true;
|
||||||
|
isIndexToDirect = false;
|
||||||
|
}
|
||||||
|
|
||||||
// handle permutations of Mapping and Reference type - it would be nice to
|
// handle permutations of Mapping and Reference type - it would be nice to
|
||||||
// deal with this more elegantly and with less redundancy, but right
|
// deal with this more elegantly and with less redundancy, but right
|
||||||
// now it seems unavoidable.
|
// now it seems unavoidable.
|
||||||
if (MappingInformationType == "ByVertice" && ReferenceInformationType == "Direct") {
|
if (MappingInformationType == "ByVertice" && isDirect) {
|
||||||
if ( !HasElement( source, indexDataElementName ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<T> tempData;
|
std::vector<T> tempData;
|
||||||
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
|
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
|
||||||
|
|
||||||
|
@ -450,14 +453,11 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (MappingInformationType == "ByVertice" && ReferenceInformationType == "IndexToDirect") {
|
else if (MappingInformationType == "ByVertice" && isIndexToDirect) {
|
||||||
std::vector<T> tempData;
|
std::vector<T> tempData;
|
||||||
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
|
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
|
||||||
|
|
||||||
data_out.resize(vertex_count);
|
data_out.resize(vertex_count);
|
||||||
if ( !HasElement( source, indexDataElementName ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<int> uvIndices;
|
std::vector<int> uvIndices;
|
||||||
ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
|
ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
|
||||||
|
@ -472,7 +472,7 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (MappingInformationType == "ByPolygonVertex" && ReferenceInformationType == "Direct") {
|
else if (MappingInformationType == "ByPolygonVertex" && isDirect) {
|
||||||
std::vector<T> tempData;
|
std::vector<T> tempData;
|
||||||
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
|
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
|
||||||
|
|
||||||
|
@ -485,7 +485,7 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
|
||||||
|
|
||||||
data_out.swap(tempData);
|
data_out.swap(tempData);
|
||||||
}
|
}
|
||||||
else if (MappingInformationType == "ByPolygonVertex" && ReferenceInformationType == "IndexToDirect") {
|
else if (MappingInformationType == "ByPolygonVertex" && isIndexToDirect) {
|
||||||
std::vector<T> tempData;
|
std::vector<T> tempData;
|
||||||
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
|
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
|
||||||
|
|
||||||
|
|
|
@ -42,13 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* Implements a filter system to filter calls to Exists() and Open()
|
* Implements a filter system to filter calls to Exists() and Open()
|
||||||
* in order to improve the success rate of file opening ...
|
* in order to improve the success rate of file opening ...
|
||||||
*/
|
*/
|
||||||
|
#pragma once
|
||||||
#ifndef AI_FILESYSTEMFILTER_H_INC
|
#ifndef AI_FILESYSTEMFILTER_H_INC
|
||||||
#define AI_FILESYSTEMFILTER_H_INC
|
#define AI_FILESYSTEMFILTER_H_INC
|
||||||
|
|
||||||
#include "../include/assimp/IOSystem.hpp"
|
#include <assimp/IOSystem.hpp>
|
||||||
#include "../include/assimp/DefaultLogger.hpp"
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include "../include/assimp/fast_atof.h"
|
#include <assimp/fast_atof.h>
|
||||||
#include "../include/assimp/ParsingUtils.h"
|
#include <assimp/ParsingUtils.h>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
@ -64,90 +65,89 @@ class FileSystemFilter : public IOSystem
|
||||||
public:
|
public:
|
||||||
/** Constructor. */
|
/** Constructor. */
|
||||||
FileSystemFilter(const std::string& file, IOSystem* old)
|
FileSystemFilter(const std::string& file, IOSystem* old)
|
||||||
: wrapped (old)
|
: mWrapped (old)
|
||||||
, src_file (file)
|
, mSrc_file(file)
|
||||||
, sep(wrapped->getOsSeparator())
|
, sep(mWrapped->getOsSeparator()) {
|
||||||
{
|
ai_assert(nullptr != mWrapped);
|
||||||
ai_assert(NULL != wrapped);
|
|
||||||
|
|
||||||
// Determine base directory
|
// Determine base directory
|
||||||
base = src_file;
|
mBase = mSrc_file;
|
||||||
std::string::size_type ss2;
|
std::string::size_type ss2;
|
||||||
if (std::string::npos != (ss2 = base.find_last_of("\\/"))) {
|
if (std::string::npos != (ss2 = mBase.find_last_of("\\/"))) {
|
||||||
base.erase(ss2,base.length()-ss2);
|
mBase.erase(ss2,mBase.length()-ss2);
|
||||||
}
|
} else {
|
||||||
else {
|
mBase = "";
|
||||||
base = "";
|
|
||||||
// return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure the directory is terminated properly
|
// make sure the directory is terminated properly
|
||||||
char s;
|
char s;
|
||||||
|
|
||||||
if (base.length() == 0) {
|
if ( mBase.empty() ) {
|
||||||
base = ".";
|
mBase = ".";
|
||||||
base += getOsSeparator();
|
mBase += getOsSeparator();
|
||||||
}
|
} else if ((s = *(mBase.end()-1)) != '\\' && s != '/') {
|
||||||
else if ((s = *(base.end()-1)) != '\\' && s != '/') {
|
mBase += getOsSeparator();
|
||||||
base += getOsSeparator();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultLogger::get()->info("Import root directory is \'" + base + "\'");
|
DefaultLogger::get()->info("Import root directory is \'" + mBase + "\'");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Destructor. */
|
/** Destructor. */
|
||||||
~FileSystemFilter()
|
~FileSystemFilter() {
|
||||||
{
|
// empty
|
||||||
// haha
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Tests for the existence of a file at the given path. */
|
/** Tests for the existence of a file at the given path. */
|
||||||
bool Exists( const char* pFile) const
|
bool Exists( const char* pFile) const {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
|
|
||||||
std::string tmp = pFile;
|
std::string tmp = pFile;
|
||||||
|
|
||||||
// Currently this IOSystem is also used to open THE ONE FILE.
|
// Currently this IOSystem is also used to open THE ONE FILE.
|
||||||
if (tmp != src_file) {
|
if (tmp != mSrc_file) {
|
||||||
BuildPath(tmp);
|
BuildPath(tmp);
|
||||||
Cleanup(tmp);
|
Cleanup(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wrapped->Exists(tmp);
|
return mWrapped->Exists(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns the directory separator. */
|
/** Returns the directory separator. */
|
||||||
char getOsSeparator() const
|
char getOsSeparator() const {
|
||||||
{
|
|
||||||
return sep;
|
return sep;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Open a new file with a given path. */
|
/** Open a new file with a given path. */
|
||||||
IOStream* Open( const char* pFile, const char* pMode = "rb")
|
IOStream* Open( const char* pFile, const char* pMode = "rb") {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
ai_assert(pFile);
|
if ( nullptr == pFile || nullptr == pMode ) {
|
||||||
ai_assert(pMode);
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ai_assert( nullptr != pFile );
|
||||||
|
ai_assert( nullptr != pMode );
|
||||||
|
|
||||||
// First try the unchanged path
|
// First try the unchanged path
|
||||||
IOStream* s = wrapped->Open(pFile,pMode);
|
IOStream* s = mWrapped->Open(pFile,pMode);
|
||||||
|
|
||||||
if (!s) {
|
if (nullptr == s) {
|
||||||
std::string tmp = pFile;
|
std::string tmp = pFile;
|
||||||
|
|
||||||
// Try to convert between absolute and relative paths
|
// Try to convert between absolute and relative paths
|
||||||
BuildPath(tmp);
|
BuildPath(tmp);
|
||||||
s = wrapped->Open(tmp,pMode);
|
s = mWrapped->Open(tmp,pMode);
|
||||||
|
|
||||||
if (!s) {
|
if (nullptr == s) {
|
||||||
// Finally, look for typical issues with paths
|
// Finally, look for typical issues with paths
|
||||||
// and try to correct them. This is our last
|
// and try to correct them. This is our last
|
||||||
// resort.
|
// resort.
|
||||||
tmp = pFile;
|
tmp = pFile;
|
||||||
Cleanup(tmp);
|
Cleanup(tmp);
|
||||||
BuildPath(tmp);
|
BuildPath(tmp);
|
||||||
s = wrapped->Open(tmp,pMode);
|
s = mWrapped->Open(tmp,pMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,27 +156,75 @@ public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Closes the given file and releases all resources associated with it. */
|
/** Closes the given file and releases all resources associated with it. */
|
||||||
void Close( IOStream* pFile)
|
void Close( IOStream* pFile) {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
return wrapped->Close(pFile);
|
return mWrapped->Close(pFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Compare two paths */
|
/** Compare two paths */
|
||||||
bool ComparePaths (const char* one, const char* second) const
|
bool ComparePaths (const char* one, const char* second) const {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
return wrapped->ComparePaths (one,second);
|
return mWrapped->ComparePaths (one,second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Pushes a new directory onto the directory stack. */
|
||||||
|
bool PushDirectory(const std::string &path ) {
|
||||||
|
ai_assert( nullptr != mWrapped );
|
||||||
|
return mWrapped->PushDirectory(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Returns the top directory from the stack. */
|
||||||
|
const std::string &CurrentDirectory() const {
|
||||||
|
ai_assert( nullptr != mWrapped );
|
||||||
|
return mWrapped->CurrentDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Returns the number of directories stored on the stack. */
|
||||||
|
size_t StackSize() const {
|
||||||
|
ai_assert( nullptr != mWrapped );
|
||||||
|
return mWrapped->StackSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Pops the top directory from the stack. */
|
||||||
|
bool PopDirectory() {
|
||||||
|
ai_assert( nullptr != mWrapped );
|
||||||
|
return mWrapped->PopDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Creates an new directory at the given path. */
|
||||||
|
bool CreateDirectory(const std::string &path) {
|
||||||
|
ai_assert( nullptr != mWrapped );
|
||||||
|
return mWrapped->CreateDirectory(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Will change the current directory to the given path. */
|
||||||
|
bool ChangeDirectory(const std::string &path) {
|
||||||
|
ai_assert( nullptr != mWrapped );
|
||||||
|
return mWrapped->ChangeDirectory(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Delete file. */
|
||||||
|
bool DeleteFile(const std::string &file) {
|
||||||
|
ai_assert( nullptr != mWrapped );
|
||||||
|
return mWrapped->DeleteFile(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Build a valid path from a given relative or absolute path.
|
/** Build a valid path from a given relative or absolute path.
|
||||||
*/
|
*/
|
||||||
void BuildPath (std::string& in) const
|
void BuildPath (std::string& in) const {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
// if we can already access the file, great.
|
// if we can already access the file, great.
|
||||||
if (in.length() < 3 || wrapped->Exists(in)) {
|
if (in.length() < 3 || mWrapped->Exists(in)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,8 +232,8 @@ private:
|
||||||
if (in[1] != ':') {
|
if (in[1] != ':') {
|
||||||
|
|
||||||
// append base path and try
|
// append base path and try
|
||||||
const std::string tmp = base + in;
|
const std::string tmp = mBase + in;
|
||||||
if (wrapped->Exists(tmp)) {
|
if (mWrapped->Exists(tmp)) {
|
||||||
in = tmp;
|
in = tmp;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -207,7 +255,7 @@ private:
|
||||||
std::string::size_type last_dirsep = std::string::npos;
|
std::string::size_type last_dirsep = std::string::npos;
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
tmp = base;
|
tmp = mBase;
|
||||||
tmp += sep;
|
tmp += sep;
|
||||||
|
|
||||||
std::string::size_type dirsep = in.rfind('/', last_dirsep);
|
std::string::size_type dirsep = in.rfind('/', last_dirsep);
|
||||||
|
@ -223,7 +271,7 @@ private:
|
||||||
last_dirsep = dirsep-1;
|
last_dirsep = dirsep-1;
|
||||||
|
|
||||||
tmp += in.substr(dirsep+1, in.length()-pos);
|
tmp += in.substr(dirsep+1, in.length()-pos);
|
||||||
if (wrapped->Exists(tmp)) {
|
if (mWrapped->Exists(tmp)) {
|
||||||
in = tmp;
|
in = tmp;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -236,15 +284,14 @@ private:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Cleanup the given path
|
/** Cleanup the given path
|
||||||
*/
|
*/
|
||||||
void Cleanup (std::string& in) const
|
void Cleanup (std::string& in) const {
|
||||||
{
|
|
||||||
char last = 0;
|
|
||||||
if(in.empty()) {
|
if(in.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a very common issue when we're parsing file names: spaces at the
|
// Remove a very common issue when we're parsing file names: spaces at the
|
||||||
// beginning of the path.
|
// beginning of the path.
|
||||||
|
char last = 0;
|
||||||
std::string::iterator it = in.begin();
|
std::string::iterator it = in.begin();
|
||||||
while (IsSpaceOrNewLine( *it ))++it;
|
while (IsSpaceOrNewLine( *it ))++it;
|
||||||
if (it != in.begin()) {
|
if (it != in.begin()) {
|
||||||
|
@ -274,9 +321,7 @@ private:
|
||||||
it = in.erase(it);
|
it = in.erase(it);
|
||||||
--it;
|
--it;
|
||||||
}
|
}
|
||||||
}
|
} else if (*it == '%' && in.end() - it > 2) {
|
||||||
else if (*it == '%' && in.end() - it > 2) {
|
|
||||||
|
|
||||||
// Hex sequence in URIs
|
// Hex sequence in URIs
|
||||||
if( IsHex((&*it)[0]) && IsHex((&*it)[1]) ) {
|
if( IsHex((&*it)[0]) && IsHex((&*it)[1]) ) {
|
||||||
*it = HexOctetToDecimal(&*it);
|
*it = HexOctetToDecimal(&*it);
|
||||||
|
@ -290,8 +335,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IOSystem* wrapped;
|
IOSystem *mWrapped;
|
||||||
std::string src_file, base;
|
std::string mSrc_file, mBase;
|
||||||
char sep;
|
char sep;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -60,9 +60,9 @@ namespace Assimp {
|
||||||
* @param in Input mesh
|
* @param in Input mesh
|
||||||
* @return Hash.
|
* @return Hash.
|
||||||
*/
|
*/
|
||||||
inline uint64_t GetMeshHash(aiMesh* in)
|
inline
|
||||||
{
|
uint64_t GetMeshHash(aiMesh* in) {
|
||||||
ai_assert(NULL != in);
|
ai_assert(nullptr != in);
|
||||||
|
|
||||||
// ... get an unique value representing the vertex format of the mesh
|
// ... get an unique value representing the vertex format of the mesh
|
||||||
const unsigned int fhash = GetMeshVFormatUnique(in);
|
const unsigned int fhash = GetMeshVFormatUnique(in);
|
||||||
|
@ -78,14 +78,14 @@ inline uint64_t GetMeshHash(aiMesh* in)
|
||||||
/** @brief Perform a component-wise comparison of two arrays
|
/** @brief Perform a component-wise comparison of two arrays
|
||||||
*
|
*
|
||||||
* @param first First array
|
* @param first First array
|
||||||
* @param second Second aray
|
* @param second Second array
|
||||||
* @param size Size of both arrays
|
* @param size Size of both arrays
|
||||||
* @param e Epsilon
|
* @param e Epsilon
|
||||||
* @return true if the arrays are identical
|
* @return true if the arrays are identical
|
||||||
*/
|
*/
|
||||||
inline bool CompareArrays(const aiVector3D* first, const aiVector3D* second,
|
inline
|
||||||
unsigned int size, float e)
|
bool CompareArrays(const aiVector3D* first, const aiVector3D* second,
|
||||||
{
|
unsigned int size, float e) {
|
||||||
for (const aiVector3D* end = first+size; first != end; ++first,++second) {
|
for (const aiVector3D* end = first+size; first != end; ++first,++second) {
|
||||||
if ( (*first - *second).SquareLength() >= e)
|
if ( (*first - *second).SquareLength() >= e)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -190,7 +190,7 @@ Importer::~Importer()
|
||||||
delete pimpl->mIOHandler;
|
delete pimpl->mIOHandler;
|
||||||
delete pimpl->mProgressHandler;
|
delete pimpl->mProgressHandler;
|
||||||
|
|
||||||
// Kill imported scene. Destructors should do that recursivly
|
// Kill imported scene. Destructor's should do that recursively
|
||||||
delete pimpl->mScene;
|
delete pimpl->mScene;
|
||||||
|
|
||||||
// Delete shared post-processing data
|
// Delete shared post-processing data
|
||||||
|
@ -200,18 +200,6 @@ Importer::~Importer()
|
||||||
delete pimpl;
|
delete pimpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Copy constructor - copies the config of another Importer, not the scene
|
|
||||||
Importer::Importer(const Importer &other)
|
|
||||||
: pimpl(NULL) {
|
|
||||||
new(this) Importer();
|
|
||||||
|
|
||||||
pimpl->mIntProperties = other.pimpl->mIntProperties;
|
|
||||||
pimpl->mFloatProperties = other.pimpl->mFloatProperties;
|
|
||||||
pimpl->mStringProperties = other.pimpl->mStringProperties;
|
|
||||||
pimpl->mMatrixProperties = other.pimpl->mMatrixProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Register a custom post-processing step
|
// Register a custom post-processing step
|
||||||
aiReturn Importer::RegisterPPStep(BaseProcess* pImp)
|
aiReturn Importer::RegisterPPStep(BaseProcess* pImp)
|
||||||
|
|
|
@ -731,17 +731,22 @@ enum MeshAttribute {
|
||||||
TexCoord
|
TexCoord
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const std::string PosToken = "position";
|
||||||
|
static const std::string ColToken = "color";
|
||||||
|
static const std::string NormalToken = "normal";
|
||||||
|
static const std::string TexCoordToken = "texcoord";
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------
|
||||||
static MeshAttribute getAttributeByName( const char *attribName ) {
|
static MeshAttribute getAttributeByName( const char *attribName ) {
|
||||||
ai_assert( nullptr != attribName );
|
ai_assert( nullptr != attribName );
|
||||||
|
|
||||||
if ( 0 == strncmp( "position", attribName, strlen( "position" ) ) ) {
|
if ( 0 == strncmp( PosToken.c_str(), attribName, PosToken.size() ) ) {
|
||||||
return Position;
|
return Position;
|
||||||
} else if ( 0 == strncmp( "color", attribName, strlen( "color" ) ) ) {
|
} else if ( 0 == strncmp( ColToken.c_str(), attribName, ColToken.size() ) ) {
|
||||||
return Color;
|
return Color;
|
||||||
} else if( 0 == strncmp( "normal", attribName, strlen( "normal" ) ) ) {
|
} else if( 0 == strncmp( NormalToken.c_str(), attribName, NormalToken.size() ) ) {
|
||||||
return Normal;
|
return Normal;
|
||||||
} else if( 0 == strncmp( "texcoord", attribName, strlen( "texcoord" ) ) ) {
|
} else if( 0 == strncmp( TexCoordToken.c_str(), attribName, TexCoordToken.size() ) ) {
|
||||||
return TexCoord;
|
return TexCoord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1098,14 +1103,12 @@ void OpenGEXImporter::handleParamNode( ODDLParser::DDLNode *node, aiScene * /*pS
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const float floatVal( val->getFloat() );
|
const float floatVal( val->getFloat() );
|
||||||
if ( prop->m_value != nullptr ) {
|
if ( 0 == ASSIMP_strincmp( "fov", prop->m_value->getString(), 3 ) ) {
|
||||||
if ( 0 == ASSIMP_strincmp( "fov", prop->m_value->getString(), 3 ) ) {
|
m_currentCamera->mHorizontalFOV = floatVal;
|
||||||
m_currentCamera->mHorizontalFOV = floatVal;
|
} else if ( 0 == ASSIMP_strincmp( "near", prop->m_value->getString(), 4 ) ) {
|
||||||
} else if ( 0 == ASSIMP_strincmp( "near", prop->m_value->getString(), 3 ) ) {
|
m_currentCamera->mClipPlaneNear = floatVal;
|
||||||
m_currentCamera->mClipPlaneNear = floatVal;
|
} else if ( 0 == ASSIMP_strincmp( "far", prop->m_value->getString(), 3 ) ) {
|
||||||
} else if ( 0 == ASSIMP_strincmp( "far", prop->m_value->getString(), 3 ) ) {
|
m_currentCamera->mClipPlaneFar = floatVal;
|
||||||
m_currentCamera->mClipPlaneFar = floatVal;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,6 +125,9 @@ corresponding preprocessor flag to selectively disable steps.
|
||||||
#ifndef ASSIMP_BUILD_NO_DEBONE_PROCESS
|
#ifndef ASSIMP_BUILD_NO_DEBONE_PROCESS
|
||||||
# include "DeboneProcess.h"
|
# include "DeboneProcess.h"
|
||||||
#endif
|
#endif
|
||||||
|
#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
|
||||||
|
# include "ScaleProcess.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
@ -136,7 +139,7 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
|
||||||
// of sequence it is executed. Steps that are added here are not
|
// of sequence it is executed. Steps that are added here are not
|
||||||
// validated - as RegisterPPStep() does - all dependencies must be given.
|
// validated - as RegisterPPStep() does - all dependencies must be given.
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
out.reserve(30);
|
out.reserve(31);
|
||||||
#if (!defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS)
|
||||||
out.push_back( new MakeLeftHandedProcess());
|
out.push_back( new MakeLeftHandedProcess());
|
||||||
#endif
|
#endif
|
||||||
|
@ -197,7 +200,9 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
|
||||||
#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS)
|
#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS)
|
||||||
out.push_back( new GenFaceNormalsProcess());
|
out.push_back( new GenFaceNormalsProcess());
|
||||||
#endif
|
#endif
|
||||||
|
#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
|
||||||
|
out.push_back( new ScaleProcess());
|
||||||
|
#endif
|
||||||
// .........................................................................
|
// .........................................................................
|
||||||
// DON'T change the order of these five ..
|
// DON'T change the order of these five ..
|
||||||
// XXX this is actually a design weakness that dates back to the time
|
// XXX this is actually a design weakness that dates back to the time
|
||||||
|
|
|
@ -39,6 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
#ifndef ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS
|
||||||
|
|
||||||
#include "ScaleProcess.h"
|
#include "ScaleProcess.h"
|
||||||
|
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
@ -104,3 +106,5 @@ void ScaleProcess::applyScaling( aiNode *currentNode ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Namespace Assimp
|
} // Namespace Assimp
|
||||||
|
|
||||||
|
#endif // !! ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS
|
||||||
|
|
|
@ -1256,29 +1256,30 @@ void SceneCombiner::Copy(aiMetadata** _dest, const aiMetadata* src) {
|
||||||
aiMetadataEntry& out = dest->mValues[i];
|
aiMetadataEntry& out = dest->mValues[i];
|
||||||
out.mType = in.mType;
|
out.mType = in.mType;
|
||||||
switch (dest->mValues[i].mType) {
|
switch (dest->mValues[i].mType) {
|
||||||
case AI_BOOL:
|
case AI_BOOL:
|
||||||
out.mData = new bool(*static_cast<bool*>(in.mData));
|
out.mData = new bool(*static_cast<bool*>(in.mData));
|
||||||
break;
|
break;
|
||||||
case AI_INT32:
|
case AI_INT32:
|
||||||
out.mData = new int32_t(*static_cast<int32_t*>(in.mData));
|
out.mData = new int32_t(*static_cast<int32_t*>(in.mData));
|
||||||
break;
|
break;
|
||||||
case AI_UINT64:
|
case AI_UINT64:
|
||||||
out.mData = new uint64_t(*static_cast<uint64_t*>(in.mData));
|
out.mData = new uint64_t(*static_cast<uint64_t*>(in.mData));
|
||||||
break;
|
break;
|
||||||
case AI_FLOAT:
|
case AI_FLOAT:
|
||||||
out.mData = new float(*static_cast<float*>(in.mData));
|
out.mData = new float(*static_cast<float*>(in.mData));
|
||||||
break;
|
break;
|
||||||
case AI_DOUBLE:
|
case AI_DOUBLE:
|
||||||
out.mData = new double(*static_cast<double*>(in.mData));
|
out.mData = new double(*static_cast<double*>(in.mData));
|
||||||
break;
|
break;
|
||||||
case AI_AISTRING:
|
case AI_AISTRING:
|
||||||
out.mData = new aiString(*static_cast<aiString*>(in.mData));
|
out.mData = new aiString(*static_cast<aiString*>(in.mData));
|
||||||
break;
|
break;
|
||||||
case AI_AIVECTOR3D:
|
case AI_AIVECTOR3D:
|
||||||
out.mData = new aiVector3D(*static_cast<aiVector3D*>(in.mData));
|
out.mData = new aiVector3D(*static_cast<aiVector3D*>(in.mData));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -294,7 +294,7 @@ void SpatialSort::FindIdenticalPositions( const aiVector3D& pPosition,
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
// Now start iterating from there until the first position lays outside of the distance range.
|
// Now start iterating from there until the first position lays outside of the distance range.
|
||||||
// Add all positions inside the distance range within the tolerance to the result aray
|
// Add all positions inside the distance range within the tolerance to the result array
|
||||||
std::vector<Entry>::const_iterator it = mPositions.begin() + index;
|
std::vector<Entry>::const_iterator it = mPositions.begin() + index;
|
||||||
while( ToBinary(it->mDistance) < maxDistBinary)
|
while( ToBinary(it->mDistance) < maxDistBinary)
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,7 +48,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "VertexTriangleAdjacency.h"
|
#include "VertexTriangleAdjacency.h"
|
||||||
#include <assimp/mesh.h>
|
#include <assimp/mesh.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -60,8 +59,8 @@ VertexTriangleAdjacency::VertexTriangleAdjacency(aiFace *pcFaces,
|
||||||
// compute the number of referenced vertices if it wasn't specified by the caller
|
// compute the number of referenced vertices if it wasn't specified by the caller
|
||||||
const aiFace* const pcFaceEnd = pcFaces + iNumFaces;
|
const aiFace* const pcFaceEnd = pcFaces + iNumFaces;
|
||||||
if (!iNumVertices) {
|
if (!iNumVertices) {
|
||||||
|
|
||||||
for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace) {
|
for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace) {
|
||||||
|
ai_assert( nullptr != pcFace );
|
||||||
ai_assert(3 == pcFace->mNumIndices);
|
ai_assert(3 == pcFace->mNumIndices);
|
||||||
iNumVertices = std::max(iNumVertices,pcFace->mIndices[0]);
|
iNumVertices = std::max(iNumVertices,pcFace->mIndices[0]);
|
||||||
iNumVertices = std::max(iNumVertices,pcFace->mIndices[1]);
|
iNumVertices = std::max(iNumVertices,pcFace->mIndices[1]);
|
||||||
|
@ -69,19 +68,18 @@ VertexTriangleAdjacency::VertexTriangleAdjacency(aiFace *pcFaces,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->iNumVertices = iNumVertices;
|
mNumVertices = iNumVertices;
|
||||||
|
|
||||||
unsigned int* pi;
|
unsigned int* pi;
|
||||||
|
|
||||||
// allocate storage
|
// allocate storage
|
||||||
if (bComputeNumTriangles) {
|
if (bComputeNumTriangles) {
|
||||||
pi = mLiveTriangles = new unsigned int[iNumVertices+1];
|
pi = mLiveTriangles = new unsigned int[iNumVertices+1];
|
||||||
memset(mLiveTriangles,0,sizeof(unsigned int)*(iNumVertices+1));
|
::memset(mLiveTriangles,0,sizeof(unsigned int)*(iNumVertices+1));
|
||||||
mOffsetTable = new unsigned int[iNumVertices+2]+1;
|
mOffsetTable = new unsigned int[iNumVertices+2]+1;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
pi = mOffsetTable = new unsigned int[iNumVertices+2]+1;
|
pi = mOffsetTable = new unsigned int[iNumVertices+2]+1;
|
||||||
memset(mOffsetTable,0,sizeof(unsigned int)*(iNumVertices+1));
|
::memset(mOffsetTable,0,sizeof(unsigned int)*(iNumVertices+1));
|
||||||
mLiveTriangles = NULL; // important, otherwise the d'tor would crash
|
mLiveTriangles = NULL; // important, otherwise the d'tor would crash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,8 +88,7 @@ VertexTriangleAdjacency::VertexTriangleAdjacency(aiFace *pcFaces,
|
||||||
*piEnd++ = 0u;
|
*piEnd++ = 0u;
|
||||||
|
|
||||||
// first pass: compute the number of faces referencing each vertex
|
// first pass: compute the number of faces referencing each vertex
|
||||||
for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace)
|
for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace) {
|
||||||
{
|
|
||||||
pi[pcFace->mIndices[0]]++;
|
pi[pcFace->mIndices[0]]++;
|
||||||
pi[pcFace->mIndices[1]]++;
|
pi[pcFace->mIndices[1]]++;
|
||||||
pi[pcFace->mIndices[2]]++;
|
pi[pcFace->mIndices[2]]++;
|
||||||
|
|
|
@ -60,10 +60,8 @@ namespace Assimp {
|
||||||
* @note Although it is called #VertexTriangleAdjacency, the current version does also
|
* @note Although it is called #VertexTriangleAdjacency, the current version does also
|
||||||
* support arbitrary polygons. */
|
* support arbitrary polygons. */
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
class ASSIMP_API VertexTriangleAdjacency
|
class ASSIMP_API VertexTriangleAdjacency {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** @brief Construction from an existing index buffer
|
/** @brief Construction from an existing index buffer
|
||||||
* @param pcFaces Index buffer
|
* @param pcFaces Index buffer
|
||||||
|
@ -77,39 +75,30 @@ public:
|
||||||
unsigned int iNumVertices = 0,
|
unsigned int iNumVertices = 0,
|
||||||
bool bComputeNumTriangles = true);
|
bool bComputeNumTriangles = true);
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** @brief Destructor */
|
/** @brief Destructor */
|
||||||
~VertexTriangleAdjacency();
|
~VertexTriangleAdjacency();
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** @brief Get all triangles adjacent to a vertex
|
/** @brief Get all triangles adjacent to a vertex
|
||||||
* @param iVertIndex Index of the vertex
|
* @param iVertIndex Index of the vertex
|
||||||
* @return A pointer to the adjacency list. */
|
* @return A pointer to the adjacency list. */
|
||||||
unsigned int* GetAdjacentTriangles(unsigned int iVertIndex) const
|
unsigned int* GetAdjacentTriangles(unsigned int iVertIndex) const {
|
||||||
{
|
ai_assert(iVertIndex < mNumVertices);
|
||||||
ai_assert(iVertIndex < iNumVertices);
|
|
||||||
return &mAdjacencyTable[ mOffsetTable[iVertIndex]];
|
return &mAdjacencyTable[ mOffsetTable[iVertIndex]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** @brief Get the number of triangles that are referenced by
|
/** @brief Get the number of triangles that are referenced by
|
||||||
* a vertex. This function returns a reference that can be modified
|
* a vertex. This function returns a reference that can be modified
|
||||||
* @param iVertIndex Index of the vertex
|
* @param iVertIndex Index of the vertex
|
||||||
* @return Number of referenced triangles */
|
* @return Number of referenced triangles */
|
||||||
unsigned int& GetNumTrianglesPtr(unsigned int iVertIndex)
|
unsigned int& GetNumTrianglesPtr(unsigned int iVertIndex) {
|
||||||
{
|
ai_assert( iVertIndex < mNumVertices );
|
||||||
ai_assert(iVertIndex < iNumVertices && NULL != mLiveTriangles);
|
ai_assert( nullptr != mLiveTriangles );
|
||||||
return mLiveTriangles[iVertIndex];
|
return mLiveTriangles[iVertIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! Offset table
|
//! Offset table
|
||||||
unsigned int* mOffsetTable;
|
unsigned int* mOffsetTable;
|
||||||
|
|
||||||
|
@ -120,9 +109,9 @@ public:
|
||||||
unsigned int* mLiveTriangles;
|
unsigned int* mLiveTriangles;
|
||||||
|
|
||||||
//! Debug: Number of referenced vertices
|
//! Debug: Number of referenced vertices
|
||||||
unsigned int iNumVertices;
|
unsigned int mNumVertices;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
} //! ns Assimp
|
||||||
|
|
||||||
#endif // !! AI_VTADJACENCY_H_INC
|
#endif // !! AI_VTADJACENCY_H_INC
|
||||||
|
|
|
@ -137,7 +137,7 @@ namespace glTF2
|
||||||
// Vec/matrix types, as raw float arrays
|
// Vec/matrix types, as raw float arrays
|
||||||
typedef float (vec3)[3];
|
typedef float (vec3)[3];
|
||||||
typedef float (vec4)[4];
|
typedef float (vec4)[4];
|
||||||
typedef float (mat4)[16];
|
typedef float (mat4)[16];
|
||||||
|
|
||||||
namespace Util
|
namespace Util
|
||||||
{
|
{
|
||||||
|
@ -166,33 +166,8 @@ namespace glTF2
|
||||||
|
|
||||||
//! Magic number for GLB files
|
//! Magic number for GLB files
|
||||||
#define AI_GLB_MAGIC_NUMBER "glTF"
|
#define AI_GLB_MAGIC_NUMBER "glTF"
|
||||||
|
#include <assimp/pbrmaterial.h>
|
||||||
|
|
||||||
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR "$mat.gltf.pbrMetallicRoughness.baseColorFactor", 0, 0
|
|
||||||
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0
|
|
||||||
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0
|
|
||||||
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE aiTextureType_DIFFUSE, 1
|
|
||||||
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 0
|
|
||||||
#define AI_MATKEY_GLTF_ALPHAMODE "$mat.gltf.alphaMode", 0, 0
|
|
||||||
#define AI_MATKEY_GLTF_ALPHACUTOFF "$mat.gltf.alphaCutoff", 0, 0
|
|
||||||
#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS "$mat.gltf.pbrSpecularGlossiness", 0, 0
|
|
||||||
#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR "$mat.gltf.pbrMetallicRoughness.glossinessFactor", 0, 0
|
|
||||||
|
|
||||||
#define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE "$tex.file.texCoord"
|
|
||||||
#define _AI_MATKEY_GLTF_MAPPINGNAME_BASE "$tex.mappingname"
|
|
||||||
#define _AI_MATKEY_GLTF_MAPPINGID_BASE "$tex.mappingid"
|
|
||||||
#define _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE "$tex.mappingfiltermag"
|
|
||||||
#define _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE "$tex.mappingfiltermin"
|
|
||||||
#define _AI_MATKEY_GLTF_SCALE_BASE "$tex.scale"
|
|
||||||
#define _AI_MATKEY_GLTF_STRENGTH_BASE "$tex.strength"
|
|
||||||
|
|
||||||
#define AI_MATKEY_GLTF_TEXTURE_TEXCOORD _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE, type, N
|
|
||||||
#define AI_MATKEY_GLTF_MAPPINGNAME(type, N) _AI_MATKEY_GLTF_MAPPINGNAME_BASE, type, N
|
|
||||||
#define AI_MATKEY_GLTF_MAPPINGID(type, N) _AI_MATKEY_GLTF_MAPPINGID_BASE, type, N
|
|
||||||
#define AI_MATKEY_GLTF_MAPPINGFILTER_MAG(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE, type, N
|
|
||||||
#define AI_MATKEY_GLTF_MAPPINGFILTER_MIN(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE, type, N
|
|
||||||
#define AI_MATKEY_GLTF_TEXTURE_SCALE(type, N) _AI_MATKEY_GLTF_SCALE_BASE, type, N
|
|
||||||
#define AI_MATKEY_GLTF_TEXTURE_STRENGTH(type, N) _AI_MATKEY_GLTF_STRENGTH_BASE, type, N
|
|
||||||
|
|
||||||
#ifdef ASSIMP_API
|
#ifdef ASSIMP_API
|
||||||
#include "./../include/assimp/Compiler/pushpack1.h"
|
#include "./../include/assimp/Compiler/pushpack1.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -248,9 +248,9 @@ bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool continuationFound( false ), endOfDataLine( false );
|
bool continuationFound( false );
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while ( !endOfDataLine ) {
|
for( ;; ) {
|
||||||
if ( continuationToken == m_cache[ m_cachePos ] ) {
|
if ( continuationToken == m_cache[ m_cachePos ] ) {
|
||||||
continuationFound = true;
|
continuationFound = true;
|
||||||
++m_cachePos;
|
++m_cachePos;
|
||||||
|
|
|
@ -137,7 +137,7 @@ public:
|
||||||
* If this Importer owns a scene it won't be copied.
|
* If this Importer owns a scene it won't be copied.
|
||||||
* Call ReadFile() to start the import process.
|
* Call ReadFile() to start the import process.
|
||||||
*/
|
*/
|
||||||
Importer(const Importer& other);
|
Importer(const Importer& other)=delete;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Assignment operator has been deleted
|
/** Assignment operator has been deleted
|
||||||
|
|
|
@ -99,19 +99,19 @@ public:
|
||||||
// Seek specific position
|
// Seek specific position
|
||||||
aiReturn Seek(size_t pOffset, aiOrigin pOrigin) {
|
aiReturn Seek(size_t pOffset, aiOrigin pOrigin) {
|
||||||
if (aiOrigin_SET == pOrigin) {
|
if (aiOrigin_SET == pOrigin) {
|
||||||
if (pOffset >= length) {
|
if (pOffset > length) {
|
||||||
return AI_FAILURE;
|
return AI_FAILURE;
|
||||||
}
|
}
|
||||||
pos = pOffset;
|
pos = pOffset;
|
||||||
}
|
}
|
||||||
else if (aiOrigin_END == pOrigin) {
|
else if (aiOrigin_END == pOrigin) {
|
||||||
if (pOffset >= length) {
|
if (pOffset > length) {
|
||||||
return AI_FAILURE;
|
return AI_FAILURE;
|
||||||
}
|
}
|
||||||
pos = length-pOffset;
|
pos = length-pOffset;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (pOffset+pos >= length) {
|
if (pOffset+pos > length) {
|
||||||
return AI_FAILURE;
|
return AI_FAILURE;
|
||||||
}
|
}
|
||||||
pos += pOffset;
|
pos += pOffset;
|
||||||
|
|
|
@ -123,7 +123,7 @@ protected:
|
||||||
|
|
||||||
Entry() { /** intentionally not initialized.*/ }
|
Entry() { /** intentionally not initialized.*/ }
|
||||||
Entry( unsigned int pIndex, const aiVector3D& pPosition, float pDistance,uint32_t pSG)
|
Entry( unsigned int pIndex, const aiVector3D& pPosition, float pDistance,uint32_t pSG)
|
||||||
:
|
:
|
||||||
mIndex( pIndex),
|
mIndex( pIndex),
|
||||||
mPosition( pPosition),
|
mPosition( pPosition),
|
||||||
mSmoothGroups (pSG),
|
mSmoothGroups (pSG),
|
||||||
|
|
|
@ -47,8 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <assimp/types.h>
|
#include <assimp/types.h>
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
/** A little helper class to quickly find all vertices in the epsilon environment of a given
|
/** A little helper class to quickly find all vertices in the epsilon environment of a given
|
||||||
|
@ -148,17 +147,20 @@ protected:
|
||||||
aiVector3D mPlaneNormal;
|
aiVector3D mPlaneNormal;
|
||||||
|
|
||||||
/** An entry in a spatially sorted position array. Consists of a vertex index,
|
/** An entry in a spatially sorted position array. Consists of a vertex index,
|
||||||
* its position and its precalculated distance from the reference plane */
|
* its position and its pre-calculated distance from the reference plane */
|
||||||
struct Entry
|
struct Entry {
|
||||||
{
|
|
||||||
unsigned int mIndex; ///< The vertex referred by this entry
|
unsigned int mIndex; ///< The vertex referred by this entry
|
||||||
aiVector3D mPosition; ///< Position
|
aiVector3D mPosition; ///< Position
|
||||||
ai_real mDistance; ///< Distance of this vertex to the sorting plane
|
ai_real mDistance; ///< Distance of this vertex to the sorting plane
|
||||||
|
|
||||||
Entry() { /** intentionally not initialized.*/ }
|
Entry()
|
||||||
|
: mIndex( 999999999 ), mPosition(), mDistance( 99999. ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
Entry( unsigned int pIndex, const aiVector3D& pPosition, ai_real pDistance)
|
Entry( unsigned int pIndex, const aiVector3D& pPosition, ai_real pDistance)
|
||||||
: mIndex( pIndex), mPosition( pPosition), mDistance( pDistance)
|
: mIndex( pIndex), mPosition( pPosition), mDistance( pDistance) {
|
||||||
{ }
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
bool operator < (const Entry& e) const { return mDistance < e.mDistance; }
|
bool operator < (const Entry& e) const { return mDistance < e.mDistance; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace Assimp {
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
/** Wrapper class around IOStream to allow for consistent writing of binary data in both
|
/** Wrapper class around IOStream to allow for consistent writing of binary data in both
|
||||||
* little and big endian format. Don't attempt to instance the template directly. Use
|
* little and big endian format. Don't attempt to instance the template directly. Use
|
||||||
* StreamWriterLE to read from a little-endian stream and StreamWriterBE to read from a
|
* StreamWriterLE to write to a little-endian stream and StreamWriterBE to write to a
|
||||||
* BE stream. Alternatively, there is StreamWriterAny if the endianness of the output
|
* BE stream. Alternatively, there is StreamWriterAny if the endianness of the output
|
||||||
* stream is to be determined at runtime.
|
* stream is to be determined at runtime.
|
||||||
*/
|
*/
|
||||||
|
@ -108,6 +108,38 @@ public:
|
||||||
stream->Flush();
|
stream->Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
/** Flush the contents of the internal buffer, and the output IOStream */
|
||||||
|
void Flush()
|
||||||
|
{
|
||||||
|
stream->Write(&buffer[0], 1, buffer.size());
|
||||||
|
stream->Flush();
|
||||||
|
buffer.clear();
|
||||||
|
cursor = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
/** Seek to the given offset / origin in the output IOStream.
|
||||||
|
*
|
||||||
|
* Flushes the internal buffer and the output IOStream prior to seeking. */
|
||||||
|
aiReturn Seek(size_t pOffset, aiOrigin pOrigin=aiOrigin_SET)
|
||||||
|
{
|
||||||
|
Flush();
|
||||||
|
return stream->Seek(pOffset, pOrigin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
/** Tell the current position in the output IOStream.
|
||||||
|
*
|
||||||
|
* First flushes the internal buffer and the output IOStream. */
|
||||||
|
size_t Tell()
|
||||||
|
{
|
||||||
|
Flush();
|
||||||
|
return stream->Tell();
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
@ -171,6 +203,32 @@ public:
|
||||||
Put(n);
|
Put(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
/** Write an aiString to the stream */
|
||||||
|
void PutString(const aiString& s)
|
||||||
|
{
|
||||||
|
// as Put(T f) below
|
||||||
|
if (cursor + s.length >= buffer.size()) {
|
||||||
|
buffer.resize(cursor + s.length);
|
||||||
|
}
|
||||||
|
void* dest = &buffer[cursor];
|
||||||
|
::memcpy(dest, s.C_Str(), s.length);
|
||||||
|
cursor += s.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
/** Write a std::string to the stream */
|
||||||
|
void PutString(const std::string& s)
|
||||||
|
{
|
||||||
|
// as Put(T f) below
|
||||||
|
if (cursor + s.size() >= buffer.size()) {
|
||||||
|
buffer.resize(cursor + s.size());
|
||||||
|
}
|
||||||
|
void* dest = &buffer[cursor];
|
||||||
|
::memcpy(dest, s.c_str(), s.size());
|
||||||
|
cursor += s.size();
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
|
@ -59,69 +59,65 @@ const double fast_atof_table[16] = { // we write [16] here instead of [] to wo
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// Convert a string in decimal format to a number
|
// Convert a string in decimal format to a number
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline unsigned int strtoul10( const char* in, const char** out=0)
|
inline
|
||||||
{
|
unsigned int strtoul10( const char* in, const char** out=0) {
|
||||||
unsigned int value = 0;
|
unsigned int value = 0;
|
||||||
|
|
||||||
bool running = true;
|
for ( ;; ) {
|
||||||
while ( running )
|
|
||||||
{
|
|
||||||
if ( *in < '0' || *in > '9' )
|
if ( *in < '0' || *in > '9' )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
value = ( value * 10 ) + ( *in - '0' );
|
value = ( value * 10 ) + ( *in - '0' );
|
||||||
++in;
|
++in;
|
||||||
}
|
}
|
||||||
if (out)*out = in;
|
if ( out ) {
|
||||||
|
*out = in;
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// Convert a string in octal format to a number
|
// Convert a string in octal format to a number
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline unsigned int strtoul8( const char* in, const char** out=0)
|
inline
|
||||||
{
|
unsigned int strtoul8( const char* in, const char** out=0) {
|
||||||
unsigned int value = 0;
|
unsigned int value( 0 );
|
||||||
|
for ( ;; ) {
|
||||||
bool running = true;
|
if ( *in < '0' || *in > '7' ) {
|
||||||
while ( running )
|
|
||||||
{
|
|
||||||
if ( *in < '0' || *in > '7' )
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
value = ( value << 3 ) + ( *in - '0' );
|
value = ( value << 3 ) + ( *in - '0' );
|
||||||
++in;
|
++in;
|
||||||
}
|
}
|
||||||
if (out)*out = in;
|
if ( out ) {
|
||||||
|
*out = in;
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// Convert a string in hex format to a number
|
// Convert a string in hex format to a number
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline unsigned int strtoul16( const char* in, const char** out=0)
|
inline
|
||||||
{
|
unsigned int strtoul16( const char* in, const char** out=0) {
|
||||||
unsigned int value = 0;
|
unsigned int value( 0 );
|
||||||
|
for ( ;; ) {
|
||||||
bool running = true;
|
if ( *in >= '0' && *in <= '9' ) {
|
||||||
while ( running )
|
|
||||||
{
|
|
||||||
if ( *in >= '0' && *in <= '9' )
|
|
||||||
{
|
|
||||||
value = ( value << 4u ) + ( *in - '0' );
|
value = ( value << 4u ) + ( *in - '0' );
|
||||||
}
|
} else if (*in >= 'A' && *in <= 'F') {
|
||||||
else if (*in >= 'A' && *in <= 'F')
|
|
||||||
{
|
|
||||||
value = ( value << 4u ) + ( *in - 'A' ) + 10;
|
value = ( value << 4u ) + ( *in - 'A' ) + 10;
|
||||||
}
|
} else if (*in >= 'a' && *in <= 'f') {
|
||||||
else if (*in >= 'a' && *in <= 'f')
|
|
||||||
{
|
|
||||||
value = ( value << 4u ) + ( *in - 'a' ) + 10;
|
value = ( value << 4u ) + ( *in - 'a' ) + 10;
|
||||||
}
|
}
|
||||||
else break;
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
++in;
|
++in;
|
||||||
}
|
}
|
||||||
if (out)*out = in;
|
if ( out ) {
|
||||||
|
*out = in;
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,15 +127,14 @@ inline unsigned int strtoul16( const char* in, const char** out=0)
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline
|
inline
|
||||||
unsigned int HexDigitToDecimal(char in) {
|
unsigned int HexDigitToDecimal(char in) {
|
||||||
unsigned int out = UINT_MAX;
|
unsigned int out( UINT_MAX );
|
||||||
if (in >= '0' && in <= '9')
|
if ( in >= '0' && in <= '9' ) {
|
||||||
out = in - '0';
|
out = in - '0';
|
||||||
|
} else if ( in >= 'a' && in <= 'f' ) {
|
||||||
else if (in >= 'a' && in <= 'f')
|
|
||||||
out = 10u + in - 'a';
|
out = 10u + in - 'a';
|
||||||
|
} else if ( in >= 'A' && in <= 'F' ) {
|
||||||
else if (in >= 'A' && in <= 'F')
|
|
||||||
out = 10u + in - 'A';
|
out = 10u + in - 'A';
|
||||||
|
}
|
||||||
|
|
||||||
// return value is UINT_MAX if the input is not a hex digit
|
// return value is UINT_MAX if the input is not a hex digit
|
||||||
return out;
|
return out;
|
||||||
|
@ -160,8 +155,9 @@ uint8_t HexOctetToDecimal(const char* in) {
|
||||||
inline
|
inline
|
||||||
int strtol10( const char* in, const char** out=0) {
|
int strtol10( const char* in, const char** out=0) {
|
||||||
bool inv = (*in=='-');
|
bool inv = (*in=='-');
|
||||||
if (inv || *in=='+')
|
if ( inv || *in == '+' ) {
|
||||||
++in;
|
++in;
|
||||||
|
}
|
||||||
|
|
||||||
int value = strtoul10(in,out);
|
int value = strtoul10(in,out);
|
||||||
if (inv) {
|
if (inv) {
|
||||||
|
@ -197,8 +193,7 @@ uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_ino
|
||||||
throw std::invalid_argument( std::string( "The string \"" ) + in + "\" cannot be converted into a value." );
|
throw std::invalid_argument( std::string( "The string \"" ) + in + "\" cannot be converted into a value." );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool running = true;
|
for ( ;; ) {
|
||||||
while ( running ) {
|
|
||||||
if ( *in < '0' || *in > '9' ) {
|
if ( *in < '0' || *in > '9' ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -378,6 +373,6 @@ ai_real fast_atof( const char** inout) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} //! namespace Assimp
|
||||||
|
|
||||||
#endif // FAST_A_TO_F_H_INCLUDED
|
#endif // FAST_A_TO_F_H_INCLUDED
|
||||||
|
|
|
@ -200,8 +200,7 @@ struct aiFace
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** @brief A single influence of a bone on a vertex.
|
/** @brief A single influence of a bone on a vertex.
|
||||||
*/
|
*/
|
||||||
struct aiVertexWeight
|
struct aiVertexWeight {
|
||||||
{
|
|
||||||
//! Index of the vertex which is influenced by the bone.
|
//! Index of the vertex which is influenced by the bone.
|
||||||
unsigned int mVertexId;
|
unsigned int mVertexId;
|
||||||
|
|
||||||
|
@ -214,15 +213,26 @@ struct aiVertexWeight
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
aiVertexWeight()
|
aiVertexWeight()
|
||||||
: mVertexId(0)
|
: mVertexId(0)
|
||||||
, mWeight(0.0f)
|
, mWeight(0.0f) {
|
||||||
{ }
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
//! Initialisation from a given index and vertex weight factor
|
//! Initialisation from a given index and vertex weight factor
|
||||||
//! \param pID ID
|
//! \param pID ID
|
||||||
//! \param pWeight Vertex weight factor
|
//! \param pWeight Vertex weight factor
|
||||||
aiVertexWeight( unsigned int pID, float pWeight)
|
aiVertexWeight( unsigned int pID, float pWeight )
|
||||||
: mVertexId( pID), mWeight( pWeight)
|
: mVertexId( pID )
|
||||||
{ /* nothing to do here */ }
|
, mWeight( pWeight ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator == ( const aiVertexWeight &rhs ) const {
|
||||||
|
return ( mVertexId == rhs.mVertexId && mWeight == rhs.mWeight );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator != ( const aiVertexWeight &rhs ) const {
|
||||||
|
return ( *this == rhs );
|
||||||
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
};
|
};
|
||||||
|
@ -235,8 +245,7 @@ struct aiVertexWeight
|
||||||
* which it can be addressed by animations. In addition it has a number of
|
* which it can be addressed by animations. In addition it has a number of
|
||||||
* influences on vertices.
|
* influences on vertices.
|
||||||
*/
|
*/
|
||||||
struct aiBone
|
struct aiBone {
|
||||||
{
|
|
||||||
//! The name of the bone.
|
//! The name of the bone.
|
||||||
C_STRUCT aiString mName;
|
C_STRUCT aiString mName;
|
||||||
|
|
||||||
|
@ -254,10 +263,10 @@ struct aiBone
|
||||||
|
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
aiBone()
|
aiBone()
|
||||||
: mName()
|
: mName()
|
||||||
, mNumWeights( 0 )
|
, mNumWeights( 0 )
|
||||||
, mWeights( NULL )
|
, mWeights( nullptr ) {
|
||||||
{
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Copy constructor
|
//! Copy constructor
|
||||||
|
@ -298,7 +307,19 @@ struct aiBone
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator == ( const aiBone &rhs ) const {
|
||||||
|
if ( mName != rhs.mName || mNumWeights != rhs.mNumWeights ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < mNumWeights; ++i ) {
|
||||||
|
if ( mWeights[ i ] != rhs.mWeights[ i ] ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
//! Destructor - deletes the array of vertex weights
|
//! Destructor - deletes the array of vertex weights
|
||||||
~aiBone()
|
~aiBone()
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2018, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file pbrmaterial.h
|
||||||
|
* @brief Defines the material system of the library
|
||||||
|
*/
|
||||||
|
#ifndef AI_PBRMATERIAL_H_INC
|
||||||
|
#define AI_PBRMATERIAL_H_INC
|
||||||
|
|
||||||
|
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR "$mat.gltf.pbrMetallicRoughness.baseColorFactor", 0, 0
|
||||||
|
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0
|
||||||
|
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0
|
||||||
|
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE aiTextureType_DIFFUSE, 1
|
||||||
|
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 0
|
||||||
|
#define AI_MATKEY_GLTF_ALPHAMODE "$mat.gltf.alphaMode", 0, 0
|
||||||
|
#define AI_MATKEY_GLTF_ALPHACUTOFF "$mat.gltf.alphaCutoff", 0, 0
|
||||||
|
#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS "$mat.gltf.pbrSpecularGlossiness", 0, 0
|
||||||
|
#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR "$mat.gltf.pbrMetallicRoughness.glossinessFactor", 0, 0
|
||||||
|
|
||||||
|
#define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE "$tex.file.texCoord"
|
||||||
|
#define _AI_MATKEY_GLTF_MAPPINGNAME_BASE "$tex.mappingname"
|
||||||
|
#define _AI_MATKEY_GLTF_MAPPINGID_BASE "$tex.mappingid"
|
||||||
|
#define _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE "$tex.mappingfiltermag"
|
||||||
|
#define _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE "$tex.mappingfiltermin"
|
||||||
|
#define _AI_MATKEY_GLTF_SCALE_BASE "$tex.scale"
|
||||||
|
#define _AI_MATKEY_GLTF_STRENGTH_BASE "$tex.strength"
|
||||||
|
|
||||||
|
#define AI_MATKEY_GLTF_TEXTURE_TEXCOORD(type, N) _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE, type, N
|
||||||
|
#define AI_MATKEY_GLTF_MAPPINGNAME(type, N) _AI_MATKEY_GLTF_MAPPINGNAME_BASE, type, N
|
||||||
|
#define AI_MATKEY_GLTF_MAPPINGID(type, N) _AI_MATKEY_GLTF_MAPPINGID_BASE, type, N
|
||||||
|
#define AI_MATKEY_GLTF_MAPPINGFILTER_MAG(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE, type, N
|
||||||
|
#define AI_MATKEY_GLTF_MAPPINGFILTER_MIN(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE, type, N
|
||||||
|
#define AI_MATKEY_GLTF_TEXTURE_SCALE(type, N) _AI_MATKEY_GLTF_SCALE_BASE, type, N
|
||||||
|
#define AI_MATKEY_GLTF_TEXTURE_STRENGTH(type, N) _AI_MATKEY_GLTF_STRENGTH_BASE, type, N
|
||||||
|
|
||||||
|
#endif //!!AI_PBRMATERIAL_H_INC
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue