Merge pull request #1379 from Areloch/VariousSubSceneFixes

Various Subscene Fixes
This commit is contained in:
Brian Roberts 2025-02-06 12:16:49 -06:00 committed by GitHub
commit b47ffb2f28
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 124 additions and 84 deletions

View file

@ -3,6 +3,8 @@
#include "gameMode.h" #include "gameMode.h"
#include "console/persistenceManager.h" #include "console/persistenceManager.h"
#include "console/script.h" #include "console/script.h"
#include "environment/meshRoad.h"
#include "environment/river.h"
#include "scene/sceneRenderState.h" #include "scene/sceneRenderState.h"
#include "renderInstance/renderPassManager.h" #include "renderInstance/renderPassManager.h"
#include "gfx/gfxDrawUtil.h" #include "gfx/gfxDrawUtil.h"
@ -29,7 +31,8 @@ SubScene::SubScene() :
mFreezeLoading(false), mFreezeLoading(false),
mTickPeriodMS(1000), mTickPeriodMS(1000),
mCurrTick(0), mCurrTick(0),
mGlobalLayer(false) mGlobalLayer(false),
mSaving(false)
{ {
mNetFlags.set(Ghostable | ScopeAlways); mNetFlags.set(Ghostable | ScopeAlways);
@ -65,6 +68,7 @@ void SubScene::initPersistFields()
addGroup("SubScene"); addGroup("SubScene");
addField("isGlobalLayer", TypeBool, Offset(mGlobalLayer, SubScene), ""); addField("isGlobalLayer", TypeBool, Offset(mGlobalLayer, SubScene), "");
INITPERSISTFIELD_LEVELASSET(Level, SubScene, "The level asset to load."); INITPERSISTFIELD_LEVELASSET(Level, SubScene, "The level asset to load.");
addField("tickPeriodMS", TypeS32, Offset(mTickPeriodMS, SubScene), "evaluation rate (ms)");
addField("gameModes", TypeGameModeList, Offset(mGameModesNames, SubScene), "The game modes that this subscene is associated with."); addField("gameModes", TypeGameModeList, Offset(mGameModesNames, SubScene), "The game modes that this subscene is associated with.");
endGroup("SubScene"); endGroup("SubScene");
@ -263,6 +267,9 @@ void SubScene::_onFileChanged(const Torque::Path& path)
if(mLevelAsset.isNull() || Torque::Path(mLevelAsset->getLevelPath()) != path) if(mLevelAsset.isNull() || Torque::Path(mLevelAsset->getLevelPath()) != path)
return; return;
if (mSaving)
return;
AssertFatal(path == mLevelAsset->getLevelPath(), "Prefab::_onFileChanged - path does not match filename."); AssertFatal(path == mLevelAsset->getLevelPath(), "Prefab::_onFileChanged - path does not match filename.");
_closeFile(false); _closeFile(false);
@ -336,6 +343,9 @@ void SubScene::load()
if (mFreezeLoading) if (mFreezeLoading)
return; return;
if (mSaving)
return;
_loadFile(true); _loadFile(true);
mLoaded = true; mLoaded = true;
@ -362,6 +372,9 @@ void SubScene::unload()
if (mFreezeLoading) if (mFreezeLoading)
return; return;
if (mSaving)
return;
if (isSelected()) if (isSelected())
{ {
mStartUnloadTimerMS = Sim::getCurrentTime(); mStartUnloadTimerMS = Sim::getCurrentTime();
@ -421,10 +434,15 @@ bool SubScene::save()
if (mLevelAsset.isNull()) if (mLevelAsset.isNull())
return false; return false;
if (mSaving)
return false;
//If we're flagged for unload, push back the unload timer so we can't accidentally trip be saving partway through an unload //If we're flagged for unload, push back the unload timer so we can't accidentally trip be saving partway through an unload
if (mStartUnloadTimerMS != -1) if (mStartUnloadTimerMS != -1)
mStartUnloadTimerMS = Sim::getCurrentTime(); mStartUnloadTimerMS = Sim::getCurrentTime();
mSaving = true;
PersistenceManager prMger; PersistenceManager prMger;
StringTableEntry levelPath = mLevelAsset->getLevelPath(); StringTableEntry levelPath = mLevelAsset->getLevelPath();
@ -449,6 +467,11 @@ bool SubScene::save()
prMger.setDirty((*itr), levelPath); prMger.setDirty((*itr), levelPath);
} }
} }
if(dynamic_cast<MeshRoad*>(childObj) || dynamic_cast<River*>(childObj))
{
prMger.addRemoveField(childObj, "position");
}
} }
prMger.saveDirty(); prMger.saveDirty();
@ -466,6 +489,8 @@ bool SubScene::save()
//Finally, save //Finally, save
saveSuccess = mLevelAsset->saveAsset(); saveSuccess = mLevelAsset->saveAsset();
mSaving = false;
return saveSuccess; return saveSuccess;
} }

View file

@ -40,6 +40,7 @@ private:
S32 mStartUnloadTimerMS; S32 mStartUnloadTimerMS;
bool mLoaded; bool mLoaded;
bool mSaving;
bool mFreezeLoading; bool mFreezeLoading;
String mLoadIf; String mLoadIf;

View file

@ -43,6 +43,7 @@
// Debug Profiling. // Debug Profiling.
#include "platform/profiler.h" #include "platform/profiler.h"
#include "gfx/gfxDrawUtil.h" #include "gfx/gfxDrawUtil.h"
#include "T3D/SubScene.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -479,8 +480,15 @@ GuiControl* GuiInspectorTypeLevelAssetPtr::constructEditControl()
// Create "Open in Editor" button // Create "Open in Editor" button
mEditButton = new GuiBitmapButtonCtrl(); mEditButton = new GuiBitmapButtonCtrl();
dSprintf(szBuffer, sizeof(szBuffer), "$createAndAssignField = %s; AssetBrowser.setupCreateNewAsset(\"LevelAsset\", AssetBrowser.selectedModule, \"createAndAssignLevelAsset\");", String setSubSceneValue = "$createLevelAssetIsSubScene = \"\";";
getIdString()); if(dynamic_cast<SubScene*>(mInspector->getInspectObject()) != NULL)
{
setSubSceneValue = "$createLevelAssetIsSubScene = true;";
}
dSprintf(szBuffer, sizeof(szBuffer), "$createAndAssignField = %s; %s AssetBrowser.setupCreateNewAsset(\"LevelAsset\", AssetBrowser.selectedModule, \"createAndAssignLevelAsset\");",
getIdString(),
setSubSceneValue.c_str());
mEditButton->setField("Command", szBuffer); mEditButton->setField("Command", szBuffer);
char bitmapName[512] = "ToolsModule:iconAdd_image"; char bitmapName[512] = "ToolsModule:iconAdd_image";

View file

@ -526,7 +526,7 @@ const char* ConvexShape::getSpecialFieldOut(StringTableEntry fieldName, const U3
char buffer[1024]; char buffer[1024];
dMemset(buffer, 0, 1024); dMemset(buffer, 0, 1024);
dSprintf(buffer, 1024, "%g %g %g %g %g %g %g %i %g %g %g %g %g %i %i", dSprintf(buffer, 1024, "surface = \"%g %g %g %g %g %g %g %i %g %g %g %g %g %i %i\";",
quat.x, quat.y, quat.z, quat.w, pos.x, pos.y, pos.z, mSurfaceUVs[index].matID, quat.x, quat.y, quat.z, quat.w, pos.x, pos.y, pos.z, mSurfaceUVs[index].matID,
mSurfaceUVs[index].offset.x, mSurfaceUVs[index].offset.y, mSurfaceUVs[index].scale.x, mSurfaceUVs[index].offset.x, mSurfaceUVs[index].offset.y, mSurfaceUVs[index].scale.x,
mSurfaceUVs[index].scale.y, mSurfaceUVs[index].zRot, mSurfaceUVs[index].horzFlip, mSurfaceUVs[index].vertFlip); mSurfaceUVs[index].scale.y, mSurfaceUVs[index].zRot, mSurfaceUVs[index].horzFlip, mSurfaceUVs[index].vertFlip);
@ -541,7 +541,7 @@ const char* ConvexShape::getSpecialFieldOut(StringTableEntry fieldName, const U3
char buffer[1024]; char buffer[1024];
dMemset(buffer, 0, 1024); dMemset(buffer, 0, 1024);
dSprintf(buffer, 1024, "%s", mSurfaceTextures[index].getMaterial()); dSprintf(buffer, 1024, "surfaceTexture = \"%s\";", mSurfaceTextures[index].getMaterial());
return StringTable->insert(buffer); return StringTable->insert(buffer);
} }

View file

@ -1224,13 +1224,13 @@ void PersistenceManager::removeField(const ParsedProperty& prop)
removeTextBlock(prop.startLine, prop.endLine, prop.startPosition, endPosition, true); removeTextBlock(prop.startLine, prop.endLine, prop.startPosition, endPosition, true);
} }
U32 PersistenceManager::writeProperties(const Vector<const char*>& properties, const U32 insertLine, const char* objectIndent) U32 PersistenceManager::writeProperties(const Vector<String>& properties, const U32 insertLine, const char* objectIndent)
{ {
U32 currInsertLine = insertLine; U32 currInsertLine = insertLine;
for (U32 i = 0; i < properties.size(); i++) for (U32 i = 0; i < properties.size(); i++)
{ {
const char* prop = properties[i]; const char* prop = properties[i].c_str();
if (!prop || dStrlen(prop) == 0) if (!prop || dStrlen(prop) == 0)
continue; continue;
@ -1248,7 +1248,7 @@ U32 PersistenceManager::writeProperties(const Vector<const char*>& properties, c
return currInsertLine - insertLine; return currInsertLine - insertLine;
} }
PersistenceManager::ParsedObject* PersistenceManager::writeNewObject(SimObject* object, const Vector<const char*>& properties, const U32 insertLine, ParsedObject* parentObject) PersistenceManager::ParsedObject* PersistenceManager::writeNewObject(SimObject* object, const Vector<String>& properties, const U32 insertLine, ParsedObject* parentObject)
{ {
ParsedObject* parsedObject = new ParsedObject; ParsedObject* parsedObject = new ParsedObject;
@ -1353,7 +1353,7 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
if (!defaultObject) if (!defaultObject)
return; return;
Vector<const char*> newLines; Vector<String> newLines;
ParsedObject* parsedObject = findParsedObject(object, parentObject); ParsedObject* parsedObject = findParsedObject(object, parentObject);
@ -1392,10 +1392,10 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
for(U32 j = 0; j < fieldArraySize; j++) for(U32 j = 0; j < fieldArraySize; j++)
{ {
const char* value = object->getSpecialFieldOut(f->pFieldname, j); String value = object->getSpecialFieldOut(f->pFieldname, j);
// Make sure we got a value // Make sure we got a value
if (!value) if (value.isEmpty())
continue; continue;
// Let's see if this field is already in the file // Let's see if this field is already in the file
@ -1409,13 +1409,12 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
if (findRemoveField(object, f->pFieldname, j)) if (findRemoveField(object, f->pFieldname, j))
{ {
removeField(parsedObject->properties[propertyIndex]); removeField(parsedObject->properties[propertyIndex]);
dFree(value);
continue; continue;
} }
// Run the parsed value through the console system conditioners so // Run the parsed value through the console system conditioners so
// that it will better match the data we got back from the object. // that it will better match the data we got back from the object.
const char* evalue = Con::getFormattedData(f->type, prop.value, f->table, f->flag); String evalue = Con::getFormattedData(f->type, prop.value, f->table, f->flag);
// If our data doesn't match then we get to update it. // If our data doesn't match then we get to update it.
// //
@ -1423,17 +1422,17 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
// is there in the file, the user does not want it inherited from the copy-source // is there in the file, the user does not want it inherited from the copy-source
// even in the case the actual values are identical. // even in the case the actual values are identical.
if (dStricmp(value, evalue) != 0) if (value != evalue)
{ {
if (value[0] == '\0' && if (value.isEmpty() &&
dStricmp(getFieldValue(defaultObject, f->pFieldname, j), value) == 0 && dStricmp(getFieldValue(defaultObject, f->pFieldname, j), value.c_str()) == 0 &&
(!object->getCopySource() || dStricmp(getFieldValue(object->getCopySource(), f->pFieldname, j), value) == 0)) (!object->getCopySource() || dStricmp(getFieldValue(object->getCopySource(), f->pFieldname, j), value.c_str()) == 0))
{ {
removeField(prop); removeField(prop);
} }
else else
{ {
updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, value, true); updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, value.c_str(), true);
} }
} }
} }
@ -1442,7 +1441,6 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
// No need to process a removed field that doesn't exist in the file // No need to process a removed field that doesn't exist in the file
if (findRemoveField(object, f->pFieldname, j)) if (findRemoveField(object, f->pFieldname, j))
{ {
dFree(value);
continue; continue;
} }
@ -1452,20 +1450,17 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
// then we need to compare against the default value // then we need to compare against the default value
// for this property and save it out if it is different // for this property and save it out if it is different
const char* defaultValue = defaultObject->getSpecialFieldOut(f->pFieldname, j); String defaultValue = defaultObject->getSpecialFieldOut(f->pFieldname, j);
if (!defaultValue || dStricmp(value, defaultValue) != 0) if (defaultValue.isEmpty() || value != defaultValue)
{ {
// Value differs. Check whether it also differs from the // Value differs. Check whether it also differs from the
// value in the copy source if there is one. // value in the copy source if there is one.
if (object->getCopySource()) if (object->getCopySource())
{ {
const char* copySourceValue = getFieldValue(object->getCopySource(), f->pFieldname, j); String copySourceValue = getFieldValue(object->getCopySource(), f->pFieldname, j);
if (!copySourceValue || dStricmp(copySourceValue, value) != 0) if (copySourceValue.isEmpty() || copySourceValue != value)
mustUpdate = true; mustUpdate = true;
if (copySourceValue)
dFree(copySourceValue);
} }
else else
mustUpdate = true; mustUpdate = true;
@ -1478,12 +1473,9 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
if (object->getCopySource()) if (object->getCopySource())
{ {
const char* copySourceValue = getFieldValue(object->getCopySource(), f->pFieldname, j); String copySourceValue = getFieldValue(object->getCopySource(), f->pFieldname, j);
if (copySourceValue && dStricmp(copySourceValue, value) != 0) if (!copySourceValue.isEmpty() && copySourceValue != value)
mustUpdate = true; mustUpdate = true;
if (copySourceValue)
dFree(copySourceValue);
} }
} }
@ -1498,11 +1490,8 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
// value then add it to the ParsedObject's newLines // value then add it to the ParsedObject's newLines
if (mustUpdate) if (mustUpdate)
{ {
newLines.push_back(String(value).c_str()); newLines.push_back(value);
} }
if (defaultValue)
dFree(defaultValue);
} }
//dFree(value); //dFree(value);
@ -1512,10 +1501,10 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
{ {
for (U32 j = 0; S32(j) < f->elementCount; j++) for (U32 j = 0; S32(j) < f->elementCount; j++)
{ {
const char* value = getFieldValue(object, f->pFieldname, j); String value = getFieldValue(object, f->pFieldname, j);
// Make sure we got a value // Make sure we got a value
if (!value) if (value.isEmpty())
continue; continue;
// Let's see if this field is already in the file // Let's see if this field is already in the file
@ -1526,16 +1515,15 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
ParsedProperty& prop = parsedObject->properties[propertyIndex]; ParsedProperty& prop = parsedObject->properties[propertyIndex];
// If this field is on the remove list then remove it and continue // If this field is on the remove list then remove it and continue
if (findRemoveField(object, f->pFieldname, j) || !object->writeField(f->pFieldname, value)) if (findRemoveField(object, f->pFieldname, j) || !object->writeField(f->pFieldname, value.c_str()))
{ {
removeField(parsedObject->properties[propertyIndex]); removeField(parsedObject->properties[propertyIndex]);
dFree(value);
continue; continue;
} }
// Run the parsed value through the console system conditioners so // Run the parsed value through the console system conditioners so
// that it will better match the data we got back from the object. // that it will better match the data we got back from the object.
const char* evalue = Con::getFormattedData(f->type, prop.value, f->table, f->flag); String evalue = Con::getFormattedData(f->type, prop.value, f->table, f->flag);
// If our data doesn't match then we get to update it. // If our data doesn't match then we get to update it.
// //
@ -1543,11 +1531,11 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
// is there in the file, the user does not want it inherited from the copy-source // is there in the file, the user does not want it inherited from the copy-source
// even in the case the actual values are identical. // even in the case the actual values are identical.
if (dStricmp(value, evalue) != 0) if (value != evalue)
{ {
if (value[0] == '\0' && if (value.isEmpty() &&
dStricmp(getFieldValue(defaultObject, f->pFieldname, j), value) == 0 && dStricmp(getFieldValue(defaultObject, f->pFieldname, j), value.c_str()) == 0 &&
(!object->getCopySource() || dStricmp(getFieldValue(object->getCopySource(), f->pFieldname, j), value) == 0)) (!object->getCopySource() || dStricmp(getFieldValue(object->getCopySource(), f->pFieldname, j), value.c_str()) == 0))
{ {
removeField(prop); removeField(prop);
} }
@ -1563,14 +1551,14 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
f->type == TypeSoundFilename) f->type == TypeSoundFilename)
{ {
char fnBuf[1024]; char fnBuf[1024];
Con::collapseScriptFilename(fnBuf, 1024, value); Con::collapseScriptFilename(fnBuf, 1024, value.c_str());
updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, fnBuf, true); updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, fnBuf, true);
} }
else if (f->type == TypeCommand || f->type == TypeString || f->type == TypeRealString) else if (f->type == TypeCommand || f->type == TypeString || f->type == TypeRealString)
{ {
char cmdBuf[1024]; char cmdBuf[1024];
expandEscape(cmdBuf, value); expandEscape(cmdBuf, value.c_str());
updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, cmdBuf, true); updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, cmdBuf, true);
} }
@ -1582,9 +1570,8 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
else else
{ {
// No need to process a removed field that doesn't exist in the file // No need to process a removed field that doesn't exist in the file
if (findRemoveField(object, f->pFieldname, j) || !object->writeField(f->pFieldname, value)) if (findRemoveField(object, f->pFieldname, j) || !object->writeField(f->pFieldname, value.c_str()))
{ {
dFree(value);
continue; continue;
} }
@ -1594,20 +1581,17 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
// then we need to compare against the default value // then we need to compare against the default value
// for this property and save it out if it is different // for this property and save it out if it is different
const char* defaultValue = getFieldValue(defaultObject, f->pFieldname, j); String defaultValue = getFieldValue(defaultObject, f->pFieldname, j);
if (!defaultValue || dStricmp(value, defaultValue) != 0) if (defaultValue.isEmpty() || value != defaultValue)
{ {
// Value differs. Check whether it also differs from the // Value differs. Check whether it also differs from the
// value in the copy source if there is one. // value in the copy source if there is one.
if (object->getCopySource()) if (object->getCopySource())
{ {
const char* copySourceValue = getFieldValue(object->getCopySource(), f->pFieldname, j); String copySourceValue = getFieldValue(object->getCopySource(), f->pFieldname, j);
if (!copySourceValue || dStricmp(copySourceValue, value) != 0) if (copySourceValue.isEmpty() || copySourceValue != value)
mustUpdate = true; mustUpdate = true;
if (copySourceValue)
dFree(copySourceValue);
} }
else else
mustUpdate = true; mustUpdate = true;
@ -1620,12 +1604,9 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
if (object->getCopySource()) if (object->getCopySource())
{ {
const char* copySourceValue = getFieldValue(object->getCopySource(), f->pFieldname, j); String copySourceValue = getFieldValue(object->getCopySource(), f->pFieldname, j);
if (copySourceValue && dStricmp(copySourceValue, value) != 0) if (!copySourceValue.isEmpty() && copySourceValue != value)
mustUpdate = true; mustUpdate = true;
if (copySourceValue)
dFree(copySourceValue);
} }
} }
@ -1650,26 +1631,21 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
f->type == TypeSoundFilename) f->type == TypeSoundFilename)
{ {
char fnBuf[1024]; char fnBuf[1024];
Con::collapseScriptFilename(fnBuf, 1024, value); Con::collapseScriptFilename(fnBuf, 1024, value.c_str());
newLines.push_back(createNewProperty(f->pFieldname, fnBuf, f->elementCount > 1, j)); newLines.push_back(createNewProperty(f->pFieldname, fnBuf, f->elementCount > 1, j));
} }
else if (f->type == TypeCommand) else if (f->type == TypeCommand)
{ {
char cmdBuf[1024]; char cmdBuf[1024];
expandEscape(cmdBuf, value); expandEscape(cmdBuf, value.c_str());
newLines.push_back(createNewProperty(f->pFieldname, cmdBuf, f->elementCount > 1, j)); newLines.push_back(createNewProperty(f->pFieldname, cmdBuf, f->elementCount > 1, j));
} }
else else
newLines.push_back(createNewProperty(f->pFieldname, value, f->elementCount > 1, j)); newLines.push_back(createNewProperty(f->pFieldname, value, f->elementCount > 1, j));
} }
if (defaultValue)
dFree(defaultValue);
} }
dFree(value);
} }
} }
} }
@ -1812,15 +1788,6 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
} }
// Clean up the newLines memory // Clean up the newLines memory
for (U32 i = 0; i < newLines.size(); i++)
{
if (!isEmptyLine(newLines[i]) && !StringTable->lookup(newLines[i]))
{//don't try killing empty lines or lines that are in the string table
dFree(newLines[i]);
}
newLines[ i ] = NULL;
}
newLines.clear(); newLines.clear();
SimSet* set = dynamic_cast<SimSet*>(object); SimSet* set = dynamic_cast<SimSet*>(object);

View file

@ -278,9 +278,9 @@ protected:
// Write out properties // Write out properties
// Returns the number of new lines added // Returns the number of new lines added
U32 writeProperties(const Vector<const char*>& properties, const U32 insertLine, const char* objectIndent); U32 writeProperties(const Vector<String>& properties, const U32 insertLine, const char* objectIndent);
// Write out a new object // Write out a new object
ParsedObject* writeNewObject(SimObject* object, const Vector<const char*>& properties, const U32 insertLine, ParsedObject* parentObject = NULL); ParsedObject* writeNewObject(SimObject* object, const Vector<String>& properties, const U32 insertLine, ParsedObject* parentObject = NULL);
public: public:
PersistenceManager(); PersistenceManager();

View file

@ -494,7 +494,7 @@ const char* DecalRoad::getSpecialFieldOut(StringTableEntry fieldName, const U32&
char buffer[1024]; char buffer[1024];
dMemset(buffer, 0, 1024); dMemset(buffer, 0, 1024);
dSprintf(buffer, 1024, "%f %f %f %f", node.point.x, node.point.y, node.point.z, node.width); dSprintf(buffer, 1024, "node = \"%f %f %f %f\";", node.point.x, node.point.y, node.point.z, node.width);
return StringTable->insert(buffer); return StringTable->insert(buffer);
} }

View file

@ -1197,7 +1197,7 @@ const char* MeshRoad::getSpecialFieldOut(StringTableEntry fieldName, const U32&
return StringTable->insert(buffer); return StringTable->insert(buffer);
} }
else if (fieldName == StringTable->insert("ProfileNode")) else if (fieldName == StringTable->insert("ProfileNode") && mSideProfile.mNodes.size())
{ {
Point3F nodePos = mSideProfile.mNodes[index].getPosition(); Point3F nodePos = mSideProfile.mNodes[index].getPosition();
U8 smooth, mtrl; U8 smooth, mtrl;

View file

@ -4,7 +4,13 @@ function AssetBrowser::setupCreateNewLevelAsset(%this)
NewAssetPropertiesInspector.addField("LevelName", "Level Name", "String", "Human-readable name of new level", "", "", %this.newAssetSettings); NewAssetPropertiesInspector.addField("LevelName", "Level Name", "String", "Human-readable name of new level", "", "", %this.newAssetSettings);
NewAssetPropertiesInspector.addField("levelPreviewImage", "Level Preview Image", "Image", "Preview Image for the level", "", "", %this.newAssetSettings); NewAssetPropertiesInspector.addField("levelPreviewImage", "Level Preview Image", "Image", "Preview Image for the level", "", "", %this.newAssetSettings);
NewAssetPropertiesInspector.addField("isSubScene", "Is SubScene", "bool", "Is this levelAsset intended as a subScene", "", "", %this.newAssetSettings); //If we forcefully set it elsewhere, adhere
if($createLevelAssetIsSubScene == true)
%this.newAssetSettings.isSubScene = true;
else
%this.newAssetSettings.isSubScene = false;
NewAssetPropertiesInspector.addField("isSubScene", "Is SubScene", "bool", "Is this levelAsset intended as a subScene", %this.newAssetSettings.isSubScene, "", %this.newAssetSettings);
NewAssetPropertiesInspector.endGroup(); NewAssetPropertiesInspector.endGroup();
} }
@ -27,6 +33,7 @@ function AssetBrowser::createLevelAsset(%this)
%tamlpath = %assetPath @ %assetName @ ".asset.taml"; %tamlpath = %assetPath @ %assetName @ ".asset.taml";
%levelPath = %assetPath @ %assetName @ %misExtension; %levelPath = %assetPath @ %assetName @ %misExtension;
%asset = new LevelAsset() %asset = new LevelAsset()
{ {
AssetName = %assetName; AssetName = %assetName;
@ -55,7 +62,24 @@ function AssetBrowser::createLevelAsset(%this)
echo("Unable to copy template level file!"); echo("Unable to copy template level file!");
} }
replaceInFile(%levelPath, "EditorTemplateLevel", %assetName); if(%asset.isSubScene)
{
%fileObj = new FileObject();
if (!%fileObj.openForWrite(%levelPath))
{
echo("Unable to write subScene file!");
}
else
{
%fileObj.writeLine("");
%fileObj.close();
%fileObj.delete();
}
}
else
{
replaceInFile(%levelPath, "EditorTemplateLevel", %assetName);
}
//Generate the associated files //Generate the associated files
DecalManagerSave( %assetPath @ %asset.DecalsFile ); DecalManagerSave( %assetPath @ %asset.DecalsFile );
@ -87,6 +111,8 @@ function AssetBrowser::setupCreateNewSubScene(%this)
function AssetBrowser::editLevelAsset(%this, %assetDef) function AssetBrowser::editLevelAsset(%this, %assetDef)
{ {
echo("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
echo(%assetDef @ ".isSubScene = " @ %assetDef.isSubScene);
if(!%assetDef.isSubScene) if(!%assetDef.isSubScene)
schedule( 1, 0, "EditorOpenMission", %assetDef); schedule( 1, 0, "EditorOpenMission", %assetDef);
} }
@ -157,7 +183,15 @@ function AssetBrowser::buildLevelAssetPreview(%this, %assetDef, %previewData)
{ {
%previewData.assetName = %assetDef.assetName; %previewData.assetName = %assetDef.assetName;
%previewData.assetPath = %assetDef.getLevelPath(); %previewData.assetPath = %assetDef.getLevelPath();
%previewData.doubleClickCommand = "schedule( 1, 0, \"EditorOpenMission\", "@%assetDef@");";
if(%this.selectMode || %assetDef.isSubScene)
{
%previewData.doubleClickCommand = "AssetBrowser.selectAsset( AssetBrowser.selectedAsset );";
}
else
{
%previewData.doubleClickCommand = "schedule( 1, 0, \"EditorOpenMission\", "@%assetDef@");";
}
%levelPreviewImage = %assetDef.PreviewImage; %levelPreviewImage = %assetDef.PreviewImage;
@ -176,7 +210,10 @@ function AssetBrowser::buildLevelAssetPreview(%this, %assetDef, %previewData)
function createAndAssignLevelAsset(%moduleName, %assetName) function createAndAssignLevelAsset(%moduleName, %assetName)
{ {
$createAndAssignField.apply(%moduleName @ ":" @ %assetName); if(AssetDatabase.isDeclaredAsset(%moduleName))
$createAndAssignField.apply(%moduleName);
else
$createAndAssignField.apply(%moduleName @ ":" @ %assetName);
} }
function EWorldEditor::createSelectedAsSubScene( %this, %object ) function EWorldEditor::createSelectedAsSubScene( %this, %object )

View file

@ -124,6 +124,8 @@ function AssetBrowser::setupCreateNewAsset(%this, %assetType, %moduleName, %call
%command = %this @ ".setupCreateNew"@%assetType @"();"; %command = %this @ ".setupCreateNew"@%assetType @"();";
eval(%command); eval(%command);
} }
NewAssetPropertiesInspector.refresh();
} }
function NewAssetPropertiesInspector::updateNewAssetField(%this) function NewAssetPropertiesInspector::updateNewAssetField(%this)