commit
2ec6b2d214
|
@ -66,7 +66,6 @@ namespace FBX {
|
||||||
|
|
||||||
using namespace Util;
|
using namespace Util;
|
||||||
|
|
||||||
|
|
||||||
#define MAGIC_NODE_TAG "_$AssimpFbx$"
|
#define MAGIC_NODE_TAG "_$AssimpFbx$"
|
||||||
|
|
||||||
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
|
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
|
||||||
|
@ -74,373 +73,6 @@ using namespace Util;
|
||||||
// XXX vc9's debugger won't step into anonymous namespaces
|
// XXX vc9's debugger won't step into anonymous namespaces
|
||||||
//namespace {
|
//namespace {
|
||||||
|
|
||||||
/** Dummy class to encapsulate the conversion process */
|
|
||||||
class Converter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* The different parts that make up the final local transformation of a fbx-node
|
|
||||||
*/
|
|
||||||
enum TransformationComp
|
|
||||||
{
|
|
||||||
TransformationComp_Translation = 0,
|
|
||||||
TransformationComp_RotationOffset,
|
|
||||||
TransformationComp_RotationPivot,
|
|
||||||
TransformationComp_PreRotation,
|
|
||||||
TransformationComp_Rotation,
|
|
||||||
TransformationComp_PostRotation,
|
|
||||||
TransformationComp_RotationPivotInverse,
|
|
||||||
TransformationComp_ScalingOffset,
|
|
||||||
TransformationComp_ScalingPivot,
|
|
||||||
TransformationComp_Scaling,
|
|
||||||
TransformationComp_ScalingPivotInverse,
|
|
||||||
TransformationComp_GeometricTranslation,
|
|
||||||
TransformationComp_GeometricRotation,
|
|
||||||
TransformationComp_GeometricScaling,
|
|
||||||
|
|
||||||
TransformationComp_MAXIMUM
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
Converter( aiScene* out, const Document& doc );
|
|
||||||
~Converter();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// find scene root and trigger recursive scene conversion
|
|
||||||
void ConvertRootNode();
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// collect and assign child nodes
|
|
||||||
void ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4() );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void ConvertLights( const Model& model );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void ConvertCameras( const Model& model );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void ConvertLight( const Model& model, const Light& light );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void ConvertCamera( const Model& model, const Camera& cam );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// this returns unified names usable within assimp identifiers (i.e. no space characters -
|
|
||||||
// while these would be allowed, they are a potential trouble spot so better not use them).
|
|
||||||
const char* NameTransformationComp( TransformationComp comp );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// note: this returns the REAL fbx property names
|
|
||||||
const char* NameTransformationCompProperty( TransformationComp comp );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
aiVector3D TransformationCompDefaultValue( TransformationComp comp );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out );
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* checks if a node has more than just scaling, rotation and translation components
|
|
||||||
*/
|
|
||||||
bool NeedsComplexTransformationChain( const Model& model );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// note: name must be a FixNodeName() result
|
|
||||||
std::string NameTransformationChainNode( const std::string& name, TransformationComp comp );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* note: memory for output_nodes will be managed by the caller
|
|
||||||
*/
|
|
||||||
void GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void SetupNodeMetadata( const Model& model, aiNode& nd );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
|
|
||||||
std::vector<unsigned int> ConvertMesh( const MeshGeometry& mesh, const Model& model,
|
|
||||||
const aiMatrix4x4& node_global_transform );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
aiMesh* SetupEmptyMesh( const MeshGeometry& mesh );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
unsigned int ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model,
|
|
||||||
const aiMatrix4x4& node_global_transform );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
std::vector<unsigned int> ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
|
|
||||||
const aiMatrix4x4& node_global_transform );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
unsigned int ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
|
|
||||||
MatIndexArray::value_type index,
|
|
||||||
const aiMatrix4x4& node_global_transform );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */
|
|
||||||
static_cast<unsigned int>(-1);
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* - if materialIndex == NO_MATERIAL_SEPARATION, materials are not taken into
|
|
||||||
* account when determining which weights to include.
|
|
||||||
* - outputVertStartIndices is only used when a material index is specified, it gives for
|
|
||||||
* each output vertex the DOM index it maps to.
|
|
||||||
*/
|
|
||||||
void ConvertWeights( aiMesh* out, const Model& model, const MeshGeometry& geo,
|
|
||||||
const aiMatrix4x4& node_global_transform = aiMatrix4x4(),
|
|
||||||
unsigned int materialIndex = NO_MATERIAL_SEPARATION,
|
|
||||||
std::vector<unsigned int>* outputVertStartIndices = NULL );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void ConvertCluster( std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
|
|
||||||
std::vector<size_t>& out_indices,
|
|
||||||
std::vector<size_t>& index_out_indices,
|
|
||||||
std::vector<size_t>& count_out_indices,
|
|
||||||
const aiMatrix4x4& node_global_transform );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void ConvertMaterialForMesh( aiMesh* out, const Model& model, const MeshGeometry& geo,
|
|
||||||
MatIndexArray::value_type materialIndex );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
unsigned int GetDefaultMaterial();
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Material -> aiMaterial
|
|
||||||
unsigned int ConvertMaterial( const Material& material, const MeshGeometry* const mesh );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Video -> aiTexture
|
|
||||||
unsigned int ConvertVideo( const Video& video );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures,
|
|
||||||
const std::string& propName,
|
|
||||||
aiTextureType target, const MeshGeometry* const mesh );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures,
|
|
||||||
const std::string& propName,
|
|
||||||
aiTextureType target, const MeshGeometry* const mesh );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void SetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void SetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
aiColor3D GetColorPropertyFromMaterial( const PropertyTable& props, const std::string& baseName,
|
|
||||||
bool& result );
|
|
||||||
aiColor3D GetColorPropertyFactored( const PropertyTable& props, const std::string& colorName,
|
|
||||||
const std::string& factorName, bool& result, bool useTemplate=true );
|
|
||||||
aiColor3D GetColorProperty( const PropertyTable& props, const std::string& colorName,
|
|
||||||
bool& result, bool useTemplate=true );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyTable& props );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// get the number of fps for a FrameRate enumerated value
|
|
||||||
static double FrameRateToDouble( FileGlobalSettings::FrameRate fp, double customFPSVal = -1.0 );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// convert animation data to aiAnimation et al
|
|
||||||
void ConvertAnimations();
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// rename a node already partially converted. fixed_name is a string previously returned by
|
|
||||||
// FixNodeName, new_name specifies the string FixNodeName should return on all further invocations
|
|
||||||
// which would previously have returned the old value.
|
|
||||||
//
|
|
||||||
// this also updates names in node animations, cameras and light sources and is thus slow.
|
|
||||||
//
|
|
||||||
// NOTE: the caller is responsible for ensuring that the new name is unique and does
|
|
||||||
// not collide with any other identifiers. The best way to ensure this is to only
|
|
||||||
// append to the old name, which is guaranteed to match these requirements.
|
|
||||||
void RenameNode( const std::string& fixed_name, const std::string& new_name );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// takes a fbx node name and returns the identifier to be used in the assimp output scene.
|
|
||||||
// the function is guaranteed to provide consistent results over multiple invocations
|
|
||||||
// UNLESS RenameNode() is called for a particular node name.
|
|
||||||
std::string FixNodeName( const std::string& name );
|
|
||||||
|
|
||||||
typedef std::map<const AnimationCurveNode*, const AnimationLayer*> LayerMap;
|
|
||||||
|
|
||||||
// XXX: better use multi_map ..
|
|
||||||
typedef std::map<std::string, std::vector<const AnimationCurveNode*> > NodeMap;
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void ConvertAnimationStack( const AnimationStack& st );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
|
|
||||||
const std::string& fixed_name,
|
|
||||||
const std::vector<const AnimationCurveNode*>& curves,
|
|
||||||
const LayerMap& layer_map,
|
|
||||||
int64_t start, int64_t stop,
|
|
||||||
double& max_time,
|
|
||||||
double& min_time );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
bool IsRedundantAnimationData( const Model& target,
|
|
||||||
TransformationComp comp,
|
|
||||||
const std::vector<const AnimationCurveNode*>& curves );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
aiNodeAnim* GenerateRotationNodeAnim( const std::string& name,
|
|
||||||
const Model& target,
|
|
||||||
const std::vector<const AnimationCurveNode*>& curves,
|
|
||||||
const LayerMap& layer_map,
|
|
||||||
int64_t start, int64_t stop,
|
|
||||||
double& max_time,
|
|
||||||
double& min_time );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
aiNodeAnim* GenerateScalingNodeAnim( const std::string& name,
|
|
||||||
const Model& /*target*/,
|
|
||||||
const std::vector<const AnimationCurveNode*>& curves,
|
|
||||||
const LayerMap& layer_map,
|
|
||||||
int64_t start, int64_t stop,
|
|
||||||
double& max_time,
|
|
||||||
double& min_time );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
aiNodeAnim* GenerateTranslationNodeAnim( const std::string& name,
|
|
||||||
const Model& /*target*/,
|
|
||||||
const std::vector<const AnimationCurveNode*>& curves,
|
|
||||||
const LayerMap& layer_map,
|
|
||||||
int64_t start, int64_t stop,
|
|
||||||
double& max_time,
|
|
||||||
double& min_time,
|
|
||||||
bool inverse = false );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// generate node anim, extracting only Rotation, Scaling and Translation from the given chain
|
|
||||||
aiNodeAnim* GenerateSimpleNodeAnim( const std::string& name,
|
|
||||||
const Model& target,
|
|
||||||
NodeMap::const_iterator chain[ TransformationComp_MAXIMUM ],
|
|
||||||
NodeMap::const_iterator iter_end,
|
|
||||||
const LayerMap& layer_map,
|
|
||||||
int64_t start, int64_t stop,
|
|
||||||
double& max_time,
|
|
||||||
double& min_time,
|
|
||||||
bool reverse_order = false );
|
|
||||||
|
|
||||||
// key (time), value, mapto (component index)
|
|
||||||
typedef std::tuple<std::shared_ptr<KeyTimeList>, std::shared_ptr<KeyValueList>, unsigned int > KeyFrameList;
|
|
||||||
typedef std::vector<KeyFrameList> KeyFrameListList;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
KeyFrameListList GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
KeyTimeList GetKeyTimeList( const KeyFrameListList& inputs );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
|
|
||||||
const aiVector3D& def_value,
|
|
||||||
double& max_time,
|
|
||||||
double& min_time );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
|
|
||||||
const aiVector3D& def_value,
|
|
||||||
double& maxTime,
|
|
||||||
double& minTime,
|
|
||||||
Model::RotOrder order );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey* out_scale,
|
|
||||||
aiVectorKey* out_translation,
|
|
||||||
const KeyFrameListList& scaling,
|
|
||||||
const KeyFrameListList& translation,
|
|
||||||
const KeyFrameListList& rotation,
|
|
||||||
const KeyTimeList& times,
|
|
||||||
double& maxTime,
|
|
||||||
double& minTime,
|
|
||||||
Model::RotOrder order,
|
|
||||||
const aiVector3D& def_scale,
|
|
||||||
const aiVector3D& def_translate,
|
|
||||||
const aiVector3D& def_rotation );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// euler xyz -> quat
|
|
||||||
aiQuaternion EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
|
|
||||||
int64_t start, int64_t stop,
|
|
||||||
double& maxTime,
|
|
||||||
double& minTime );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
|
||||||
const LayerMap& /*layers*/,
|
|
||||||
int64_t start, int64_t stop,
|
|
||||||
double& maxTime,
|
|
||||||
double& minTime );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
|
||||||
const LayerMap& /*layers*/,
|
|
||||||
int64_t start, int64_t stop,
|
|
||||||
double& maxTime,
|
|
||||||
double& minTime,
|
|
||||||
Model::RotOrder order );
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// copy generated meshes, animations, lights, cameras and textures to the output scene
|
|
||||||
void TransferDataToScene();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// 0: not assigned yet, others: index is value - 1
|
|
||||||
unsigned int defaultMaterialIndex;
|
|
||||||
|
|
||||||
std::vector<aiMesh*> meshes;
|
|
||||||
std::vector<aiMaterial*> materials;
|
|
||||||
std::vector<aiAnimation*> animations;
|
|
||||||
std::vector<aiLight*> lights;
|
|
||||||
std::vector<aiCamera*> cameras;
|
|
||||||
std::vector<aiTexture*> textures;
|
|
||||||
|
|
||||||
typedef std::map<const Material*, unsigned int> MaterialMap;
|
|
||||||
MaterialMap materials_converted;
|
|
||||||
|
|
||||||
typedef std::map<const Video*, unsigned int> VideoMap;
|
|
||||||
VideoMap textures_converted;
|
|
||||||
|
|
||||||
typedef std::map<const Geometry*, std::vector<unsigned int> > MeshMap;
|
|
||||||
MeshMap meshes_converted;
|
|
||||||
|
|
||||||
// fixed node name -> which trafo chain components have animations?
|
|
||||||
typedef std::map<std::string, unsigned int> NodeAnimBitMap;
|
|
||||||
NodeAnimBitMap node_anim_chain_bits;
|
|
||||||
|
|
||||||
// name -> has had its prefix_stripped?
|
|
||||||
typedef std::map<std::string, bool> NodeNameMap;
|
|
||||||
NodeNameMap node_names;
|
|
||||||
|
|
||||||
typedef std::map<std::string, std::string> NameNameMap;
|
|
||||||
NameNameMap renamed_nodes;
|
|
||||||
|
|
||||||
double anim_fps;
|
|
||||||
|
|
||||||
aiScene* const out;
|
|
||||||
const FBX::Document& doc;
|
|
||||||
};
|
|
||||||
|
|
||||||
Converter::Converter( aiScene* out, const Document& doc )
|
Converter::Converter( aiScene* out, const Document& doc )
|
||||||
: defaultMaterialIndex()
|
: defaultMaterialIndex()
|
||||||
|
@ -472,6 +104,7 @@ Converter::Converter( aiScene* out, const Document& doc )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConvertGlobalSettings();
|
||||||
TransferDataToScene();
|
TransferDataToScene();
|
||||||
|
|
||||||
// if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE
|
// if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE
|
||||||
|
@ -3341,9 +2974,21 @@ void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const Ani
|
||||||
|
|
||||||
na->mNumRotationKeys = static_cast<unsigned int>( keys.size() );
|
na->mNumRotationKeys = static_cast<unsigned int>( keys.size() );
|
||||||
na->mRotationKeys = new aiQuatKey[ keys.size() ];
|
na->mRotationKeys = new aiQuatKey[ keys.size() ];
|
||||||
if ( keys.size() > 0 )
|
if (!keys.empty()) {
|
||||||
InterpolateKeys(na->mRotationKeys, keys, inputs, aiVector3D(0.0f, 0.0f, 0.0f), maxTime, minTime, order);
|
InterpolateKeys(na->mRotationKeys, keys, inputs, aiVector3D(0.0f, 0.0f, 0.0f), maxTime, minTime, order);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Converter::ConvertGlobalSettings() {
|
||||||
|
if (nullptr == out) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->mMetaData = aiMetadata::Alloc(1);
|
||||||
|
unsigned int index(0);
|
||||||
|
const double unitScalFactor(doc.GlobalSettings().UnitScaleFactor());
|
||||||
|
out->mMetaData->Set(index, "UnitScaleFactor", unitScalFactor);
|
||||||
|
}
|
||||||
|
|
||||||
void Converter::TransferDataToScene()
|
void Converter::TransferDataToScene()
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,7 +45,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef INCLUDED_AI_FBX_CONVERTER_H
|
#ifndef INCLUDED_AI_FBX_CONVERTER_H
|
||||||
#define INCLUDED_AI_FBX_CONVERTER_H
|
#define INCLUDED_AI_FBX_CONVERTER_H
|
||||||
|
|
||||||
|
#include "FBXParser.h"
|
||||||
|
#include "FBXMeshGeometry.h"
|
||||||
|
#include "FBXDocument.h"
|
||||||
|
#include "FBXUtil.h"
|
||||||
|
#include "FBXProperties.h"
|
||||||
|
#include "FBXImporter.h"
|
||||||
|
#include <assimp/anim.h>
|
||||||
|
#include <assimp/material.h>
|
||||||
|
#include <assimp/light.h>
|
||||||
|
#include <assimp/texture.h>
|
||||||
|
#include <assimp/camera.h>
|
||||||
|
#include <assimp/StringComparison.h>
|
||||||
|
|
||||||
struct aiScene;
|
struct aiScene;
|
||||||
|
struct aiNode;
|
||||||
|
struct aiMaterial;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace FBX {
|
namespace FBX {
|
||||||
|
@ -59,6 +74,373 @@ class Document;
|
||||||
*/
|
*/
|
||||||
void ConvertToAssimpScene(aiScene* out, const Document& doc);
|
void ConvertToAssimpScene(aiScene* out, const Document& doc);
|
||||||
|
|
||||||
|
/** Dummy class to encapsulate the conversion process */
|
||||||
|
class Converter {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* The different parts that make up the final local transformation of a fbx-node
|
||||||
|
*/
|
||||||
|
enum TransformationComp {
|
||||||
|
TransformationComp_Translation = 0,
|
||||||
|
TransformationComp_RotationOffset,
|
||||||
|
TransformationComp_RotationPivot,
|
||||||
|
TransformationComp_PreRotation,
|
||||||
|
TransformationComp_Rotation,
|
||||||
|
TransformationComp_PostRotation,
|
||||||
|
TransformationComp_RotationPivotInverse,
|
||||||
|
TransformationComp_ScalingOffset,
|
||||||
|
TransformationComp_ScalingPivot,
|
||||||
|
TransformationComp_Scaling,
|
||||||
|
TransformationComp_ScalingPivotInverse,
|
||||||
|
TransformationComp_GeometricTranslation,
|
||||||
|
TransformationComp_GeometricRotation,
|
||||||
|
TransformationComp_GeometricScaling,
|
||||||
|
|
||||||
|
TransformationComp_MAXIMUM
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
Converter(aiScene* out, const Document& doc);
|
||||||
|
~Converter();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// find scene root and trigger recursive scene conversion
|
||||||
|
void ConvertRootNode();
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// collect and assign child nodes
|
||||||
|
void ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4());
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ConvertLights(const Model& model);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ConvertCameras(const Model& model);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ConvertLight(const Model& model, const Light& light);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ConvertCamera(const Model& model, const Camera& cam);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// this returns unified names usable within assimp identifiers (i.e. no space characters -
|
||||||
|
// while these would be allowed, they are a potential trouble spot so better not use them).
|
||||||
|
const char* NameTransformationComp(TransformationComp comp);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// note: this returns the REAL fbx property names
|
||||||
|
const char* NameTransformationCompProperty(TransformationComp comp);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiVector3D TransformationCompDefaultValue(TransformationComp comp);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void GetRotationMatrix(Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out);
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* checks if a node has more than just scaling, rotation and translation components
|
||||||
|
*/
|
||||||
|
bool NeedsComplexTransformationChain(const Model& model);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// note: name must be a FixNodeName() result
|
||||||
|
std::string NameTransformationChainNode(const std::string& name, TransformationComp comp);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* note: memory for output_nodes will be managed by the caller
|
||||||
|
*/
|
||||||
|
void GenerateTransformationNodeChain(const Model& model, std::vector<aiNode*>& output_nodes);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void SetupNodeMetadata(const Model& model, aiNode& nd);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
|
||||||
|
std::vector<unsigned int> ConvertMesh(const MeshGeometry& mesh, const Model& model,
|
||||||
|
const aiMatrix4x4& node_global_transform);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiMesh* SetupEmptyMesh(const MeshGeometry& mesh);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model,
|
||||||
|
const aiMatrix4x4& node_global_transform);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
std::vector<unsigned int> ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
|
||||||
|
const aiMatrix4x4& node_global_transform);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
unsigned int ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
|
||||||
|
MatIndexArray::value_type index,
|
||||||
|
const aiMatrix4x4& node_global_transform);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */
|
||||||
|
static_cast<unsigned int>(-1);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* - if materialIndex == NO_MATERIAL_SEPARATION, materials are not taken into
|
||||||
|
* account when determining which weights to include.
|
||||||
|
* - outputVertStartIndices is only used when a material index is specified, it gives for
|
||||||
|
* each output vertex the DOM index it maps to.
|
||||||
|
*/
|
||||||
|
void ConvertWeights(aiMesh* out, const Model& model, const MeshGeometry& geo,
|
||||||
|
const aiMatrix4x4& node_global_transform = aiMatrix4x4(),
|
||||||
|
unsigned int materialIndex = NO_MATERIAL_SEPARATION,
|
||||||
|
std::vector<unsigned int>* outputVertStartIndices = NULL);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ConvertCluster(std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
|
||||||
|
std::vector<size_t>& out_indices,
|
||||||
|
std::vector<size_t>& index_out_indices,
|
||||||
|
std::vector<size_t>& count_out_indices,
|
||||||
|
const aiMatrix4x4& node_global_transform);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo,
|
||||||
|
MatIndexArray::value_type materialIndex);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
unsigned int GetDefaultMaterial();
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Material -> aiMaterial
|
||||||
|
unsigned int ConvertMaterial(const Material& material, const MeshGeometry* const mesh);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Video -> aiTexture
|
||||||
|
unsigned int ConvertVideo(const Video& video);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void TrySetTextureProperties(aiMaterial* out_mat, const TextureMap& textures,
|
||||||
|
const std::string& propName,
|
||||||
|
aiTextureType target, const MeshGeometry* const mesh);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void TrySetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures,
|
||||||
|
const std::string& propName,
|
||||||
|
aiTextureType target, const MeshGeometry* const mesh);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void SetTextureProperties(aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiColor3D GetColorPropertyFromMaterial(const PropertyTable& props, const std::string& baseName,
|
||||||
|
bool& result);
|
||||||
|
aiColor3D GetColorPropertyFactored(const PropertyTable& props, const std::string& colorName,
|
||||||
|
const std::string& factorName, bool& result, bool useTemplate = true);
|
||||||
|
aiColor3D GetColorProperty(const PropertyTable& props, const std::string& colorName,
|
||||||
|
bool& result, bool useTemplate = true);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void SetShadingPropertiesCommon(aiMaterial* out_mat, const PropertyTable& props);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// get the number of fps for a FrameRate enumerated value
|
||||||
|
static double FrameRateToDouble(FileGlobalSettings::FrameRate fp, double customFPSVal = -1.0);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// convert animation data to aiAnimation et al
|
||||||
|
void ConvertAnimations();
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// rename a node already partially converted. fixed_name is a string previously returned by
|
||||||
|
// FixNodeName, new_name specifies the string FixNodeName should return on all further invocations
|
||||||
|
// which would previously have returned the old value.
|
||||||
|
//
|
||||||
|
// this also updates names in node animations, cameras and light sources and is thus slow.
|
||||||
|
//
|
||||||
|
// NOTE: the caller is responsible for ensuring that the new name is unique and does
|
||||||
|
// not collide with any other identifiers. The best way to ensure this is to only
|
||||||
|
// append to the old name, which is guaranteed to match these requirements.
|
||||||
|
void RenameNode(const std::string& fixed_name, const std::string& new_name);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// takes a fbx node name and returns the identifier to be used in the assimp output scene.
|
||||||
|
// the function is guaranteed to provide consistent results over multiple invocations
|
||||||
|
// UNLESS RenameNode() is called for a particular node name.
|
||||||
|
std::string FixNodeName(const std::string& name);
|
||||||
|
|
||||||
|
typedef std::map<const AnimationCurveNode*, const AnimationLayer*> LayerMap;
|
||||||
|
|
||||||
|
// XXX: better use multi_map ..
|
||||||
|
typedef std::map<std::string, std::vector<const AnimationCurveNode*> > NodeMap;
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ConvertAnimationStack(const AnimationStack& st);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void GenerateNodeAnimations(std::vector<aiNodeAnim*>& node_anims,
|
||||||
|
const std::string& fixed_name,
|
||||||
|
const std::vector<const AnimationCurveNode*>& curves,
|
||||||
|
const LayerMap& layer_map,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
|
double& max_time,
|
||||||
|
double& min_time);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool IsRedundantAnimationData(const Model& target,
|
||||||
|
TransformationComp comp,
|
||||||
|
const std::vector<const AnimationCurveNode*>& curves);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiNodeAnim* GenerateRotationNodeAnim(const std::string& name,
|
||||||
|
const Model& target,
|
||||||
|
const std::vector<const AnimationCurveNode*>& curves,
|
||||||
|
const LayerMap& layer_map,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
|
double& max_time,
|
||||||
|
double& min_time);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiNodeAnim* GenerateScalingNodeAnim(const std::string& name,
|
||||||
|
const Model& /*target*/,
|
||||||
|
const std::vector<const AnimationCurveNode*>& curves,
|
||||||
|
const LayerMap& layer_map,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
|
double& max_time,
|
||||||
|
double& min_time);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiNodeAnim* GenerateTranslationNodeAnim(const std::string& name,
|
||||||
|
const Model& /*target*/,
|
||||||
|
const std::vector<const AnimationCurveNode*>& curves,
|
||||||
|
const LayerMap& layer_map,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
|
double& max_time,
|
||||||
|
double& min_time,
|
||||||
|
bool inverse = false);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// generate node anim, extracting only Rotation, Scaling and Translation from the given chain
|
||||||
|
aiNodeAnim* GenerateSimpleNodeAnim(const std::string& name,
|
||||||
|
const Model& target,
|
||||||
|
NodeMap::const_iterator chain[TransformationComp_MAXIMUM],
|
||||||
|
NodeMap::const_iterator iter_end,
|
||||||
|
const LayerMap& layer_map,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
|
double& max_time,
|
||||||
|
double& min_time,
|
||||||
|
bool reverse_order = false);
|
||||||
|
|
||||||
|
// key (time), value, mapto (component index)
|
||||||
|
typedef std::tuple<std::shared_ptr<KeyTimeList>, std::shared_ptr<KeyValueList>, unsigned int > KeyFrameList;
|
||||||
|
typedef std::vector<KeyFrameList> KeyFrameListList;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
KeyFrameListList GetKeyframeList(const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
KeyTimeList GetKeyTimeList(const KeyFrameListList& inputs);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void InterpolateKeys(aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
|
||||||
|
const aiVector3D& def_value,
|
||||||
|
double& max_time,
|
||||||
|
double& min_time);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void InterpolateKeys(aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
|
||||||
|
const aiVector3D& def_value,
|
||||||
|
double& maxTime,
|
||||||
|
double& minTime,
|
||||||
|
Model::RotOrder order);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ConvertTransformOrder_TRStoSRT(aiQuatKey* out_quat, aiVectorKey* out_scale,
|
||||||
|
aiVectorKey* out_translation,
|
||||||
|
const KeyFrameListList& scaling,
|
||||||
|
const KeyFrameListList& translation,
|
||||||
|
const KeyFrameListList& rotation,
|
||||||
|
const KeyTimeList& times,
|
||||||
|
double& maxTime,
|
||||||
|
double& minTime,
|
||||||
|
Model::RotOrder order,
|
||||||
|
const aiVector3D& def_scale,
|
||||||
|
const aiVector3D& def_translate,
|
||||||
|
const aiVector3D& def_rotation);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// euler xyz -> quat
|
||||||
|
aiQuaternion EulerToQuaternion(const aiVector3D& rot, Model::RotOrder order);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ConvertScaleKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
|
double& maxTime,
|
||||||
|
double& minTime);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||||
|
const LayerMap& /*layers*/,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
|
double& maxTime,
|
||||||
|
double& minTime);
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void ConvertRotationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||||
|
const LayerMap& /*layers*/,
|
||||||
|
int64_t start, int64_t stop,
|
||||||
|
double& maxTime,
|
||||||
|
double& minTime,
|
||||||
|
Model::RotOrder order);
|
||||||
|
|
||||||
|
void ConvertGlobalSettings();
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// copy generated meshes, animations, lights, cameras and textures to the output scene
|
||||||
|
void TransferDataToScene();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// 0: not assigned yet, others: index is value - 1
|
||||||
|
unsigned int defaultMaterialIndex;
|
||||||
|
|
||||||
|
std::vector<aiMesh*> meshes;
|
||||||
|
std::vector<aiMaterial*> materials;
|
||||||
|
std::vector<aiAnimation*> animations;
|
||||||
|
std::vector<aiLight*> lights;
|
||||||
|
std::vector<aiCamera*> cameras;
|
||||||
|
std::vector<aiTexture*> textures;
|
||||||
|
|
||||||
|
typedef std::map<const Material*, unsigned int> MaterialMap;
|
||||||
|
MaterialMap materials_converted;
|
||||||
|
|
||||||
|
typedef std::map<const Video*, unsigned int> VideoMap;
|
||||||
|
VideoMap textures_converted;
|
||||||
|
|
||||||
|
typedef std::map<const Geometry*, std::vector<unsigned int> > MeshMap;
|
||||||
|
MeshMap meshes_converted;
|
||||||
|
|
||||||
|
// fixed node name -> which trafo chain components have animations?
|
||||||
|
typedef std::map<std::string, unsigned int> NodeAnimBitMap;
|
||||||
|
NodeAnimBitMap node_anim_chain_bits;
|
||||||
|
|
||||||
|
// name -> has had its prefix_stripped?
|
||||||
|
typedef std::map<std::string, bool> NodeNameMap;
|
||||||
|
NodeNameMap node_names;
|
||||||
|
|
||||||
|
typedef std::map<std::string, std::string> NameNameMap;
|
||||||
|
NameNameMap renamed_nodes;
|
||||||
|
|
||||||
|
double anim_fps;
|
||||||
|
|
||||||
|
aiScene* const out;
|
||||||
|
const FBX::Document& doc;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -344,9 +344,8 @@ void Document::ReadGlobalSettings()
|
||||||
{
|
{
|
||||||
const Scope& sc = parser.GetRootScope();
|
const Scope& sc = parser.GetRootScope();
|
||||||
const Element* const ehead = sc["GlobalSettings"];
|
const Element* const ehead = sc["GlobalSettings"];
|
||||||
if(!ehead || !ehead->Compound()) {
|
if ( nullptr == ehead || !ehead->Compound() ) {
|
||||||
DOMWarning( "no GlobalSettings dictionary found" );
|
DOMWarning( "no GlobalSettings dictionary found" );
|
||||||
|
|
||||||
globals.reset(new FileGlobalSettings(*this, std::make_shared<const PropertyTable>()));
|
globals.reset(new FileGlobalSettings(*this, std::make_shared<const PropertyTable>()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -999,8 +999,7 @@ typedef std::multimap<uint64_t, const Connection*> ConnectionMap;
|
||||||
|
|
||||||
/** DOM class for global document settings, a single instance per document can
|
/** DOM class for global document settings, a single instance per document can
|
||||||
* be accessed via Document.Globals(). */
|
* be accessed via Document.Globals(). */
|
||||||
class FileGlobalSettings
|
class FileGlobalSettings {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
FileGlobalSettings(const Document& doc, std::shared_ptr<const PropertyTable> props);
|
FileGlobalSettings(const Document& doc, std::shared_ptr<const PropertyTable> props);
|
||||||
~FileGlobalSettings();
|
~FileGlobalSettings();
|
||||||
|
|
|
@ -140,8 +140,7 @@ void FBXImporter::SetupProperties(const Importer* pImp)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void FBXImporter::InternReadFile( const std::string& pFile,
|
void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
|
||||||
aiScene* pScene, IOSystem* pIOHandler)
|
|
||||||
{
|
{
|
||||||
std::unique_ptr<IOStream> stream(pIOHandler->Open(pFile,"rb"));
|
std::unique_ptr<IOStream> stream(pIOHandler->Open(pFile,"rb"));
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
|
|
|
@ -174,11 +174,9 @@ private:
|
||||||
friend class Element;
|
friend class Element;
|
||||||
|
|
||||||
TokenPtr AdvanceToNextToken();
|
TokenPtr AdvanceToNextToken();
|
||||||
|
|
||||||
TokenPtr LastToken() const;
|
TokenPtr LastToken() const;
|
||||||
TokenPtr CurrentToken() const;
|
TokenPtr CurrentToken() const;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const TokenList& tokens;
|
const TokenList& tokens;
|
||||||
|
|
||||||
|
@ -199,7 +197,6 @@ int ParseTokenAsInt(const Token& t, const char*& err_out);
|
||||||
int64_t ParseTokenAsInt64(const Token& t, const char*& err_out);
|
int64_t ParseTokenAsInt64(const Token& t, const char*& err_out);
|
||||||
std::string ParseTokenAsString(const Token& t, const char*& err_out);
|
std::string ParseTokenAsString(const Token& t, const char*& err_out);
|
||||||
|
|
||||||
|
|
||||||
/* wrapper around ParseTokenAsXXX() with DOMError handling */
|
/* wrapper around ParseTokenAsXXX() with DOMError handling */
|
||||||
uint64_t ParseTokenAsID(const Token& t);
|
uint64_t ParseTokenAsID(const Token& t);
|
||||||
size_t ParseTokenAsDim(const Token& t);
|
size_t ParseTokenAsDim(const Token& t);
|
||||||
|
|
|
@ -118,19 +118,20 @@ ASSIMP_API const char *aiGetBranchName() {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API aiScene::aiScene()
|
ASSIMP_API aiScene::aiScene()
|
||||||
: mFlags(0)
|
: mFlags(0)
|
||||||
, mRootNode(NULL)
|
, mRootNode(nullptr)
|
||||||
, mNumMeshes(0)
|
, mNumMeshes(0)
|
||||||
, mMeshes(NULL)
|
, mMeshes(nullptr)
|
||||||
, mNumMaterials(0)
|
, mNumMaterials(0)
|
||||||
, mMaterials(NULL)
|
, mMaterials(nullptr)
|
||||||
, mNumAnimations(0)
|
, mNumAnimations(0)
|
||||||
, mAnimations(NULL)
|
, mAnimations(nullptr)
|
||||||
, mNumTextures(0)
|
, mNumTextures(0)
|
||||||
, mTextures(NULL)
|
, mTextures(nullptr)
|
||||||
, mNumLights(0)
|
, mNumLights(0)
|
||||||
, mLights(NULL)
|
, mLights(nullptr)
|
||||||
, mNumCameras(0)
|
, mNumCameras(0)
|
||||||
, mCameras(NULL)
|
, mCameras(nullptr)
|
||||||
|
, mMetaData(nullptr)
|
||||||
, mPrivate(new Assimp::ScenePrivateData()) {
|
, mPrivate(new Assimp::ScenePrivateData()) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
@ -173,6 +174,9 @@ ASSIMP_API aiScene::~aiScene() {
|
||||||
delete mCameras[a];
|
delete mCameras[a];
|
||||||
delete [] mCameras;
|
delete [] mCameras;
|
||||||
|
|
||||||
|
aiMetadata::Dealloc(mMetaData);
|
||||||
|
mMetaData = nullptr;
|
||||||
|
|
||||||
delete static_cast<Assimp::ScenePrivateData*>( mPrivate );
|
delete static_cast<Assimp::ScenePrivateData*>( mPrivate );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -326,6 +326,16 @@ struct aiScene
|
||||||
*/
|
*/
|
||||||
C_STRUCT aiCamera** mCameras;
|
C_STRUCT aiCamera** mCameras;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The global metadata assigned to the scene itself.
|
||||||
|
*
|
||||||
|
* This data contains global metadata which belongs to the scene like
|
||||||
|
* unit-conversions, versions, vendors or other model-specific data. This
|
||||||
|
* can be used to store format-specific metadata as well.
|
||||||
|
*/
|
||||||
|
C_STRUCT aiMetadata* mMetaData;
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
//! Default constructor - set everything to 0/NULL
|
//! Default constructor - set everything to 0/NULL
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,24 +0,0 @@
|
||||||
ply
|
|
||||||
format ascii 1.0
|
|
||||||
comment Created by Open Asset Import Library - http://assimp.sf.net (v4.1.1712791017)
|
|
||||||
element vertex 8
|
|
||||||
property float x
|
|
||||||
property float y
|
|
||||||
property float z
|
|
||||||
element face 6
|
|
||||||
property list uchar int vertex_index
|
|
||||||
end_header
|
|
||||||
0 0 0
|
|
||||||
0 0 1
|
|
||||||
0 1 1
|
|
||||||
0 1 0
|
|
||||||
1 0 0
|
|
||||||
1 0 1
|
|
||||||
1 1 1
|
|
||||||
1 1 0
|
|
||||||
4 0 1 2 3
|
|
||||||
4 7 6 5 4
|
|
||||||
4 0 4 5 1
|
|
||||||
4 1 5 6 2
|
|
||||||
4 2 6 7 3
|
|
||||||
4 3 7 4 0
|
|
|
@ -97,3 +97,15 @@ TEST_F( utFBXImporterExporter, importPhongMaterial ) {
|
||||||
EXPECT_EQ( mat->Get(AI_MATKEY_OPACITY, f), aiReturn_SUCCESS );
|
EXPECT_EQ( mat->Get(AI_MATKEY_OPACITY, f), aiReturn_SUCCESS );
|
||||||
EXPECT_EQ( f, 0.5 );
|
EXPECT_EQ( f, 0.5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(utFBXImporterExporter, importUnitScaleFactor) {
|
||||||
|
Assimp::Importer importer;
|
||||||
|
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/spider.fbx", aiProcess_ValidateDataStructure);
|
||||||
|
|
||||||
|
EXPECT_NE(nullptr, scene);
|
||||||
|
EXPECT_NE(nullptr, scene->mMetaData);
|
||||||
|
|
||||||
|
double factor(0.0);
|
||||||
|
scene->mMetaData->Get("UnitScaleFactor", factor);
|
||||||
|
EXPECT_DOUBLE_EQ(1.0, factor);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue