Skip to content

Commit

Permalink
Merge pull request #1852 from Areloch/ColladaExportutilities
Browse files Browse the repository at this point in the history
Adds some bake-to-collada functions
  • Loading branch information
Areloch authored Dec 12, 2016
2 parents 274bfb2 + eb2d3a9 commit feb60fe
Show file tree
Hide file tree
Showing 9 changed files with 244 additions and 1 deletion.
13 changes: 13 additions & 0 deletions Engine/source/T3D/prefab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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" )
{
Expand Down
2 changes: 2 additions & 0 deletions Engine/source/T3D/prefab.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ class Prefab : public SceneObject
/// 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 );
Expand Down
1 change: 1 addition & 0 deletions Engine/source/T3D/tsStatic.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ class TSStatic : public SceneObject

Resource<TSShape> getShape() const { return mShape; }
StringTableEntry getShapeFileName() { return mShapeName; }
void setShapeFileName(StringTableEntry shapeName) { mShapeName = shapeName; }

TSShapeInstance* getShapeInstance() const { return mShapeInstance; }

Expand Down
161 changes: 160 additions & 1 deletion Engine/source/gui/worldEditor/worldEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
#include "platform/typetraits.h"
#include "T3D/prefab.h"
#include "math/mEase.h"

#include "T3D/tsStatic.h"


IMPLEMENT_CONOBJECT( WorldEditor );
Expand Down Expand Up @@ -3753,6 +3753,158 @@ void WorldEditor::explodeSelectedPrefab()
setDirty();
}

void WorldEditor::makeSelectionAMesh(const char *filename)
{
if (mSelected->size() == 0)
{
Con::errorf("WorldEditor::makeSelectionAMesh - Nothing selected.");
return;
}

SimGroup *missionGroup;
if (!Sim::findObject("MissionGroup", missionGroup))
{
Con::errorf("WorldEditor::makeSelectionAMesh - 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.")
Expand All @@ -3766,6 +3918,13 @@ DefineEngineMethod( WorldEditor, explodeSelectedPrefab, void, (),,
object->explodeSelectedPrefab();
}

DefineEngineMethod(WorldEditor, makeSelectionAMesh, 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->makeSelectionAMesh(filename);
}

DefineEngineMethod( WorldEditor, mountRelative, void, ( SceneObject *objA, SceneObject *objB ),,
"Mount object B relatively to object A."
"@param objA Object to mount to."
Expand Down
2 changes: 2 additions & 0 deletions Engine/source/gui/worldEditor/worldEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ class WorldEditor : public EditTSCtrl
void makeSelectionPrefab( const char *filename );
void explodeSelectedPrefab();

void makeSelectionAMesh(const char *filename);

//
static SceneObject* getClientObj(SceneObject *);
static void markAsSelected( SimObject* object, bool state );
Expand Down
32 changes: 32 additions & 0 deletions Templates/Empty/game/tools/worldEditor/scripts/menuHandlers.ed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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" );
Expand Down
1 change: 1 addition & 0 deletions Templates/Empty/game/tools/worldEditor/scripts/menus.ed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ class = "EditorUtilitiesMenu";

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());

Expand Down
32 changes: 32 additions & 0 deletions Templates/Full/game/tools/worldEditor/scripts/menuHandlers.ed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,38 @@ function EditorExplodePrefab()
EditorTree.buildVisibleTree( true );
}

function makeSelectedAMesh()
{

%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.makeSelectionAMesh( %saveFile );

EditorTree.buildVisibleTree( true );
}

function EditorMount()
{
echo( "EditorMount" );
Expand Down
1 change: 1 addition & 0 deletions Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ class = "EditorUtilitiesMenu";

item[0] = "Network Graph" TAB "n" TAB "toggleNetGraph();";
item[1] = "Profiler" TAB "ctrl F2" TAB "showMetrics(true);";
item[2] = "Make Selected a Mesh" TAB "" TAB "makeSelectedAMesh();";
};
%this.menuBar.insert(%toolsMenu, %this.menuBar.getCount());

Expand Down

0 comments on commit feb60fe

Please sign in to comment.