浏览代码

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.

OTHGMars 6 年之前
父节点
当前提交
75440918e5

+ 12 - 18
Engine/source/ts/assimp/assimpAppMesh.cpp

@@ -31,6 +31,9 @@
 #include <assimp/postprocess.h>
 #include <assimp/types.h>
 
+bool AssimpAppMesh::fixedSizeEnabled = false;
+S32 AssimpAppMesh::fixedSize = 2;
+
 //------------------------------------------------------------------------------
 
 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
    // to the name
-   //return allowFixed && fixedSizeEnabled ? avar("%s %d", nodeName, fixedSize) : nodeName;
-   return nodeName;
+   return allowFixed && fixedSizeEnabled ? avar("%s %d", nodeName, fixedSize) : nodeName;
 }
 
 MatrixF AssimpAppMesh::getMeshTransform(F32 time)
@@ -77,6 +79,8 @@ void AssimpAppMesh::lockMesh(F32 t, const MatrixF& objOffset)
    uvs.reserve(mMeshData->mNumVertices);
    normals.reserve(mMeshData->mNumVertices);
 
+   bool flipNormals = Con::getBoolVariable("$Assimp::FlipNormals", false);
+
    bool noUVFound = false;
    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);
       tmpNormal = Point3F(nrm.x, nrm.y, nrm.z);
+      if (flipNormals)
+         tmpNormal *= -1.0f;
 
       objOffset.mulP(tmpVert);
 
@@ -155,23 +161,11 @@ void AssimpAppMesh::lockMesh(F32 t, const MatrixF& objOffset)
       const struct aiFace* face = &mMeshData->mFaces[n];
       if ( face->mNumIndices == 3 )
       {
-         if (Con::getBoolVariable("$Assimp::FlipNormals", true))
-         {
-            U32 indexCount = face->mNumIndices;
-            for (S32 ind = indexCount - 1; ind >= 0; ind--)
-            {
-               U32 index = face->mIndices[ind];
-               indices.push_back(index);
-            }
-         }
-         else
+         U32 indexCount = face->mNumIndices;
+         for (U32 ind = 0; ind < indexCount; ind++)
          {
-            U32 indexCount = face->mNumIndices;
-            for (U32 ind = 0; ind < indexCount; ind++)
-            {
-               U32 index = face->mIndices[ind];
-               indices.push_back(index);
-            }
+            U32 index = face->mIndices[ind];
+            indices.push_back(index);
          }
       } 
       else 

+ 5 - 2
Engine/source/ts/assimp/assimpAppMesh.h

@@ -42,6 +42,9 @@ protected:
    const struct aiMesh* mMeshData;
    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:
 
    AssimpAppMesh(const struct aiMesh* mesh, AssimpAppNode* node);
@@ -54,8 +57,8 @@ public:
 
    static void fixDetailSize(bool fixed, S32 size=2)
    {
-      //fixedSizeEnabled = fixed;
-      //fixedSize = size;
+      fixedSizeEnabled = fixed;
+      fixedSize = size;
    }
 
    /// Get the name of this mesh

+ 108 - 10
Engine/source/ts/assimp/assimpShapeLoader.cpp

@@ -33,6 +33,7 @@
 
 #include "ts/assimp/assimpShapeLoader.h"
 #include "ts/assimp/assimpAppNode.h"
+#include "ts/assimp/assimpAppMesh.h"
 #include "ts/assimp/assimpAppMaterial.h"
 #include "ts/assimp/assimpAppSequence.h"
 
@@ -150,6 +151,9 @@ void AssimpShapeLoader::enumerateScene()
    if(Con::getBoolVariable("$Assimp::FlipUVs", true))
       ppsteps |= aiProcess_FlipUVs;
 
+   if(Con::getBoolVariable("$Assimp::FlipWindingOrder", true))
+      ppsteps |= aiProcess_FlipWindingOrder;
+
    if(Con::getBoolVariable("$Assimp::Triangulate", true))
       ppsteps |= aiProcess_Triangulate;
 
@@ -163,17 +167,21 @@ void AssimpShapeLoader::enumerateScene()
 
    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_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);
 
-   //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.
    //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++ )
          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);
       
@@ -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)
 {
    Torque::Path scriptPath(path);
@@ -289,6 +349,44 @@ bool AssimpShapeLoader::ignoreNode(const String& name)
    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.
 TSShape* assimpLoadShape(const Torque::Path &path)
@@ -377,7 +475,7 @@ DefineEngineFunction(GetShapeInfo, GuiTreeViewCtrl*, (String filePath), ,
    //Details!
    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++)

+ 3 - 0
Engine/source/ts/assimp/assimpShapeLoader.h

@@ -36,6 +36,7 @@ protected:
    const struct aiScene* mScene;
 
    virtual bool ignoreNode(const String& name);
+   void detectDetails();
 
 public:
    AssimpShapeLoader();
@@ -46,6 +47,8 @@ public:
    void updateMaterialsScript(const Torque::Path &path);
    void processAnimations();
 
+   void computeBounds(Box3F& bounds);
+
    static bool canLoadCachedDTS(const Torque::Path& path);
 };