Merge pull request #434 from Areloch/UpdatedCppAssets

Adjusts handling of C++ asset types
This commit is contained in:
Brian Roberts 2021-01-02 11:09:13 -06:00 committed by GitHub
commit ab4c19e5ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 1378 additions and 47 deletions

View file

@ -333,17 +333,7 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName )
//special-case entry
if(getFieldCount(%asset) > 1)
{
%specialType = getField(%asset,0);
/*if(%specialType $= "Folder")
{
}
else if(%specialType $= "Datablock")
{
%sdfasdgah = true;
}*/
%assetType = %specialType;
%assetType = getField(%asset,0);
%assetName = getField(%asset, 1);
%sdfasdgah = true;
@ -389,6 +379,38 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName )
%fullPath = strreplace(%fullPath, "/", "_");
%fullPath = strreplace(%fullPath, ".", "-");
if(isObject(%fullPath))
%assetDesc = %fullPath;
else
%assetDesc = new ScriptObject(%fullPath);
%assetDesc.dirPath = %moduleName;
%assetDesc.assetName = %assetName;
%assetDesc.description = %moduleName @ "/" @ %assetName;
%assetDesc.assetType = %assetType;
}
else if(%assetType $= "Cpp")
{
%fullPath = %moduleName !$= "" ? %moduleName @ "/" @ %assetName : %assetName;
%fullPath = strreplace(%fullPath, "/", "_");
%fullPath = strreplace(%fullPath, ".", "-");
if(isObject(%fullPath))
%assetDesc = %fullPath;
else
%assetDesc = new ScriptObject(%fullPath);
%assetDesc.dirPath = %moduleName;
%assetDesc.assetName = %assetName;
%assetDesc.description = %moduleName @ "/" @ %assetName;
%assetDesc.assetType = %assetType;
}
else if(%assetType $= "tscript")
{
%fullPath = %moduleName !$= "" ? %moduleName @ "/" @ %assetName : %assetName;
%fullPath = strreplace(%fullPath, "/", "_");
%fullPath = strreplace(%fullPath, ".", "-");
if(isObject(%fullPath))
%assetDesc = %fullPath;
else
@ -1568,6 +1590,7 @@ function AssetBrowser::doRebuildAssetArray(%this)
%looseFileFullPath = ABLooseFileArray.getKey(%i);
%looseFilePath = filePath(%looseFileFullPath);
%looseFileName = fileName(%looseFileFullPath);
%looseFileExt = fileExt(%looseFileFullPath);
%assetArray.add( %looseFilePath, "LooseFile" TAB %looseFileName );
}
@ -1599,6 +1622,78 @@ function AssetBrowser::doRebuildAssetArray(%this)
%fullPrefabPath = findNextFile( %breadcrumbPath @ "/" @ %expr );
}
//C++ files
%cppPattern = %breadcrumbPath @ "/" @ "*.cpp";
for (%fullCppPath = findFirstFile(%cppPattern); %fullCppPath !$= ""; %fullCppPath = findNextFile(%cppPattern))
{
%cppPath = filePath(%fullCppPath);
%cppName = fileName(%fullCppPath);
%searchActive = AssetSearchTerms.count() != 0;
if(%searchActive)
{
if(startsWith(%cppPath, %breadcrumbPath))
{
if(matchesSearch(%cppName, "Cpp"))
{
%assetArray.add( %cppPath, "Cpp" TAB %cppName );
}
}
}
else if(%cppPath $= %breadcrumbPath)
{
%assetArray.add( %cppPath, "Cpp" TAB %cppName );
}
}
//C++ Header files
%cppPattern = %breadcrumbPath @ "/" @ "*.h";
for (%fullCppPath = findFirstFile(%cppPattern); %fullCppPath !$= ""; %fullCppPath = findNextFile(%cppPattern))
{
%cppPath = filePath(%fullCppPath);
%cppName = fileName(%fullCppPath);
%searchActive = AssetSearchTerms.count() != 0;
if(%searchActive)
{
if(startsWith(%cppPath, %breadcrumbPath))
{
if(matchesSearch(%cppName, "Cpp"))
{
%assetArray.add( %cppPath, "Cpp" TAB %cppName );
}
}
}
else if(%cppPath $= %breadcrumbPath)
{
%assetArray.add( %cppPath, "Cpp" TAB %cppName );
}
}
//script files
%tscriptPattern = %breadcrumbPath @ "/" @ "*.tscript";
for (%fullScriptPath = findFirstFile(%tscriptPattern); %fullScriptPath !$= ""; %fullScriptPath = findNextFile(%tscriptPattern))
{
%tscriptPath = filePath(%fullScriptPath);
%tscriptName = fileName(%fullScriptPath);
%searchActive = AssetSearchTerms.count() != 0;
if(%searchActive)
{
if(startsWith(%tscriptPath, %breadcrumbPath))
{
if(matchesSearch(%tscriptName, "tscript"))
{
%assetArray.add( %tscriptPath, "tscript" TAB %tscriptName );
}
}
}
else if(%tscriptPath $= %breadcrumbPath)
{
%assetArray.add( %tscriptPath, "tscript" TAB %tscriptName );
}
}
}
for(%i=0; %i < %assetArray.count(); %i++)

View file

@ -1,4 +1,4 @@
function AssetBrowser::buildCppAssetPreview(%this, %assetDef, %previewData)
function AssetBrowser::buildCppPreview(%this, %assetDef, %previewData)
{
%previewData.assetName = %assetDef.assetName;
%previewData.assetPath = %assetDef.codeFilePath;
@ -11,7 +11,7 @@ function AssetBrowser::buildCppAssetPreview(%this, %assetDef, %previewData)
%previewData.tooltip = %assetDef.assetName;
}
function AssetBrowser::createCppAsset(%this)
function AssetBrowser::createCpp(%this)
{
%moduleName = AssetBrowser.newAssetSettings.moduleName;
%modulePath = "data/" @ %moduleName;
@ -20,21 +20,12 @@ function AssetBrowser::createCppAsset(%this)
%assetPath = AssetBrowser.dirHandler.currentAddress @ "/";
%tamlpath = %assetPath @ %assetName @ ".asset.taml";
//%tamlpath = %assetPath @ %assetName @ ".asset.taml";
%codePath = %assetPath @ %assetName @ ".cpp";
%headerPath = %assetPath @ %assetName @ ".h";
//Do the work here
%assetType = AssetBrowser.newAssetSettings.assetType;
/*if(%assetType $= "CppStaticClassAsset"
|| %assetType $= "CppRegularClassAsset"
|| %assetType $= "CppGameObjectAsset"
|| %assetType $= "CppComponentAsset"
|| %assetType $= "CppScriptClass")
{
}*/
/*%assetType = AssetBrowser.newAssetSettings.assetType;
%asset = new CppAsset()
{
@ -44,26 +35,48 @@ function AssetBrowser::createCppAsset(%this)
headerFile = %headerPath;
};
TamlWrite(%asset, %tamlpath);
TamlWrite(%asset, %tamlpath);*/
%moduleDef = ModuleDatabase.findModule(%moduleName, 1);
AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath);
AssetBrowser.loadFilters();
//AssetBrowser.loadFilters();
%treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName);
/*%treeItemId = AssetBrowserFilterTree.findItemByName(%moduleName);
%smItem = AssetBrowserFilterTree.findChildItemByName(%treeItemId, "CppAsset");
AssetBrowserFilterTree.onSelect(%smItem);
AssetBrowserFilterTree.onSelect(%smItem);*/
%file = new FileObject();
%templateFile = new FileObject();
if(%assetType $= "CppStaticClassAsset")
if($AssetBrowser::newAssetTypeOverride $= "StaticClass")
{
%cppTemplateCodeFilePath = %this.templateFilesPath @ "CppStaticClassFile.cpp";
%cppTemplateHeaderFilePath = %this.templateFilesPath @ "CppStaticClassFile.h";
%cppTemplateCodeFilePath = %this.templateFilesPath @ "CppStaticClassFile.cpp.template";
%cppTemplateHeaderFilePath = %this.templateFilesPath @ "CppStaticClassFile.h.template";
}
else if($AssetBrowser::newAssetTypeOverride $= "ScriptClass")
{
%cppTemplateCodeFilePath = %this.templateFilesPath @ "CppScriptClassFile.cpp.template";
%cppTemplateHeaderFilePath = %this.templateFilesPath @ "CppScriptClassFile.h.template";
}
else if($AssetBrowser::newAssetTypeOverride $= "AssetTypeCppClass")
{
%cppTemplateCodeFilePath = %this.templateFilesPath @ "CppAssetTypeClassFile.cpp.template";
%cppTemplateHeaderFilePath = %this.templateFilesPath @ "CppAssetTypeClassFile.h.template";
}
else if($AssetBrowser::newAssetTypeOverride $= "RenderCppClass")
{
%cppTemplateCodeFilePath = %this.templateFilesPath @ "CppRenderClassFile.cpp.template";
%cppTemplateHeaderFilePath = %this.templateFilesPath @ "CppRenderClassFile.h.template";
}
else if($AssetBrowser::newAssetTypeOverride $= "SceneObjectCppClass")
{
%cppTemplateCodeFilePath = %this.templateFilesPath @ "CppSceneObjectClassFile.cpp.template";
%cppTemplateHeaderFilePath = %this.templateFilesPath @ "CppSceneObjectClassFile.h.template";
}
$AssetBrowser::newAssetTypeOverride = "";
if(%file.openForWrite(%codePath) && %templateFile.openForRead(%cppTemplateCodeFilePath))
{
@ -73,7 +86,7 @@ function AssetBrowser::createCppAsset(%this)
%line = strreplace( %line, "@", %assetName );
%file.writeline(%line);
echo(%line);
//echo(%line);
}
%file.close();
@ -84,7 +97,7 @@ function AssetBrowser::createCppAsset(%this)
%file.close();
%templateFile.close();
warnf("CreateNewCppAsset - Something went wrong and we couldn't write the C++ code file!");
warn("CreateNewCppAsset - Something went wrong and we couldn't write the C++ code file!");
}
if(%file.openForWrite(%headerPath) && %templateFile.openForRead(%cppTemplateHeaderFilePath))
@ -95,7 +108,7 @@ function AssetBrowser::createCppAsset(%this)
%line = strreplace( %line, "@", %assetName );
%file.writeline(%line);
echo(%line);
//echo(%line);
}
%file.close();
@ -124,7 +137,7 @@ function AssetBrowser::createCppAsset(%this)
%line = strreplace( %line, "@", %moduleName );
%file.writeline(%line);
echo(%line);
//echo(%line);
}
%file.close();
@ -139,15 +152,15 @@ function AssetBrowser::createCppAsset(%this)
}
}
return %tamlpath;
return "";
}
function AssetBrowser::editCppAsset(%this, %assetDef)
function AssetBrowser::editCpp(%this, %assetDef)
{
}
//Renames the asset
function AssetBrowser::renameCppAsset(%this, %assetDef, %newAssetName)
function AssetBrowser::renameCpp(%this, %assetDef, %newAssetName)
{
%newCodeLooseFilename = renameAssetLooseFile(%assetDef.codefile, %newAssetName);
@ -167,13 +180,13 @@ function AssetBrowser::renameCppAsset(%this, %assetDef, %newAssetName)
}
//Deletes the asset
function AssetBrowser::deleteCppAsset(%this, %assetDef)
function AssetBrowser::deleteCpp(%this, %assetDef)
{
AssetDatabase.deleteAsset(%assetDef.getAssetId(), true);
}
//Moves the asset to a new path/module
function AssetBrowser::moveCppAsset(%this, %assetDef, %destination)
function AssetBrowser::moveCpp(%this, %assetDef, %destination)
{
%currentModule = AssetDatabase.getAssetModule(%assetDef.getAssetId());
%targetModule = AssetBrowser.getModuleFromAddress(%destination);

View file

@ -154,13 +154,11 @@ function AssetBrowser::buildPopupMenus(%this)
class = "EditorWorldMenu";
//isPopup = true;
/*item[ 0 ] = "Create Static Class" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"CppStaticClassAsset\", AssetBrowser.selectedModule);";
item[ 1 ] = "Create Regular Class" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"CppRegularClassAsset\", AssetBrowser.selectedModule);";
item[ 2 ] = "Create GameObject Class" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"CppGameObjectAsset\", AssetBrowser.selectedModule);";
item[ 3 ] = "Create Component Class" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"CppComponentAsset\", AssetBrowser.selectedModule);";
item[ 4 ] = "Create Script Class" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"CppScriptClass\", AssetBrowser.selectedModule);";*/
item[ 0 ] = "Create C++ Class" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"CppAsset\", AssetBrowser.selectedModule);";
item[ 0 ] = "Create Static C++ Class" TAB "" TAB "$AssetBrowser::newAssetTypeOverride = \"StaticClass\"; AssetBrowser.setupCreateNewAsset(\"CppAsset\", AssetBrowser.selectedModule);";
item[ 1 ] = "Create ScriptObject C++ Class" TAB "" TAB "$AssetBrowser::newAssetTypeOverride = \"ScriptClass\"; AssetBrowser.setupCreateNewAsset(\"CppAsset\", AssetBrowser.selectedModule);";
item[ 2 ] = "Create AssetType C++ Class" TAB "" TAB "$AssetBrowser::newAssetTypeOverride = \"AssetTypeCppClass\"; AssetBrowser.setupCreateNewAsset(\"CppAsset\", AssetBrowser.selectedModule);";
item[ 3 ] = "Create Render C++ Class" TAB "" TAB "$AssetBrowser::newAssetTypeOverride = \"RenderCppClass\"; AssetBrowser.setupCreateNewAsset(\"CppAsset\", AssetBrowser.selectedModule);";
item[ 3 ] = "Create SceneObject Class" TAB "" TAB "$AssetBrowser::newAssetTypeOverride = \"SceneObjectCppClass\"; AssetBrowser.setupCreateNewAsset(\"CppAsset\", AssetBrowser.selectedModule);";
};
//%this.AddNewScriptAssetPopup.insertSubMenu(0, "Create Component", AddNewComponentAssetPopup);
}

View file

@ -0,0 +1,409 @@
#ifndef @_H_
#include "@.h"
#endif
#ifndef _ASSET_MANAGER_H_
#include "assets/assetManager.h"
#endif
#ifndef _CONSOLETYPES_H_
#include "console/consoleTypes.h"
#endif
#ifndef _TAML_
#include "persistence/taml/taml.h"
#endif
#ifndef _ASSET_PTR_H_
#include "assets/assetPtr.h"
#endif
#include "core/resourceManager.h"
// Debug Profiling.
#include "platform/profiler.h"
#include "T3D/assets/assetImporter.h"
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT(@);
ConsoleType(assetIdString, Type@Ptr, String, ASSET_ID_FIELD_PREFIX)
ConsoleGetType(Type@Ptr)
{
// Fetch asset Id.
//return *((StringTableEntry*)dptr);
return (*((AssetPtr<@>*)dptr)).getAssetId();
}
ConsoleSetType(Type@Ptr)
{
// Was a single argument specified?
if (argc == 1)
{
// Yes, so fetch field value.
const char* pFieldValue = argv[0];
// Fetch asset Id.
StringTableEntry* assetId = (StringTableEntry*)(dptr);
// Update asset value.
*assetId = StringTable->insert(pFieldValue);
return;
}
// Warn.
Con::warnf("(TypeAssetId) - Cannot set multiple args to a single asset.");
}
//-----------------------------------------------------------------------------
ConsoleType(assetIdString, Type@Id, String, ASSET_ID_FIELD_PREFIX)
ConsoleGetType(Type@Id)
{
// Fetch asset Id.
return *((const char**)(dptr));
}
ConsoleSetType(Type@Id)
{
// Was a single argument specified?
if (argc == 1)
{
// Yes, so fetch field value.
const char* pFieldValue = argv[0];
// Fetch asset Id.
StringTableEntry* assetId = (StringTableEntry*)(dptr);
// Update asset value.
*assetId = StringTable->insert(pFieldValue);
return;
}
// Warn.
Con::warnf("(TypeAssetId) - Cannot set multiple args to a single asset.");
}
//-----------------------------------------------------------------------------
const String @::mErrCodeStrings[] =
{
"UnKnown"
};
//-----------------------------------------------------------------------------
@::@()
{
mFileName = StringTable->EmptyString();
mFilePath = StringTable->EmptyString();
mLoadedState = AssetErrCode::NotLoaded;
}
//-----------------------------------------------------------------------------
@::~@()
{
}
//-----------------------------------------------------------------------------
void @::initPersistFields()
{
// Call parent.
Parent::initPersistFields();
addProtectedField("fileName", TypeAssetLooseFilePath, Offset(mFileName, @),
&set@File, &get@File, "Path to the asset file");
}
// In the event we have any special case logic where the asset's values are changed(such as a dependency value is updated), this
// will let us react to that variable changing to implement behavior in response
void @::setDataField(StringTableEntry slotName, const char *array, const char *value)
{
Parent::setDataField(slotName, array, value);
}
void @::initializeAsset()
{
// Call parent.
Parent::initializeAsset();
if (mFileName == StringTable->EmptyString())
return;
ResourceManager::get().getChangedSignal().notify(this, &@::_onResourceChanged);
//Ensure our path is expando'd if it isn't already
if (!Platform::isFullPath(mFilePath))
mFilePath = getOwned() ? expandAssetFilePath(mFileName) : mFilePath;
//Do a loading function here to do the actual load logic
}
void @::set@File(const char* pFile)
{
// Sanity!
AssertFatal(pFile != NULL, "Cannot use a NULL file.");
// Fetch file.
pFile = StringTable->insert(pFile);
// Ignore no change,
if (pFile == mFileName)
return;
mFileName = pFile;
// Refresh the asset.
refreshAsset();
}
void @::_onResourceChanged(const Torque::Path &path)
{
if (path != Torque::Path(mFilePath) )
return;
refreshAsset();
//Do a loading function here to do the actual load logic
}
//------------------------------------------------------------------------------
//Utility function to 'fill out' bindings and resources with a matching asset if one exists
bool @::getAssetByFilename(StringTableEntry fileName, AssetPtr<@>* @)
{
AssetQuery query;
S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
if (foundAssetcount == 0)
{
//Didn't find any assets
//If possible, see if we can run an in-place import and the get the asset from that
#if TORQUE_DEBUG
Con::warnf("@::getAssetByFilename - Attempted to in-place import a file(%s) that had no associated asset", fileName);
#endif
AssetImporter* autoAssetImporter;
if (!Sim::findObject("autoAssetImporter", autoAssetImporter))
{
autoAssetImporter = new AssetImporter();
autoAssetImporter->registerObject("autoAssetImporter");
}
StringTableEntry resultingAssetId = autoAssetImporter->autoImportFile(fileName);
if (resultingAssetId != StringTable->EmptyString())
{
@->setAssetId(resultingAssetId);
if (!@->isNull())
return true;
}
//Didn't work, so have us fall back to a placeholder asset
@->setAssetId(StringTable->insert("Core_Rendering:noshape"));
if (!@->isNull())
return true;
//That didn't work, so fail out
return false;
}
else
{
//acquire and bind the asset, and return it out
@->setAssetId(query.mAssetList[0]);
return true;
}
}
StringTableEntry @::getAssetIdByFilename(StringTableEntry fileName)
{
if (fileName == StringTable->EmptyString())
return StringTable->EmptyString();
StringTableEntry @Id = StringTable->EmptyString();
AssetQuery query;
S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
if (foundAssetcount == 0)
{
//Didn't find any assets
//If possible, see if we can run an in-place import and the get the asset from that
#if TORQUE_DEBUG
Con::warnf("@::getAssetByFilename - Attempted to in-place import a file(%s) that had no associated asset", fileName);
#endif
AssetImporter* autoAssetImporter;
if (!Sim::findObject("autoAssetImporter", autoAssetImporter))
{
autoAssetImporter = new AssetImporter();
autoAssetImporter->registerObject("autoAssetImporter");
}
StringTableEntry resultingAssetId = autoAssetImporter->autoImportFile(fileName);
if (resultingAssetId != StringTable->EmptyString())
{
@Id = resultingAssetId;
return @Id;
}
//Didn't work, so have us fall back to a placeholder asset
@Id = StringTable->insert("Core_Rendering:noshape");
}
else
{
//acquire and bind the asset, and return it out
@Id = query.mAssetList[0];
}
return @Id;
}
U32 @::getAssetById(StringTableEntry assetId, AssetPtr<@>* @)
{
(*@) = assetId;
if ((*@))
return (*@)->mLoadedState;
//Didn't work, so have us fall back to a placeholder asset
StringTableEntry noShapeId = StringTable->insert("Core_Rendering:noshape");
@->setAssetId(noShapeId);
(*@)->mLoadedState = AssetErrCode::UsingFallback;
if (@->notNull())
return AssetErrCode::UsingFallback;
return AssetErrCode::Failed;
}
//------------------------------------------------------------------------------
void @::copyTo(SimObject* object)
{
// Call to parent.
Parent::copyTo(object);
}
void @::onAssetRefresh(void)
{
if (mFileName == StringTable->EmptyString())
return;
// Update.
if(!Platform::isFullPath(mFileName))
mFilePath = getOwned() ? expandAssetFilePath(mFileName) : mFilePath;
//Do a loading function here to do the actual load logic
}
//-----------------------------------------------------------------------------
// GuiInspectorTypeAssetId
//-----------------------------------------------------------------------------
#ifdef TORQUE_TOOLS
IMPLEMENT_CONOBJECT(GuiInspectorType@Ptr);
ConsoleDocClass(GuiInspectorType@Ptr,
"@brief Inspector field type for @\n\n"
"Editor use only.\n\n"
"@internal"
);
void GuiInspectorType@Ptr::consoleInit()
{
Parent::consoleInit();
ConsoleBaseType::getType(Type@Ptr)->setInspectorFieldType("GuiInspectorType@Ptr");
}
GuiControl* GuiInspectorType@Ptr::constructEditControl()
{
// Create base filename edit controls
GuiControl *retCtrl = Parent::constructEditControl();
if (retCtrl == NULL)
return retCtrl;
// Change filespec
char szBuffer[512];
dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"@\", \"AssetBrowser.changeAsset\", %s, %s);",
mInspector->getInspectObject()->getIdString(), mCaption);
mBrowseButton->setField("Command", szBuffer);
const char* id = mInspector->getInspectObject()->getIdString();
setDataField(StringTable->insert("targetObject"), NULL, mInspector->getInspectObject()->getIdString());
// Create "Open in ShapeEditor" button
mShapeEdButton = new GuiBitmapButtonCtrl();
dSprintf(szBuffer, sizeof(szBuffer), "ShapeEditorPlugin.open@Id(%d.getText());", retCtrl->getId());
mShapeEdButton->setField("Command", szBuffer);
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
mShapeEdButton->setBitmap(bitmapName);
mShapeEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
mShapeEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
mShapeEdButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
mShapeEdButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this file in the Shape Editor");
mShapeEdButton->registerObject();
addObject(mShapeEdButton);
return retCtrl;
}
bool GuiInspectorType@Ptr::updateRects()
{
S32 dividerPos, dividerMargin;
mInspector->getDivider(dividerPos, dividerMargin);
Point2I fieldExtent = getExtent();
Point2I fieldPos = getPosition();
mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y);
mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y);
bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent);
if (mBrowseButton != NULL)
{
mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4);
resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent);
}
if (mShapeEdButton != NULL)
{
RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4);
resized |= mShapeEdButton->resize(shapeEdRect.point, shapeEdRect.extent);
}
return resized;
}
IMPLEMENT_CONOBJECT(GuiInspectorType@Id);
ConsoleDocClass(GuiInspectorType@Id,
"@brief Inspector field type for @\n\n"
"Editor use only.\n\n"
"@internal"
);
void GuiInspectorType@Id::consoleInit()
{
Parent::consoleInit();
ConsoleBaseType::getType(Type@Id)->setInspectorFieldType("GuiInspectorType@Id");
}
#endif
DefineEngineMethod(@, getFilePath, const char*, (), ,
"Creates a new script asset using the targetFilePath.\n"
"@return The bool result of calling exec")
{
return object->get@FilePath();
}

View file

@ -0,0 +1,157 @@
#ifndef @_H
#define @_H
#ifndef _ASSET_BASE_H_
#include "assets/assetBase.h"
#endif
#ifndef _ASSET_DEFINITION_H_
#include "assets/assetDefinition.h"
#endif
#ifndef _STRINGUNIT_H_
#include "string/stringUnit.h"
#endif
#ifndef _ASSET_FIELD_TYPES_H_
#include "assets/assetFieldTypes.h"
#endif
#ifndef __RESOURCE_H__
#include "core/resource.h"
#endif
#ifndef _ASSET_PTR_H_
#include "assets/assetPtr.h"
#endif
#ifdef TORQUE_TOOLS
#include "gui/editor/guiInspectorTypes.h"
#endif
//-----------------------------------------------------------------------------
class @ : public AssetBase
{
typedef AssetBase Parent;
protected:
StringTableEntry mFileName;
StringTableEntry mFilePath;
typedef Signal<void()> @Changed;
@Changed mChangeSignal;
public:
enum @ErrCode
{
Extended = AssetErrCode::Extended
};
static const String mErrCodeStrings[@ErrCode::Extended - Parent::Extended + 1];
static String getAssetErrstrn(U32 errCode)
{
if (errCode < Parent::Extended) return Parent::getAssetErrstrn(errCode);
if (errCode > @ErrCode::Extended) return "undefined error";
return mErrCodeStrings[errCode];
};
@();
virtual ~@();
/// Engine.
static void initPersistFields();
virtual void copyTo(SimObject* object);
virtual void setDataField(StringTableEntry slotName, const char *array, const char *value);
virtual void initializeAsset();
/// Declare Console Object.
DECLARE_CONOBJECT(@);
U32 mLoadedState;
void _onResourceChanged(const Torque::Path &path);
@Changed& getChangedSignal() { return mChangeSignal; }
void set@File(const char* pFile);
inline StringTableEntry get@File(void) const { return mFileName; };
inline StringTableEntry get@FilePath(void) const { return mFilePath; };
static bool getAssetByFilename(StringTableEntry fileName, AssetPtr<@>* @);
static StringTableEntry getAssetIdByFilename(StringTableEntry fileName);
static U32 getAssetById(StringTableEntry assetId, AssetPtr<@>* @);
static StringTableEntry getNo@Id() { return StringTable->insert("Core_Rendering:noshape"); }
protected:
virtual void onAssetRefresh(void);
static bool set@File(void* obj, const char* index, const char* data) { static_cast<@*>(obj)->set@File(data); return false; }
static const char* get@File(void* obj, const char* data) { return static_cast<@*>(obj)->get@File(); }
};
#ifdef TORQUE_TOOLS
DefineConsoleType(Type@Ptr, S32)
DefineConsoleType(Type@Id, String)
//-----------------------------------------------------------------------------
// TypeAssetId GuiInspectorField Class
//-----------------------------------------------------------------------------
class GuiInspectorType@Ptr : public GuiInspectorTypeFileName
{
typedef GuiInspectorTypeFileName Parent;
public:
GuiBitmapButtonCtrl *mShapeEdButton;
DECLARE_CONOBJECT(GuiInspectorType@Ptr);
static void consoleInit();
virtual GuiControl* constructEditControl();
virtual bool updateRects();
};
class GuiInspectorType@Id : public GuiInspectorType@Ptr
{
typedef GuiInspectorType@Ptr Parent;
public:
DECLARE_CONOBJECT(GuiInspectorType@Id);
static void consoleInit();
};
#endif
#define assetText(x,suff) std::string(std::string(#x) + std::string(#suff)).c_str()
#define init@(name) m##name##AssetId = StringTable->EmptyString(); m##name##Asset = NULL;
#define bind@(name) if (m##name##AssetId != StringTable->EmptyString()) m##name##Asset = m##name##AssetId;
#define scriptBind@(name, consoleClass, docs) addProtectedField(assetText(name, Asset), Type@Id, Offset(m##name##AssetId, consoleClass), consoleClass::_set##name##Asset, & defaultProtectedGetFn, assetText(name, asset reference.));
#define DECLARE_@(className,name) protected: \
StringTableEntry m##name##AssetId;\
AssetPtr<@> m##name##Asset;\
public: \
const AssetPtr<@> & get##name##Asset() const { return m##name##Asset; }\
void set##name##Asset(AssetPtr<@>_in) { m##name##Asset = _in; }\
static bool _set##name##Asset(void* obj, const char* index, const char* data)\
{\
className* shape = static_cast<className*>(obj);\
shape->m##name##AssetId = StringTable->insert(data);\
if (@::getAssetById(shape->m##name##AssetId, &shape->m##name##Asset))\
{\
if (shape->m##name##Asset.getAssetId() != StringTable->insert("Core_Rendering:noShape"))\
shape->m##name##Filename = StringTable->EmptyString();\
\
shape->setMaskBits(-1);\
return true;\
}\
return false;\
}
#endif

View file

@ -0,0 +1,325 @@
#include "@.h"
#include "platform/platform.h"
#include "math/mathIO.h"
#include "scene/sceneRenderState.h"
#include "console/consoleTypes.h"
#include "core/stream/bitStream.h"
#include "materials/materialManager.h"
#include "materials/baseMatInstance.h"
#include "renderInstance/renderPassManager.h"
#include "lighting/lightQuery.h"
#include "console/engineAPI.h"
IMPLEMENT_CO_NETOBJECT_V1(@);
ConsoleDocClass( @,
"@brief An example scene object which renders a mesh.\n\n" );
//-----------------------------------------------------------------------------
// Object setup and teardown
//-----------------------------------------------------------------------------
@::@()
{
// Flag this object so that it will always
// be sent across the network to clients
mNetFlags.set( Ghostable | ScopeAlways );
// Set it as a "static" object that casts shadows
mTypeMask |= StaticObjectType | StaticShapeObjectType;
// Make sure we the Material instance to NULL
// so we don't try to access it incorrectly
mMaterialInst = NULL;
}
@::~@()
{
if ( mMaterialInst )
SAFE_DELETE( mMaterialInst );
}
//-----------------------------------------------------------------------------
// Object Editing
//-----------------------------------------------------------------------------
void @::initPersistFields()
{
addGroup( "Rendering" );
addField( "material", TypeMaterialName, Offset( mMaterialName, @ ),
"The name of the material used to render the mesh." );
endGroup( "Rendering" );
// SceneObject already handles exposing the transform
Parent::initPersistFields();
}
void @::inspectPostApply()
{
Parent::inspectPostApply();
// Flag the network mask to send the updates
// to the client object
setMaskBits( UpdateMask );
}
bool @::onAdd()
{
if ( !Parent::onAdd() )
return false;
// Set up a 1x1x1 bounding box
mObjBox.set( Point3F( -0.5f, -0.5f, -0.5f ),
Point3F( 0.5f, 0.5f, 0.5f ) );
resetWorldBox();
// Add this object to the scene
addToScene();
// Refresh this object's material (if any)
updateMaterial();
return true;
}
void @::onRemove()
{
// Remove this object from the scene
removeFromScene();
Parent::onRemove();
}
void @::setTransform(const MatrixF & mat)
{
// Let SceneObject handle all of the matrix manipulation
Parent::setTransform( mat );
// Dirty our network mask so that the new transform gets
// transmitted to the client object
setMaskBits( TransformMask );
}
U32 @::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
{
// Allow the Parent to get a crack at writing its info
U32 retMask = Parent::packUpdate( conn, mask, stream );
// Write our transform information
if ( stream->writeFlag( mask & TransformMask ) )
{
mathWrite(*stream, getTransform());
mathWrite(*stream, getScale());
}
// Write out any of the updated editable properties
if ( stream->writeFlag( mask & UpdateMask ) )
stream->write( mMaterialName );
return retMask;
}
void @::unpackUpdate(NetConnection *conn, BitStream *stream)
{
// Let the Parent read any info it sent
Parent::unpackUpdate(conn, stream);
if ( stream->readFlag() ) // TransformMask
{
mathRead(*stream, &mObjToWorld);
mathRead(*stream, &mObjScale);
setTransform( mObjToWorld );
}
if ( stream->readFlag() ) // UpdateMask
{
stream->read( &mMaterialName );
if ( isProperlyAdded() )
updateMaterial();
}
}
//-----------------------------------------------------------------------------
// Object Rendering
//-----------------------------------------------------------------------------
void @::createGeometry()
{
static const Point3F cubePoints[8] =
{
Point3F( 1, -1, -1), Point3F( 1, -1, 1), Point3F( 1, 1, -1), Point3F( 1, 1, 1),
Point3F(-1, -1, -1), Point3F(-1, 1, -1), Point3F(-1, -1, 1), Point3F(-1, 1, 1)
};
static const Point3F cubeNormals[6] =
{
Point3F( 1, 0, 0), Point3F(-1, 0, 0), Point3F( 0, 1, 0),
Point3F( 0, -1, 0), Point3F( 0, 0, 1), Point3F( 0, 0, -1)
};
static const Point2F cubeTexCoords[4] =
{
Point2F( 0, 0), Point2F( 0, -1),
Point2F( 1, 0), Point2F( 1, -1)
};
static const U32 cubeFaces[36][3] =
{
{ 3, 0, 3 }, { 0, 0, 0 }, { 1, 0, 1 },
{ 2, 0, 2 }, { 0, 0, 0 }, { 3, 0, 3 },
{ 7, 1, 1 }, { 4, 1, 2 }, { 5, 1, 0 },
{ 6, 1, 3 }, { 4, 1, 2 }, { 7, 1, 1 },
{ 3, 2, 1 }, { 5, 2, 2 }, { 2, 2, 0 },
{ 7, 2, 3 }, { 5, 2, 2 }, { 3, 2, 1 },
{ 1, 3, 3 }, { 4, 3, 0 }, { 6, 3, 1 },
{ 0, 3, 2 }, { 4, 3, 0 }, { 1, 3, 3 },
{ 3, 4, 3 }, { 6, 4, 0 }, { 7, 4, 1 },
{ 1, 4, 2 }, { 6, 4, 0 }, { 3, 4, 3 },
{ 2, 5, 1 }, { 4, 5, 2 }, { 0, 5, 0 },
{ 5, 5, 3 }, { 4, 5, 2 }, { 2, 5, 1 }
};
// Fill the vertex buffer
VertexType *pVert = NULL;
mVertexBuffer.set( GFX, 36, GFXBufferTypeStatic );
pVert = mVertexBuffer.lock();
Point3F halfSize = getObjBox().getExtents() * 0.5f;
for (U32 i = 0; i < 36; i++)
{
const U32& vdx = cubeFaces[i][0];
const U32& ndx = cubeFaces[i][1];
const U32& tdx = cubeFaces[i][2];
pVert[i].point = cubePoints[vdx] * halfSize;
pVert[i].normal = cubeNormals[ndx];
pVert[i].texCoord = cubeTexCoords[tdx];
}
mVertexBuffer.unlock();
// Fill the primitive buffer
U16 *pIdx = NULL;
mPrimitiveBuffer.set( GFX, 36, 12, GFXBufferTypeStatic );
mPrimitiveBuffer.lock(&pIdx);
for (U16 i = 0; i < 36; i++)
pIdx[i] = i;
mPrimitiveBuffer.unlock();
}
void @::updateMaterial()
{
if ( mMaterialName.isEmpty() )
return;
// If the material name matches then don't bother updating it.
if ( mMaterialInst && mMaterialName.equal( mMaterialInst->getMaterial()->getName(), String::NoCase ) )
return;
SAFE_DELETE( mMaterialInst );
mMaterialInst = MATMGR->createMatInstance( mMaterialName, getGFXVertexFormat< VertexType >() );
if ( !mMaterialInst )
Con::errorf( "@::updateMaterial - no Material called '%s'", mMaterialName.c_str() );
}
void @::prepRenderImage( SceneRenderState *state )
{
// Do a little prep work if needed
if ( mVertexBuffer.isNull() )
createGeometry();
// If we have no material then skip out.
if ( !mMaterialInst || !state)
return;
// If we don't have a material instance after the override then
// we can skip rendering all together.
BaseMatInstance *matInst = state->getOverrideMaterial( mMaterialInst );
if ( !matInst )
return;
// Get a handy pointer to our RenderPassmanager
RenderPassManager *renderPass = state->getRenderPass();
// Allocate an MeshRenderInst so that we can submit it to the RenderPassManager
MeshRenderInst *ri = renderPass->allocInst<MeshRenderInst>();
// Set our RenderInst as a standard mesh render
ri->type = RenderPassManager::RIT_Mesh;
//If our material has transparency set on this will redirect it to proper render bin
if ( matInst->getMaterial()->isTranslucent() )
{
ri->type = RenderPassManager::RIT_Translucent;
ri->translucentSort = true;
}
// Calculate our sorting point
if ( state )
{
// Calculate our sort point manually.
const Box3F& rBox = getRenderWorldBox();
ri->sortDistSq = rBox.getSqDistanceToPoint( state->getCameraPosition() );
}
else
ri->sortDistSq = 0.0f;
// Set up our transforms
MatrixF objectToWorld = getRenderTransform();
objectToWorld.scale( getScale() );
ri->objectToWorld = renderPass->allocUniqueXform( objectToWorld );
ri->worldToCamera = renderPass->allocSharedXform(RenderPassManager::View);
ri->projection = renderPass->allocSharedXform(RenderPassManager::Projection);
// If our material needs lights then fill the RIs
// light vector with the best lights.
if ( matInst->isForwardLit() )
{
LightQuery query;
query.init( getWorldSphere() );
query.getLights( ri->lights, 8 );
}
// Make sure we have an up-to-date backbuffer in case
// our Material would like to make use of it
// NOTICE: SFXBB is removed and refraction is disabled!
//ri->backBuffTex = GFX->getSfxBackBuffer();
// Set our Material
ri->matInst = matInst;
// Set up our vertex buffer and primitive buffer
ri->vertBuff = &mVertexBuffer;
ri->primBuff = &mPrimitiveBuffer;
ri->prim = renderPass->allocPrim();
ri->prim->type = GFXTriangleList;
ri->prim->minIndex = 0;
ri->prim->startIndex = 0;
ri->prim->numPrimitives = 12;
ri->prim->startVertex = 0;
ri->prim->numVertices = 36;
// We sort by the material then vertex buffer
ri->defaultKey = matInst->getStateHint();
ri->defaultKey2 = (uintptr_t)ri->vertBuff; // Not 64bit safe!
// Submit our RenderInst to the RenderPassManager
state->getRenderPass()->addInst( ri );
}
DefineEngineMethod( @, postApply, void, (),,
"A utility method for forcing a network update.\n")
{
object->inspectPostApply();
}

View file

@ -0,0 +1,102 @@
#ifndef _@_H_
#define _@_H_
#ifndef _SCENEOBJECT_H_
#include "scene/sceneObject.h"
#endif
#ifndef _GFXVERTEXBUFFER_H_
#include "gfx/gfxVertexBuffer.h"
#endif
#ifndef _GFXPRIMITIVEBUFFER_H_
#include "gfx/gfxPrimitiveBuffer.h"
#endif
class BaseMatInstance;
class @ : public SceneObject
{
typedef SceneObject Parent;
// Networking masks
// We need to implement a mask specifically to handle
// updating our transform from the server object to its
// client-side "ghost". We also need to implement a
// maks for handling editor updates to our properties
// (like material).
enum MaskBits
{
TransformMask = Parent::NextFreeMask << 0,
UpdateMask = Parent::NextFreeMask << 1,
NextFreeMask = Parent::NextFreeMask << 2
};
//--------------------------------------------------------------------------
// Rendering variables
//--------------------------------------------------------------------------
// The name of the Material we will use for rendering
String mMaterialName;
// The actual Material instance
BaseMatInstance* mMaterialInst;
// Define our vertex format here so we don't have to
// change it in multiple spots later
typedef GFXVertexPNT VertexType;
// The GFX vertex and primitive buffers
GFXVertexBufferHandle< VertexType > mVertexBuffer;
GFXPrimitiveBufferHandle mPrimitiveBuffer;
public:
@();
virtual ~@();
// Handle when we are added to the scene and removed from the scene
bool onAdd();
void onRemove();
// Declare this object as a ConsoleObject so that we can
// instantiate it into the world and network it
DECLARE_CONOBJECT(@);
//--------------------------------------------------------------------------
// Object Editing
// Since there is always a server and a client object in Torque and we
// actually edit the server object we need to implement some basic
// networking functions
//--------------------------------------------------------------------------
// Set up any fields that we want to be editable (like position)
static void initPersistFields();
// Allows the object to update its editable settings
// from the server object to the client
virtual void inspectPostApply();
// Override this so that we can dirty the network flag when it is called
void setTransform( const MatrixF &mat );
// This function handles sending the relevant data from the server
// object to the client object
U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream );
// This function handles receiving relevant data from the server
// object and applying it to the client object
void unpackUpdate( NetConnection *conn, BitStream *stream );
//--------------------------------------------------------------------------
// Object Rendering
// Torque utilizes a "batch" rendering system. This means that it builds a
// list of objects that need to render (via RenderInst's) and then renders
// them all in one batch. This allows it to optimized on things like
// minimizing texture, state, and shader switching by grouping objects that
// use the same Materials.
//--------------------------------------------------------------------------
// Create the geometry for rendering
void createGeometry();
// Get the Material instance
void updateMaterial();
// This is the function that allows this object to submit itself for rendering
void prepRenderImage( SceneRenderState *state );
};
#endif // _@_H_

View file

@ -0,0 +1,105 @@
#include "@.h"
#include "math/mathIO.h"
#include "console/consoleTypes.h"
#include "core/stream/bitStream.h"
IMPLEMENT_CO_NETOBJECT_V1(@);
@::@()
{
// Flag this object so that it will always
// be sent across the network to clients
mNetFlags.set( Ghostable | ScopeAlways );
// Set it as a "static" object that casts shadows
mTypeMask |= StaticObjectType | StaticShapeObjectType;
}
@::~@()
{
}
bool @::onAdd()
{
if (!Parent::onAdd())
return false;
// Set up a 1x1x1 bounding box
mObjBox.set( Point3F( -0.5f, -0.5f, -0.5f ),
Point3F( 0.5f, 0.5f, 0.5f ) );
resetWorldBox();
// Add this object to the scene
addToScene();
return true;
}
void @::onRemove()
{
// Remove this object from the scene
removeFromScene();
Parent::onRemove();
}
void @::initPersistFields()
{
Parent::initPersistFields();
}
void @::inspectPostApply()
{
Parent::inspectPostApply();
// Flag the network mask to send the updates
// to the client object
setMaskBits( TransformMask );
}
void @::setTransform(const MatrixF & mat)
{
// Let SceneObject handle all of the matrix manipulation
Parent::setTransform( mat );
// Dirty our network mask so that the new transform gets
// transmitted to the client object
setMaskBits( TransformMask );
}
U32 @::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
{
// Allow the Parent to get a crack at writing its info
U32 retMask = Parent::packUpdate( conn, mask, stream );
// Write our transform information
if ( stream->writeFlag( mask & TransformMask ) )
{
mathWrite(*stream, getTransform());
mathWrite(*stream, getScale());
}
return retMask;
}
void @::unpackUpdate(NetConnection *conn, BitStream *stream)
{
// Let the Parent read any info it sent
Parent::unpackUpdate(conn, stream);
if ( stream->readFlag() ) // TransformMask
{
mathRead(*stream, &mObjToWorld);
mathRead(*stream, &mObjScale);
setTransform( mObjToWorld );
}
}
DefineEngineMethod( @, postApply, void, (),,
"A utility method for forcing a network update.\n")
{
object->inspectPostApply();
}

View file

@ -0,0 +1,53 @@
#pragma once
#ifndef _SCENEOBJECT_H_
#include "scene/sceneObject.h"
#endif
class @ : public SceneObject
{
typedef SceneObject Parent;
private:
enum MaskBits
{
TransformMask = Parent::NextFreeMask << 0,
NextFreeMask = Parent::NextFreeMask << 1
};
protected:
public:
@();
virtual ~@();
// Declare this object as a ConsoleObject so that we can
// instantiate it into the world and network it
DECLARE_CONOBJECT(@);
// Handle when we are added to the scene and removed from the scene
bool onAdd();
void onRemove();
// Set up any fields that we want to be editable (like position)
static void initPersistFields();
// Allows the object to update its editable settings
// from the server object to the client
virtual void inspectPostApply();
// Override this so that we can dirty the network flag when it is called
void setTransform( const MatrixF &mat );
// This function handles sending the relevant data from the server
// object to the client object
U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream );
// This function handles receiving relevant data from the server
// object and applying it to the client object
void unpackUpdate( NetConnection *conn, BitStream *stream );
virtual void interpolateTick( F32 delta );
virtual void processTick();
virtual void advanceTime( F32 timeDelta );
};

View file

@ -0,0 +1,45 @@
#include "@.h"
IMPLEMENT_CONOBJECT(@);
@::@()
{
}
@::~@()
{
}
void @::initPersistFields()
{
Parent::initPersistFields();
}
bool @::onAdd()
{
if (!Parent::onAdd())
return false;
return true;
}
void @::onRemove()
{
Parent::onRemove();
}
void @::interpolateTick( F32 delta )
{
Parent::interpolateTick(delta);
}
void @::processTick()
{
Parent::processTick();
}
void @::advanceTime( F32 timeDelta )
{
Parent::advanceTime(timeDelta);
}

View file

@ -0,0 +1,29 @@
#pragma once
#include "console/engineAPI.h"
#include "console/scriptObjects.h"
class @ : public ScriptTickObject
{
typedef ScriptTickObject Parent;
private:
protected:
public:
@();
~@();
// Declare this object as a ConsoleObject so that we can
// instantiate it
DECLARE_CONOBJECT(@);
static void initPersistFields();
bool onAdd();
void onRemove();
virtual void interpolateTick( F32 delta );
virtual void processTick();
virtual void advanceTime( F32 timeDelta );
};