mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 04:34:48 +00:00
Merge branch 'ColladaExportutilities' of https://github.com/Areloch/Torque3D into development
This commit is contained in:
commit
8ec88a26b6
|
|
@ -525,6 +525,19 @@ bool Prefab::isValidChild( SimObject *simobj, bool logWarnings )
|
|||
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 )
|
||||
: UndoAction( "Explode Prefab" )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@ public:
|
|||
/// which is added to the MissionGroup and returned to the caller.
|
||||
SimGroup* explode();
|
||||
|
||||
bool buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF& sphere);
|
||||
|
||||
protected:
|
||||
|
||||
void _closeFile( bool removeFileNotify );
|
||||
|
|
|
|||
|
|
@ -228,6 +228,7 @@ public:
|
|||
|
||||
Resource<TSShape> getShape() const { return mShape; }
|
||||
StringTableEntry getShapeFileName() { return mShapeName; }
|
||||
void setShapeFileName(StringTableEntry shapeName) { mShapeName = shapeName; }
|
||||
|
||||
TSShapeInstance* getShapeInstance() const { return mShapeInstance; }
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
#include "platform/typetraits.h"
|
||||
#include "T3D/prefab.h"
|
||||
#include "math/mEase.h"
|
||||
|
||||
#include "T3D/tsStatic.h"
|
||||
|
||||
|
||||
IMPLEMENT_CONOBJECT( WorldEditor );
|
||||
|
|
@ -3753,6 +3753,158 @@ void WorldEditor::explodeSelectedPrefab()
|
|||
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 ),,
|
||||
"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.")
|
||||
|
|
@ -3766,6 +3918,13 @@ DefineEngineMethod( WorldEditor, explodeSelectedPrefab, void, (),,
|
|||
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 ),,
|
||||
"Mount object B relatively to object A."
|
||||
"@param objA Object to mount to."
|
||||
|
|
|
|||
|
|
@ -117,6 +117,8 @@ class WorldEditor : public EditTSCtrl
|
|||
void makeSelectionPrefab( const char *filename );
|
||||
void explodeSelectedPrefab();
|
||||
|
||||
void bakeSelectionToMesh(const char *filename);
|
||||
|
||||
//
|
||||
static SceneObject* getClientObj(SceneObject *);
|
||||
static void markAsSelected( SimObject* object, bool state );
|
||||
|
|
|
|||
|
|
@ -555,6 +555,38 @@ function EditorExplodePrefab()
|
|||
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()
|
||||
{
|
||||
echo( "EditorMount" );
|
||||
|
|
|
|||
|
|
@ -263,6 +263,7 @@ function EditorGui::buildMenus(%this)
|
|||
|
||||
item[0] = "Network Graph" TAB "n" TAB "toggleNetGraph();";
|
||||
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());
|
||||
|
||||
|
|
|
|||
|
|
@ -555,6 +555,38 @@ function EditorExplodePrefab()
|
|||
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()
|
||||
{
|
||||
echo( "EditorMount" );
|
||||
|
|
|
|||
|
|
@ -263,6 +263,7 @@ function EditorGui::buildMenus(%this)
|
|||
|
||||
item[0] = "Network Graph" TAB "n" TAB "toggleNetGraph();";
|
||||
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());
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue