mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-29 16:25:42 +00:00
Update assimp importing
assimp importer now works for the most part for fbx and gltf animations for gltf still need to be sorted out
This commit is contained in:
parent
d3f8fee74e
commit
ca6e26520b
5 changed files with 229 additions and 124 deletions
|
|
@ -70,7 +70,7 @@ if (NOT ASSIMP_BUILD_M3D_EXPORTER)
|
||||||
endif () # if (not ASSIMP_BUILD_M3D_EXPORTER)
|
endif () # if (not ASSIMP_BUILD_M3D_EXPORTER)
|
||||||
|
|
||||||
# Toggles the use of the hunter package manager
|
# Toggles the use of the hunter package manager
|
||||||
option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" ON)
|
option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
|
||||||
|
|
||||||
IF(ASSIMP_HUNTER_ENABLED)
|
IF(ASSIMP_HUNTER_ENABLED)
|
||||||
include("cmake-modules/HunterGate.cmake")
|
include("cmake-modules/HunterGate.cmake")
|
||||||
|
|
@ -127,7 +127,7 @@ OPTION ( ASSIMP_COVERALLS
|
||||||
)
|
)
|
||||||
OPTION( ASSIMP_INSTALL
|
OPTION( ASSIMP_INSTALL
|
||||||
"Disable this if you want to use assimp as a submodule."
|
"Disable this if you want to use assimp as a submodule."
|
||||||
OFF
|
ON
|
||||||
)
|
)
|
||||||
OPTION ( ASSIMP_WARNINGS_AS_ERRORS
|
OPTION ( ASSIMP_WARNINGS_AS_ERRORS
|
||||||
"Treat all warnings as errors."
|
"Treat all warnings as errors."
|
||||||
|
|
@ -511,12 +511,12 @@ IF(ASSIMP_HUNTER_ENABLED)
|
||||||
find_package(ZLIB CONFIG REQUIRED)
|
find_package(ZLIB CONFIG REQUIRED)
|
||||||
|
|
||||||
add_definitions(-DASSIMP_BUILD_NO_OWN_ZLIB)
|
add_definitions(-DASSIMP_BUILD_NO_OWN_ZLIB)
|
||||||
set( TRUE)
|
set(ZLIB_FOUND TRUE)
|
||||||
set(ZLIB_LIBRARIES ZLIB::zlib)
|
set(ZLIB_LIBRARIES ZLIB::zlib)
|
||||||
set(ASSIMP_BUILD_MINIZIP TRUE)
|
set(ASSIMP_BUILD_MINIZIP TRUE)
|
||||||
ELSE()
|
ELSE()
|
||||||
# If the zlib is already found outside, add an export in case assimpTargets can't find it.
|
# If the zlib is already found outside, add an export in case assimpTargets can't find it.
|
||||||
IF( AND ASSIMP_INSTALL)
|
IF( ZLIB_FOUND AND ASSIMP_INSTALL)
|
||||||
INSTALL( TARGETS zlib zlibstatic
|
INSTALL( TARGETS zlib zlibstatic
|
||||||
EXPORT "${TARGETS_EXPORT_NAME}")
|
EXPORT "${TARGETS_EXPORT_NAME}")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
@ -525,11 +525,11 @@ ELSE()
|
||||||
FIND_PACKAGE(ZLIB)
|
FIND_PACKAGE(ZLIB)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF ( NOT AND NOT ASSIMP_BUILD_ZLIB )
|
IF ( NOT ZLIB_FOUND AND NOT ASSIMP_BUILD_ZLIB )
|
||||||
message( FATAL_ERROR
|
message( FATAL_ERROR
|
||||||
"Build configured with -DASSIMP_BUILD_ZLIB=OFF but unable to find zlib"
|
"Build configured with -DASSIMP_BUILD_ZLIB=OFF but unable to find zlib"
|
||||||
)
|
)
|
||||||
ELSEIF( NOT )
|
ELSEIF( NOT ZLIB_FOUND )
|
||||||
MESSAGE(STATUS "compiling zlib from sources")
|
MESSAGE(STATUS "compiling zlib from sources")
|
||||||
INCLUDE(CheckIncludeFile)
|
INCLUDE(CheckIncludeFile)
|
||||||
INCLUDE(CheckTypeSize)
|
INCLUDE(CheckTypeSize)
|
||||||
|
|
@ -545,7 +545,7 @@ ELSE()
|
||||||
|
|
||||||
# compile from sources
|
# compile from sources
|
||||||
ADD_SUBDIRECTORY(contrib/zlib)
|
ADD_SUBDIRECTORY(contrib/zlib)
|
||||||
SET( 1)
|
SET(ZLIB_FOUND 1)
|
||||||
SET(ZLIB_LIBRARIES zlibstatic)
|
SET(ZLIB_LIBRARIES zlibstatic)
|
||||||
SET(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/zlib ${CMAKE_CURRENT_BINARY_DIR}/contrib/zlib)
|
SET(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/zlib ${CMAKE_CURRENT_BINARY_DIR}/contrib/zlib)
|
||||||
# need to ensure we don't link with system zlib or minizip as well.
|
# need to ensure we don't link with system zlib or minizip as well.
|
||||||
|
|
|
||||||
|
|
@ -35,14 +35,17 @@ aiAnimation* AssimpAppNode::sActiveSequence = NULL;
|
||||||
F32 AssimpAppNode::sTimeMultiplier = 1.0f;
|
F32 AssimpAppNode::sTimeMultiplier = 1.0f;
|
||||||
|
|
||||||
AssimpAppNode::AssimpAppNode(const struct aiScene* scene, const struct aiNode* node, AssimpAppNode* parent)
|
AssimpAppNode::AssimpAppNode(const struct aiScene* scene, const struct aiNode* node, AssimpAppNode* parent)
|
||||||
: mInvertMeshes(false),
|
: mScene(scene),
|
||||||
mLastTransformTime(TSShapeLoader::DefaultTime - 1),
|
mNode(node ? node : scene->mRootNode),
|
||||||
mDefaultTransformValid(false)
|
appParent(parent),
|
||||||
|
mInvertMeshes(false),
|
||||||
|
mLastTransformTime(TSShapeLoader::DefaultTime - 1),
|
||||||
|
mDefaultTransformValid(false)
|
||||||
{
|
{
|
||||||
mScene = scene;
|
|
||||||
mNode = node;
|
|
||||||
appParent = parent;
|
|
||||||
|
|
||||||
|
mScene = scene;
|
||||||
|
mNode = node ? node : scene->mRootNode;
|
||||||
|
// Initialize node and parent names.
|
||||||
mName = dStrdup(mNode->mName.C_Str());
|
mName = dStrdup(mNode->mName.C_Str());
|
||||||
if ( dStrlen(mName) == 0 )
|
if ( dStrlen(mName) == 0 )
|
||||||
{
|
{
|
||||||
|
|
@ -51,6 +54,8 @@ AssimpAppNode::AssimpAppNode(const struct aiScene* scene, const struct aiNode* n
|
||||||
}
|
}
|
||||||
|
|
||||||
mParentName = dStrdup(parent ? parent->getName() : "ROOT");
|
mParentName = dStrdup(parent ? parent->getName() : "ROOT");
|
||||||
|
|
||||||
|
// Convert transformation matrix
|
||||||
assimpToTorqueMat(node->mTransformation, mNodeTransform);
|
assimpToTorqueMat(node->mTransformation, mNodeTransform);
|
||||||
Con::printf("[ASSIMP] Node Created: %s, Parent: %s", mName, mParentName);
|
Con::printf("[ASSIMP] Node Created: %s, Parent: %s", mName, mParentName);
|
||||||
}
|
}
|
||||||
|
|
@ -58,12 +63,21 @@ AssimpAppNode::AssimpAppNode(const struct aiScene* scene, const struct aiNode* n
|
||||||
// Get all child nodes
|
// Get all child nodes
|
||||||
void AssimpAppNode::buildChildList()
|
void AssimpAppNode::buildChildList()
|
||||||
{
|
{
|
||||||
if (!mNode)
|
// Ensure mNode is valid
|
||||||
{
|
if (!mNode) {
|
||||||
mNode = mScene->mRootNode;
|
Con::errorf("[ASSIMP] Error: mNode is null in buildChildList");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mNode->mChildren)
|
||||||
|
return;
|
||||||
|
|
||||||
for (U32 n = 0; n < mNode->mNumChildren; ++n) {
|
for (U32 n = 0; n < mNode->mNumChildren; ++n) {
|
||||||
|
if (!mNode->mChildren[n]) {
|
||||||
|
Con::errorf("[ASSIMP] Warning: Null child node at index %d", n);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
mChildNodes.push_back(new AssimpAppNode(mScene, mNode->mChildren[n], this));
|
mChildNodes.push_back(new AssimpAppNode(mScene, mNode->mChildren[n], this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,8 @@ class AssimpAppNode : public AppNode
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
const struct aiScene* mScene;
|
const aiScene* mScene;
|
||||||
const struct aiNode* mNode; ///< Pointer to the assimp scene node
|
const aiNode* mNode; ///< Pointer to the assimp scene node
|
||||||
AssimpAppNode* appParent; ///< Parent node
|
AssimpAppNode* appParent; ///< Parent node
|
||||||
MatrixF mNodeTransform; ///< Scene node transform converted to TorqueSpace (filled for ALL nodes)
|
MatrixF mNodeTransform; ///< Scene node transform converted to TorqueSpace (filled for ALL nodes)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,6 @@
|
||||||
#include <assimp/config.h>
|
#include <assimp/config.h>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
#include <assimp/Importer.hpp>
|
|
||||||
|
|
||||||
MODULE_BEGIN( AssimpShapeLoader )
|
MODULE_BEGIN( AssimpShapeLoader )
|
||||||
MODULE_INIT_AFTER( ShapeLoader )
|
MODULE_INIT_AFTER( ShapeLoader )
|
||||||
MODULE_INIT
|
MODULE_INIT
|
||||||
|
|
@ -124,7 +122,80 @@ AssimpShapeLoader::~AssimpShapeLoader()
|
||||||
|
|
||||||
void AssimpShapeLoader::releaseImport()
|
void AssimpShapeLoader::releaseImport()
|
||||||
{
|
{
|
||||||
aiReleaseImport(mScene);
|
}
|
||||||
|
|
||||||
|
void debugSceneMetaData(const aiScene* scene) {
|
||||||
|
if (!scene->mMetaData) {
|
||||||
|
Con::printf("[ASSIMP] No metadata available.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < scene->mMetaData->mNumProperties; ++i) {
|
||||||
|
const char* key = scene->mMetaData->mKeys[i].C_Str();
|
||||||
|
aiMetadataType type = scene->mMetaData->mValues[i].mType;
|
||||||
|
Con::printf("[ASSIMP] Metadata key: %s", key);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case AI_BOOL:
|
||||||
|
Con::printf(" Value: %d (bool)", *(bool*)scene->mMetaData->mValues[i].mData);
|
||||||
|
break;
|
||||||
|
case AI_INT32:
|
||||||
|
Con::printf(" Value: %d (int)", *(int*)scene->mMetaData->mValues[i].mData);
|
||||||
|
break;
|
||||||
|
case AI_UINT64:
|
||||||
|
Con::printf(" Value: %llu (uint64)", *(uint64_t*)scene->mMetaData->mValues[i].mData);
|
||||||
|
break;
|
||||||
|
case AI_FLOAT:
|
||||||
|
Con::printf(" Value: %f (float)", *(float*)scene->mMetaData->mValues[i].mData);
|
||||||
|
break;
|
||||||
|
case AI_DOUBLE:
|
||||||
|
Con::printf(" Value: %f (double)", *(double*)scene->mMetaData->mValues[i].mData);
|
||||||
|
break;
|
||||||
|
case AI_AISTRING:
|
||||||
|
Con::printf(" Value: %s (string)", ((aiString*)scene->mMetaData->mValues[i].mData)->C_Str());
|
||||||
|
break;
|
||||||
|
case AI_AIVECTOR3D:
|
||||||
|
{
|
||||||
|
aiVector3D* vec = (aiVector3D*)scene->mMetaData->mValues[i].mData;
|
||||||
|
Con::printf(" Value: (%f, %f, %f) (vector3d)", vec->x, vec->y, vec->z);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Con::printf(" Unknown metadata type.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void applyTransformation(aiNode* node, const aiMatrix4x4& transform) {
|
||||||
|
node->mTransformation = transform * node->mTransformation; // Apply transformation to the node
|
||||||
|
}
|
||||||
|
|
||||||
|
void reorientGLTFScene(const aiScene* scene) {
|
||||||
|
aiMatrix4x4 rotationMatrix;
|
||||||
|
rotationMatrix = aiMatrix4x4::RotationX(AI_MATH_PI / 2, rotationMatrix); // Rotate -90 degrees around X-axis
|
||||||
|
|
||||||
|
applyTransformation(scene->mRootNode, rotationMatrix);
|
||||||
|
|
||||||
|
rotationMatrix = aiMatrix4x4::RotationZ(AI_MATH_PI, rotationMatrix); // Rotate -90 degrees around X-axis
|
||||||
|
applyTransformation(scene->mRootNode, rotationMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
float getUnitScaleFactor(const aiScene* scene) {
|
||||||
|
float scale = 1.0f;
|
||||||
|
|
||||||
|
if (scene->mMetaData) {
|
||||||
|
double unitScaleFactor;
|
||||||
|
if (scene->mMetaData->Get("UnitScaleFactor", unitScaleFactor)) {
|
||||||
|
scale = static_cast<float>(unitScaleFactor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scaleScene(const aiScene* scene, float scaleFactor) {
|
||||||
|
aiMatrix4x4 scaleMatrix = aiMatrix4x4::Scaling(aiVector3D(scaleFactor, scaleFactor, scaleFactor), aiMatrix4x4());
|
||||||
|
applyTransformation(scene->mRootNode, scaleMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssimpShapeLoader::enumerateScene()
|
void AssimpShapeLoader::enumerateScene()
|
||||||
|
|
@ -132,31 +203,28 @@ void AssimpShapeLoader::enumerateScene()
|
||||||
TSShapeLoader::updateProgress(TSShapeLoader::Load_ReadFile, "Reading File");
|
TSShapeLoader::updateProgress(TSShapeLoader::Load_ReadFile, "Reading File");
|
||||||
Con::printf("[ASSIMP] Attempting to load file: %s", shapePath.getFullPath().c_str());
|
Con::printf("[ASSIMP] Attempting to load file: %s", shapePath.getFullPath().c_str());
|
||||||
|
|
||||||
// Post-Processing
|
// Define post-processing steps
|
||||||
unsigned int ppsteps =
|
unsigned int ppsteps = aiProcess_Triangulate | aiProcess_ValidateDataStructure | aiProcess_MakeLeftHanded | aiProcess_FlipUVs;
|
||||||
(ColladaUtils::getOptions().convertLeftHanded ? aiProcess_MakeLeftHanded : 0) |
|
|
||||||
(ColladaUtils::getOptions().reverseWindingOrder ? aiProcess_FlipWindingOrder : 0) |
|
|
||||||
(ColladaUtils::getOptions().calcTangentSpace ? aiProcess_CalcTangentSpace : 0) |
|
|
||||||
(ColladaUtils::getOptions().joinIdenticalVerts ? aiProcess_JoinIdenticalVertices : 0) |
|
|
||||||
(ColladaUtils::getOptions().removeRedundantMats ? aiProcess_RemoveRedundantMaterials : 0) |
|
|
||||||
(ColladaUtils::getOptions().genUVCoords ? aiProcess_GenUVCoords : 0) |
|
|
||||||
(ColladaUtils::getOptions().transformUVCoords ? aiProcess_TransformUVCoords : 0) |
|
|
||||||
(ColladaUtils::getOptions().flipUVCoords ? aiProcess_FlipUVs : 0) |
|
|
||||||
(ColladaUtils::getOptions().findInstances ? aiProcess_FindInstances : 0) |
|
|
||||||
(ColladaUtils::getOptions().limitBoneWeights ? aiProcess_LimitBoneWeights : 0);
|
|
||||||
|
|
||||||
if (Con::getBoolVariable("$Assimp::OptimizeMeshes", false))
|
const auto& options = ColladaUtils::getOptions();
|
||||||
|
if (options.convertLeftHanded) ppsteps |= aiProcess_MakeLeftHanded;
|
||||||
|
if (options.reverseWindingOrder) ppsteps |= aiProcess_FlipWindingOrder;
|
||||||
|
if (options.calcTangentSpace) ppsteps |= aiProcess_CalcTangentSpace;
|
||||||
|
if (options.joinIdenticalVerts) ppsteps |= aiProcess_JoinIdenticalVertices;
|
||||||
|
if (options.removeRedundantMats) ppsteps |= aiProcess_RemoveRedundantMaterials;
|
||||||
|
if (options.genUVCoords) ppsteps |= aiProcess_GenUVCoords;
|
||||||
|
if (options.transformUVCoords) ppsteps |= aiProcess_TransformUVCoords;
|
||||||
|
if (options.findInstances) ppsteps |= aiProcess_FindInstances;
|
||||||
|
if (options.limitBoneWeights) ppsteps |= aiProcess_LimitBoneWeights;
|
||||||
|
|
||||||
|
if (Con::getBoolVariable("$Assimp::OptimizeMeshes", false)) {
|
||||||
ppsteps |= aiProcess_OptimizeMeshes | aiProcess_OptimizeGraph;
|
ppsteps |= aiProcess_OptimizeMeshes | aiProcess_OptimizeGraph;
|
||||||
|
}
|
||||||
if (Con::getBoolVariable("$Assimp::SplitLargeMeshes", false))
|
if (Con::getBoolVariable("$Assimp::SplitLargeMeshes", false)) {
|
||||||
ppsteps |= aiProcess_SplitLargeMeshes;
|
ppsteps |= aiProcess_SplitLargeMeshes;
|
||||||
|
}
|
||||||
|
|
||||||
// Mandatory options
|
ppsteps |= aiProcess_ValidateDataStructure;
|
||||||
//ppsteps |= aiProcess_ValidateDataStructure | aiProcess_Triangulate | aiProcess_ImproveCacheLocality;
|
|
||||||
ppsteps |= aiProcess_Triangulate;
|
|
||||||
//aiProcess_SortByPType | // make 'clean' meshes which consist of a single typ of primitives
|
|
||||||
|
|
||||||
aiPropertyStore* props = aiCreatePropertyStore();
|
|
||||||
|
|
||||||
struct aiLogStream shapeLog = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT, NULL);
|
struct aiLogStream shapeLog = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT, NULL);
|
||||||
shapeLog.callback = assimpLogCallback;
|
shapeLog.callback = assimpLogCallback;
|
||||||
|
|
@ -165,94 +233,113 @@ void AssimpShapeLoader::enumerateScene()
|
||||||
#ifdef TORQUE_DEBUG
|
#ifdef TORQUE_DEBUG
|
||||||
aiEnableVerboseLogging(true);
|
aiEnableVerboseLogging(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Read the file
|
||||||
|
mScene = mImporter.ReadFile(shapePath.getFullPath().c_str(), ppsteps);
|
||||||
|
|
||||||
mScene = (aiScene*)aiImportFileExWithProperties(shapePath.getFullPath().c_str(), ppsteps, NULL, props);
|
if (!mScene || (mScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE) || !mScene->mRootNode) {
|
||||||
|
Con::errorf("[ASSIMP] ERROR: Could not load file: %s", shapePath.getFullPath().c_str());
|
||||||
aiReleasePropertyStore(props);
|
Con::errorf("[ASSIMP] Importer error: %s", mImporter.GetErrorString());
|
||||||
|
|
||||||
if ( mScene )
|
|
||||||
{
|
|
||||||
Con::printf("[ASSIMP] Mesh Count: %d", mScene->mNumMeshes);
|
|
||||||
Con::printf("[ASSIMP] Material Count: %d", mScene->mNumMaterials);
|
|
||||||
|
|
||||||
// Setup default units for shape format
|
|
||||||
String importFormat;
|
|
||||||
|
|
||||||
String fileExt = String::ToLower(shapePath.getExtension());
|
|
||||||
const aiImporterDesc* importerDescription = aiGetImporterDesc(fileExt.c_str());
|
|
||||||
if (importerDescription && StringTable->insert(importerDescription->mName) == StringTable->insert("Autodesk FBX Importer"))
|
|
||||||
{
|
|
||||||
ColladaUtils::getOptions().formatScaleFactor = 0.01f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set import options (if they are not set to override)
|
|
||||||
if (ColladaUtils::getOptions().unit <= 0.0f)
|
|
||||||
{
|
|
||||||
F64 unit;
|
|
||||||
if (!getMetaDouble("UnitScaleFactor", unit))
|
|
||||||
{
|
|
||||||
F32 floatVal;
|
|
||||||
S32 intVal;
|
|
||||||
if (getMetaFloat("UnitScaleFactor", floatVal))
|
|
||||||
unit = (F64)floatVal;
|
|
||||||
else if (getMetaInt("UnitScaleFactor", intVal))
|
|
||||||
unit = (F64)intVal;
|
|
||||||
else
|
|
||||||
unit = 1.0;
|
|
||||||
}
|
|
||||||
ColladaUtils::getOptions().unit = (F32)unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ColladaUtils::getOptions().upAxis == UPAXISTYPE_COUNT)
|
|
||||||
{
|
|
||||||
S32 upAxis;
|
|
||||||
if (!getMetaInt("UpAxis", upAxis))
|
|
||||||
upAxis = UPAXISTYPE_Z_UP;
|
|
||||||
ColladaUtils::getOptions().upAxis = (domUpAxisType) upAxis;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract embedded textures
|
|
||||||
for (U32 i = 0; i < mScene->mNumTextures; ++i)
|
|
||||||
extractTexture(i, mScene->mTextures[i]);
|
|
||||||
|
|
||||||
// Load all the materials.
|
|
||||||
AssimpAppMaterial::sDefaultMatNumber = 0;
|
|
||||||
for ( U32 i = 0; i < mScene->mNumMaterials; i++ )
|
|
||||||
AppMesh::appMaterials.push_back(new AssimpAppMaterial(mScene->mMaterials[i]));
|
|
||||||
|
|
||||||
// Setup LOD checks
|
|
||||||
detectDetails();
|
|
||||||
|
|
||||||
// Define the root node, and process down the chain.
|
|
||||||
AssimpAppNode* node = new AssimpAppNode(mScene, mScene->mRootNode, 0);
|
|
||||||
|
|
||||||
if (!processNode(node))
|
|
||||||
delete node;
|
|
||||||
|
|
||||||
// add bounds node.
|
|
||||||
if (!boundsNode)
|
|
||||||
{
|
|
||||||
aiNode* req[1];
|
|
||||||
req[0] = new aiNode("bounds");
|
|
||||||
mScene->mRootNode->addChildren(1, req);
|
|
||||||
|
|
||||||
AssimpAppNode* appBounds = new AssimpAppNode(mScene, req[0]);
|
|
||||||
if (!processNode(appBounds))
|
|
||||||
delete appBounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for animations and process those.
|
|
||||||
processAnimations();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TSShapeLoader::updateProgress(TSShapeLoader::Load_Complete, "Import failed");
|
TSShapeLoader::updateProgress(TSShapeLoader::Load_Complete, "Import failed");
|
||||||
Con::printf("[ASSIMP] Import Error: %s", aiGetErrorString());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//debugSceneMetaData(mScene);
|
||||||
|
|
||||||
|
Con::printf("[ASSIMP] Mesh Count: %d", mScene->mNumMeshes);
|
||||||
|
Con::printf("[ASSIMP] Material Count: %d", mScene->mNumMaterials);
|
||||||
|
|
||||||
|
// Format-specific adjustments
|
||||||
|
String fileExt = String::ToLower(shapePath.getExtension());
|
||||||
|
const aiImporterDesc* importerDescription = aiGetImporterDesc(fileExt.c_str());
|
||||||
|
if (fileExt == String::ToString("gltf") || fileExt == String::ToString("glb")) {
|
||||||
|
Con::printf("[ASSIMP] Detected GLTF format, applying reorientation...");
|
||||||
|
reorientGLTFScene(mScene); // Reorient GLTF
|
||||||
|
}
|
||||||
|
|
||||||
|
if (importerDescription && dStrcmp(importerDescription->mName, "Autodesk FBX Importer") == 0) {
|
||||||
|
Con::printf("[ASSIMP] Detected FBX format, checking unit scale...");
|
||||||
|
F32 scaleFactor = getUnitScaleFactor(mScene);
|
||||||
|
if (scaleFactor != 1.0f) {
|
||||||
|
Con::printf("[ASSIMP] Applying FBX scale factor: %f", scaleFactor);
|
||||||
|
scaleScene(mScene, scaleFactor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scaleScene(mScene, 0.01f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle scaling and up-axis conversions if necessary
|
||||||
|
configureImportUnitsAndAxis();
|
||||||
|
|
||||||
|
// Extract embedded textures
|
||||||
|
for (unsigned int i = 0; i < mScene->mNumTextures; ++i) {
|
||||||
|
extractTexture(i, mScene->mTextures[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load all materials
|
||||||
|
AssimpAppMaterial::sDefaultMatNumber = 0;
|
||||||
|
for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
|
||||||
|
AppMesh::appMaterials.push_back(new AssimpAppMaterial(mScene->mMaterials[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup LOD checks
|
||||||
|
detectDetails();
|
||||||
|
|
||||||
|
// Process the scene graph
|
||||||
|
AssimpAppNode* rootNode = new AssimpAppNode(mScene, mScene->mRootNode, 0);
|
||||||
|
if (!processNode(rootNode)) {
|
||||||
|
delete rootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a bounds node if none exists
|
||||||
|
if (!boundsNode) {
|
||||||
|
aiNode* req[1];
|
||||||
|
req[0] = new aiNode("bounds");
|
||||||
|
mScene->mRootNode->addChildren(1, req);
|
||||||
|
|
||||||
|
auto* appBoundsNode = new AssimpAppNode(mScene, req[0]);
|
||||||
|
if (!processNode(appBoundsNode)) {
|
||||||
|
delete appBoundsNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process animations if available
|
||||||
|
processAnimations();
|
||||||
|
|
||||||
|
// Clean up log stream
|
||||||
aiDetachLogStream(&shapeLog);
|
aiDetachLogStream(&shapeLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssimpShapeLoader::configureImportUnitsAndAxis() {
|
||||||
|
auto& options = ColladaUtils::getOptions();
|
||||||
|
|
||||||
|
// Configure unit scaling
|
||||||
|
if (options.unit <= 0.0f) {
|
||||||
|
F64 unitScaleFactor = 1.0;
|
||||||
|
if (!getMetaDouble("UnitScaleFactor", unitScaleFactor)) {
|
||||||
|
float floatVal;
|
||||||
|
int intVal;
|
||||||
|
if (getMetaFloat("UnitScaleFactor", floatVal)) {
|
||||||
|
unitScaleFactor = static_cast<F64>(floatVal);
|
||||||
|
}
|
||||||
|
else if (getMetaInt("UnitScaleFactor", intVal)) {
|
||||||
|
unitScaleFactor = static_cast<F64>(intVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
options.unit = static_cast<float>(unitScaleFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure up-axis
|
||||||
|
if (options.upAxis == UPAXISTYPE_COUNT) {
|
||||||
|
int upAxis = UPAXISTYPE_Z_UP;
|
||||||
|
if (getMetaInt("UpAxis", upAxis)) {
|
||||||
|
options.upAxis = static_cast<domUpAxisType>(upAxis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AssimpShapeLoader::processAnimations()
|
void AssimpShapeLoader::processAnimations()
|
||||||
{
|
{
|
||||||
// add all animations into 1 ambient animation.
|
// add all animations into 1 ambient animation.
|
||||||
|
|
@ -266,6 +353,7 @@ void AssimpShapeLoader::processAnimations()
|
||||||
for (U32 i = 0; i < mScene->mNumAnimations; ++i)
|
for (U32 i = 0; i < mScene->mNumAnimations; ++i)
|
||||||
{
|
{
|
||||||
aiAnimation* anim = mScene->mAnimations[i];
|
aiAnimation* anim = mScene->mAnimations[i];
|
||||||
|
duration = anim->mDuration;
|
||||||
for (U32 j = 0; j < anim->mNumChannels; j++)
|
for (U32 j = 0; j < anim->mNumChannels; j++)
|
||||||
{
|
{
|
||||||
aiNodeAnim* nodeAnim = anim->mChannels[j];
|
aiNodeAnim* nodeAnim = anim->mChannels[j];
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#ifndef _TSSHAPELOADER_H_
|
#ifndef _TSSHAPELOADER_H_
|
||||||
#include "ts/loader/tsShapeLoader.h"
|
#include "ts/loader/tsShapeLoader.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
#include <assimp/texture.h>
|
#include <assimp/texture.h>
|
||||||
|
|
||||||
class GuiTreeViewCtrl;
|
class GuiTreeViewCtrl;
|
||||||
|
|
@ -37,7 +38,8 @@ class AssimpShapeLoader : public TSShapeLoader
|
||||||
friend TSShape* assimpLoadShape(const Torque::Path &path);
|
friend TSShape* assimpLoadShape(const Torque::Path &path);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const struct aiScene* mScene;
|
Assimp::Importer mImporter;
|
||||||
|
const aiScene* mScene;
|
||||||
|
|
||||||
bool ignoreNode(const String& name) override;
|
bool ignoreNode(const String& name) override;
|
||||||
bool ignoreMesh(const String& name) override;
|
bool ignoreMesh(const String& name) override;
|
||||||
|
|
@ -59,6 +61,7 @@ public:
|
||||||
|
|
||||||
void releaseImport();
|
void releaseImport();
|
||||||
void enumerateScene() override;
|
void enumerateScene() override;
|
||||||
|
void configureImportUnitsAndAxis();
|
||||||
void updateMaterialsScript(const Torque::Path &path);
|
void updateMaterialsScript(const Torque::Path &path);
|
||||||
void processAnimations();
|
void processAnimations();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue