2012-06-28 18:02:09 +00:00
|
|
|
/*
|
|
|
|
Open Asset Import Library (assimp)
|
|
|
|
----------------------------------------------------------------------
|
|
|
|
|
2022-01-10 20:13:43 +00:00
|
|
|
Copyright (c) 2006-2022, assimp team
|
2018-01-28 18:42:05 +00:00
|
|
|
|
2017-05-09 17:57:36 +00:00
|
|
|
|
2012-06-28 18:02:09 +00:00
|
|
|
All rights reserved.
|
|
|
|
|
2015-05-19 03:52:10 +00:00
|
|
|
Redistribution and use of this software in source and binary forms,
|
|
|
|
with or without modification, are permitted provided that the
|
2012-06-28 18:02:09 +00:00
|
|
|
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.
|
|
|
|
|
2015-05-19 03:52:10 +00:00
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
2012-06-28 18:02:09 +00:00
|
|
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
2015-05-19 03:52:10 +00:00
|
|
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
2012-06-28 18:02:09 +00:00
|
|
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
2015-05-19 03:52:10 +00:00
|
|
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
2012-06-28 18:02:09 +00:00
|
|
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
2015-05-19 03:52:10 +00:00
|
|
|
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
|
2012-06-28 18:02:09 +00:00
|
|
|
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
|
|
|
|
|
2018-01-23 14:13:23 +00:00
|
|
|
#include "FBXParser.h"
|
|
|
|
#include "FBXMeshGeometry.h"
|
|
|
|
#include "FBXDocument.h"
|
|
|
|
#include "FBXUtil.h"
|
|
|
|
#include "FBXProperties.h"
|
|
|
|
#include "FBXImporter.h"
|
2019-06-06 06:29:12 +00:00
|
|
|
|
2018-01-23 14:13:23 +00:00
|
|
|
#include <assimp/anim.h>
|
|
|
|
#include <assimp/material.h>
|
|
|
|
#include <assimp/light.h>
|
|
|
|
#include <assimp/texture.h>
|
|
|
|
#include <assimp/camera.h>
|
|
|
|
#include <assimp/StringComparison.h>
|
2019-03-27 10:20:16 +00:00
|
|
|
#include <unordered_map>
|
2019-04-03 10:19:23 +00:00
|
|
|
#include <unordered_set>
|
2018-01-23 14:13:23 +00:00
|
|
|
|
2015-04-16 10:32:35 +00:00
|
|
|
struct aiScene;
|
2018-01-23 14:13:23 +00:00
|
|
|
struct aiNode;
|
|
|
|
struct aiMaterial;
|
2015-04-15 19:22:26 +00:00
|
|
|
|
2019-01-06 18:37:30 +00:00
|
|
|
struct morphKeyData {
|
|
|
|
std::vector<unsigned int> values;
|
|
|
|
std::vector<float> weights;
|
|
|
|
};
|
|
|
|
typedef std::map<int64_t, morphKeyData*> morphAnimData;
|
|
|
|
|
2012-06-28 18:02:09 +00:00
|
|
|
namespace Assimp {
|
|
|
|
namespace FBX {
|
|
|
|
|
2022-04-28 19:12:26 +00:00
|
|
|
class MeshGeometry;
|
|
|
|
|
|
|
|
using SkeletonBoneArray = std::vector<aiSkeletonBone *>;
|
|
|
|
using SkeletonBoneToMesh = std::map<aiMesh*, SkeletonBoneArray*>;
|
|
|
|
|
|
|
|
struct SkeletonBoneContainer {
|
|
|
|
std::vector<aiMesh *> MeshArray;
|
|
|
|
SkeletonBoneToMesh SkeletonBoneToMeshLookup;
|
|
|
|
};
|
|
|
|
|
2016-02-28 16:30:11 +00:00
|
|
|
class Document;
|
2022-04-28 19:12:26 +00:00
|
|
|
|
2021-07-29 11:28:51 +00:00
|
|
|
/**
|
2016-03-03 17:38:50 +00:00
|
|
|
* Convert a FBX #Document to #aiScene
|
2012-06-28 18:02:09 +00:00
|
|
|
* @param out Empty scene to be populated
|
2019-05-05 14:23:42 +00:00
|
|
|
* @param doc Parsed FBX document
|
|
|
|
* @param removeEmptyBones Will remove bones, which do not have any references to vertices.
|
2016-03-03 17:38:50 +00:00
|
|
|
*/
|
2019-08-27 14:54:12 +00:00
|
|
|
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones);
|
2012-06-28 18:02:09 +00:00
|
|
|
|
2018-01-23 14:13:23 +00:00
|
|
|
/** Dummy class to encapsulate the conversion process */
|
2018-08-09 19:51:53 +00:00
|
|
|
class FBXConverter {
|
2018-01-23 14:13:23 +00:00
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* The different parts that make up the final local transformation of a fbx-node
|
|
|
|
*/
|
|
|
|
enum TransformationComp {
|
2018-02-21 11:23:28 +00:00
|
|
|
TransformationComp_GeometricScalingInverse = 0,
|
|
|
|
TransformationComp_GeometricRotationInverse,
|
|
|
|
TransformationComp_GeometricTranslationInverse,
|
|
|
|
TransformationComp_Translation,
|
2018-01-23 14:13:23 +00:00
|
|
|
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:
|
2019-08-27 14:54:12 +00:00
|
|
|
FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones);
|
2018-08-09 19:51:53 +00:00
|
|
|
~FBXConverter();
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
// find scene root and trigger recursive scene conversion
|
|
|
|
void ConvertRootNode();
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
// collect and assign child nodes
|
2023-04-05 10:19:39 +00:00
|
|
|
void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node);
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2018-03-31 14:37:39 +00:00
|
|
|
void ConvertLights(const Model& model, const std::string &orig_name );
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2023-04-05 10:19:39 +00:00
|
|
|
void ConvertCameras(const Model& model, const std::string &orig_name );
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2018-03-31 14:37:39 +00:00
|
|
|
void ConvertLight( const Light& light, const std::string &orig_name );
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2023-04-05 10:19:39 +00:00
|
|
|
void ConvertCamera( const Camera& cam, const std::string &orig_name );
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2018-07-13 20:25:04 +00:00
|
|
|
void GetUniqueName( const std::string &name, std::string& uniqueName );
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
// 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);
|
|
|
|
|
2019-05-14 16:58:06 +00:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
// Returns an unique name for a node or traverses up a hierarchy until a non-empty name is found and
|
|
|
|
// then makes this name unique
|
|
|
|
std::string MakeUniqueNodeName(const Model* const model, const aiNode& parent);
|
|
|
|
|
2018-01-23 14:13:23 +00:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
// 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);
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
2020-11-17 10:39:03 +00:00
|
|
|
* note: memory for output_nodes is managed by the caller, via the PotentialNode struct.
|
2018-01-23 14:13:23 +00:00
|
|
|
*/
|
2020-11-17 10:39:03 +00:00
|
|
|
struct PotentialNode;
|
|
|
|
bool GenerateTransformationNodeChain(const Model& model, const std::string& name, std::vector<PotentialNode>& output_nodes, std::vector<PotentialNode>& post_output_nodes);
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
void SetupNodeMetadata(const Model& model, aiNode& nd);
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2022-06-11 16:50:18 +00:00
|
|
|
void ConvertModel(const Model &model, aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform);
|
2021-07-29 11:28:51 +00:00
|
|
|
|
2018-01-23 14:13:23 +00:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
// MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
|
2019-10-26 15:28:51 +00:00
|
|
|
std::vector<unsigned int>
|
2022-06-11 16:50:18 +00:00
|
|
|
ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform);
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2020-03-08 20:24:01 +00:00
|
|
|
std::vector<unsigned int> ConvertLine(const LineGeometry& line, aiNode *root_node);
|
2019-01-17 11:26:22 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2019-10-26 15:28:51 +00:00
|
|
|
aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode *parent);
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2022-06-11 16:50:18 +00:00
|
|
|
unsigned int ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform,
|
2022-04-18 15:10:59 +00:00
|
|
|
aiNode *parent, aiNode *root_node);
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2019-10-26 15:28:51 +00:00
|
|
|
std::vector<unsigned int>
|
2022-06-11 16:50:18 +00:00
|
|
|
ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform, aiNode *parent, aiNode *root_node);
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2022-06-11 16:50:18 +00:00
|
|
|
unsigned int ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform, MatIndexArray::value_type index,
|
2022-04-18 15:10:59 +00:00
|
|
|
aiNode *parent, aiNode *root_node);
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
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.
|
|
|
|
*/
|
2022-06-11 16:50:18 +00:00
|
|
|
void ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform, aiNode *parent = nullptr,
|
2022-04-18 15:10:59 +00:00
|
|
|
unsigned int materialIndex = NO_MATERIAL_SEPARATION,
|
2020-06-23 19:05:42 +00:00
|
|
|
std::vector<unsigned int> *outputVertStartIndices = nullptr);
|
2020-03-08 20:24:01 +00:00
|
|
|
|
2022-04-28 19:12:26 +00:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
void ConvertWeightsToSkeleton(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
|
|
|
|
aiNode *parent, unsigned int materialIndex, std::vector<unsigned int> *outputVertStartIndices,
|
|
|
|
SkeletonBoneContainer &skeletonContainer);
|
|
|
|
|
2018-01-23 14:13:23 +00:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
2019-10-26 15:28:51 +00:00
|
|
|
void ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
|
|
|
|
std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
|
2022-06-11 16:50:18 +00:00
|
|
|
std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform, aiNode *parent);
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
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);
|
|
|
|
|
2018-05-30 12:56:53 +00:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
// convert embedded texture if necessary and return actual texture path
|
|
|
|
aiString GetTexturePath(const Texture* tex);
|
|
|
|
|
2018-01-23 14:13:23 +00:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
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);
|
2019-01-08 21:14:45 +00:00
|
|
|
void SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTable& props, const TextureMap& textures, const MeshGeometry* const mesh);
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
// 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();
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
// 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);
|
2019-01-06 18:37:30 +00:00
|
|
|
std::string FixAnimMeshName(const std::string& name);
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2019-01-06 18:37:30 +00:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
2022-04-28 19:12:26 +00:00
|
|
|
void ProcessMorphAnimDatas(std::map<std::string, morphAnimData*>* morphAnimDatas,
|
|
|
|
const BlendShapeChannel* bsc, const AnimationCurveNode* node);
|
2019-01-06 18:37:30 +00:00
|
|
|
|
2018-01-23 14:13:23 +00:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
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],
|
2020-03-25 06:20:31 +00:00
|
|
|
NodeMap::const_iterator iterEnd,
|
2018-01-23 14:13:23 +00:00
|
|
|
int64_t start, int64_t stop,
|
2020-03-25 06:20:31 +00:00
|
|
|
double& maxTime,
|
|
|
|
double& minTime);
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
// 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);
|
2021-11-29 14:11:26 +00:00
|
|
|
KeyFrameListList GetRotationKeyframeList(const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop);
|
2018-01-23 14:13:23 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
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);
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
// 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);
|
|
|
|
|
2019-12-05 11:25:12 +00:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
2019-12-05 14:09:36 +00:00
|
|
|
// Copy global geometric data and some information about the source asset into scene metadata.
|
2018-01-23 14:13:23 +00:00
|
|
|
void ConvertGlobalSettings();
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
// copy generated meshes, animations, lights, cameras and textures to the output scene
|
|
|
|
void TransferDataToScene();
|
|
|
|
|
2019-11-01 12:29:54 +00:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
// FBX file could have embedded textures not connected to anything
|
2020-05-14 16:43:31 +00:00
|
|
|
void ConvertOrphanedEmbeddedTextures();
|
2019-11-01 12:29:54 +00:00
|
|
|
|
2018-01-23 14:13:23 +00:00
|
|
|
private:
|
|
|
|
// 0: not assigned yet, others: index is value - 1
|
|
|
|
unsigned int defaultMaterialIndex;
|
|
|
|
|
2020-03-08 20:24:01 +00:00
|
|
|
std::vector<aiMesh*> mMeshes;
|
2018-01-23 14:13:23 +00:00
|
|
|
std::vector<aiMaterial*> materials;
|
|
|
|
std::vector<aiAnimation*> animations;
|
|
|
|
std::vector<aiLight*> lights;
|
|
|
|
std::vector<aiCamera*> cameras;
|
|
|
|
std::vector<aiTexture*> textures;
|
|
|
|
|
2019-11-01 12:29:54 +00:00
|
|
|
using MaterialMap = std::fbx_unordered_map<const Material*, unsigned int>;
|
2018-01-23 14:13:23 +00:00
|
|
|
MaterialMap materials_converted;
|
|
|
|
|
2020-11-26 16:29:37 +00:00
|
|
|
using VideoMap = std::fbx_unordered_map<const Video*, unsigned int>;
|
2018-01-23 14:13:23 +00:00
|
|
|
VideoMap textures_converted;
|
|
|
|
|
2019-11-01 12:29:54 +00:00
|
|
|
using MeshMap = std::fbx_unordered_map<const Geometry*, std::vector<unsigned int> >;
|
2018-01-23 14:13:23 +00:00
|
|
|
MeshMap meshes_converted;
|
|
|
|
|
|
|
|
// fixed node name -> which trafo chain components have animations?
|
2019-11-01 12:29:54 +00:00
|
|
|
using NodeAnimBitMap = std::fbx_unordered_map<std::string, unsigned int> ;
|
2018-01-23 14:13:23 +00:00
|
|
|
NodeAnimBitMap node_anim_chain_bits;
|
|
|
|
|
2019-03-27 10:20:16 +00:00
|
|
|
// number of nodes with the same name
|
2019-11-01 12:29:54 +00:00
|
|
|
using NodeNameCache = std::fbx_unordered_map<std::string, unsigned int>;
|
2019-04-03 10:19:23 +00:00
|
|
|
NodeNameCache mNodeNames;
|
2019-03-27 10:20:16 +00:00
|
|
|
|
2019-10-26 15:28:51 +00:00
|
|
|
// Deformer name is not the same as a bone name - it does contain the bone name though :)
|
|
|
|
// Deformer names in FBX are always unique in an FBX file.
|
|
|
|
std::map<const std::string, aiBone *> bone_map;
|
|
|
|
|
2018-01-23 14:13:23 +00:00
|
|
|
double anim_fps;
|
|
|
|
|
2022-04-28 19:43:02 +00:00
|
|
|
std::vector<aiSkeleton *> mSkeletons;
|
2020-03-08 20:24:01 +00:00
|
|
|
aiScene* const mSceneOut;
|
2018-01-23 14:13:23 +00:00
|
|
|
const FBX::Document& doc;
|
2020-03-08 20:24:01 +00:00
|
|
|
bool mRemoveEmptyBones;
|
2019-10-26 15:28:51 +00:00
|
|
|
static void BuildBoneList(aiNode *current_node, const aiNode *root_node, const aiScene *scene,
|
|
|
|
std::vector<aiBone*>& bones);
|
|
|
|
|
|
|
|
void BuildBoneStack(aiNode *current_node, const aiNode *root_node, const aiScene *scene,
|
|
|
|
const std::vector<aiBone *> &bones,
|
|
|
|
std::map<aiBone *, aiNode *> &bone_stack,
|
|
|
|
std::vector<aiNode*> &node_stack );
|
|
|
|
|
|
|
|
static void BuildNodeList(aiNode *current_node, std::vector<aiNode *> &nodes);
|
|
|
|
|
|
|
|
static aiNode *GetNodeFromStack(const aiString &node_name, std::vector<aiNode *> &nodes);
|
|
|
|
|
|
|
|
static aiNode *GetArmatureRoot(aiNode *bone_node, std::vector<aiBone*> &bone_list);
|
|
|
|
|
|
|
|
static bool IsBoneNode(const aiString &bone_name, std::vector<aiBone *> &bones);
|
2018-01-23 14:13:23 +00:00
|
|
|
};
|
|
|
|
|
2012-06-28 18:02:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-03 17:38:50 +00:00
|
|
|
#endif // INCLUDED_AI_FBX_CONVERTER_H
|