Explorar o código

Expanded mesh baking functionality, now supporting baking of LODs and Collision meshes

Areloch %!s(int64=7) %!d(string=hai) anos
pai
achega
49639a908f

+ 101 - 0
Engine/source/T3D/tsStatic.cpp

@@ -1073,6 +1073,97 @@ bool TSStatic::buildPolyList(PolyListContext context, AbstractPolyList* polyList
    return true;
 }
 
+bool TSStatic::buildExportPolyList(PolyListContext context, ColladaUtils::ExportData* exportData, const Box3F &box, const SphereF &)
+{
+   if (!mShapeInstance)
+      return false;
+
+   if (mCollisionType == Bounds)
+   {
+      ColladaUtils::ExportData::colMesh* colMesh;
+      exportData->colMeshes.increment();
+      colMesh = &exportData->colMeshes.last();
+
+      colMesh->mesh.setTransform(&mObjToWorld, mObjScale);
+      colMesh->mesh.setObject(this);
+
+      colMesh->mesh.addBox(mObjBox);
+
+      colMesh->colMeshName = String::ToString("ColBox%d-1", exportData->colMeshes.size());
+   }
+   else if (mCollisionType == VisibleMesh)
+   {
+      ColladaUtils::ExportData::colMesh* colMesh;
+      exportData->colMeshes.increment();
+      colMesh = &exportData->colMeshes.last();
+
+      colMesh->mesh.setTransform(&mObjToWorld, mObjScale);
+      colMesh->mesh.setObject(this);
+
+      mShapeInstance->buildPolyList(&colMesh->mesh, 0);
+
+      colMesh->colMeshName = String::ToString("ColMesh%d-1", exportData->colMeshes.size());
+   }
+   else if (mCollisionType == CollisionMesh)
+   {
+      // Everything else is done from the collision meshes
+      // which may be built from either the visual mesh or
+      // special collision geometry.
+      for (U32 i = 0; i < mCollisionDetails.size(); i++)
+      {
+         ColladaUtils::ExportData::colMesh* colMesh;
+         exportData->colMeshes.increment();
+         colMesh = &exportData->colMeshes.last();
+
+         colMesh->mesh.setTransform(&mObjToWorld, mObjScale);
+         colMesh->mesh.setObject(this);
+
+         mShapeInstance->buildPolyListOpcode(mCollisionDetails[i], &colMesh->mesh, box);
+
+         colMesh->colMeshName = String::ToString("ColMesh%d-1", exportData->colMeshes.size());
+      }
+   }
+
+   //Next, process the LOD levels and materials.
+   if (isServerObject() && getClientObject())
+   {
+      TSStatic* clientShape = dynamic_cast<TSStatic*>(getClientObject());
+      U32 numDetails = clientShape->mShapeInstance->getNumDetails() - 1;
+
+      exportData->meshData.increment();
+
+      //Prep a meshData for this shape in particular
+      ColladaUtils::ExportData::meshLODData* meshData = &exportData->meshData.last();
+
+      //Fill out the info we'll need later to actually append our mesh data for the detail levels during the processing phase
+      meshData->shapeInst = clientShape->mShapeInstance;
+      meshData->originatingObject = this;
+      meshData->meshTransform = mObjToWorld;
+      meshData->scale = mObjScale;
+
+      //Iterate over all our detail levels
+      for (U32 i = 0; i < clientShape->mShapeInstance->getNumDetails(); i++)
+      {
+         TSShape::Detail detail = clientShape->mShapeInstance->getShape()->details[i];
+
+         String detailName = String::ToLower(clientShape->mShapeInstance->getShape()->getName(detail.nameIndex));
+
+         //Skip it if it's a collision or line of sight element
+         if (detailName.startsWith("col") || detailName.startsWith("los"))
+            continue;
+
+         meshData->meshDetailLevels.increment();
+
+         ColladaUtils::ExportData::detailLevel* curDetail = &meshData->meshDetailLevels.last();
+
+         //Make sure we denote the size this detail level has
+         curDetail->size = detail.size;
+      }
+   }
+
+   return true;
+}
+
 void TSStatic::buildConvex(const Box3F& box, Convex* convex)
 {
    if ( mCollisionType == None )
@@ -1279,6 +1370,16 @@ void TSStatic::onUnmount( SceneObject *obj, S32 node )
    _updateShouldTick();
 }
 
+U32 TSStatic::getNumDetails()
+{
+	if (isServerObject() && getClientObject())
+	{
+		TSStatic* clientShape = dynamic_cast<TSStatic*>(getClientObject());
+		return clientShape->mShapeInstance->getNumDetails();
+	}
+	return 0;
+};
+
 //------------------------------------------------------------------------
 //These functions are duplicated in tsStatic and shapeBase.
 //They each function a little differently; but achieve the same purpose of gathering

+ 3 - 0
Engine/source/T3D/tsStatic.h

@@ -138,6 +138,7 @@ protected:
    bool castRay(const Point3F &start, const Point3F &end, RayInfo* info);
    bool castRayRendered(const Point3F &start, const Point3F &end, RayInfo* info);
    bool buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF& sphere);
+   bool buildExportPolyList(PolyListContext context, ColladaUtils::ExportData* exportData, const Box3F &box, const SphereF &);
    void buildConvex(const Box3F& box, Convex* convex);
    
    bool _createShape();
@@ -237,6 +238,8 @@ public:
   
    TSShapeInstance* getShapeInstance() const { return mShapeInstance; }
 
+   U32 getNumDetails();
+
    const Vector<S32>& getCollisionDetails() const { return mCollisionDetails; }
 
    const Vector<S32>& getLOSDetails() const { return mLOSDetails; }

+ 25 - 2
Engine/source/gui/worldEditor/worldEditor.cpp

@@ -3927,15 +3927,38 @@ void WorldEditor::makeSelectionAMesh(const char *filename)
    OptimizedPolyList polyList;
    polyList.setBaseTransform(orientation);
 
+   ColladaUtils::ExportData exportData;
+
    for (S32 i = 0; i < objectList.size(); i++)
    {
       SceneObject *pObj = objectList[i];
-      if (!pObj->buildPolyList(PLC_Export, &polyList, pObj->getWorldBox(), pObj->getWorldSphere()))
+      if (!pObj->buildExportPolyList(PLC_Export, &exportData, pObj->getWorldBox(), pObj->getWorldSphere()))
          Con::warnf("colladaExportObjectList() - object %i returned no geometry.", pObj->getId());
    }
 
+   //Now that we have all of our mesh data, process it so we can correctly collapse everything.
+   exportData.processData();
+
+   //recenter generated visual mesh results
+   for (U32 dl = 0; dl < exportData.colMeshes.size(); dl++)
+   {
+      for (U32 pnt = 0; pnt < exportData.colMeshes[dl].mesh.mPoints.size(); pnt++)
+      {
+         exportData.colMeshes[dl].mesh.mPoints[pnt] -= centroid;
+      }
+   }
+
+   //recenter generated collision mesh results
+   for (U32 dl = 0; dl < exportData.detailLevels.size(); dl++)
+   {
+      for (U32 pnt = 0; pnt < exportData.detailLevels[dl].mesh.mPoints.size(); pnt++)
+      {
+         exportData.detailLevels[dl].mesh.mPoints[pnt] -= centroid;
+      }
+   }
+
    // Use a ColladaUtils function to do the actual export to a Collada file
-   ColladaUtils::exportToCollada(filename, polyList);
+   ColladaUtils::exportToCollada(filename, exportData);
    //
 
    // Allocate TSStatic object and add to level.

+ 21 - 0
Engine/source/scene/sceneObject.h

@@ -60,6 +60,9 @@
 #include "gfx/gfxDevice.h"
 #endif
 
+#ifndef _COLLADA_UTILS_H_
+#include "ts/collada/colladaUtils.h"
+#endif
 
 class SceneManager;
 class SceneRenderState;
@@ -550,6 +553,24 @@ class SceneObject : public NetObject, private SceneContainer::Link, public Proce
                                     const Box3F& box, 
                                     const SphereF& sphere ) { return false; }
 
+      /// Builds a list of polygons which intersect a bounding volume for exporting
+      ///
+      /// This will use either the sphere or the box, not both, the
+      /// SceneObject implementation ignores sphere.
+      ///
+      /// @see AbstractPolyList
+      /// @param   context    A contentual hint as to the type of polylist to build.
+      /// @param   polyList   Poly list build (out)
+      /// @param   box        Box bounding volume
+      /// @param   sphere     Sphere bounding volume
+      ///
+      virtual bool buildExportPolyList(PolyListContext context,
+         ColladaUtils::ExportData *exportData,
+         const Box3F& box,
+         const SphereF& sphere) {
+         return false;
+      }
+
       /// Casts a ray and obtain collision information, returns true if RayInfo is modified.
       ///
       /// @param   start   Start point of ray

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 925 - 22
Engine/source/ts/collada/colladaUtils.cpp


+ 133 - 4
Engine/source/ts/collada/colladaUtils.h

@@ -50,6 +50,10 @@
 #include "console/console.h"
 #endif
 
+#ifndef _TSSHAPEINSTANCE_H_
+#include "ts/tsShapeInstance.h"
+#endif
+
 #include "platform/tmm_off.h"
 
 #include "dae.h"
@@ -63,6 +67,7 @@
 #include "dom/domCOLLADA.h"
 
 #include "platform/tmm_on.h"
+#include "core/strings/findMatch.h"
 
 namespace ColladaUtils
 {
@@ -100,7 +105,7 @@ namespace ColladaUtils
       {
          upAxis = UPAXISTYPE_COUNT;
          unit = -1.0f;
-         lodType = DetectDTS;
+         lodType = TrailingNumber;
          singleDetailSize = 2;
          matNamePrefix = "";
          alwaysImport = "";
@@ -117,6 +122,123 @@ namespace ColladaUtils
 
    ImportOptions& getOptions();
 
+   struct ExportData
+   {
+      struct detailLevel
+      {
+         OptimizedPolyList mesh;
+         S32 size;
+         Map<int, int> materialRefList;
+      };
+
+      struct meshLODData
+      {
+         Vector<detailLevel> meshDetailLevels;
+         TSShapeInstance* shapeInst;
+         MatrixF meshTransform;
+         SceneObject* originatingObject;
+
+         Point3F scale;
+
+         S32 hasDetailLevel(S32 size)
+         {
+            for (U32 i = 0; i < meshDetailLevels.size(); ++i)
+            {
+               U32 mdlSize = meshDetailLevels[i].size;
+
+               if (mdlSize == size)
+                  return i;
+            }
+
+            return -1;
+         }
+      };
+
+      struct colMesh
+      {
+         OptimizedPolyList mesh;
+         String colMeshName;
+      };
+
+      Vector<detailLevel> detailLevels;
+      Vector<meshLODData> meshData;
+      Vector<colMesh> colMeshes;
+      Vector<BaseMatInstance*> materials;
+
+      void processData();
+
+      S32 hasDetailLevel(U32 dl)
+      {
+         for (U32 i = 0; i < detailLevels.size(); i++)
+         {
+            if (detailLevels[i].size == dl)
+               return i;
+         }
+
+         return -1;
+      }
+
+      S32 hasMaterialInstance(BaseMatInstance* matInst)
+      {
+         for (U32 i = 0; i < materials.size(); i++)
+         {
+            if (materials[i] == matInst)
+               return i;
+         }
+
+         return -1;
+      }
+
+      S32 numberOfDetailLevels()
+      {
+         Vector<S32> detailLevelIdxs;
+
+         for (U32 i = 0; i < meshData.size(); ++i)
+         {
+            for (U32 d = 0; d < meshData[i].meshDetailLevels.size(); ++d)
+            {
+               detailLevelIdxs.push_back_unique(meshData[i].meshDetailLevels[d].size);
+            }
+         }
+
+         return detailLevelIdxs.size();
+      }
+
+      static S32 _Sort(const S32 *p1, const S32 *p2)
+      {
+         S32 e1 = (*p1);
+         S32 e2 = (*p2);
+
+         if (e1 > e2)
+            return 1;
+         else if (e1 < e2)
+            return -1;
+
+         return 0;
+      }
+
+      S32 getDetailLevelSize(U32 detailIdx)
+      {
+         Vector<S32> detailLevelIdxs;
+
+         for (U32 i = 0; i < meshData.size(); ++i)
+         {
+            for (U32 d = 0; d < meshData[i].meshDetailLevels.size(); ++d)
+            {
+               S32 mdlSize = meshData[i].meshDetailLevels[d].size;
+               detailLevelIdxs.push_back_unique(mdlSize);
+            }
+         }
+
+         if (detailIdx >= detailLevelIdxs.size())
+            return -1;
+
+         detailLevelIdxs.sort(&_Sort);
+
+         return detailLevelIdxs[detailIdx];
+      }
+   };
+
    void convertTransform(MatrixF& m);
 
    void collapsePath(std::string& path);
@@ -139,8 +261,15 @@ namespace ColladaUtils
    void exportColladaMesh(TiXmlElement* rootNode, const OptimizedPolyList& mesh, const String& meshName, const Vector<String>& matNames);
    void exportColladaScene(TiXmlElement* rootNode, const String& meshName, const Vector<String>& matNames);
 
+   void exportColladaMaterials(TiXmlElement* rootNode, const ExportData& exportData, const Torque::Path& colladaFile);
+   void exportColladaMesh(TiXmlElement* rootNode, const ExportData& exportData, const String& meshName);
+   void exportColladaCollisionTriangles(TiXmlElement* meshNode, const ExportData& exportData, const U32 collisionIdx);
+   void exportColladaTriangles(TiXmlElement* meshNode, const ExportData& exportData, const U32 detailLevel, const String& meshName);
+   void exportColladaScene(TiXmlElement* rootNode, const ExportData& exportData, const String& meshName);
+
    // Export an OptimizedPolyList to a simple Collada file
    void exportToCollada(const Torque::Path& colladaFile, const OptimizedPolyList& mesh, const String& meshName = String::EmptyString);
+   void exportToCollada(const Torque::Path& colladaFile, const ExportData& exportData);
 };
 
 //-----------------------------------------------------------------------------
@@ -535,7 +664,7 @@ template<> inline const domListOfUInts *ColladaPrimitive<domTristrips>::getTrian
             continue;
 
          domUint* pSrcData = &(P->getValue()[0]);
-         S32 numTriangles = (P->getValue().getCount() / stride) - 2;
+         size_t numTriangles = (P->getValue().getCount() / stride) - 2;
 
          // Convert the strip back to a triangle list
          domUint* v0 = pSrcData;
@@ -576,7 +705,7 @@ template<> inline const domListOfUInts *ColladaPrimitive<domTrifans>::getTriangl
             continue;
 
          domUint* pSrcData = &(P->getValue()[0]);
-         S32 numTriangles = (P->getValue().getCount() / stride) - 2;
+         size_t numTriangles = (P->getValue().getCount() / stride) - 2;
 
          // Convert the fan back to a triangle list
          domUint* v0 = pSrcData + stride;
@@ -608,7 +737,7 @@ template<> inline const domListOfUInts *ColladaPrimitive<domPolygons>::getTriang
             continue;
 
          domUint* pSrcData = &(P->getValue()[0]);
-         S32 numPoints = P->getValue().getCount() / stride;
+         size_t numPoints = P->getValue().getCount() / stride;
 
          // Use a simple tri-fan (centered at the first point) method of
          // converting the polygon to triangles.

+ 14 - 0
Engine/source/ts/tsShapeConstruct.cpp

@@ -135,6 +135,20 @@ IMPLEMENT_CONOBJECT(TSShapeConstructor);
 TSShapeConstructor::TSShapeConstructor()
  : mShapePath(""), mLoadingShape(false)
 {
+   mOptions.upAxis = UPAXISTYPE_COUNT;
+   mOptions.unit = -1.0f;
+   mOptions.lodType = ColladaUtils::ImportOptions::TrailingNumber;
+   mOptions.singleDetailSize = 2;
+   mOptions.matNamePrefix = "";
+   mOptions.alwaysImport = "";
+   mOptions.neverImport = String(Con::getVariable("$TSShapeConstructor::neverImport"));
+   mOptions.alwaysImportMesh = "";
+   mOptions.neverImportMesh = String(Con::getVariable("$TSShapeConstructor::neverImportMesh"));
+   mOptions.ignoreNodeScale = false;
+   mOptions.adjustCenter = false;
+   mOptions.adjustFloor = false;
+   mOptions.forceUpdateMaterials = false;
+   mOptions.useDiffuseNames = false;
    mShape = NULL;
 }
 

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio