mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-03-09 23:40:42 +00:00
Merge branch 'EngineAssetify' of https://github.com/Areloch/Torque3D into EngineAssetify_Followups_XML2Check
# Conflicts: # Engine/source/ts/tsShapeConstruct.cpp
This commit is contained in:
commit
c5d0310bc3
180 changed files with 2337 additions and 1572 deletions
|
|
@ -536,12 +536,19 @@ DefineEngineMethod(ShapeAsset, getAnimation, ShapeAnimationAsset*, (S32 index),
|
|||
}
|
||||
|
||||
DefineEngineMethod(ShapeAsset, getShapeFile, const char*, (), ,
|
||||
"Creates a new script asset using the targetFilePath.\n"
|
||||
"@return The bool result of calling exec")
|
||||
"Gets the shape's file path\n"
|
||||
"@return The filename of the shape file")
|
||||
{
|
||||
return object->getShapeFilePath();
|
||||
}
|
||||
|
||||
DefineEngineMethod(ShapeAsset, getShapeConstructorFilePath, const char*, (), ,
|
||||
"Gets the shape's constructor file.\n"
|
||||
"@return The filename of the shape constructor file")
|
||||
{
|
||||
return object->getShapeConstructorFilePath();
|
||||
}
|
||||
|
||||
DefineEngineMethod(ShapeAsset, getStatusString, String, (), , "get status string")\
|
||||
{
|
||||
return ShapeAsset::getAssetErrstrn(object->getStatus());
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ ConsoleDocClass(AssetImportConfig,
|
|||
IMPLEMENT_CONOBJECT(AssetImportConfig);
|
||||
|
||||
AssetImportConfig::AssetImportConfig() :
|
||||
DuplicatAutoResolution("AutoRename"),
|
||||
DuplicateAutoResolution("AutoRename"),
|
||||
WarningsAsErrors(false),
|
||||
PreventImportWithErrors(true),
|
||||
AutomaticallyPromptMissingFiles(false),
|
||||
|
|
@ -132,7 +132,7 @@ void AssetImportConfig::initPersistFields()
|
|||
Parent::initPersistFields();
|
||||
|
||||
addGroup("General");
|
||||
addField("DuplicatAutoResolution", TypeRealString, Offset(DuplicatAutoResolution, AssetImportConfig), "Duplicate Asset Auto-Resolution Action. Options are None, AutoPrune, AutoRename, FolderPrefix");
|
||||
addField("DuplicateAutoResolution", TypeRealString, Offset(DuplicateAutoResolution, AssetImportConfig), "Duplicate Asset Auto-Resolution Action. Options are None, AutoPrune, AutoRename, FolderPrefix");
|
||||
addField("WarningsAsErrors", TypeBool, Offset(WarningsAsErrors, AssetImportConfig), "Indicates if warnings should be treated as errors");
|
||||
addField("PreventImportWithErrors", TypeBool, Offset(PreventImportWithErrors, AssetImportConfig), "Indicates if importing should be prevented from completing if any errors are detected at all");
|
||||
addField("AutomaticallyPromptMissingFiles", TypeBool, Offset(AutomaticallyPromptMissingFiles, AssetImportConfig), "Should the importer automatically prompt to find missing files if they are not detected automatically by the importer");
|
||||
|
|
@ -230,7 +230,7 @@ void AssetImportConfig::initPersistFields()
|
|||
void AssetImportConfig::loadImportConfig(Settings* configSettings, String configName)
|
||||
{
|
||||
//General
|
||||
DuplicatAutoResolution = configSettings->value(String(configName + "/General/DuplicatAutoResolution").c_str());
|
||||
DuplicateAutoResolution = configSettings->value(String(configName + "/General/DuplicateAutoResolution").c_str());
|
||||
WarningsAsErrors = dAtob(configSettings->value(String(configName + "/General/WarningsAsErrors").c_str()));
|
||||
PreventImportWithErrors = dAtob(configSettings->value(String(configName + "/General/PreventImportWithErrors").c_str()));
|
||||
AutomaticallyPromptMissingFiles = dAtob(configSettings->value(String(configName + "/General/AutomaticallyPromptMissingFiles").c_str()));
|
||||
|
|
@ -320,7 +320,7 @@ void AssetImportConfig::loadImportConfig(Settings* configSettings, String config
|
|||
|
||||
void AssetImportConfig::CopyTo(AssetImportConfig* target) const
|
||||
{
|
||||
target->DuplicatAutoResolution = DuplicatAutoResolution;
|
||||
target->DuplicateAutoResolution = DuplicateAutoResolution;
|
||||
target->WarningsAsErrors = WarningsAsErrors;
|
||||
target->PreventImportWithErrors = PreventImportWithErrors;
|
||||
target->AutomaticallyPromptMissingFiles = AutomaticallyPromptMissingFiles;
|
||||
|
|
@ -2345,7 +2345,7 @@ void AssetImporter::resolveAssetItemIssues(AssetImportObject* assetItem)
|
|||
String humanReadableReason = assetItem->statusType == String("DuplicateImportAsset") ? "Importing asset was duplicate of another importing asset" : "Importing asset was duplicate of an existing asset";
|
||||
|
||||
//get the config value for duplicateAutoResolution
|
||||
if (activeImportConfig->DuplicatAutoResolution == String("AutoPrune"))
|
||||
if (activeImportConfig->DuplicateAutoResolution == String("AutoPrune"))
|
||||
{
|
||||
//delete the item
|
||||
deleteImportingAsset(assetItem);
|
||||
|
|
@ -2356,7 +2356,7 @@ void AssetImporter::resolveAssetItemIssues(AssetImportObject* assetItem)
|
|||
|
||||
importIssues = false;
|
||||
}
|
||||
else if (activeImportConfig->DuplicatAutoResolution == String("AutoRename"))
|
||||
else if (activeImportConfig->DuplicateAutoResolution == String("AutoRename"))
|
||||
{
|
||||
//Set trailing number
|
||||
String renamedAssetName = assetItem->assetName;
|
||||
|
|
@ -2375,11 +2375,11 @@ void AssetImporter::resolveAssetItemIssues(AssetImportObject* assetItem)
|
|||
resetAssetValidationStatus(assetItem);
|
||||
importIssues = false;
|
||||
}
|
||||
else if (activeImportConfig->DuplicatAutoResolution == String("UseExisting"))
|
||||
else if (activeImportConfig->DuplicateAutoResolution == String("UseExisting"))
|
||||
{
|
||||
|
||||
}
|
||||
else if (activeImportConfig->DuplicatAutoResolution == String("FolderPrefix"))
|
||||
else if (activeImportConfig->DuplicateAutoResolution == String("FolderPrefix"))
|
||||
{
|
||||
//Set trailing number
|
||||
String renamedAssetName = assetItem->assetName;
|
||||
|
|
@ -3150,7 +3150,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
|||
activityLog.push_back(importLogBuffer);
|
||||
|
||||
//find/create shape constructor
|
||||
TSShapeConstructor* constructor = TSShapeConstructor::findShapeConstructor(Torque::Path(qualifiedToFile).getFullPath());
|
||||
TSShapeConstructor* constructor = TSShapeConstructor::findShapeConstructorByFilename(Torque::Path(qualifiedToFile).getFullPath());
|
||||
if (constructor == nullptr)
|
||||
{
|
||||
constructor = new TSShapeConstructor(StringTable->insert(qualifiedToFile));
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public:
|
|||
/// <summary>
|
||||
/// Duplicate Asset Auto-Resolution Action. Options are None, AutoPrune, AutoRename
|
||||
/// </summary>
|
||||
String DuplicatAutoResolution;
|
||||
String DuplicateAutoResolution;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if warnings should be treated as errors.
|
||||
|
|
|
|||
|
|
@ -398,6 +398,21 @@ DefineEngineFunction(isFile, bool, ( const char* fileName ),,
|
|||
return Torque::FS::IsFile(givenPath);
|
||||
}
|
||||
|
||||
DefineEngineFunction(isScriptFile, bool, (const char* fileName), ,
|
||||
"@brief Determines if the specified file exists or not\n\n"
|
||||
|
||||
"@param fileName The path to the file.\n"
|
||||
"@return Returns true if the file was found.\n"
|
||||
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
String cleanfilename(Torque::Path::CleanSeparators(fileName));
|
||||
Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), cleanfilename.c_str());
|
||||
|
||||
Torque::Path givenPath(Torque::Path::CompressPath(sgScriptFilenameBuffer));
|
||||
return Torque::FS::IsScriptFile(givenPath.getFullPath());
|
||||
}
|
||||
|
||||
DefineEngineFunction( IsDirectory, bool, ( const char* directory ),,
|
||||
"@brief Determines if a specified directory exists or not\n\n"
|
||||
|
||||
|
|
|
|||
|
|
@ -128,6 +128,8 @@ GuiBitmapButtonCtrl::GuiBitmapButtonCtrl()
|
|||
mUseStates = true;
|
||||
setExtent( 140, 30 );
|
||||
mMasked = false;
|
||||
|
||||
INIT_IMAGEASSET(Bitmap);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -135,13 +137,12 @@ GuiBitmapButtonCtrl::GuiBitmapButtonCtrl()
|
|||
void GuiBitmapButtonCtrl::initPersistFields()
|
||||
{
|
||||
addGroup( "Bitmap" );
|
||||
|
||||
addProtectedField( "bitmap", TypeStringFilename, Offset( mBitmapName, GuiBitmapButtonCtrl ),
|
||||
&_setBitmap, &defaultProtectedGetFn,
|
||||
"Texture file to display on this button.\n"
|
||||
|
||||
INITPERSISTFIELD_IMAGEASSET(Bitmap, GuiBitmapButtonCtrl, "Texture file to display on this button.\n"
|
||||
"If useStates is false, this will be the file that renders on the control. Otherwise, this will "
|
||||
"specify the default texture name to which the various state and modifier suffixes are appended "
|
||||
"to find the per-state and per-modifier (if enabled) textures." );
|
||||
"to find the per-state and per-modifier (if enabled) textures.");
|
||||
|
||||
addField( "bitmapMode", TYPEID< BitmapMode >(), Offset( mBitmapMode, GuiBitmapButtonCtrl ),
|
||||
"Behavior for fitting the bitmap to the control extents.\n"
|
||||
"If set to 'Stretched', the bitmap will be stretched both verticall and horizontally to fit inside "
|
||||
|
|
@ -176,7 +177,7 @@ bool GuiBitmapButtonCtrl::onWake()
|
|||
return false;
|
||||
|
||||
setActive( true );
|
||||
setBitmap( mBitmapName );
|
||||
setBitmap( getBitmap() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -208,22 +209,22 @@ bool GuiBitmapButtonCtrl::_setAutoFitExtents( void *object, const char *index, c
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool GuiBitmapButtonCtrl::_setBitmap( void *object, const char *index, const char *data )
|
||||
/*bool GuiBitmapButtonCtrl::_setBitmap(void* object, const char* index, const char* data)
|
||||
{
|
||||
GuiBitmapButtonCtrl* ctrl = reinterpret_cast< GuiBitmapButtonCtrl* >( object );
|
||||
ctrl->setBitmap( StringTable->insert(data) );
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Legacy method. Can just assign to bitmap field.
|
||||
DefineEngineMethod( GuiBitmapButtonCtrl, setBitmap, void, ( const char* path ),,
|
||||
/*DefineEngineMethod(GuiBitmapButtonCtrl, setBitmap, void, (const char* path), ,
|
||||
"Set the bitmap to show on the button.\n"
|
||||
"@param path Path to the texture file in any of the supported formats.\n" )
|
||||
{
|
||||
object->setBitmap( StringTable->insert(path) );
|
||||
}
|
||||
}*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -282,13 +283,13 @@ void GuiBitmapButtonCtrl::setBitmap( StringTableEntry name )
|
|||
{
|
||||
PROFILE_SCOPE( GuiBitmapButtonCtrl_setBitmap );
|
||||
|
||||
mBitmapName = name;
|
||||
_setBitmap(name);
|
||||
if( !isAwake() )
|
||||
return;
|
||||
|
||||
if( mBitmapName != StringTable->EmptyString())
|
||||
if( mBitmapAsset.notNull())
|
||||
{
|
||||
if( dStricmp( mBitmapName, "texhandle" ) != 0 )
|
||||
if( dStricmp( getBitmap(), "texhandle" ) != 0 )
|
||||
{
|
||||
const U32 count = mUseModifiers ? NumModifiers : 1;
|
||||
for( U32 i = 0; i < count; ++ i )
|
||||
|
|
@ -301,31 +302,102 @@ void GuiBitmapButtonCtrl::setBitmap( StringTableEntry name )
|
|||
"_shift"
|
||||
};
|
||||
|
||||
static String s_n = "_n";
|
||||
static String s_d = "_d";
|
||||
static String s_h = "_h";
|
||||
static String s_i = "_i";
|
||||
static String s_n[2] = { "_n", "_n_image" };
|
||||
static String s_d[2] = { "_d", "_d_image" };
|
||||
static String s_h[2] = { "_h", "_h_image" };
|
||||
static String s_i[2] = { "_i", "_i_image" };
|
||||
|
||||
String baseName = mBitmapAssetId;
|
||||
|
||||
//strip any pre-assigned suffix, just in case
|
||||
baseName = baseName.replace("_n_image", "");
|
||||
baseName = baseName.replace("_n", "");
|
||||
|
||||
String baseName = mBitmapName;
|
||||
if( mUseModifiers )
|
||||
baseName += modifiers[ i ];
|
||||
|
||||
mTextures[ i ].mTextureNormal = GFXTexHandle( baseName, &GFXDefaultGUIProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__));
|
||||
mTextures[ i ].mTextureNormal = GFXTexHandle( mBitmapAsset->getImagePath(), &GFXDefaultGUIProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__));
|
||||
|
||||
if( mUseStates )
|
||||
{
|
||||
if( !mTextures[ i ].mTextureNormal )
|
||||
mTextures[ i ].mTextureNormal = GFXTexHandle( baseName + s_n, &GFXDefaultGUIProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__));
|
||||
|
||||
mTextures[ i ].mTextureHilight = GFXTexHandle( baseName + s_h, &GFXDefaultGUIProfile, avar("%s() - mTextureHighlight (line %d)", __FUNCTION__, __LINE__));
|
||||
//normal lookup
|
||||
StringTableEntry lookupName;
|
||||
for (U32 s = 0; s < 2; s++)
|
||||
{
|
||||
if (!mTextures[i].mTextureNormal)
|
||||
{
|
||||
lookupName = StringTable->insert(String(baseName + s_n[s]).c_str());
|
||||
if (AssetDatabase.isDeclaredAsset(lookupName))
|
||||
{
|
||||
mTextures[i].mTextureNormalAssetId = lookupName;
|
||||
mTextures[i].mTextureNormalAsset = mTextures[i].mTextureNormalAssetId;
|
||||
}
|
||||
|
||||
if (mTextures[i].mTextureNormalAsset.notNull() && mTextures[i].mTextureNormalAsset->getStatus() == AssetBase::Ok)
|
||||
{
|
||||
mTextures[i].mTextureNormal = GFXTexHandle(mTextures[i].mTextureNormalAsset->getImagePath(), &GFXDefaultGUIProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Hilight lookup
|
||||
for (U32 s = 0; s < 2; s++)
|
||||
{
|
||||
lookupName = StringTable->insert(String(baseName + s_h[s]).c_str());
|
||||
if (AssetDatabase.isDeclaredAsset(lookupName))
|
||||
{
|
||||
mTextures[i].mTextureHilightAssetId = lookupName;
|
||||
mTextures[i].mTextureHilightAsset = mTextures[i].mTextureHilightAssetId;
|
||||
}
|
||||
|
||||
if (mTextures[i].mTextureHilightAsset.notNull() && mTextures[i].mTextureHilightAsset->getStatus() == AssetBase::Ok)
|
||||
{
|
||||
mTextures[i].mTextureHilight = GFXTexHandle(mTextures[i].mTextureHilightAsset->getImagePath(), &GFXDefaultGUIProfile, avar("%s() - mTextureHighlight (line %d)", __FUNCTION__, __LINE__));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !mTextures[ i ].mTextureHilight )
|
||||
mTextures[ i ].mTextureHilight = mTextures[ i ].mTextureNormal;
|
||||
|
||||
mTextures[ i ].mTextureDepressed = GFXTexHandle( baseName + s_d, &GFXDefaultGUIProfile, avar("%s() - mTextureDepressed (line %d)", __FUNCTION__, __LINE__));
|
||||
|
||||
//Depressed lookup
|
||||
for (U32 s = 0; s < 2; s++)
|
||||
{
|
||||
lookupName = StringTable->insert(String(baseName + s_d[s]).c_str());
|
||||
if (AssetDatabase.isDeclaredAsset(lookupName))
|
||||
{
|
||||
mTextures[i].mTextureDepressedAssetId = lookupName;
|
||||
mTextures[i].mTextureDepressedAsset = mTextures[i].mTextureDepressedAssetId;
|
||||
}
|
||||
|
||||
if (mTextures[i].mTextureDepressedAsset.notNull() && mTextures[i].mTextureDepressedAsset->getStatus() == AssetBase::Ok)
|
||||
{
|
||||
mTextures[i].mTextureDepressed = GFXTexHandle(mTextures[i].mTextureDepressedAsset->getImagePath(), &GFXDefaultGUIProfile, avar("%s() - mTextureDepressed (line %d)", __FUNCTION__, __LINE__));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !mTextures[ i ].mTextureDepressed )
|
||||
mTextures[ i ].mTextureDepressed = mTextures[ i ].mTextureHilight;
|
||||
|
||||
mTextures[ i ].mTextureInactive = GFXTexHandle( baseName + s_i, &GFXDefaultGUIProfile, avar("%s() - mTextureInactive (line %d)", __FUNCTION__, __LINE__));
|
||||
//Depressed lookup
|
||||
for (U32 s = 0; s < 2; s++)
|
||||
{
|
||||
lookupName = StringTable->insert(String(baseName + s_i[s]).c_str());
|
||||
if (AssetDatabase.isDeclaredAsset(lookupName))
|
||||
{
|
||||
mTextures[i].mTextureInactiveAssetId = lookupName;
|
||||
mTextures[i].mTextureInactiveAsset = mTextures[i].mTextureInactiveAssetId;
|
||||
}
|
||||
|
||||
if (mTextures[i].mTextureInactiveAsset.notNull() && mTextures[i].mTextureInactiveAsset->getStatus() == AssetBase::Ok)
|
||||
{
|
||||
mTextures[i].mTextureInactive = GFXTexHandle(mTextures[i].mTextureInactiveAsset->getImagePath(), &GFXDefaultGUIProfile, avar("%s() - mTextureInactive (line %d)", __FUNCTION__, __LINE__));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !mTextures[ i ].mTextureInactive )
|
||||
mTextures[ i ].mTextureInactive = mTextures[ i ].mTextureNormal;
|
||||
}
|
||||
|
|
@ -594,4 +666,6 @@ bool GuiBitmapButtonCtrl::pointInControl(const Point2I& parentCoordPoint)
|
|||
}
|
||||
else
|
||||
return Parent::pointInControl(parentCoordPoint);
|
||||
}
|
||||
}
|
||||
|
||||
DEF_IMAGEASSET_BINDS(GuiBitmapButtonCtrl, Bitmap);
|
||||
|
|
|
|||
|
|
@ -84,15 +84,23 @@ class GuiBitmapButtonCtrl : public GuiButtonCtrl
|
|||
struct Textures
|
||||
{
|
||||
/// Texture for normal state.
|
||||
StringTableEntry mTextureNormalAssetId;
|
||||
AssetPtr<ImageAsset> mTextureNormalAsset;
|
||||
GFXTexHandle mTextureNormal;
|
||||
|
||||
/// Texture for highlight state.
|
||||
StringTableEntry mTextureHilightAssetId;
|
||||
AssetPtr<ImageAsset> mTextureHilightAsset;
|
||||
GFXTexHandle mTextureHilight;
|
||||
|
||||
/// Texture for depressed state.
|
||||
StringTableEntry mTextureDepressedAssetId;
|
||||
AssetPtr<ImageAsset> mTextureDepressedAsset;
|
||||
GFXTexHandle mTextureDepressed;
|
||||
|
||||
/// Texture for inactive state.
|
||||
StringTableEntry mTextureInactiveAssetId;
|
||||
AssetPtr<ImageAsset> mTextureInactiveAsset;
|
||||
GFXTexHandle mTextureInactive;
|
||||
};
|
||||
|
||||
|
|
@ -110,8 +118,8 @@ class GuiBitmapButtonCtrl : public GuiButtonCtrl
|
|||
///
|
||||
BitmapMode mBitmapMode;
|
||||
|
||||
/// File name for bitmap.
|
||||
StringTableEntry mBitmapName;
|
||||
DECLARE_IMAGEASSET(GuiBitmapButtonCtrl, Bitmap, onBitmapChange, GFXDefaultGUIProfile);
|
||||
DECLARE_IMAGEASSET_SETGET(GuiBitmapButtonCtrl, Bitmap);
|
||||
|
||||
/// alpha masking
|
||||
bool mMasked;
|
||||
|
|
@ -122,7 +130,7 @@ class GuiBitmapButtonCtrl : public GuiButtonCtrl
|
|||
virtual void renderButton( GFXTexHandle &texture, const Point2I& offset, const RectI& updateRect );
|
||||
|
||||
static bool _setAutoFitExtents( void *object, const char *index, const char *data );
|
||||
static bool _setBitmap( void *object, const char *index, const char *data );
|
||||
//static bool _setBitmap( void *object, const char *index, const char *data );
|
||||
|
||||
State getState() const
|
||||
{
|
||||
|
|
@ -149,6 +157,8 @@ class GuiBitmapButtonCtrl : public GuiButtonCtrl
|
|||
|
||||
/// @}
|
||||
|
||||
void onBitmapChange() {}
|
||||
|
||||
public:
|
||||
|
||||
GuiBitmapButtonCtrl();
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@
|
|||
#include "gfx/gfxDrawUtil.h"
|
||||
#include "collision/concretePolyList.h"
|
||||
|
||||
#include "T3D/assets/ShapeAsset.h"
|
||||
#include "T3D/assets/ShapeAnimationAsset.h"
|
||||
|
||||
#ifdef TORQUE_COLLADA
|
||||
#include "collision/optimizedPolyList.h"
|
||||
#include "ts/collada/colladaUtils.h"
|
||||
|
|
@ -399,6 +402,35 @@ bool GuiShapeEdPreview::setObjectModel(const char* modelName)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GuiShapeEdPreview::setObjectShapeAsset(const char* assetId)
|
||||
{
|
||||
SAFE_DELETE(mModel);
|
||||
unmountAll();
|
||||
mThreads.clear();
|
||||
mActiveThread = -1;
|
||||
|
||||
StringTableEntry modelName = StringTable->EmptyString();
|
||||
if (AssetDatabase.isDeclaredAsset(assetId))
|
||||
{
|
||||
StringTableEntry id = StringTable->insert(assetId);
|
||||
StringTableEntry assetType = AssetDatabase.getAssetType(id);
|
||||
if (assetType == StringTable->insert("ShapeAsset"))
|
||||
{
|
||||
ShapeAsset* asset = AssetDatabase.acquireAsset<ShapeAsset>(id);
|
||||
modelName = asset->getShapeFilePath();
|
||||
AssetDatabase.releaseAsset(id);
|
||||
}
|
||||
else if (assetType == StringTable->insert("ShapeAnimationAsset"))
|
||||
{
|
||||
ShapeAnimationAsset* asset = AssetDatabase.acquireAsset<ShapeAnimationAsset>(id);
|
||||
modelName = asset->getAnimationPath();
|
||||
AssetDatabase.releaseAsset(id);
|
||||
}
|
||||
}
|
||||
|
||||
return setObjectModel(modelName);
|
||||
}
|
||||
|
||||
void GuiShapeEdPreview::_onResourceChanged(const Torque::Path& path)
|
||||
{
|
||||
if (path != Torque::Path(mModelName))
|
||||
|
|
@ -1717,6 +1749,14 @@ DefineEngineMethod( GuiShapeEdPreview, setModel, bool, ( const char* shapePath )
|
|||
return object->setObjectModel( shapePath );
|
||||
}
|
||||
|
||||
DefineEngineMethod(GuiShapeEdPreview, setShapeAsset, bool, (const char* shapeAsset), ,
|
||||
"Sets the model to be displayed in this control\n\n"
|
||||
"@param shapeName Name of the model to display.\n"
|
||||
"@return True if the model was loaded successfully, false otherwise.\n")
|
||||
{
|
||||
return object->setObjectShapeAsset(shapeAsset);
|
||||
}
|
||||
|
||||
DefineEngineMethod( GuiShapeEdPreview, fitToShape, void, (),,
|
||||
"Adjust the camera position and zoom to fit the shape within the view.\n\n" )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ public:
|
|||
|
||||
void setCurrentDetail(S32 dl);
|
||||
bool setObjectModel(const char * modelName);
|
||||
bool setObjectShapeAsset(const char* assetId);
|
||||
|
||||
void _onResourceChanged(const Torque::Path& path);
|
||||
|
||||
|
|
|
|||
|
|
@ -805,7 +805,7 @@ TSShape* assimpLoadShape(const Torque::Path &path)
|
|||
|
||||
// Allow TSShapeConstructor object to override properties
|
||||
ColladaUtils::getOptions().reset();
|
||||
TSShapeConstructor* tscon = TSShapeConstructor::findShapeConstructor(path.getFullPath());
|
||||
TSShapeConstructor* tscon = TSShapeConstructor::findShapeConstructorByFilename(path.getFullPath());
|
||||
if (tscon)
|
||||
{
|
||||
ColladaUtils::getOptions() = tscon->mOptions;
|
||||
|
|
|
|||
|
|
@ -693,7 +693,7 @@ TSShape* loadColladaShape(const Torque::Path &path)
|
|||
|
||||
// Allow TSShapeConstructor object to override properties
|
||||
ColladaUtils::getOptions().reset();
|
||||
TSShapeConstructor* tscon = TSShapeConstructor::findShapeConstructor(path.getFullPath());
|
||||
TSShapeConstructor* tscon = TSShapeConstructor::findShapeConstructorByFilename(path.getFullPath());
|
||||
if (tscon)
|
||||
{
|
||||
ColladaUtils::getOptions() = tscon->mOptions;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -42,6 +42,9 @@
|
|||
#include "console/engineAPI.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ShapeAsset.h"
|
||||
#include "T3D/assets/ShapeAnimationAsset.h"
|
||||
|
||||
/// This class allows an artist to export their animations for the model
|
||||
/// into the .dsq format. This class in particular matches up the model
|
||||
/// with the .dsqs to create a nice animated model.
|
||||
|
|
@ -101,17 +104,17 @@ public:
|
|||
String argv[MAX_ARGS]; // Command arguments
|
||||
S32 argc; // Number of arguments
|
||||
Command() : type(CmdInvalid), name(0), argc(0) { }
|
||||
Command( const char* _name )
|
||||
Command(const char* _name)
|
||||
: type(CmdInvalid), argc(0)
|
||||
{
|
||||
name = StringTable->insert( _name );
|
||||
name = StringTable->insert(_name);
|
||||
}
|
||||
|
||||
// Helper functions to fill in the command arguments
|
||||
template<typename ...ArgTs> inline void addArgs(ArgTs ...args) {
|
||||
using Helper = engineAPI::detail::MarshallHelpers<String>;
|
||||
Helper::marshallEach(argc, argv, args...);
|
||||
}
|
||||
|
||||
// Helper functions to fill in the command arguments
|
||||
template<typename ...ArgTs> inline void addArgs(ArgTs ...args){
|
||||
using Helper = engineAPI::detail::MarshallHelpers<String>;
|
||||
Helper::marshallEach(argc, argv, args...);
|
||||
}
|
||||
};
|
||||
|
||||
Vector<Command> mCommands;
|
||||
|
|
@ -120,40 +123,40 @@ public:
|
|||
void clear() { mCommands.clear(); }
|
||||
bool empty() { return mCommands.empty(); }
|
||||
|
||||
void add( Command& cmd );
|
||||
void add(Command& cmd);
|
||||
|
||||
// These methods handle change set optimisation based on the newly added command
|
||||
bool addCmd_setNodeParent( const Command& newCmd );
|
||||
bool addCmd_setNodeTransform( const Command& newCmd );
|
||||
bool addCmd_renameNode( const Command& newCmd );
|
||||
bool addCmd_removeNode( const Command& newCmd );
|
||||
bool addCmd_setNodeParent(const Command& newCmd);
|
||||
bool addCmd_setNodeTransform(const Command& newCmd);
|
||||
bool addCmd_renameNode(const Command& newCmd);
|
||||
bool addCmd_removeNode(const Command& newCmd);
|
||||
|
||||
bool addCmd_setMeshSize( const Command& newCmd );
|
||||
bool addCmd_setMeshType( const Command& newCmd );
|
||||
bool addCmd_setMeshMaterial( const Command& newCmd );
|
||||
bool addCmd_removeMesh( const Command& newCmd );
|
||||
bool addCmd_setMeshSize(const Command& newCmd);
|
||||
bool addCmd_setMeshType(const Command& newCmd);
|
||||
bool addCmd_setMeshMaterial(const Command& newCmd);
|
||||
bool addCmd_removeMesh(const Command& newCmd);
|
||||
|
||||
bool addCmd_setObjectNode( const Command& newCmd );
|
||||
bool addCmd_renameObject( const Command& newCmd );
|
||||
bool addCmd_removeObject( const Command& newCmd );
|
||||
bool addCmd_setBounds( const Command& newCmd );
|
||||
bool addCmd_setObjectNode(const Command& newCmd);
|
||||
bool addCmd_renameObject(const Command& newCmd);
|
||||
bool addCmd_removeObject(const Command& newCmd);
|
||||
bool addCmd_setBounds(const Command& newCmd);
|
||||
|
||||
bool addCmd_renameDetailLevel( const Command& newCmd );
|
||||
bool addCmd_removeDetailLevel( const Command& newCmd );
|
||||
bool addCmd_setDetailSize( const Command& newCmd );
|
||||
bool addCmd_addImposter( const Command& newCmd );
|
||||
bool addCmd_removeImposter( const Command& newCmd );
|
||||
bool addCmd_renameDetailLevel(const Command& newCmd);
|
||||
bool addCmd_removeDetailLevel(const Command& newCmd);
|
||||
bool addCmd_setDetailSize(const Command& newCmd);
|
||||
bool addCmd_addImposter(const Command& newCmd);
|
||||
bool addCmd_removeImposter(const Command& newCmd);
|
||||
|
||||
bool addCmd_addSequence( Command& newCmd );
|
||||
bool addCmd_setSequencePriority( const Command& newCmd );
|
||||
bool addCmd_setSequenceGroundSpeed( const Command& newCmd );
|
||||
bool addCmd_setSequenceCyclic( const Command& newCmd );
|
||||
bool addCmd_setSequenceBlend( const Command& newCmd );
|
||||
bool addCmd_renameSequence( const Command& newCmd );
|
||||
bool addCmd_removeSequence( const Command& newCmd );
|
||||
bool addCmd_addSequence(Command& newCmd);
|
||||
bool addCmd_setSequencePriority(const Command& newCmd);
|
||||
bool addCmd_setSequenceGroundSpeed(const Command& newCmd);
|
||||
bool addCmd_setSequenceCyclic(const Command& newCmd);
|
||||
bool addCmd_setSequenceBlend(const Command& newCmd);
|
||||
bool addCmd_renameSequence(const Command& newCmd);
|
||||
bool addCmd_removeSequence(const Command& newCmd);
|
||||
|
||||
bool addCmd_addTrigger( const Command& newCmd );
|
||||
bool addCmd_removeTrigger( const Command& newCmd );
|
||||
bool addCmd_addTrigger(const Command& newCmd);
|
||||
bool addCmd_removeTrigger(const Command& newCmd);
|
||||
|
||||
void write(TSShape* shape, Stream& stream, const String& savePath);
|
||||
};
|
||||
|
|
@ -161,8 +164,12 @@ public:
|
|||
static const S32 MaxLegacySequences = 127;
|
||||
|
||||
protected:
|
||||
StringTableEntry mShapePath;
|
||||
Vector<StringTableEntry> mSequences;
|
||||
StringTableEntry mShapeAssetId;
|
||||
AssetPtr<ShapeAsset> mShapeAsset;
|
||||
|
||||
Vector<StringTableEntry> mSequenceAssetIds;
|
||||
Vector<AssetPtr<ShapeAnimationAsset>> mSequencesAssets;
|
||||
|
||||
ChangeSet mChangeSet;
|
||||
|
||||
// Paths to shapes used by MeshFit
|
||||
|
|
@ -170,46 +177,47 @@ protected:
|
|||
static String smCubeShapePath;
|
||||
static String smSphereShapePath;
|
||||
|
||||
static bool addSequenceFromField( void *obj, const char *index, const char *data );
|
||||
|
||||
static void _onTSShapeLoaded( Resource< TSShape >& shape );
|
||||
static void _onTSShapeUnloaded( const Torque::Path& path, TSShape* shape );
|
||||
|
||||
static bool addSequenceFromField(void* obj, const char* index, const char* data);
|
||||
|
||||
static void _onTSShapeLoaded(Resource< TSShape >& shape);
|
||||
static void _onTSShapeUnloaded(const Torque::Path& path, TSShape* shape);
|
||||
|
||||
static ResourceRegisterPostLoadSignal< TSShape > _smAutoLoad;
|
||||
static ResourceRegisterUnloadSignal< TSShape > _smAutoUnload;
|
||||
|
||||
|
||||
/// @name Callbacks
|
||||
///@{
|
||||
DECLARE_CALLBACK( void, onLoad, () );
|
||||
DECLARE_CALLBACK( void, onUnload, () );
|
||||
DECLARE_CALLBACK(void, onLoad, ());
|
||||
DECLARE_CALLBACK(void, onUnload, ());
|
||||
///@}
|
||||
|
||||
virtual void _onLoad( TSShape* shape );
|
||||
virtual void _onLoad(TSShape* shape);
|
||||
virtual void _onUnload();
|
||||
|
||||
public:
|
||||
|
||||
TSShape* mShape; // Edited shape; NULL while not loaded; not a Resource<TSShape> as we don't want it to prevent from unloading.
|
||||
TSShape* mShape; // Edited shape; NULL while not loaded; not a Resource<TSShape> as we don't want it to prevent from unloading.
|
||||
ColladaUtils::ImportOptions mOptions;
|
||||
bool mLoadingShape;
|
||||
|
||||
public:
|
||||
|
||||
TSShapeConstructor();
|
||||
TSShapeConstructor(StringTableEntry path) : mShapePath(path), mShape(NULL), mLoadingShape(false){ }
|
||||
TSShapeConstructor(StringTableEntry path) : mShapeAssetId(path), mShape(NULL), mLoadingShape(false) { }
|
||||
~TSShapeConstructor();
|
||||
|
||||
DECLARE_CONOBJECT(TSShapeConstructor);
|
||||
static void initPersistFields();
|
||||
static void consoleInit();
|
||||
static TSShapeConstructor* findShapeConstructor(const FileName& path);
|
||||
static TSShapeConstructor* findShapeConstructorByAssetId(StringTableEntry path);
|
||||
static TSShapeConstructor* findShapeConstructorByFilename(const FileName& path);
|
||||
|
||||
bool onAdd();
|
||||
|
||||
void onScriptChanged(const Torque::Path& path);
|
||||
void onActionPerformed();
|
||||
|
||||
bool writeField(StringTableEntry fieldname, const char *value);
|
||||
bool writeField(StringTableEntry fieldname, const char* value);
|
||||
void writeChangeSet();
|
||||
|
||||
void notifyShapeChanged();
|
||||
|
|
@ -222,107 +230,118 @@ public:
|
|||
///@}
|
||||
|
||||
TSShape* getShape() const { return mShape; }
|
||||
StringTableEntry getShapePath() const { return mShapePath; }
|
||||
StringTableEntry getShapePath() const
|
||||
{
|
||||
if (mShapeAsset.notNull())
|
||||
return mShapeAsset->getShapeFilePath();
|
||||
else
|
||||
return StringTable->EmptyString();
|
||||
}
|
||||
|
||||
StringTableEntry getShapeAssetId() const
|
||||
{
|
||||
return mShapeAssetId;
|
||||
}
|
||||
|
||||
/// @name Dumping
|
||||
///@{
|
||||
void dumpShape( const char* filename );
|
||||
void saveShape( const char* filename );
|
||||
void dumpShape(const char* filename);
|
||||
void saveShape(const char* filename);
|
||||
///@}
|
||||
|
||||
/// @name Nodes
|
||||
///@{
|
||||
S32 getNodeCount();
|
||||
S32 getNodeIndex( const char* name );
|
||||
const char* getNodeName( S32 index );
|
||||
const char* getNodeParentName( const char* name );
|
||||
bool setNodeParent( const char* name, const char* parentName );
|
||||
S32 getNodeChildCount( const char* name );
|
||||
const char* getNodeChildName( const char* name, S32 index );
|
||||
S32 getNodeObjectCount( const char* name );
|
||||
const char* getNodeObjectName( const char* name, S32 index );
|
||||
TransformF getNodeTransform( const char* name, bool isWorld=false );
|
||||
bool setNodeTransform( const char* name, TransformF txfm, bool isWorld=false );
|
||||
bool renameNode( const char* oldName, const char* newName );
|
||||
bool addNode( const char* name, const char* parentName, TransformF txfm=TransformF::Identity, bool isWorld=false);
|
||||
bool removeNode( const char* name );
|
||||
S32 getNodeIndex(const char* name);
|
||||
const char* getNodeName(S32 index);
|
||||
const char* getNodeParentName(const char* name);
|
||||
bool setNodeParent(const char* name, const char* parentName);
|
||||
S32 getNodeChildCount(const char* name);
|
||||
const char* getNodeChildName(const char* name, S32 index);
|
||||
S32 getNodeObjectCount(const char* name);
|
||||
const char* getNodeObjectName(const char* name, S32 index);
|
||||
TransformF getNodeTransform(const char* name, bool isWorld = false);
|
||||
bool setNodeTransform(const char* name, TransformF txfm, bool isWorld = false);
|
||||
bool renameNode(const char* oldName, const char* newName);
|
||||
bool addNode(const char* name, const char* parentName, TransformF txfm = TransformF::Identity, bool isWorld = false);
|
||||
bool removeNode(const char* name);
|
||||
///@}
|
||||
|
||||
/// @name Materials
|
||||
///@{
|
||||
S32 getTargetCount();
|
||||
const char* getTargetName( S32 index );
|
||||
const char* getTargetName(S32 index);
|
||||
///@}
|
||||
|
||||
///@{
|
||||
S32 getObjectCount();
|
||||
const char* getObjectName( S32 index );
|
||||
S32 getObjectIndex( const char* name );
|
||||
const char* getObjectNode( const char* name );
|
||||
bool setObjectNode( const char* objName, const char* nodeName );
|
||||
bool renameObject( const char* oldName, const char* newName );
|
||||
bool removeObject( const char* name );
|
||||
const char* getObjectName(S32 index);
|
||||
S32 getObjectIndex(const char* name);
|
||||
const char* getObjectNode(const char* name);
|
||||
bool setObjectNode(const char* objName, const char* nodeName);
|
||||
bool renameObject(const char* oldName, const char* newName);
|
||||
bool removeObject(const char* name);
|
||||
///@}
|
||||
|
||||
/// @name Meshes
|
||||
///@{
|
||||
S32 getMeshCount( const char* name );
|
||||
const char* getMeshName( const char* name, S32 index );
|
||||
S32 getMeshSize( const char* name, S32 index );
|
||||
bool setMeshSize( const char* name, S32 size );
|
||||
const char* getMeshType( const char* name );
|
||||
bool setMeshType( const char* name, const char* type );
|
||||
const char* getMeshMaterial( const char* name );
|
||||
bool setMeshMaterial( const char* meshName, const char* matName );
|
||||
bool addMesh( const char* meshName, const char* srcShape, const char* srcMesh );
|
||||
bool addPrimitive( const char* meshName, const char* type, const char* params, TransformF txfm, const char* nodeName );
|
||||
bool removeMesh( const char* name );
|
||||
S32 getMeshCount(const char* name);
|
||||
const char* getMeshName(const char* name, S32 index);
|
||||
S32 getMeshSize(const char* name, S32 index);
|
||||
bool setMeshSize(const char* name, S32 size);
|
||||
const char* getMeshType(const char* name);
|
||||
bool setMeshType(const char* name, const char* type);
|
||||
const char* getMeshMaterial(const char* name);
|
||||
bool setMeshMaterial(const char* meshName, const char* matName);
|
||||
bool addMesh(const char* meshName, const char* srcShape, const char* srcMesh);
|
||||
bool addPrimitive(const char* meshName, const char* type, const char* params, TransformF txfm, const char* nodeName);
|
||||
bool removeMesh(const char* name);
|
||||
///@}
|
||||
|
||||
/// @name Detail Levels
|
||||
///@{
|
||||
Box3F getBounds();
|
||||
bool setBounds( Box3F bbox );
|
||||
bool setBounds(Box3F bbox);
|
||||
S32 getDetailLevelCount();
|
||||
const char* getDetailLevelName( S32 index );
|
||||
S32 getDetailLevelSize( S32 index);
|
||||
S32 getDetailLevelIndex( S32 size );
|
||||
bool renameDetailLevel( const char* oldName, const char* newName );
|
||||
bool removeDetailLevel( S32 index );
|
||||
S32 setDetailLevelSize( S32 index, S32 newSize );
|
||||
const char* getDetailLevelName(S32 index);
|
||||
S32 getDetailLevelSize(S32 index);
|
||||
S32 getDetailLevelIndex(S32 size);
|
||||
bool renameDetailLevel(const char* oldName, const char* newName);
|
||||
bool removeDetailLevel(S32 index);
|
||||
S32 setDetailLevelSize(S32 index, S32 newSize);
|
||||
S32 getImposterDetailLevel();
|
||||
const char* getImposterSettings( S32 index );
|
||||
S32 addImposter( S32 size, S32 equatorSteps, S32 polarSteps, S32 dl, S32 dim, bool includePoles, F32 polarAngle );
|
||||
const char* getImposterSettings(S32 index);
|
||||
S32 addImposter(S32 size, S32 equatorSteps, S32 polarSteps, S32 dl, S32 dim, bool includePoles, F32 polarAngle);
|
||||
bool removeImposter();
|
||||
bool addCollisionDetail( S32 size, const char* type, const char* target, S32 depth=4, F32 merge=30.0f, F32 concavity=30.0f, S32 maxVerts=32, F32 boxMaxError=0, F32 sphereMaxError=0, F32 capsuleMaxError=0 );
|
||||
bool addCollisionDetail(S32 size, const char* type, const char* target, S32 depth = 4, F32 merge = 30.0f, F32 concavity = 30.0f, S32 maxVerts = 32, F32 boxMaxError = 0, F32 sphereMaxError = 0, F32 capsuleMaxError = 0);
|
||||
///@}
|
||||
|
||||
/// @name Sequences
|
||||
///@{
|
||||
S32 getSequenceCount();
|
||||
S32 getSequenceIndex( const char* name);
|
||||
const char* getSequenceName( S32 index );
|
||||
const char* getSequenceSource( const char* name );
|
||||
S32 getSequenceFrameCount( const char* name );
|
||||
F32 getSequencePriority( const char* name );
|
||||
bool setSequencePriority( const char* name, F32 priority );
|
||||
const char* getSequenceGroundSpeed( const char* name );
|
||||
bool setSequenceGroundSpeed( const char* name, Point3F transSpeed, Point3F rotSpeed=Point3F::Zero );
|
||||
bool getSequenceCyclic( const char* name );
|
||||
bool setSequenceCyclic( const char* name, bool cyclic );
|
||||
const char* getSequenceBlend( const char* name );
|
||||
bool setSequenceBlend( const char* name, bool blend, const char* blendSeq, S32 blendFrame );
|
||||
bool renameSequence( const char* oldName, const char* newName );
|
||||
bool addSequence( const char* source, const char* name, S32 start=0, S32 end=-1, bool padRot=true, bool padTrans=false );
|
||||
bool removeSequence( const char* name );
|
||||
S32 getSequenceIndex(const char* name);
|
||||
const char* getSequenceName(S32 index);
|
||||
const char* getSequenceSource(const char* name);
|
||||
S32 getSequenceFrameCount(const char* name);
|
||||
F32 getSequencePriority(const char* name);
|
||||
bool setSequencePriority(const char* name, F32 priority);
|
||||
const char* getSequenceGroundSpeed(const char* name);
|
||||
bool setSequenceGroundSpeed(const char* name, Point3F transSpeed, Point3F rotSpeed = Point3F::Zero);
|
||||
bool getSequenceCyclic(const char* name);
|
||||
bool setSequenceCyclic(const char* name, bool cyclic);
|
||||
const char* getSequenceBlend(const char* name);
|
||||
bool setSequenceBlend(const char* name, bool blend, const char* blendSeq, S32 blendFrame);
|
||||
bool renameSequence(const char* oldName, const char* newName);
|
||||
bool addSequence(const char* source, const char* name, S32 start = 0, S32 end = -1, bool padRot = true, bool padTrans = false);
|
||||
bool removeSequence(const char* name);
|
||||
///@}
|
||||
|
||||
/// @name Triggers
|
||||
///@{
|
||||
S32 getTriggerCount( const char* name );
|
||||
const char* getTrigger( const char* name, S32 index );
|
||||
bool addTrigger( const char* name, S32 keyframe, S32 state );
|
||||
bool removeTrigger( const char* name, S32 keyframe, S32 state );
|
||||
S32 getTriggerCount(const char* name);
|
||||
const char* getTrigger(const char* name, S32 index);
|
||||
bool addTrigger(const char* name, S32 keyframe, S32 state);
|
||||
bool removeTrigger(const char* name, S32 keyframe, S32 state);
|
||||
///@}
|
||||
};
|
||||
|
||||
|
|
@ -330,7 +349,7 @@ typedef domUpAxisType TSShapeConstructorUpAxis;
|
|||
typedef ColladaUtils::ImportOptions::eLodType TSShapeConstructorLodType;
|
||||
typedef ColladaUtils::ImportOptions::eAnimTimingType TSShapeConstructorAnimType;
|
||||
|
||||
DefineEnumType( TSShapeConstructorUpAxis );
|
||||
DefineEnumType(TSShapeConstructorUpAxis);
|
||||
DefineEnumType(TSShapeConstructorLodType);
|
||||
DefineEnumType(TSShapeConstructorAnimType);
|
||||
|
||||
|
|
@ -339,7 +358,7 @@ class TSShapeConstructorMethodActionCallback
|
|||
TSShapeConstructor* mObject;
|
||||
|
||||
public:
|
||||
TSShapeConstructorMethodActionCallback(TSShapeConstructor *object) : mObject(object) { ; }
|
||||
TSShapeConstructorMethodActionCallback(TSShapeConstructor* object) : mObject(object) { ; }
|
||||
~TSShapeConstructorMethodActionCallback() { mObject->onActionPerformed(); }
|
||||
};
|
||||
|
||||
|
|
@ -372,8 +391,8 @@ public:
|
|||
TORQUE_UNUSED(newCmd);
|
||||
|
||||
|
||||
/* This macro just hides the name of the auto-created ChangeSet::Command from
|
||||
above, so we are free to change the implementation later if needed */
|
||||
/* This macro just hides the name of the auto-created ChangeSet::Command from
|
||||
above, so we are free to change the implementation later if needed */
|
||||
#define ADD_TO_CHANGE_SET() mChangeSet.add( newCmd );
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue