mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-20 23:23:47 +00:00
Import settings persistence
Adds new settings to ColladaUtils::ImportSettings and TSShapeConstructor::ImportSettings for persistence. Shape will now be re-imported with the original settings if the source art is newer or the cached.dts file has been deleted. Fixes material transparency blend mode assignment. Adds implementation for override scale, material prefix and always/never import options. Reads and applies metadata fields for scale and up axis from formats that provide it. Eliminates the assimp.log file and redirects log messages to console.log. Verbose logging is enabled in debug builds.
This commit is contained in:
parent
45f631b5e5
commit
2eaa917e00
10 changed files with 575 additions and 141 deletions
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include "core/util/tVector.h"
|
||||
#include "core/strings/findMatch.h"
|
||||
#include "core/strings/stringUnit.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "core/fileObject.h"
|
||||
#include "ts/tsShape.h"
|
||||
|
|
@ -133,29 +134,16 @@ void AssimpShapeLoader::enumerateScene()
|
|||
|
||||
// Post-Processing
|
||||
unsigned int ppsteps =
|
||||
Con::getBoolVariable("$Assimp::ConvertToLeftHanded", false) ? aiProcess_ConvertToLeftHanded : 0 |
|
||||
Con::getBoolVariable("$Assimp::CalcTangentSpace", false) ? aiProcess_CalcTangentSpace : 0 |
|
||||
Con::getBoolVariable("$Assimp::JoinIdenticalVertices", false) ? aiProcess_JoinIdenticalVertices : 0 |
|
||||
Con::getBoolVariable("$Assimp::ValidateDataStructure", false) ? aiProcess_ValidateDataStructure : 0 |
|
||||
Con::getBoolVariable("$Assimp::ImproveCacheLocality", false) ? aiProcess_ImproveCacheLocality : 0 |
|
||||
Con::getBoolVariable("$Assimp::RemoveRedundantMaterials", false) ? aiProcess_RemoveRedundantMaterials : 0 |
|
||||
Con::getBoolVariable("$Assimp::FindDegenerates", false) ? aiProcess_FindDegenerates : 0 |
|
||||
Con::getBoolVariable("$Assimp::FindInvalidData", false) ? aiProcess_FindInvalidData : 0 |
|
||||
Con::getBoolVariable("$Assimp::GenUVCoords", false) ? aiProcess_GenUVCoords : 0 |
|
||||
Con::getBoolVariable("$Assimp::TransformUVCoords", false) ? aiProcess_TransformUVCoords : 0 |
|
||||
Con::getBoolVariable("$Assimp::FindInstances", false) ? aiProcess_FindInstances : 0 |
|
||||
Con::getBoolVariable("$Assimp::LimitBoneWeights", false) ? aiProcess_LimitBoneWeights : 0 |
|
||||
Con::getBoolVariable("$Assimp::OptimizeMeshes", false) ? aiProcess_OptimizeMeshes | aiProcess_OptimizeGraph : 0 |
|
||||
0;
|
||||
|
||||
if(Con::getBoolVariable("$Assimp::FlipUVs", true))
|
||||
ppsteps |= aiProcess_FlipUVs;
|
||||
|
||||
if(Con::getBoolVariable("$Assimp::FlipWindingOrder", false))
|
||||
ppsteps |= aiProcess_FlipWindingOrder;
|
||||
|
||||
if(Con::getBoolVariable("$Assimp::Triangulate", true))
|
||||
ppsteps |= aiProcess_Triangulate;
|
||||
(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))
|
||||
ppsteps |= aiProcess_OptimizeMeshes | aiProcess_OptimizeGraph;
|
||||
|
|
@ -163,34 +151,21 @@ void AssimpShapeLoader::enumerateScene()
|
|||
if (Con::getBoolVariable("$Assimp::SplitLargeMeshes", false))
|
||||
ppsteps |= aiProcess_SplitLargeMeshes;
|
||||
|
||||
// Mandatory options
|
||||
//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();
|
||||
|
||||
//aiSetImportPropertyInteger(props, AI_CONFIG_IMPORT_TER_MAKE_UVS, 1);
|
||||
//aiSetImportPropertyInteger(props, AI_CONFIG_PP_SBP_REMOVE, (aiProcessPreset_TargetRealtime_Quality
|
||||
// | aiProcess_FlipWindingOrder | aiProcess_FlipUVs
|
||||
// | aiProcess_CalcTangentSpace
|
||||
// | aiProcess_FixInfacingNormals)
|
||||
// & ~aiProcess_RemoveRedundantMaterials);
|
||||
//aiSetImportPropertyInteger(props, AI_CONFIG_GLOB_MEASURE_TIME, 1);
|
||||
//aiSetImportPropertyFloat(props, AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, 80.f);
|
||||
//aiSetImportPropertyInteger(props,AI_CONFIG_PP_PTV_KEEP_HIERARCHY,1);
|
||||
|
||||
struct aiLogStream shapeLog;
|
||||
shapeLog = aiGetPredefinedLogStream(aiDefaultLogStream_FILE, "assimp.log");
|
||||
struct aiLogStream shapeLog = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT, NULL);
|
||||
shapeLog.callback = assimpLogCallback;
|
||||
shapeLog.user = 0;
|
||||
aiAttachLogStream(&shapeLog);
|
||||
#ifdef TORQUE_DEBUG
|
||||
aiEnableVerboseLogging(true);
|
||||
#endif
|
||||
|
||||
//c = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT, NULL);
|
||||
//aiAttachLogStream(&c);
|
||||
|
||||
// Attempt to import with Assimp.
|
||||
//mScene = importer.ReadFile(shapePath.getFullPath().c_str(), (aiProcessPreset_TargetRealtime_Quality | aiProcess_FlipWindingOrder | aiProcess_FlipUVs | aiProcess_CalcTangentSpace)
|
||||
// & ~aiProcess_RemoveRedundantMaterials);
|
||||
|
||||
mScene = (aiScene*)aiImportFileExWithProperties(shapePath.getFullPath().c_str(), ppsteps, NULL, props);
|
||||
|
||||
aiReleasePropertyStore(props);
|
||||
|
|
@ -200,11 +175,38 @@ void AssimpShapeLoader::enumerateScene()
|
|||
Con::printf("[ASSIMP] Mesh Count: %d", mScene->mNumMeshes);
|
||||
Con::printf("[ASSIMP] Material Count: %d", mScene->mNumMaterials);
|
||||
|
||||
// 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]));
|
||||
|
||||
|
|
@ -245,8 +247,8 @@ void AssimpShapeLoader::computeBounds(Box3F& bounds)
|
|||
TSShapeLoader::computeBounds(bounds);
|
||||
|
||||
// Check if the model origin needs adjusting
|
||||
bool adjustCenter = Con::getBoolVariable("$Assimp::adjustCenter", false); //ColladaUtils::getOptions().adjustCenter
|
||||
bool adjustFloor = Con::getBoolVariable("$Assimp::adjustFloor", false); //ColladaUtils::getOptions().adjustFloor
|
||||
bool adjustCenter = ColladaUtils::getOptions().adjustCenter;
|
||||
bool adjustFloor = ColladaUtils::getOptions().adjustFloor;
|
||||
if (bounds.isValidBox() && (adjustCenter || adjustFloor))
|
||||
{
|
||||
// Compute shape offset
|
||||
|
|
@ -289,6 +291,126 @@ void AssimpShapeLoader::computeBounds(Box3F& bounds)
|
|||
}
|
||||
}
|
||||
|
||||
bool AssimpShapeLoader::fillGuiTreeView(const char* sourceShapePath, GuiTreeViewCtrl* tree)
|
||||
{
|
||||
Assimp::Importer importer;
|
||||
Torque::Path path(sourceShapePath);
|
||||
String cleanFile = AppMaterial::cleanString(path.getFileName());
|
||||
|
||||
// Attempt to import with Assimp.
|
||||
const aiScene* shapeScene = importer.ReadFile(path.getFullPath().c_str(), (aiProcessPreset_TargetRealtime_Quality | aiProcess_CalcTangentSpace)
|
||||
& ~aiProcess_RemoveRedundantMaterials & ~aiProcess_GenSmoothNormals);
|
||||
|
||||
if (!shapeScene)
|
||||
return false;
|
||||
mScene = shapeScene;
|
||||
|
||||
// Initialize tree
|
||||
tree->removeItem(0);
|
||||
S32 meshItem = tree->insertItem(0, "Meshes", String::ToString("%i", shapeScene->mNumMeshes));
|
||||
S32 matItem = tree->insertItem(0, "Materials", String::ToString("%i", shapeScene->mNumMaterials));
|
||||
S32 animItem = tree->insertItem(0, "Animations", String::ToString("%i", shapeScene->mNumAnimations));
|
||||
//S32 lightsItem = tree->insertItem(0, "Lights", String::ToString("%i", shapeScene->mNumLights));
|
||||
//S32 texturesItem = tree->insertItem(0, "Textures", String::ToString("%i", shapeScene->mNumTextures));
|
||||
|
||||
//Details!
|
||||
U32 numPolys = 0;
|
||||
U32 numVerts = 0;
|
||||
for (U32 i = 0; i < shapeScene->mNumMeshes; i++)
|
||||
{
|
||||
tree->insertItem(meshItem, String::ToString("%s", shapeScene->mMeshes[i]->mName.C_Str()));
|
||||
numPolys += shapeScene->mMeshes[i]->mNumFaces;
|
||||
numVerts += shapeScene->mMeshes[i]->mNumVertices;
|
||||
}
|
||||
|
||||
U32 defaultMatNumber = 0;
|
||||
for (U32 i = 0; i < shapeScene->mNumMaterials; i++)
|
||||
{
|
||||
aiMaterial* aiMat = shapeScene->mMaterials[i];
|
||||
|
||||
aiString matName;
|
||||
aiMat->Get(AI_MATKEY_NAME, matName);
|
||||
String name = matName.C_Str();
|
||||
if (name.isEmpty())
|
||||
{
|
||||
name = AppMaterial::cleanString(path.getFileName());
|
||||
name += "_defMat";
|
||||
name += String::ToString("%d", defaultMatNumber);
|
||||
defaultMatNumber++;
|
||||
}
|
||||
|
||||
aiString texPath;
|
||||
aiMat->GetTexture(aiTextureType::aiTextureType_DIFFUSE, 0, &texPath);
|
||||
String texName = texPath.C_Str();
|
||||
if (texName.isEmpty())
|
||||
{
|
||||
aiColor3D read_color(1.f, 1.f, 1.f);
|
||||
if (AI_SUCCESS == aiMat->Get(AI_MATKEY_COLOR_DIFFUSE, read_color))
|
||||
texName = String::ToString("Color: (%0.3f, %0.3f, %0.3f)", (F32)read_color.r, (F32)read_color.g, (F32)read_color.b);
|
||||
else
|
||||
texName = "No Texture";
|
||||
}
|
||||
else
|
||||
texName = AssimpAppMaterial::cleanTextureName(texName, cleanFile, sourceShapePath, true);
|
||||
|
||||
tree->insertItem(matItem, String::ToString("%s", name.c_str()), String::ToString("%s", texName.c_str()));
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < shapeScene->mNumAnimations; i++)
|
||||
{
|
||||
String sequenceName = shapeScene->mAnimations[i]->mName.C_Str();
|
||||
if (sequenceName.isEmpty())
|
||||
sequenceName = "ambient";
|
||||
tree->insertItem(animItem, sequenceName.c_str());
|
||||
}
|
||||
|
||||
U32 numNodes = 0;
|
||||
if (shapeScene->mRootNode)
|
||||
{
|
||||
S32 nodesItem = tree->insertItem(0, "Nodes", "");
|
||||
addNodeToTree(nodesItem, shapeScene->mRootNode, tree, numNodes);
|
||||
tree->setItemValue(nodesItem, String::ToString("%i", numNodes));
|
||||
}
|
||||
|
||||
U32 numMetaTags = shapeScene->mMetaData ? shapeScene->mMetaData->mNumProperties : 0;
|
||||
if (numMetaTags)
|
||||
addMetaDataToTree(shapeScene->mMetaData, tree);
|
||||
|
||||
F64 unit;
|
||||
if (!getMetaDouble("UnitScaleFactor", unit))
|
||||
unit = 1.0f;
|
||||
|
||||
S32 upAxis;
|
||||
if (!getMetaInt("UpAxis", upAxis))
|
||||
upAxis = UPAXISTYPE_Z_UP;
|
||||
|
||||
/*for (U32 i = 0; i < shapeScene->mNumLights; i++)
|
||||
{
|
||||
treeObj->insertItem(lightsItem, String::ToString("%s", shapeScene->mLights[i]->mType));
|
||||
}*/
|
||||
|
||||
// Store shape information in the tree control
|
||||
tree->setDataField(StringTable->insert("_nodeCount"), 0, avar("%d", numNodes));
|
||||
tree->setDataField(StringTable->insert("_meshCount"), 0, avar("%d", shapeScene->mNumMeshes));
|
||||
tree->setDataField(StringTable->insert("_polygonCount"), 0, avar("%d", numPolys));
|
||||
tree->setDataField(StringTable->insert("_materialCount"), 0, avar("%d", shapeScene->mNumMaterials));
|
||||
tree->setDataField(StringTable->insert("_lightCount"), 0, avar("%d", shapeScene->mNumLights));
|
||||
tree->setDataField(StringTable->insert("_animCount"), 0, avar("%d", shapeScene->mNumAnimations));
|
||||
tree->setDataField(StringTable->insert("_textureCount"), 0, avar("%d", shapeScene->mNumTextures));
|
||||
tree->setDataField(StringTable->insert("_vertCount"), 0, avar("%d", numVerts));
|
||||
tree->setDataField(StringTable->insert("_metaTagCount"), 0, avar("%d", numMetaTags));
|
||||
tree->setDataField(StringTable->insert("_unit"), 0, avar("%g", (F32)unit));
|
||||
|
||||
if (upAxis == UPAXISTYPE_X_UP)
|
||||
tree->setDataField(StringTable->insert("_upAxis"), 0, "X_AXIS");
|
||||
else if (upAxis == UPAXISTYPE_Y_UP)
|
||||
tree->setDataField(StringTable->insert("_upAxis"), 0, "Y_AXIS");
|
||||
else
|
||||
tree->setDataField(StringTable->insert("_upAxis"), 0, "Z_AXIS");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AssimpShapeLoader::updateMaterialsScript(const Torque::Path &path)
|
||||
{
|
||||
Torque::Path scriptPath(path);
|
||||
|
|
@ -306,7 +428,7 @@ void AssimpShapeLoader::updateMaterialsScript(const Torque::Path &path)
|
|||
if ( Sim::findObject( MATMGR->getMapEntry( mat->getName() ), mappedMat ) )
|
||||
{
|
||||
// Only update existing materials if forced to
|
||||
if (Con::getBoolVariable("$Assimp::ForceUpdateMats", false))
|
||||
if (ColladaUtils::getOptions().forceUpdateMaterials)
|
||||
{
|
||||
mat->initMaterial(scriptPath, mappedMat);
|
||||
persistMgr.setDirty(mappedMat);
|
||||
|
|
@ -351,20 +473,37 @@ bool AssimpShapeLoader::canLoadCachedDTS(const Torque::Path& path)
|
|||
return false;
|
||||
}
|
||||
|
||||
void AssimpShapeLoader::assimpLogCallback(const char* message, char* user)
|
||||
{
|
||||
Con::printf("[Assimp log message] %s", StringUnit::getUnit(message, 0, "\n"));
|
||||
}
|
||||
|
||||
bool AssimpShapeLoader::ignoreNode(const String& name)
|
||||
{
|
||||
// Do not add AssimpFbx dummy nodes to the TSShape. See: Assimp::FBX::ImportSettings::preservePivots
|
||||
// https://github.com/assimp/assimp/blob/master/code/FBXImportSettings.h#L116-L135
|
||||
if (name.find("_$AssimpFbx$_") != String::NPos)
|
||||
return true;
|
||||
return false;
|
||||
|
||||
if (FindMatch::isMatchMultipleExprs(ColladaUtils::getOptions().alwaysImport, name, false))
|
||||
return false;
|
||||
|
||||
return FindMatch::isMatchMultipleExprs(ColladaUtils::getOptions().neverImport, name, false);
|
||||
}
|
||||
|
||||
bool AssimpShapeLoader::ignoreMesh(const String& name)
|
||||
{
|
||||
if (FindMatch::isMatchMultipleExprs(ColladaUtils::getOptions().alwaysImportMesh, name, false))
|
||||
return false;
|
||||
else
|
||||
return FindMatch::isMatchMultipleExprs(ColladaUtils::getOptions().neverImportMesh, name, false);
|
||||
}
|
||||
|
||||
void AssimpShapeLoader::detectDetails()
|
||||
{
|
||||
// Set LOD option
|
||||
bool singleDetail = true;
|
||||
switch (Con::getIntVariable("$Assimp::lodType", 0))
|
||||
switch (ColladaUtils::getOptions().lodType)
|
||||
{
|
||||
case ColladaUtils::ImportOptions::DetectDTS:
|
||||
// Check for a baseXX->startXX hierarchy at the top-level, if we find
|
||||
|
|
@ -395,7 +534,7 @@ void AssimpShapeLoader::detectDetails()
|
|||
break;
|
||||
}
|
||||
|
||||
AssimpAppMesh::fixDetailSize(singleDetail, Con::getIntVariable("$Assimp::singleDetailSize", 2));
|
||||
AssimpAppMesh::fixDetailSize(singleDetail, ColladaUtils::getOptions().singleDetailSize);
|
||||
}
|
||||
|
||||
void AssimpShapeLoader::extractTexture(U32 index, aiTexture* pTex)
|
||||
|
|
@ -448,6 +587,148 @@ void AssimpShapeLoader::extractTexture(U32 index, aiTexture* pTex)
|
|||
}
|
||||
}
|
||||
|
||||
void AssimpShapeLoader::addNodeToTree(S32 parentItem, aiNode* node, GuiTreeViewCtrl* tree, U32& nodeCount)
|
||||
{
|
||||
// Add this node
|
||||
S32 nodeItem = parentItem;
|
||||
String nodeName = node->mName.C_Str();
|
||||
if (!ignoreNode(nodeName))
|
||||
{
|
||||
if (nodeName.isEmpty())
|
||||
nodeName = "null";
|
||||
nodeItem = tree->insertItem(parentItem, nodeName.c_str(), String::ToString("%i", node->mNumChildren));
|
||||
nodeCount++;
|
||||
}
|
||||
|
||||
// Add any child nodes
|
||||
for (U32 n = 0; n < node->mNumChildren; ++n)
|
||||
addNodeToTree(nodeItem, node->mChildren[n], tree, nodeCount);
|
||||
}
|
||||
|
||||
void AssimpShapeLoader::addMetaDataToTree(const aiMetadata* metaData, GuiTreeViewCtrl* tree)
|
||||
{
|
||||
S32 metaItem = tree->insertItem(0, "MetaData", String::ToString("%i", metaData->mNumProperties));
|
||||
|
||||
aiString valString;
|
||||
aiVector3D valVec;
|
||||
|
||||
for (U32 n = 0; n < metaData->mNumProperties; ++n)
|
||||
{
|
||||
String keyStr = metaData->mKeys[n].C_Str();
|
||||
keyStr += ": ";
|
||||
switch (metaData->mValues[n].mType)
|
||||
{
|
||||
case AI_BOOL:
|
||||
keyStr += ((bool)metaData->mValues[n].mData) ? "true" : "false";
|
||||
break;
|
||||
case AI_INT32:
|
||||
keyStr += String::ToString(*((S32*)(metaData->mValues[n].mData)));
|
||||
break;
|
||||
case AI_UINT64:
|
||||
keyStr += String::ToString("%I64u", *((U64*)metaData->mValues[n].mData));
|
||||
break;
|
||||
case AI_FLOAT:
|
||||
keyStr += String::ToString(*((F32*)metaData->mValues[n].mData));
|
||||
break;
|
||||
case AI_DOUBLE:
|
||||
keyStr += String::ToString(*((F64*)metaData->mValues[n].mData));
|
||||
break;
|
||||
case AI_AISTRING:
|
||||
metaData->Get<aiString>(metaData->mKeys[n], valString);
|
||||
keyStr += valString.C_Str();
|
||||
break;
|
||||
case AI_AIVECTOR3D:
|
||||
metaData->Get<aiVector3D>(metaData->mKeys[n], valVec);
|
||||
keyStr += String::ToString("%f, %f, %f", valVec.x, valVec.y, valVec.z);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
tree->insertItem(metaItem, keyStr.c_str(), String::ToString("%i", n));
|
||||
}
|
||||
}
|
||||
|
||||
bool AssimpShapeLoader::getMetabool(const char* key, bool& boolVal)
|
||||
{
|
||||
if (!mScene || !mScene->mMetaData)
|
||||
return false;
|
||||
|
||||
String keyStr = key;
|
||||
for (U32 n = 0; n < mScene->mMetaData->mNumProperties; ++n)
|
||||
{
|
||||
if (keyStr.equal(mScene->mMetaData->mKeys[n].C_Str(), String::NoCase))
|
||||
{
|
||||
if (mScene->mMetaData->mValues[n].mType == AI_BOOL)
|
||||
{
|
||||
boolVal = (bool)mScene->mMetaData->mValues[n].mData;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AssimpShapeLoader::getMetaInt(const char* key, S32& intVal)
|
||||
{
|
||||
if (!mScene || !mScene->mMetaData)
|
||||
return false;
|
||||
|
||||
String keyStr = key;
|
||||
for (U32 n = 0; n < mScene->mMetaData->mNumProperties; ++n)
|
||||
{
|
||||
if (keyStr.equal(mScene->mMetaData->mKeys[n].C_Str(), String::NoCase))
|
||||
{
|
||||
if (mScene->mMetaData->mValues[n].mType == AI_INT32)
|
||||
{
|
||||
intVal = *((S32*)(mScene->mMetaData->mValues[n].mData));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AssimpShapeLoader::getMetaFloat(const char* key, F32& floatVal)
|
||||
{
|
||||
if (!mScene || !mScene->mMetaData)
|
||||
return false;
|
||||
|
||||
String keyStr = key;
|
||||
for (U32 n = 0; n < mScene->mMetaData->mNumProperties; ++n)
|
||||
{
|
||||
if (keyStr.equal(mScene->mMetaData->mKeys[n].C_Str(), String::NoCase))
|
||||
{
|
||||
if (mScene->mMetaData->mValues[n].mType == AI_FLOAT)
|
||||
{
|
||||
floatVal = *((F32*)mScene->mMetaData->mValues[n].mData);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AssimpShapeLoader::getMetaDouble(const char* key, F64& doubleVal)
|
||||
{
|
||||
if (!mScene || !mScene->mMetaData)
|
||||
return false;
|
||||
|
||||
String keyStr = key;
|
||||
for (U32 n = 0; n < mScene->mMetaData->mNumProperties; ++n)
|
||||
{
|
||||
if (keyStr.equal(mScene->mMetaData->mKeys[n].C_Str(), String::NoCase))
|
||||
{
|
||||
if (mScene->mMetaData->mValues[n].mType == AI_DOUBLE)
|
||||
{
|
||||
doubleVal = *((F64*)mScene->mMetaData->mValues[n].mData);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// This function is invoked by the resource manager based on file extension.
|
||||
TSShape* assimpLoadShape(const Torque::Path &path)
|
||||
|
|
@ -489,6 +770,14 @@ TSShape* assimpLoadShape(const Torque::Path &path)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Allow TSShapeConstructor object to override properties
|
||||
ColladaUtils::getOptions().reset();
|
||||
TSShapeConstructor* tscon = TSShapeConstructor::findShapeConstructor(path.getFullPath());
|
||||
if (tscon)
|
||||
{
|
||||
ColladaUtils::getOptions() = tscon->mOptions;
|
||||
}
|
||||
|
||||
AssimpShapeLoader loader;
|
||||
TSShape* tss = loader.generateShape(path);
|
||||
if (tss)
|
||||
|
|
@ -510,57 +799,30 @@ TSShape* assimpLoadShape(const Torque::Path &path)
|
|||
return tss;
|
||||
}
|
||||
|
||||
DefineEngineFunction(GetShapeInfo, GuiTreeViewCtrl*, (String filePath), ,
|
||||
"Returns a list of supported shape formats in filter form.\n"
|
||||
"Example output: DSQ Files|*.dsq|COLLADA Files|*.dae|")
|
||||
DefineEngineFunction(GetShapeInfo, bool, (const char* shapePath, const char* ctrl), ,
|
||||
"(string shapePath, GuiTreeViewCtrl ctrl) Collect scene information from "
|
||||
"a shape file and store it in a GuiTreeView control. This function is "
|
||||
"used by the assimp import gui to show a preview of the scene contents "
|
||||
"prior to import, and is probably not much use for anything else.\n"
|
||||
"@param shapePath shape filename\n"
|
||||
"@param ctrl GuiTreeView control to add elements to\n"
|
||||
"@return true if successful, false otherwise\n"
|
||||
"@ingroup Editors\n"
|
||||
"@internal")
|
||||
{
|
||||
Assimp::Importer importer;
|
||||
|
||||
GuiTreeViewCtrl* treeObj = new GuiTreeViewCtrl();
|
||||
treeObj->registerObject();
|
||||
|
||||
Torque::Path path = Torque::Path(filePath);
|
||||
|
||||
// Attempt to import with Assimp.
|
||||
const aiScene* shapeScene = importer.ReadFile(path.getFullPath().c_str(), (aiProcessPreset_TargetRealtime_Quality | aiProcess_CalcTangentSpace)
|
||||
& ~aiProcess_RemoveRedundantMaterials & ~aiProcess_GenSmoothNormals);
|
||||
|
||||
//Populate info
|
||||
S32 meshItem = treeObj->insertItem(0, "Shape", String::ToString("%i", shapeScene->mNumMeshes));
|
||||
S32 matItem = treeObj->insertItem(0, "Materials", String::ToString("%i", shapeScene->mNumMaterials));
|
||||
S32 animItem = treeObj->insertItem(0, "Animations", String::ToString("%i", shapeScene->mNumAnimations));
|
||||
S32 lightsItem = treeObj->insertItem(0, "Lights", String::ToString("%i", shapeScene->mNumLights));
|
||||
S32 texturesItem = treeObj->insertItem(0, "Textures", String::ToString("%i", shapeScene->mNumTextures));
|
||||
//S32 meshItem = ->insertItem(0, "Cameras", String::ToString("%s", shapeScene->mNumCameras));
|
||||
|
||||
//Details!
|
||||
for (U32 i = 0; i < shapeScene->mNumMeshes; i++)
|
||||
GuiTreeViewCtrl* tree;
|
||||
if (!Sim::findObject(ctrl, tree))
|
||||
{
|
||||
treeObj->insertItem(meshItem, String::ToString("%s", shapeScene->mMeshes[i]->mName.C_Str()));
|
||||
Con::errorf("enumColladaScene::Could not find GuiTreeViewCtrl '%s'", ctrl);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < shapeScene->mNumMaterials; i++)
|
||||
{
|
||||
aiMaterial* aiMat = shapeScene->mMaterials[i];
|
||||
// Check if a cached DTS is available => no need to import the source file
|
||||
// if we can load the DTS instead
|
||||
Torque::Path path(shapePath);
|
||||
if (AssimpShapeLoader::canLoadCachedDTS(path))
|
||||
return false;
|
||||
|
||||
aiString matName;
|
||||
aiMat->Get(AI_MATKEY_NAME, matName);
|
||||
|
||||
aiString texPath;
|
||||
aiMat->GetTexture(aiTextureType::aiTextureType_DIFFUSE, 0, &texPath);
|
||||
|
||||
treeObj->insertItem(matItem, String::ToString("%s", matName.C_Str()), String::ToString("%s", texPath.C_Str()));
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < shapeScene->mNumAnimations; i++)
|
||||
{
|
||||
treeObj->insertItem(animItem, String::ToString("%s", shapeScene->mAnimations[i]->mName.C_Str()));
|
||||
}
|
||||
|
||||
/*for (U32 i = 0; i < shapeScene->mNumLights; i++)
|
||||
{
|
||||
treeObj->insertItem(lightsItem, String::ToString("%s", shapeScene->mLights[i]->mType));
|
||||
}*/
|
||||
|
||||
return treeObj;
|
||||
}
|
||||
AssimpShapeLoader loader;
|
||||
return loader.fillGuiTreeView(shapePath, tree);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue