mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-13 11:43:49 +00:00
@rextimmy fix for GuiWindowCtrl so they snap correctly again
Added asset loose files for editor and bake level files on level asset Correct return of ConsoleGetType on TypeShapeAssetPtr Adds shape asset support to TSStatic, now will support either raw shape file or ShapeAsset Adds onInspect function behavior, so when object is inspected, it can do special editor behavior Adds callback for when editTSCtrl is resized Added editor setting to force the world editor sidebar(scene tree and inspector windows) to resize to fit to the right side of the screen automatically instead of float If assimp loader encounters error, it's output into the console log Makes root Data item in folder hierarchy tree in Asset Browser able to support right mouse popup menu action Material and Shape assets now correctly base on current browsed folder Material asset generation now more properly fills out common maps, as well as handles skipped dependencies better More theme corrections Updated TestGrid images asset defs to have proper loose file handling
This commit is contained in:
parent
7ff451ec89
commit
7b5e1c3c58
35 changed files with 619 additions and 295 deletions
|
|
@ -94,6 +94,9 @@ LevelAsset::LevelAsset() : AssetBase(), mIsSubLevel(false)
|
|||
|
||||
mGamemodeName = StringTable->EmptyString();
|
||||
mMainLevelAsset = StringTable->EmptyString();
|
||||
|
||||
mEditorFile = StringTable->EmptyString();
|
||||
mBakedSceneFile = StringTable->EmptyString();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -128,6 +131,11 @@ void LevelAsset::initPersistFields()
|
|||
addProtectedField("NavmeshFile", TypeAssetLooseFilePath, Offset(mNavmeshFile, LevelAsset),
|
||||
&setLevelFile, &getLevelFile, "Path to the navmesh file.");
|
||||
|
||||
addProtectedField("EditorFile", TypeAssetLooseFilePath, Offset(mEditorFile, LevelAsset),
|
||||
&setEditorFile, &getEditorFile, "Path to the level file with objects that were removed as part of the baking process. Loaded when the editor is loaded for ease of editing.");
|
||||
addProtectedField("BakedSceneFile", TypeAssetLooseFilePath, Offset(mBakedSceneFile, LevelAsset),
|
||||
&setBakedSceneFile, &getBakedSceneFile, "Path to the level file with the objects generated as part of the baking process");
|
||||
|
||||
addField("isSubScene", TypeBool, Offset(mIsSubLevel, LevelAsset), "Is this a sublevel to another Scene");
|
||||
addField("gameModeName", TypeString, Offset(mGamemodeName, LevelAsset), "Name of the Game Mode to be used with this level");
|
||||
}
|
||||
|
|
@ -189,3 +197,41 @@ void LevelAsset::setImageFile(const char* pImageFile)
|
|||
// Refresh the asset.
|
||||
refreshAsset();
|
||||
}
|
||||
|
||||
void LevelAsset::setEditorFile(const char* pEditorFile)
|
||||
{
|
||||
// Sanity!
|
||||
AssertFatal(pEditorFile != NULL, "Cannot use a NULL level file.");
|
||||
|
||||
// Fetch image file.
|
||||
pEditorFile = StringTable->insert(pEditorFile);
|
||||
|
||||
// Ignore no change,
|
||||
if (pEditorFile == mEditorFile)
|
||||
return;
|
||||
|
||||
// Update.
|
||||
mEditorFile = getOwned() ? expandAssetFilePath(pEditorFile) : StringTable->insert(pEditorFile);
|
||||
|
||||
// Refresh the asset.
|
||||
refreshAsset();
|
||||
}
|
||||
|
||||
void LevelAsset::setBakedSceneFile(const char* pBakedSceneFile)
|
||||
{
|
||||
// Sanity!
|
||||
AssertFatal(pBakedSceneFile != NULL, "Cannot use a NULL level file.");
|
||||
|
||||
// Fetch image file.
|
||||
pBakedSceneFile = StringTable->insert(pBakedSceneFile);
|
||||
|
||||
// Ignore no change,
|
||||
if (pBakedSceneFile == mBakedSceneFile)
|
||||
return;
|
||||
|
||||
// Update.
|
||||
mBakedSceneFile = getOwned() ? expandAssetFilePath(pBakedSceneFile) : StringTable->insert(pBakedSceneFile);
|
||||
|
||||
// Refresh the asset.
|
||||
refreshAsset();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@ class LevelAsset : public AssetBase
|
|||
StringTableEntry mNavmeshFile;
|
||||
StringTableEntry mPreviewImage;
|
||||
|
||||
StringTableEntry mEditorFile;
|
||||
StringTableEntry mBakedSceneFile;
|
||||
|
||||
bool mIsSubLevel;
|
||||
StringTableEntry mMainLevelAsset;
|
||||
|
||||
|
|
@ -81,6 +84,11 @@ public:
|
|||
void setImageFile(const char* pImageFile);
|
||||
inline StringTableEntry getImageFile(void) const { return mPreviewImage; };
|
||||
|
||||
void setEditorFile(const char* pEditorFile);
|
||||
inline StringTableEntry getEditorFile(void) const { return mEditorFile; };
|
||||
void setBakedSceneFile(const char* pBakedSceneFile);
|
||||
inline StringTableEntry getBakedSceneFile(void) const { return mBakedSceneFile; };
|
||||
|
||||
SimObjectId load();
|
||||
|
||||
protected:
|
||||
|
|
@ -89,6 +97,12 @@ protected:
|
|||
static bool setPreviewImageFile(void *obj, const char *index, const char *data) { static_cast<LevelAsset*>(obj)->setImageFile(data); return false; }
|
||||
static const char* getPreviewImageFile(void* obj, const char* data) { return static_cast<LevelAsset*>(obj)->getImageFile(); }
|
||||
|
||||
static bool setEditorFile(void* obj, const char* index, const char* data) { static_cast<LevelAsset*>(obj)->setEditorFile(data); return false; }
|
||||
static const char* getEditorFile(void* obj, const char* data) { return static_cast<LevelAsset*>(obj)->getEditorFile(); }
|
||||
static bool setBakedSceneFile(void* obj, const char* index, const char* data) { static_cast<LevelAsset*>(obj)->setBakedSceneFile(data); return false; }
|
||||
static const char* getBakedSceneFile(void* obj, const char* data) { return static_cast<LevelAsset*>(obj)->getBakedSceneFile(); }
|
||||
|
||||
|
||||
virtual void initializeAsset(void);
|
||||
virtual void onAssetRefresh(void) {}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -56,7 +56,8 @@ ConsoleType(assetIdString, TypeShapeAssetPtr, String, ASSET_ID_FIELD_PREFIX)
|
|||
ConsoleGetType(TypeShapeAssetPtr)
|
||||
{
|
||||
// Fetch asset Id.
|
||||
return *((StringTableEntry*)dptr);
|
||||
//return *((StringTableEntry*)dptr);
|
||||
return (*((AssetPtr<ShapeAsset>*)dptr)).getAssetId();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@
|
|||
#include "console/engineAPI.h"
|
||||
#include "T3D/accumulationVolume.h"
|
||||
|
||||
#include "gui/editor/inspector/group.h"
|
||||
|
||||
using namespace Torque;
|
||||
|
||||
extern bool gEditingMission;
|
||||
|
|
@ -140,6 +142,9 @@ TSStatic::TSStatic()
|
|||
#ifdef TORQUE_AFX_ENABLED
|
||||
afxZodiacData::convertGradientRangeFromDegrees(mGradientRange, mGradientRangeUser);
|
||||
#endif
|
||||
|
||||
mShapeAsset = StringTable->EmptyString();
|
||||
mShapeAssetId = StringTable->EmptyString();
|
||||
}
|
||||
|
||||
TSStatic::~TSStatic()
|
||||
|
|
@ -162,6 +167,10 @@ void TSStatic::initPersistFields()
|
|||
{
|
||||
addGroup("Media");
|
||||
|
||||
addProtectedField("shapeAsset", TypeShapeAssetPtr, Offset(mShapeAsset, TSStatic),
|
||||
&TSStatic::_setShapeAsset, &defaultProtectedGetFn,
|
||||
"The source shape asset.");
|
||||
|
||||
addField("shapeName", TypeShapeFilename, Offset( mShapeName, TSStatic ),
|
||||
"%Path and filename of the model file (.DTS, .DAE) to use for this TSStatic." );
|
||||
|
||||
|
|
@ -250,6 +259,15 @@ void TSStatic::initPersistFields()
|
|||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool TSStatic::_setShapeAsset(void* obj, const char* index, const char* data)
|
||||
{
|
||||
TSStatic* ts = static_cast<TSStatic*>(obj);// ->setFile(FileName(data));
|
||||
|
||||
ts->setShapeAsset(StringTable->insert(data));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TSStatic::_setFieldSkin( void *object, const char *index, const char *data )
|
||||
{
|
||||
TSStatic *ts = static_cast<TSStatic*>( object );
|
||||
|
|
@ -344,6 +362,14 @@ bool TSStatic::onAdd()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TSStatic::setShapeAsset(const StringTableEntry shapeAssetId)
|
||||
{
|
||||
mShapeAssetId = shapeAssetId;
|
||||
|
||||
_createShape();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TSStatic::_createShape()
|
||||
{
|
||||
// Cleanup before we create.
|
||||
|
|
@ -356,15 +382,37 @@ bool TSStatic::_createShape()
|
|||
mAmbientThread = NULL;
|
||||
mShape = NULL;
|
||||
|
||||
if (!mShapeName || mShapeName[0] == '\0')
|
||||
if (mShapeAssetId != StringTable->EmptyString())
|
||||
{
|
||||
Con::errorf( "TSStatic::_createShape() - No shape name!" );
|
||||
return false;
|
||||
mShapeAsset = mShapeAssetId;
|
||||
|
||||
if (mShapeAsset.isNull())
|
||||
{
|
||||
Con::errorf("[TSStatic] Failed to load shape asset.");
|
||||
return false;
|
||||
}
|
||||
|
||||
mShape = mShapeAsset->getShapeResource();
|
||||
|
||||
if(!mShape)
|
||||
{
|
||||
Con::errorf("TSStatic::_createShape() - Shape Asset had no valid shape!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mShapeName || mShapeName[0] == '\0')
|
||||
{
|
||||
Con::errorf("TSStatic::_createShape() - No shape name!");
|
||||
return false;
|
||||
}
|
||||
|
||||
mShapeHash = _StringTable::hashString(mShapeName);
|
||||
|
||||
mShape = ResourceManager::get().load(mShapeName);
|
||||
}
|
||||
|
||||
mShapeHash = _StringTable::hashString(mShapeName);
|
||||
|
||||
mShape = ResourceManager::get().load(mShapeName);
|
||||
if ( bool(mShape) == false )
|
||||
{
|
||||
Con::errorf( "TSStatic::_createShape() - Unable to load shape: %s", mShapeName );
|
||||
|
|
@ -831,7 +879,9 @@ U32 TSStatic::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
|
|||
|
||||
if (stream->writeFlag(mask & AdvancedStaticOptionsMask))
|
||||
{
|
||||
stream->writeString(mShapeAssetId);
|
||||
stream->writeString(mShapeName);
|
||||
|
||||
stream->write((U32)mDecalType);
|
||||
|
||||
stream->writeFlag(mAllowPlayerStep);
|
||||
|
|
@ -923,6 +973,10 @@ void TSStatic::unpackUpdate(NetConnection *con, BitStream *stream)
|
|||
|
||||
if (stream->readFlag()) // AdvancedStaticOptionsMask
|
||||
{
|
||||
char buffer[256];
|
||||
stream->readString(buffer);
|
||||
mShapeAssetId = StringTable->insert(buffer);
|
||||
|
||||
mShapeName = stream->readSTString();
|
||||
|
||||
stream->read((U32*)&mDecalType);
|
||||
|
|
@ -1409,6 +1463,62 @@ U32 TSStatic::getNumDetails()
|
|||
//They each function a little differently; but achieve the same purpose of gathering
|
||||
//target names/counts without polluting simObject.
|
||||
|
||||
void TSStatic::onInspect(GuiInspector* inspector)
|
||||
{
|
||||
//Put the GameObject group before everything that'd be gameobject-effecting, for orginazational purposes
|
||||
GuiInspectorGroup* tsStaticInspGroup = new GuiInspectorGroup("Shape", inspector);
|
||||
|
||||
tsStaticInspGroup->registerObject();
|
||||
inspector->addInspectorGroup(tsStaticInspGroup);
|
||||
inspector->addObject(tsStaticInspGroup);
|
||||
|
||||
//Do this on both the server and client
|
||||
/*S32 materialCount = mShapeAsset->getShape()->materialList->getMaterialNameList().size(); //mMeshAsset->getMaterialCount();
|
||||
|
||||
if (isServerObject())
|
||||
{
|
||||
//we need to update the editor
|
||||
for (U32 i = 0; i < mFields.size(); i++)
|
||||
{
|
||||
//find any with the materialslot title and clear them out
|
||||
if (FindMatch::isMatch("MaterialSlot*", mFields[i].mFieldName, false))
|
||||
{
|
||||
setDataField(mFields[i].mFieldName, NULL, "");
|
||||
mFields.erase(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//next, get a listing of our materials in the shape, and build our field list for them
|
||||
char matFieldName[128];
|
||||
|
||||
if (materialCount > 0)
|
||||
mComponentGroup = StringTable->insert("Materials");
|
||||
|
||||
for (U32 i = 0; i < materialCount; i++)
|
||||
{
|
||||
StringTableEntry materialname = StringTable->insert(mMeshAsset->getShape()->materialList->getMaterialName(i).c_str());
|
||||
|
||||
//Iterate through our assetList to find the compliant entry in our matList
|
||||
for (U32 m = 0; m < mMeshAsset->getMaterialCount(); m++)
|
||||
{
|
||||
AssetPtr<MaterialAsset> matAsset = mMeshAsset->getMaterialAsset(m);
|
||||
|
||||
if (matAsset->getMaterialDefinitionName() == materialname)
|
||||
{
|
||||
dSprintf(matFieldName, 128, "MaterialSlot%d", i);
|
||||
|
||||
addComponentField(matFieldName, "A material used in the shape file", "Material", matAsset->getAssetId(), "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (materialCount > 0)
|
||||
mComponentGroup = "";
|
||||
}*/
|
||||
}
|
||||
|
||||
DefineEngineMethod( TSStatic, getTargetName, const char*, ( S32 index ),(0),
|
||||
"Get the name of the indexed shape material.\n"
|
||||
"@param index index of the material to get (valid range is 0 - getTargetCount()-1).\n"
|
||||
|
|
|
|||
|
|
@ -48,6 +48,13 @@
|
|||
#include "scene/reflector.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ASSET_PTR_H_
|
||||
#include "assets/assetPtr.h"
|
||||
#endif
|
||||
#ifndef SHAPEASSET_H
|
||||
#include "T3D/assets/ShapeAsset.h"
|
||||
#endif
|
||||
|
||||
class TSShapeInstance;
|
||||
class TSThread;
|
||||
class TSStatic;
|
||||
|
|
@ -140,7 +147,9 @@ protected:
|
|||
bool buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF& sphere);
|
||||
bool buildExportPolyList(ColladaUtils::ExportData* exportData, const Box3F &box, const SphereF &);
|
||||
void buildConvex(const Box3F& box, Convex* convex);
|
||||
|
||||
|
||||
bool setShapeAsset(const StringTableEntry shapeAssetId);
|
||||
|
||||
bool _createShape();
|
||||
|
||||
void _updatePhysics();
|
||||
|
|
@ -173,6 +182,9 @@ protected:
|
|||
Vector<S32> mLOSDetails;
|
||||
TSShapeInstance *mShapeInstance;
|
||||
|
||||
AssetPtr<ShapeAsset> mShapeAsset;
|
||||
StringTableEntry mShapeAssetId;
|
||||
|
||||
NetStringHandle mSkinNameHandle;
|
||||
String mAppliedSkinName;
|
||||
|
||||
|
|
@ -210,6 +222,7 @@ public:
|
|||
|
||||
DECLARE_CONOBJECT(TSStatic);
|
||||
static void initPersistFields();
|
||||
static bool _setShapeAsset(void* obj, const char* index, const char* data);
|
||||
static bool _setFieldSkin( void *object, const char* index, const char* data );
|
||||
static const char *_getFieldSkin( void *object, const char *data );
|
||||
|
||||
|
|
@ -246,6 +259,8 @@ public:
|
|||
|
||||
const Vector<S32>& getLOSDetails() const { return mLOSDetails; }
|
||||
|
||||
virtual void onInspect(GuiInspector*);
|
||||
|
||||
private:
|
||||
virtual void onStaticModified(const char* slotName, const char*newValue = NULL);
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class Stream;
|
|||
class LightManager;
|
||||
class SimFieldDictionary;
|
||||
class SimPersistID;
|
||||
|
||||
class GuiInspector;
|
||||
|
||||
/// Base class for objects involved in the simulation.
|
||||
///
|
||||
|
|
@ -647,6 +647,9 @@ class SimObject: public ConsoleObject, public TamlCallbacks
|
|||
/// Called when the editor is deactivated.
|
||||
virtual void onEditorDisable(){};
|
||||
|
||||
/// Called when the object is inspected via a GuiInspector control
|
||||
virtual void onInspect(GuiInspector*) {};
|
||||
|
||||
/// @}
|
||||
|
||||
/// Find a named sub-object of this object.
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#include "gfx/gfxDevice.h"
|
||||
#include "gfx/gfxDrawUtil.h"
|
||||
#include "gui/containers/guiRolloutCtrl.h"
|
||||
|
||||
#include "gui/editor/guiMenuBar.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT( GuiWindowCtrl );
|
||||
|
||||
|
|
@ -855,6 +855,18 @@ void GuiWindowCtrl::onMouseDragged(const GuiEvent &event)
|
|||
snapZone.point.y -= SnapDistance;
|
||||
snapZone.extent.x += SnapDistance + SnapDistance;
|
||||
snapZone.extent.y += SnapDistance + SnapDistance;
|
||||
|
||||
//check if we need to offset because of the menubar
|
||||
U32 menuBarHeight = 0;
|
||||
GuiCanvas* guiCanvas = getRoot();
|
||||
if (guiCanvas)
|
||||
{
|
||||
GuiMenuBar* menuBar = dynamic_cast<GuiMenuBar*>(guiCanvas->getMenuBar());
|
||||
if (menuBar)
|
||||
{
|
||||
menuBarHeight = menuBar->getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
// Build valid snap and window vectors to compare against
|
||||
Vector< GuiWindowCtrl* > windowList;
|
||||
|
|
@ -864,11 +876,15 @@ void GuiWindowCtrl::onMouseDragged(const GuiEvent &event)
|
|||
{
|
||||
// Make sure the window is both horizontally and vertically
|
||||
// within the snap zone for this window.
|
||||
if( !snapZone.overlaps( windowList[i]->getGlobalBounds() ) )
|
||||
RectI windowBounds = windowList[i]->getGlobalBounds();
|
||||
//offset position by menubar height
|
||||
windowBounds.point.y -= menuBarHeight;
|
||||
|
||||
if( !snapZone.overlaps(windowBounds) )
|
||||
continue;
|
||||
|
||||
// Build edges for snap detection
|
||||
EdgeRectI snapRect( windowList[i]->getGlobalBounds(), mResizeMargin );
|
||||
EdgeRectI snapRect(windowBounds, mResizeMargin );
|
||||
|
||||
if( snapRect.right.position.x <= edges.left.position.x + SnapDistance &&
|
||||
snapRect.right.position.x >= edges.left.position.x - SnapDistance )
|
||||
|
|
|
|||
|
|
@ -589,6 +589,8 @@ void GuiInspector::refresh()
|
|||
mGroups.push_back(general);
|
||||
addObject(general);
|
||||
|
||||
mTargets.first()->onInspect(this);
|
||||
|
||||
//Entity inspector group
|
||||
if (mTargets.first()->getClassRep()->isSubclassOf("Entity"))
|
||||
{
|
||||
|
|
@ -669,7 +671,7 @@ void GuiInspector::refresh()
|
|||
#endif
|
||||
|
||||
// The group ended up having no fields. Remove it.
|
||||
newGroup->deleteObject();
|
||||
newGroup->deleteObject();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -106,6 +106,11 @@ public:
|
|||
/// @note Only valid in single-object mode.
|
||||
void setName( StringTableEntry newName );
|
||||
|
||||
void addInspectorGroup(GuiInspectorGroup* group)
|
||||
{
|
||||
mGroups.push_back(group);
|
||||
}
|
||||
|
||||
/// Deletes all GuiInspectorGroups
|
||||
void clearGroups();
|
||||
|
||||
|
|
@ -163,4 +168,4 @@ protected:
|
|||
void refresh();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -284,6 +284,18 @@ void EditTSCtrl::consoleInit()
|
|||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool EditTSCtrl::resize(const Point2I& newPosition, const Point2I& newExtent)
|
||||
{
|
||||
if (!Parent::resize(newPosition, newExtent))
|
||||
return false;
|
||||
|
||||
// Notify the scripts
|
||||
if (isMethod("onResize"))
|
||||
Con::executef(this, "onResize", newPosition, newExtent);
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void EditTSCtrl::make3DMouseEvent(Gui3DMouseEvent & gui3DMouseEvent, const GuiEvent & event)
|
||||
{
|
||||
(GuiEvent&)(gui3DMouseEvent) = event;
|
||||
|
|
|
|||
|
|
@ -191,6 +191,8 @@ class EditTSCtrl : public GuiTSCtrl
|
|||
|
||||
virtual bool isMiddleMouseDown() {return mMiddleMouseDown;}
|
||||
|
||||
virtual bool resize(const Point2I& newPosition, const Point2I& newExtent);
|
||||
|
||||
S32 getDisplayType() const {return mDisplayType;}
|
||||
virtual void setDisplayType(S32 type);
|
||||
|
||||
|
|
|
|||
|
|
@ -302,7 +302,10 @@ bool AssimpShapeLoader::fillGuiTreeView(const char* sourceShapePath, GuiTreeView
|
|||
& ~aiProcess_RemoveRedundantMaterials & ~aiProcess_GenSmoothNormals);
|
||||
|
||||
if (!shapeScene)
|
||||
{
|
||||
Con::printf("AssimpShapeLoader::fillGuiTreeView - Assimp Error: %s", importer.GetErrorString());
|
||||
return false;
|
||||
}
|
||||
mScene = shapeScene;
|
||||
|
||||
// Initialize tree
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue