mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-29 16:25:42 +00:00
Merge branch 'ColladaExportutilities' of https://github.com/Areloch/Torque3D into development
This commit is contained in:
commit
8ec88a26b6
9 changed files with 244 additions and 1 deletions
|
|
@ -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" )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
|
|
|
||||||
|
|
@ -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; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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."
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
|
|
|
||||||
|
|
@ -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" );
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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" );
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue