Browse Source

Merge branch 'ColladaExportutilities' of https://github.com/Areloch/Torque3D into development

Areloch 8 years ago
parent
commit
8ec88a26b6

+ 13 - 0
Engine/source/T3D/prefab.cpp

@@ -525,6 +525,19 @@ bool Prefab::isValidChild( SimObject *simobj, bool logWarnings )
    return true;
    return true;
 }
 }
 
 
+bool Prefab::buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF& sphere)
+{
+   Vector<SceneObject*> foundObjects;
+   mChildGroup->findObjectByType(foundObjects);
+
+   for (S32 i = 0; i < foundObjects.size(); i++)
+   {
+      foundObjects[i]->buildPolyList(context, polyList, box, sphere);
+   }
+
+   return true;
+}
+
 ExplodePrefabUndoAction::ExplodePrefabUndoAction( Prefab *prefab )
 ExplodePrefabUndoAction::ExplodePrefabUndoAction( Prefab *prefab )
 : UndoAction( "Explode Prefab" )
 : UndoAction( "Explode Prefab" )
 {
 {

+ 2 - 0
Engine/source/T3D/prefab.h

@@ -96,6 +96,8 @@ public:
    /// which is added to the MissionGroup and returned to the caller.
    /// which is added to the MissionGroup and returned to the caller.
    SimGroup* explode();
    SimGroup* explode();
 
 
+   bool buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF& sphere);
+
 protected:
 protected:
 
 
    void _closeFile( bool removeFileNotify );
    void _closeFile( bool removeFileNotify );

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

@@ -228,6 +228,7 @@ public:
 
 
    Resource<TSShape> getShape() const { return mShape; }
    Resource<TSShape> getShape() const { return mShape; }
 	StringTableEntry getShapeFileName() { return mShapeName; }
 	StringTableEntry getShapeFileName() { return mShapeName; }
+   void setShapeFileName(StringTableEntry shapeName) { mShapeName = shapeName; }
   
   
    TSShapeInstance* getShapeInstance() const { return mShapeInstance; }
    TSShapeInstance* getShapeInstance() const { return mShapeInstance; }
 
 

+ 160 - 1
Engine/source/gui/worldEditor/worldEditor.cpp

@@ -47,7 +47,7 @@
 #include "platform/typetraits.h"
 #include "platform/typetraits.h"
 #include "T3D/prefab.h"
 #include "T3D/prefab.h"
 #include "math/mEase.h"
 #include "math/mEase.h"
-
+#include "T3D/tsStatic.h"
 
 
 
 
 IMPLEMENT_CONOBJECT( WorldEditor );
 IMPLEMENT_CONOBJECT( WorldEditor );
@@ -3753,6 +3753,158 @@ void WorldEditor::explodeSelectedPrefab()
    setDirty();
    setDirty();
 }
 }
 
 
+void WorldEditor::bakeSelectionToMesh(const char *filename)
+{
+   if (mSelected->size() == 0)
+   {
+      Con::errorf("WorldEditor::makeSelectionPrefab - Nothing selected.");
+      return;
+   }
+
+   SimGroup *missionGroup;
+   if (!Sim::findObject("MissionGroup", missionGroup))
+   {
+      Con::errorf("WorldEditor::makeSelectionPrefab - Could not find MissionGroup.");
+      return;
+   }
+
+   Vector< SimObject* > stack;
+   Vector< SimObject* > found;
+
+   for (S32 i = 0; i < mSelected->size(); i++)
+   {
+      SimObject *obj = (*mSelected)[i];
+      stack.push_back(obj);
+   }
+
+   Vector< SimGroup* > cleanup;
+
+   while (!stack.empty())
+   {
+      SimObject *obj = stack.last();
+      SimGroup *grp = dynamic_cast< SimGroup* >(obj);
+
+      stack.pop_back();
+
+      if (grp)
+      {
+         for (S32 i = 0; i < grp->size(); i++)
+            stack.push_back(grp->at(i));
+
+         SceneObject* scn = dynamic_cast< SceneObject* >(grp);
+         if (scn)
+         {
+            if (Prefab::isValidChild(obj, true))
+               found.push_back(obj);
+         }
+         else
+         {
+            //Only push the cleanup of the group if it's ONLY a SimGroup.
+            cleanup.push_back(grp);
+         }
+      }
+      else
+      {
+         if (Prefab::isValidChild(obj, true))
+            found.push_back(obj);
+      }
+   }
+
+   if (found.empty())
+   {
+      Con::warnf("WorldEditor::makeSelectionPrefab - No valid objects selected.");
+      return;
+   }
+
+   // SimGroup we collect prefab objects into.
+   SimGroup *group = new SimGroup();
+   group->registerObject();
+
+   // Transform from World to Prefab space.
+   MatrixF fabMat(true);
+   fabMat.setPosition(mSelected->getCentroid());
+   fabMat.inverse();
+
+   MatrixF objMat;
+   SimObject *obj = NULL;
+   SceneObject *sObj = NULL;
+
+   Vector< SceneObject* > objectList;
+
+   for ( S32 i = 0; i < mSelected->size(); i++ )
+   {
+      SceneObject *pObj = dynamic_cast< SceneObject* >( ( *mSelected )[i] );
+      if ( pObj )
+         objectList.push_back( pObj );
+   }
+
+   if ( objectList.empty() )
+      return;
+
+   //
+   Point3F centroid;
+   MatrixF orientation;
+
+   if (objectList.size() == 1)
+   {
+      orientation = objectList[0]->getTransform();
+      centroid = objectList[0]->getPosition();
+   }
+   else
+   {
+      orientation.identity();
+      centroid.zero();
+
+      S32 count = 0;
+
+      for (S32 i = 0; i < objectList.size(); i++)
+      {
+         SceneObject *pObj = objectList[i];
+         if (pObj->isGlobalBounds())
+            continue;
+
+         centroid += pObj->getPosition();
+         count++;
+      }
+
+      centroid /= count;
+   }
+
+   orientation.setPosition(centroid);
+   orientation.inverse();
+
+   OptimizedPolyList polyList;
+   polyList.setBaseTransform(orientation);
+
+   for (S32 i = 0; i < objectList.size(); i++)
+   {
+      SceneObject *pObj = objectList[i];
+      if (!pObj->buildPolyList(PLC_Export, &polyList, pObj->getWorldBox(), pObj->getWorldSphere()))
+         Con::warnf("colladaExportObjectList() - object %i returned no geometry.", pObj->getId());
+   }
+
+   // Use a ColladaUtils function to do the actual export to a Collada file
+   ColladaUtils::exportToCollada(filename, polyList);
+   //
+
+   // Allocate TSStatic object and add to level.
+   TSStatic *ts = new TSStatic();
+   ts->setShapeFileName(StringTable->insert(filename));
+   fabMat.inverse();
+   ts->setTransform(fabMat);
+   ts->registerObject();
+   missionGroup->addObject(ts);
+
+   // Select it, mark level as dirty.
+   clearSelection();
+   selectObject(ts);
+   setDirty();
+
+   // Delete original objects and temporary SimGroup.
+   for (S32 i = 0; i < objectList.size(); i++)
+      objectList[i]->deleteObject();
+}
+
 DefineEngineMethod( WorldEditor, makeSelectionPrefab, void, ( const char* filename ),,
 DefineEngineMethod( WorldEditor, makeSelectionPrefab, void, ( const char* filename ),,
 	"Save selected objects to a .prefab file and replace them in the level with a Prefab object."
 	"Save selected objects to a .prefab file and replace them in the level with a Prefab object."
 	"@param filename Prefab file to save the selected objects to.")
 	"@param filename Prefab file to save the selected objects to.")
@@ -3766,6 +3918,13 @@ DefineEngineMethod( WorldEditor, explodeSelectedPrefab, void, (),,
    object->explodeSelectedPrefab();
    object->explodeSelectedPrefab();
 }
 }
 
 
+DefineEngineMethod(WorldEditor, bakeSelectionToMesh, void, (const char* filename), ,
+   "Save selected objects to a .dae collada file and replace them in the level with a TSStatic object."
+   "@param filename collada file to save the selected objects to.")
+{
+   object->bakeSelectionToMesh(filename);
+}
+
 DefineEngineMethod( WorldEditor, mountRelative, void, ( SceneObject *objA, SceneObject *objB ),,
 DefineEngineMethod( WorldEditor, mountRelative, void, ( SceneObject *objA, SceneObject *objB ),,
 	"Mount object B relatively to object A."
 	"Mount object B relatively to object A."
 	"@param objA Object to mount to."
 	"@param objA Object to mount to."

+ 2 - 0
Engine/source/gui/worldEditor/worldEditor.h

@@ -117,6 +117,8 @@ class WorldEditor : public EditTSCtrl
       void makeSelectionPrefab( const char *filename );
       void makeSelectionPrefab( const char *filename );
       void explodeSelectedPrefab();
       void explodeSelectedPrefab();
 
 
+      void bakeSelectionToMesh(const char *filename);
+
       //
       //
       static SceneObject* getClientObj(SceneObject *);
       static SceneObject* getClientObj(SceneObject *);
       static void markAsSelected( SimObject* object, bool state );
       static void markAsSelected( SimObject* object, bool state );

+ 32 - 0
Templates/Empty/game/tools/worldEditor/scripts/menuHandlers.ed.cs

@@ -555,6 +555,38 @@ function EditorExplodePrefab()
    EditorTree.buildVisibleTree( true );
    EditorTree.buildVisibleTree( true );
 }
 }
 
 
+function bakeSelectedToMesh()
+{
+
+   %dlg = new SaveFileDialog()
+   {
+      Filters        = "Collada file (*.dae)|*.dae|";
+      DefaultPath    = $Pref::WorldEditor::LastPath;
+      DefaultFile    = "";
+      ChangePath     = false;
+      OverwritePrompt   = true;
+   };
+         
+   %ret = %dlg.Execute();
+   if ( %ret )
+   {
+      $Pref::WorldEditor::LastPath = filePath( %dlg.FileName );
+      %saveFile = %dlg.FileName;
+   }
+   
+   if( fileExt( %saveFile ) !$= ".dae" )
+      %saveFile = %saveFile @ ".dae";
+   
+   %dlg.delete();
+   
+   if ( !%ret )
+      return;
+   
+   EWorldEditor.bakeSelectionToMesh( %saveFile );    
+   
+   EditorTree.buildVisibleTree( true );  
+}
+
 function EditorMount()
 function EditorMount()
 {
 {
    echo( "EditorMount" );
    echo( "EditorMount" );

+ 1 - 0
Templates/Empty/game/tools/worldEditor/scripts/menus.ed.cs

@@ -263,6 +263,7 @@ function EditorGui::buildMenus(%this)
          
          
       item[0] = "Network Graph" TAB "n" TAB "toggleNetGraph();";
       item[0] = "Network Graph" TAB "n" TAB "toggleNetGraph();";
       item[1] = "Profiler" TAB "ctrl F2" TAB "showMetrics(true);";
       item[1] = "Profiler" TAB "ctrl F2" TAB "showMetrics(true);";
+      item[2] = "Bake Selected to Mesh" TAB "" TAB "bakeSelectedToMesh();";
    };
    };
    %this.menuBar.insert(%toolsMenu, %this.menuBar.getCount());
    %this.menuBar.insert(%toolsMenu, %this.menuBar.getCount());
       
       

+ 32 - 0
Templates/Full/game/tools/worldEditor/scripts/menuHandlers.ed.cs

@@ -555,6 +555,38 @@ function EditorExplodePrefab()
    EditorTree.buildVisibleTree( true );
    EditorTree.buildVisibleTree( true );
 }
 }
 
 
+function bakeSelectedToMesh()
+{
+
+   %dlg = new SaveFileDialog()
+   {
+      Filters        = "Collada file (*.dae)|*.dae|";
+      DefaultPath    = $Pref::WorldEditor::LastPath;
+      DefaultFile    = "";
+      ChangePath     = false;
+      OverwritePrompt   = true;
+   };
+         
+   %ret = %dlg.Execute();
+   if ( %ret )
+   {
+      $Pref::WorldEditor::LastPath = filePath( %dlg.FileName );
+      %saveFile = %dlg.FileName;
+   }
+   
+   if( fileExt( %saveFile ) !$= ".dae" )
+      %saveFile = %saveFile @ ".dae";
+   
+   %dlg.delete();
+   
+   if ( !%ret )
+      return;
+   
+   EWorldEditor.bakeSelectionToMesh( %saveFile );    
+   
+   EditorTree.buildVisibleTree( true );  
+}
+
 function EditorMount()
 function EditorMount()
 {
 {
    echo( "EditorMount" );
    echo( "EditorMount" );

+ 1 - 0
Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs

@@ -263,6 +263,7 @@ function EditorGui::buildMenus(%this)
          
          
       item[0] = "Network Graph" TAB "n" TAB "toggleNetGraph();";
       item[0] = "Network Graph" TAB "n" TAB "toggleNetGraph();";
       item[1] = "Profiler" TAB "ctrl F2" TAB "showMetrics(true);";
       item[1] = "Profiler" TAB "ctrl F2" TAB "showMetrics(true);";
+      item[2] = "Bake Selected to Mesh" TAB "" TAB "bakeSelectedToMesh();";
    };
    };
    %this.menuBar.insert(%toolsMenu, %this.menuBar.getCount());
    %this.menuBar.insert(%toolsMenu, %this.menuBar.getCount());