commit
880e5ee32c
|
@ -77,7 +77,7 @@ namespace Assimp {
|
||||||
|
|
||||||
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
|
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
|
||||||
|
|
||||||
FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones)
|
FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit )
|
||||||
: defaultMaterialIndex()
|
: defaultMaterialIndex()
|
||||||
, lights()
|
, lights()
|
||||||
, cameras()
|
, cameras()
|
||||||
|
@ -91,7 +91,8 @@ namespace Assimp {
|
||||||
, anim_fps()
|
, anim_fps()
|
||||||
, out(out)
|
, out(out)
|
||||||
, doc(doc)
|
, doc(doc)
|
||||||
, mRemoveEmptyBones( removeEmptyBones ) {
|
, mRemoveEmptyBones( removeEmptyBones )
|
||||||
|
, mCurrentUnit(FbxUnit::cm) {
|
||||||
// animations need to be converted first since this will
|
// animations need to be converted first since this will
|
||||||
// populate the node_anim_chain_bits map, which is needed
|
// populate the node_anim_chain_bits map, which is needed
|
||||||
// to determine which nodes need to be generated.
|
// to determine which nodes need to be generated.
|
||||||
|
@ -119,6 +120,7 @@ namespace Assimp {
|
||||||
|
|
||||||
ConvertGlobalSettings();
|
ConvertGlobalSettings();
|
||||||
TransferDataToScene();
|
TransferDataToScene();
|
||||||
|
ConvertToUnitScale(unit);
|
||||||
|
|
||||||
// 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
|
||||||
// to make sure the scene passes assimp's validation. FBX files
|
// to make sure the scene passes assimp's validation. FBX files
|
||||||
|
@ -3417,9 +3419,10 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
|
||||||
|
|
||||||
na->mNumScalingKeys = static_cast<unsigned int>(keys.size());
|
na->mNumScalingKeys = static_cast<unsigned int>(keys.size());
|
||||||
na->mScalingKeys = new aiVectorKey[keys.size()];
|
na->mScalingKeys = new aiVectorKey[keys.size()];
|
||||||
if (keys.size() > 0)
|
if (keys.size() > 0) {
|
||||||
InterpolateKeys(na->mScalingKeys, keys, inputs, aiVector3D(1.0f, 1.0f, 1.0f), maxTime, minTime);
|
InterpolateKeys(na->mScalingKeys, keys, inputs, aiVector3D(1.0f, 1.0f, 1.0f), maxTime, minTime);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FBXConverter::ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
void FBXConverter::ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||||
const LayerMap& /*layers*/,
|
const LayerMap& /*layers*/,
|
||||||
|
@ -3482,6 +3485,46 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
|
||||||
out->mMetaData->Set(14, "CustomFrameRate", doc.GlobalSettings().CustomFrameRate());
|
out->mMetaData->Set(14, "CustomFrameRate", doc.GlobalSettings().CustomFrameRate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FBXConverter::ConvertToUnitScale( FbxUnit unit ) {
|
||||||
|
if (mCurrentUnit == unit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ai_real scale = 1.0;
|
||||||
|
if (mCurrentUnit == FbxUnit::cm) {
|
||||||
|
if (unit == FbxUnit::m) {
|
||||||
|
scale = (ai_real)0.01;
|
||||||
|
} else if (unit == FbxUnit::km) {
|
||||||
|
scale = (ai_real)0.00001;
|
||||||
|
}
|
||||||
|
} else if (mCurrentUnit == FbxUnit::m) {
|
||||||
|
if (unit == FbxUnit::cm) {
|
||||||
|
scale = (ai_real)100.0;
|
||||||
|
} else if (unit == FbxUnit::km) {
|
||||||
|
scale = (ai_real)0.001;
|
||||||
|
}
|
||||||
|
} else if (mCurrentUnit == FbxUnit::km) {
|
||||||
|
if (unit == FbxUnit::cm) {
|
||||||
|
scale = (ai_real)100000.0;
|
||||||
|
} else if (unit == FbxUnit::m) {
|
||||||
|
scale = (ai_real)1000.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto mesh : meshes) {
|
||||||
|
if (nullptr == mesh) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh->HasPositions()) {
|
||||||
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
|
aiVector3D &pos = mesh->mVertices[i];
|
||||||
|
pos *= scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FBXConverter::TransferDataToScene()
|
void FBXConverter::TransferDataToScene()
|
||||||
{
|
{
|
||||||
ai_assert(!out->mMeshes);
|
ai_assert(!out->mMeshes);
|
||||||
|
@ -3535,9 +3578,9 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones)
|
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit)
|
||||||
{
|
{
|
||||||
FBXConverter converter(out, doc, removeEmptyBones);
|
FBXConverter converter(out, doc, removeEmptyBones, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // !FBX
|
} // !FBX
|
||||||
|
|
|
@ -76,13 +76,22 @@ namespace FBX {
|
||||||
|
|
||||||
class Document;
|
class Document;
|
||||||
|
|
||||||
|
enum class FbxUnit {
|
||||||
|
cm = 0,
|
||||||
|
m,
|
||||||
|
km,
|
||||||
|
NumUnits,
|
||||||
|
|
||||||
|
Undefined
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a FBX #Document to #aiScene
|
* Convert a FBX #Document to #aiScene
|
||||||
* @param out Empty scene to be populated
|
* @param out Empty scene to be populated
|
||||||
* @param doc Parsed FBX document
|
* @param doc Parsed FBX document
|
||||||
* @param removeEmptyBones Will remove bones, which do not have any references to vertices.
|
* @param removeEmptyBones Will remove bones, which do not have any references to vertices.
|
||||||
*/
|
*/
|
||||||
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones );
|
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit);
|
||||||
|
|
||||||
/** Dummy class to encapsulate the conversion process */
|
/** Dummy class to encapsulate the conversion process */
|
||||||
class FBXConverter {
|
class FBXConverter {
|
||||||
|
@ -113,7 +122,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones );
|
FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit);
|
||||||
~FBXConverter();
|
~FBXConverter();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -415,6 +424,10 @@ private:
|
||||||
|
|
||||||
void ConvertGlobalSettings();
|
void ConvertGlobalSettings();
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Will perform the conversion from a given unit to the requested unit.
|
||||||
|
void ConvertToUnitScale(FbxUnit unit);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// copy generated meshes, animations, lights, cameras and textures to the output scene
|
// copy generated meshes, animations, lights, cameras and textures to the output scene
|
||||||
void TransferDataToScene();
|
void TransferDataToScene();
|
||||||
|
@ -456,6 +469,8 @@ private:
|
||||||
const FBX::Document& doc;
|
const FBX::Document& doc;
|
||||||
|
|
||||||
bool mRemoveEmptyBones;
|
bool mRemoveEmptyBones;
|
||||||
|
|
||||||
|
FbxUnit mCurrentUnit;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,8 @@ struct ImportSettings
|
||||||
, preservePivots(true)
|
, preservePivots(true)
|
||||||
, optimizeEmptyAnimationCurves(true)
|
, optimizeEmptyAnimationCurves(true)
|
||||||
, useLegacyEmbeddedTextureNaming(false)
|
, useLegacyEmbeddedTextureNaming(false)
|
||||||
, removeEmptyBones( true ) {
|
, removeEmptyBones( true )
|
||||||
|
, convertToMeters( false ) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,6 +150,10 @@ struct ImportSettings
|
||||||
/** Empty bones shall be removed
|
/** Empty bones shall be removed
|
||||||
*/
|
*/
|
||||||
bool removeEmptyBones;
|
bool removeEmptyBones;
|
||||||
|
|
||||||
|
/** Set to true to perform a conversion from cm to meter after the import
|
||||||
|
*/
|
||||||
|
bool convertToMeters;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,7 @@ void FBXImporter::SetupProperties(const Importer* pImp)
|
||||||
settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
|
settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
|
||||||
settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
|
settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
|
||||||
settings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
|
settings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
|
||||||
|
settings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -184,8 +185,12 @@ void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
||||||
// take the raw parse-tree and convert it to a FBX DOM
|
// take the raw parse-tree and convert it to a FBX DOM
|
||||||
Document doc(parser,settings);
|
Document doc(parser,settings);
|
||||||
|
|
||||||
|
FbxUnit unit(FbxUnit::cm);
|
||||||
|
if (settings.convertToMeters) {
|
||||||
|
unit = FbxUnit::m;
|
||||||
|
}
|
||||||
// convert the FBX DOM to aiScene
|
// convert the FBX DOM to aiScene
|
||||||
ConvertToAssimpScene(pScene,doc, settings.removeEmptyBones);
|
ConvertToAssimpScene(pScene,doc, settings.removeEmptyBones, unit);
|
||||||
|
|
||||||
std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
|
std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
|
||||||
}
|
}
|
||||||
|
|
|
@ -568,15 +568,15 @@ void MeshGeometry::ReadVertexDataColors(std::vector<aiColor4D>& colors_out, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
static const std::string TangentIndexToken = "TangentIndex";
|
static const char *TangentIndexToken = "TangentIndex";
|
||||||
static const std::string TangentsIndexToken = "TangentsIndex";
|
static const char *TangentsIndexToken = "TangentsIndex";
|
||||||
|
|
||||||
void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out, const Scope& source,
|
void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out, const Scope& source,
|
||||||
const std::string& MappingInformationType,
|
const std::string& MappingInformationType,
|
||||||
const std::string& ReferenceInformationType)
|
const std::string& ReferenceInformationType)
|
||||||
{
|
{
|
||||||
const char * str = source.Elements().count( "Tangents" ) > 0 ? "Tangents" : "Tangent";
|
const char * str = source.Elements().count( "Tangents" ) > 0 ? "Tangents" : "Tangent";
|
||||||
const char * strIdx = source.Elements().count( "Tangents" ) > 0 ? TangentsIndexToken.c_str() : TangentIndexToken.c_str();
|
const char * strIdx = source.Elements().count( "Tangents" ) > 0 ? TangentsIndexToken : TangentIndexToken;
|
||||||
ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType,
|
ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType,
|
||||||
str,
|
str,
|
||||||
strIdx,
|
strIdx,
|
||||||
|
|
|
@ -117,7 +117,7 @@ namespace FBX {
|
||||||
Element::Element(const Token& key_token, Parser& parser)
|
Element::Element(const Token& key_token, Parser& parser)
|
||||||
: key_token(key_token)
|
: key_token(key_token)
|
||||||
{
|
{
|
||||||
TokenPtr n = NULL;
|
TokenPtr n = nullptr;
|
||||||
do {
|
do {
|
||||||
n = parser.AdvanceToNextToken();
|
n = parser.AdvanceToNextToken();
|
||||||
if(!n) {
|
if(!n) {
|
||||||
|
|
|
@ -659,13 +659,20 @@ enum aiComponent
|
||||||
"AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
|
"AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** @brief Set wether the FBX importer shall not remove empty bones.
|
/** @brief Set wether the importer shall not remove empty bones.
|
||||||
*
|
*
|
||||||
* Empty bone are often used to define connections for other models.
|
* Empty bone are often used to define connections for other models.
|
||||||
*/
|
*/
|
||||||
#define AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES \
|
#define AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES \
|
||||||
"AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES"
|
"AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES"
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** @brief Set wether the FBX importer shall convert the unit from cm to m.
|
||||||
|
*/
|
||||||
|
#define AI_CONFIG_FBX_CONVERT_TO_M \
|
||||||
|
"AI_CONFIG_FBX_CONVERT_TO_M"
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** @brief Set the vertex animation keyframe to be imported
|
/** @brief Set the vertex animation keyframe to be imported
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue