mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-15 08:34:40 +00:00
Copies Collada import options to Assimp.
The lodType, singleDetailSize, adjustCenter and adjustFloor options been added to the importer. Implementation of $Assimp::FlipNormals has been fixed. $Assimp::FlipWindingOrder has been added to expose aiProcess_FlipWindingOrder. Logging is now enabled and directed to assimp.log.
This commit is contained in:
parent
186a44fab3
commit
2d20995867
4 changed files with 128 additions and 30 deletions
|
|
@ -31,6 +31,9 @@
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
#include <assimp/types.h>
|
#include <assimp/types.h>
|
||||||
|
|
||||||
|
bool AssimpAppMesh::fixedSizeEnabled = false;
|
||||||
|
S32 AssimpAppMesh::fixedSize = 2;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
AssimpAppMesh::AssimpAppMesh(const struct aiMesh* mesh, AssimpAppNode* node)
|
AssimpAppMesh::AssimpAppMesh(const struct aiMesh* mesh, AssimpAppNode* node)
|
||||||
|
|
@ -59,8 +62,7 @@ const char* AssimpAppMesh::getName(bool allowFixed)
|
||||||
|
|
||||||
// If all geometry is being fixed to the same size, append the size
|
// If all geometry is being fixed to the same size, append the size
|
||||||
// to the name
|
// to the name
|
||||||
//return allowFixed && fixedSizeEnabled ? avar("%s %d", nodeName, fixedSize) : nodeName;
|
return allowFixed && fixedSizeEnabled ? avar("%s %d", nodeName, fixedSize) : nodeName;
|
||||||
return nodeName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MatrixF AssimpAppMesh::getMeshTransform(F32 time)
|
MatrixF AssimpAppMesh::getMeshTransform(F32 time)
|
||||||
|
|
@ -77,6 +79,8 @@ void AssimpAppMesh::lockMesh(F32 t, const MatrixF& objOffset)
|
||||||
uvs.reserve(mMeshData->mNumVertices);
|
uvs.reserve(mMeshData->mNumVertices);
|
||||||
normals.reserve(mMeshData->mNumVertices);
|
normals.reserve(mMeshData->mNumVertices);
|
||||||
|
|
||||||
|
bool flipNormals = Con::getBoolVariable("$Assimp::FlipNormals", false);
|
||||||
|
|
||||||
bool noUVFound = false;
|
bool noUVFound = false;
|
||||||
for (U32 i = 0; i<mMeshData->mNumVertices; i++)
|
for (U32 i = 0; i<mMeshData->mNumVertices; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -93,6 +97,8 @@ void AssimpAppMesh::lockMesh(F32 t, const MatrixF& objOffset)
|
||||||
|
|
||||||
tmpVert = Point3F(pt.x, pt.y, pt.z);
|
tmpVert = Point3F(pt.x, pt.y, pt.z);
|
||||||
tmpNormal = Point3F(nrm.x, nrm.y, nrm.z);
|
tmpNormal = Point3F(nrm.x, nrm.y, nrm.z);
|
||||||
|
if (flipNormals)
|
||||||
|
tmpNormal *= -1.0f;
|
||||||
|
|
||||||
objOffset.mulP(tmpVert);
|
objOffset.mulP(tmpVert);
|
||||||
|
|
||||||
|
|
@ -155,23 +161,11 @@ void AssimpAppMesh::lockMesh(F32 t, const MatrixF& objOffset)
|
||||||
const struct aiFace* face = &mMeshData->mFaces[n];
|
const struct aiFace* face = &mMeshData->mFaces[n];
|
||||||
if ( face->mNumIndices == 3 )
|
if ( face->mNumIndices == 3 )
|
||||||
{
|
{
|
||||||
if (Con::getBoolVariable("$Assimp::FlipNormals", true))
|
U32 indexCount = face->mNumIndices;
|
||||||
|
for (U32 ind = 0; ind < indexCount; ind++)
|
||||||
{
|
{
|
||||||
U32 indexCount = face->mNumIndices;
|
U32 index = face->mIndices[ind];
|
||||||
for (S32 ind = indexCount - 1; ind >= 0; ind--)
|
indices.push_back(index);
|
||||||
{
|
|
||||||
U32 index = face->mIndices[ind];
|
|
||||||
indices.push_back(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
U32 indexCount = face->mNumIndices;
|
|
||||||
for (U32 ind = 0; ind < indexCount; ind++)
|
|
||||||
{
|
|
||||||
U32 index = face->mIndices[ind];
|
|
||||||
indices.push_back(index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,9 @@ protected:
|
||||||
const struct aiMesh* mMeshData;
|
const struct aiMesh* mMeshData;
|
||||||
bool mIsSkinMesh;
|
bool mIsSkinMesh;
|
||||||
|
|
||||||
|
static bool fixedSizeEnabled; ///< Set to true to fix the detail size to a particular value for all geometry
|
||||||
|
static S32 fixedSize; ///< The fixed detail size value for all geometry
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AssimpAppMesh(const struct aiMesh* mesh, AssimpAppNode* node);
|
AssimpAppMesh(const struct aiMesh* mesh, AssimpAppNode* node);
|
||||||
|
|
@ -54,8 +57,8 @@ public:
|
||||||
|
|
||||||
static void fixDetailSize(bool fixed, S32 size=2)
|
static void fixDetailSize(bool fixed, S32 size=2)
|
||||||
{
|
{
|
||||||
//fixedSizeEnabled = fixed;
|
fixedSizeEnabled = fixed;
|
||||||
//fixedSize = size;
|
fixedSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the name of this mesh
|
/// Get the name of this mesh
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include "ts/assimp/assimpShapeLoader.h"
|
#include "ts/assimp/assimpShapeLoader.h"
|
||||||
#include "ts/assimp/assimpAppNode.h"
|
#include "ts/assimp/assimpAppNode.h"
|
||||||
|
#include "ts/assimp/assimpAppMesh.h"
|
||||||
#include "ts/assimp/assimpAppMaterial.h"
|
#include "ts/assimp/assimpAppMaterial.h"
|
||||||
#include "ts/assimp/assimpAppSequence.h"
|
#include "ts/assimp/assimpAppSequence.h"
|
||||||
|
|
||||||
|
|
@ -150,6 +151,9 @@ void AssimpShapeLoader::enumerateScene()
|
||||||
if(Con::getBoolVariable("$Assimp::FlipUVs", true))
|
if(Con::getBoolVariable("$Assimp::FlipUVs", true))
|
||||||
ppsteps |= aiProcess_FlipUVs;
|
ppsteps |= aiProcess_FlipUVs;
|
||||||
|
|
||||||
|
if(Con::getBoolVariable("$Assimp::FlipWindingOrder", true))
|
||||||
|
ppsteps |= aiProcess_FlipWindingOrder;
|
||||||
|
|
||||||
if(Con::getBoolVariable("$Assimp::Triangulate", true))
|
if(Con::getBoolVariable("$Assimp::Triangulate", true))
|
||||||
ppsteps |= aiProcess_Triangulate;
|
ppsteps |= aiProcess_Triangulate;
|
||||||
|
|
||||||
|
|
@ -163,17 +167,21 @@ void AssimpShapeLoader::enumerateScene()
|
||||||
|
|
||||||
aiPropertyStore* props = aiCreatePropertyStore();
|
aiPropertyStore* props = aiCreatePropertyStore();
|
||||||
|
|
||||||
aiSetImportPropertyInteger(props, AI_CONFIG_IMPORT_TER_MAKE_UVS, 1);
|
//aiSetImportPropertyInteger(props, AI_CONFIG_IMPORT_TER_MAKE_UVS, 1);
|
||||||
aiSetImportPropertyInteger(props, AI_CONFIG_PP_SBP_REMOVE, (aiProcessPreset_TargetRealtime_Quality
|
//aiSetImportPropertyInteger(props, AI_CONFIG_PP_SBP_REMOVE, (aiProcessPreset_TargetRealtime_Quality
|
||||||
| aiProcess_FlipWindingOrder | aiProcess_FlipUVs
|
// | aiProcess_FlipWindingOrder | aiProcess_FlipUVs
|
||||||
| aiProcess_CalcTangentSpace
|
// | aiProcess_CalcTangentSpace
|
||||||
| aiProcess_FixInfacingNormals)
|
// | aiProcess_FixInfacingNormals)
|
||||||
& ~aiProcess_RemoveRedundantMaterials);
|
// & ~aiProcess_RemoveRedundantMaterials);
|
||||||
aiSetImportPropertyInteger(props, AI_CONFIG_GLOB_MEASURE_TIME, 1);
|
//aiSetImportPropertyInteger(props, AI_CONFIG_GLOB_MEASURE_TIME, 1);
|
||||||
aiSetImportPropertyFloat(props, AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, 80.f);
|
//aiSetImportPropertyFloat(props, AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, 80.f);
|
||||||
//aiSetImportPropertyInteger(props,AI_CONFIG_PP_PTV_KEEP_HIERARCHY,1);
|
//aiSetImportPropertyInteger(props,AI_CONFIG_PP_PTV_KEEP_HIERARCHY,1);
|
||||||
|
|
||||||
//Assimp::Importer importer;
|
struct aiLogStream c;
|
||||||
|
c = aiGetPredefinedLogStream(aiDefaultLogStream_FILE, "assimp.log");
|
||||||
|
aiAttachLogStream(&c);
|
||||||
|
c = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT, NULL);
|
||||||
|
aiAttachLogStream(&c);
|
||||||
|
|
||||||
// Attempt to import with Assimp.
|
// Attempt to import with Assimp.
|
||||||
//mScene = importer.ReadFile(shapePath.getFullPath().c_str(), (aiProcessPreset_TargetRealtime_Quality | aiProcess_FlipWindingOrder | aiProcess_FlipUVs | aiProcess_CalcTangentSpace)
|
//mScene = importer.ReadFile(shapePath.getFullPath().c_str(), (aiProcessPreset_TargetRealtime_Quality | aiProcess_FlipWindingOrder | aiProcess_FlipUVs | aiProcess_CalcTangentSpace)
|
||||||
|
|
@ -192,6 +200,9 @@ void AssimpShapeLoader::enumerateScene()
|
||||||
for ( U32 i = 0; i < mScene->mNumMaterials; i++ )
|
for ( U32 i = 0; i < mScene->mNumMaterials; i++ )
|
||||||
AppMesh::appMaterials.push_back(new AssimpAppMaterial(mScene->mMaterials[i]));
|
AppMesh::appMaterials.push_back(new AssimpAppMaterial(mScene->mMaterials[i]));
|
||||||
|
|
||||||
|
// Setup LOD checks
|
||||||
|
detectDetails();
|
||||||
|
|
||||||
// Define the root node, and process down the chain.
|
// Define the root node, and process down the chain.
|
||||||
AssimpAppNode* node = new AssimpAppNode(mScene, mScene->mRootNode, 0);
|
AssimpAppNode* node = new AssimpAppNode(mScene, mScene->mRootNode, 0);
|
||||||
|
|
||||||
|
|
@ -219,6 +230,55 @@ void AssimpShapeLoader::processAnimations()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
if (bounds.isValidBox() && (adjustCenter || adjustFloor))
|
||||||
|
{
|
||||||
|
// Compute shape offset
|
||||||
|
Point3F shapeOffset = Point3F::Zero;
|
||||||
|
if (adjustCenter)
|
||||||
|
{
|
||||||
|
bounds.getCenter(&shapeOffset);
|
||||||
|
shapeOffset = -shapeOffset;
|
||||||
|
}
|
||||||
|
if (adjustFloor)
|
||||||
|
shapeOffset.z = -bounds.minExtents.z;
|
||||||
|
|
||||||
|
// Adjust bounds
|
||||||
|
bounds.minExtents += shapeOffset;
|
||||||
|
bounds.maxExtents += shapeOffset;
|
||||||
|
|
||||||
|
// Now adjust all positions for root level nodes (nodes with no parent)
|
||||||
|
for (S32 iNode = 0; iNode < shape->nodes.size(); iNode++)
|
||||||
|
{
|
||||||
|
if (!appNodes[iNode]->isParentRoot())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Adjust default translation
|
||||||
|
shape->defaultTranslations[iNode] += shapeOffset;
|
||||||
|
|
||||||
|
// Adjust animated translations
|
||||||
|
for (S32 iSeq = 0; iSeq < shape->sequences.size(); iSeq++)
|
||||||
|
{
|
||||||
|
const TSShape::Sequence& seq = shape->sequences[iSeq];
|
||||||
|
if (seq.translationMatters.test(iNode))
|
||||||
|
{
|
||||||
|
for (S32 iFrame = 0; iFrame < seq.numKeyframes; iFrame++)
|
||||||
|
{
|
||||||
|
S32 index = seq.baseTranslation + seq.translationMatters.count(iNode)*seq.numKeyframes + iFrame;
|
||||||
|
shape->nodeTranslations[index] += shapeOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AssimpShapeLoader::updateMaterialsScript(const Torque::Path &path)
|
void AssimpShapeLoader::updateMaterialsScript(const Torque::Path &path)
|
||||||
{
|
{
|
||||||
Torque::Path scriptPath(path);
|
Torque::Path scriptPath(path);
|
||||||
|
|
@ -289,6 +349,44 @@ bool AssimpShapeLoader::ignoreNode(const String& name)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssimpShapeLoader::detectDetails()
|
||||||
|
{
|
||||||
|
// Set LOD option
|
||||||
|
bool singleDetail = true;
|
||||||
|
switch (Con::getIntVariable("$Assimp::lodType", 0))
|
||||||
|
{
|
||||||
|
case ColladaUtils::ImportOptions::DetectDTS:
|
||||||
|
// Check for a baseXX->startXX hierarchy at the top-level, if we find
|
||||||
|
// one, use trailing numbers for LOD, otherwise use a single size
|
||||||
|
for (S32 iNode = 0; singleDetail && (iNode < mScene->mRootNode->mNumChildren); iNode++) {
|
||||||
|
aiNode* node = mScene->mRootNode->mChildren[iNode];
|
||||||
|
if (node && dStrStartsWith(node->mName.C_Str(), "base")) {
|
||||||
|
for (S32 iChild = 0; iChild < node->mNumChildren; iChild++) {
|
||||||
|
aiNode* child = node->mChildren[iChild];
|
||||||
|
if (child && dStrStartsWith(child->mName.C_Str(), "start")) {
|
||||||
|
singleDetail = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ColladaUtils::ImportOptions::SingleSize:
|
||||||
|
singleDetail = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ColladaUtils::ImportOptions::TrailingNumber:
|
||||||
|
singleDetail = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssimpAppMesh::fixDetailSize(singleDetail, Con::getIntVariable("$Assimp::singleDetailSize", 2));
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/// This function is invoked by the resource manager based on file extension.
|
/// This function is invoked by the resource manager based on file extension.
|
||||||
TSShape* assimpLoadShape(const Torque::Path &path)
|
TSShape* assimpLoadShape(const Torque::Path &path)
|
||||||
|
|
@ -377,7 +475,7 @@ DefineEngineFunction(GetShapeInfo, GuiTreeViewCtrl*, (String filePath), ,
|
||||||
//Details!
|
//Details!
|
||||||
for (U32 i = 0; i < shapeScene->mNumMeshes; i++)
|
for (U32 i = 0; i < shapeScene->mNumMeshes; i++)
|
||||||
{
|
{
|
||||||
treeObj->insertItem(meshItem, String::ToString("%s", shapeScene->mMeshes[i]->mName));
|
treeObj->insertItem(meshItem, String::ToString("%s", shapeScene->mMeshes[i]->mName.C_Str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (U32 i = 0; i < shapeScene->mNumMaterials; i++)
|
for (U32 i = 0; i < shapeScene->mNumMaterials; i++)
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ protected:
|
||||||
const struct aiScene* mScene;
|
const struct aiScene* mScene;
|
||||||
|
|
||||||
virtual bool ignoreNode(const String& name);
|
virtual bool ignoreNode(const String& name);
|
||||||
|
void detectDetails();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AssimpShapeLoader();
|
AssimpShapeLoader();
|
||||||
|
|
@ -46,6 +47,8 @@ public:
|
||||||
void updateMaterialsScript(const Torque::Path &path);
|
void updateMaterialsScript(const Torque::Path &path);
|
||||||
void processAnimations();
|
void processAnimations();
|
||||||
|
|
||||||
|
void computeBounds(Box3F& bounds);
|
||||||
|
|
||||||
static bool canLoadCachedDTS(const Torque::Path& path);
|
static bool canLoadCachedDTS(const Torque::Path& path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue