123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 |
- /*
- 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 FBXDConverter.h
- * @brief FBX DOM to aiScene conversion
- */
- #ifndef 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 aiNode;
- struct aiMaterial;
- namespace Assimp {
- namespace FBX {
- class Document;
- /**
- * Convert a FBX #Document to #aiScene
- * @param out Empty scene to be populated
- * @param doc Parsed FBX document
- */
- 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;
- };
- }
- }
- #endif // INCLUDED_AI_FBX_CONVERTER_H
|