From 157b114ec7590f8e71979fe1a2aab8fc11535a02 Mon Sep 17 00:00:00 2001 From: Areloch Date: Wed, 15 Apr 2020 12:15:12 -0500 Subject: [PATCH] Added ImageAsset type mode for cubemaps. Added new inspector type TypeShapeAssetId which is processed as a assetId string instead of an AssetPtr. Added utility function to ShapeAsset to getAssetIdByFilename, which lets you find - if any exist - the asset that utilizes a given loose file. If it doesn't find one, it can attempt to run an auto-import if the editor settings allow, then proceed. Fixed callback of the shapeAsset inspector fields so the Open in Shape Editor correctly binds the asset's shape to the editor for modification. Added function to open a shapeAssetId in the shape editor to facilitate the above. Added additional check to findShapeConstructor to look up the full path of the shape in the cases where a full path is provided instead of a local path. This prevents the shapeConstructor from not finding shapes that absolutely exist. Added beginnings of Datablock representation in Asset Browser. Fixed a few minor issues with asset auto import causing false positive errors, preventing Import or erroneous logging. Fixed issue where editing of asset import configs didn't save. Fixed logic of materials in asset browser so they will open in the material editor as expected. Re-enabled AutoImport of assets editor setting by default. --- Engine/source/T3D/assets/ImageAsset.cpp | 1 + Engine/source/T3D/assets/ImageAsset.h | 1 + Engine/source/T3D/assets/ShapeAsset.cpp | 95 +- Engine/source/T3D/assets/ShapeAsset.h | 13 + Engine/source/T3D/tsStatic.cpp | 885 +++++++++--------- Engine/source/T3D/tsStatic.h | 103 +- Engine/source/ts/tsShapeConstruct.cpp | 6 +- .../BaseGame/game/tools/assetBrowser/main.cs | 1 + .../assetBrowser/scripts/assetBrowser.cs | 118 ++- .../tools/assetBrowser/scripts/assetImport.cs | 9 +- .../scripts/assetImportConfigEditor.cs | 5 + .../scripts/assetTypes/datablockObjects.cs | 127 +++ .../scripts/assetTypes/material.cs | 18 +- Templates/BaseGame/game/tools/settings.xml | 354 +++---- .../BaseGame/game/tools/shapeEditor/main.cs | 7 + 15 files changed, 1057 insertions(+), 686 deletions(-) diff --git a/Engine/source/T3D/assets/ImageAsset.cpp b/Engine/source/T3D/assets/ImageAsset.cpp index d69c8290c..046d98b4c 100644 --- a/Engine/source/T3D/assets/ImageAsset.cpp +++ b/Engine/source/T3D/assets/ImageAsset.cpp @@ -97,6 +97,7 @@ ImplementEnumType(ImageAssetType, { ImageAsset::Glow, "Glow", "" }, { ImageAsset::Particle, "Particle", "" }, { ImageAsset::Decal, "Decal", "" }, + { ImageAsset::Cubemap, "Cubemap", "" }, EndImplementEnumType; diff --git a/Engine/source/T3D/assets/ImageAsset.h b/Engine/source/T3D/assets/ImageAsset.h index 3759a8bfa..a053c80b2 100644 --- a/Engine/source/T3D/assets/ImageAsset.h +++ b/Engine/source/T3D/assets/ImageAsset.h @@ -64,6 +64,7 @@ public: Glow = 7, Particle = 8, Decal = 9, + Cubemap = 10, }; protected: diff --git a/Engine/source/T3D/assets/ShapeAsset.cpp b/Engine/source/T3D/assets/ShapeAsset.cpp index fc25df2ac..c51be0860 100644 --- a/Engine/source/T3D/assets/ShapeAsset.cpp +++ b/Engine/source/T3D/assets/ShapeAsset.cpp @@ -51,8 +51,6 @@ IMPLEMENT_CONOBJECT(ShapeAsset); ConsoleType(assetIdString, TypeShapeAssetPtr, String, ASSET_ID_FIELD_PREFIX) -//----------------------------------------------------------------------------- - ConsoleGetType(TypeShapeAssetPtr) { // Fetch asset Id. @@ -60,9 +58,38 @@ ConsoleGetType(TypeShapeAssetPtr) return (*((AssetPtr*)dptr)).getAssetId(); } +ConsoleSetType(TypeShapeAssetPtr) +{ + // 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."); +} + //----------------------------------------------------------------------------- -ConsoleSetType(TypeShapeAssetPtr) +ConsoleType(assetIdString, TypeShapeAssetId, String, ASSET_ID_FIELD_PREFIX) + +ConsoleGetType(TypeShapeAssetId) +{ + // Fetch asset Id. + return *((const char**)(dptr)); +} + +ConsoleSetType(TypeShapeAssetId) { // Was a single argument specified? if (argc == 1) @@ -334,14 +361,55 @@ bool ShapeAsset::getAssetByFilename(StringTableEntry fileName, AssetPtrEmptyString(); + + 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("ShapeAsset::getAssetByFilename - Attempted to in-place import a shapefile(%s) that had no associated asset", fileName); +#endif + + ConsoleValueRef result = Con::executef("importLooseFile", fileName, true); + + if (result.getBoolValue()) + { + StringTableEntry resultingAssetId = StringTable->insert(Con::getVariable("$importedLooseFileAsset")); + + if (resultingAssetId != StringTable->EmptyString()) + { + shapeAssetId = resultingAssetId; + return shapeAssetId; + } + } + + //Didn't work, so have us fall back to a placeholder asset + shapeAssetId = StringTable->insert("Core_Rendering:noshape"); + } + else + { + //acquire and bind the asset, and return it out + shapeAssetId = query.mAssetList[0]; + } + + return shapeAssetId; +} + bool ShapeAsset::getAssetById(StringTableEntry assetId, AssetPtr* shapeAsset) { - shapeAsset->setAssetId(assetId); + (*shapeAsset) = assetId; + if (!shapeAsset->isNull()) return true; //Didn't work, so have us fall back to a placeholder asset - shapeAsset->setAssetId(StringTable->insert("Core_Rendering:noshape")); + StringTableEntry noShapeId = StringTable->insert("Core_Rendering:noshape"); + shapeAsset->setAssetId(noShapeId); if (!shapeAsset->isNull()) return true; @@ -460,7 +528,7 @@ GuiControl* GuiInspectorTypeShapeAssetPtr::constructEditControl() // Create "Open in ShapeEditor" button mShapeEdButton = new GuiBitmapButtonCtrl(); - dSprintf(szBuffer, sizeof(szBuffer), "ShapeEditorPlugin.openShapeAsset(%d.getText());", retCtrl->getId()); + dSprintf(szBuffer, sizeof(szBuffer), "ShapeEditorPlugin.openShapeAssetId(%d.getText());", retCtrl->getId()); mShapeEdButton->setField("Command", szBuffer); char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor"; @@ -502,3 +570,18 @@ bool GuiInspectorTypeShapeAssetPtr::updateRects() return resized; } + +IMPLEMENT_CONOBJECT(GuiInspectorTypeShapeAssetId); + +ConsoleDocClass(GuiInspectorTypeShapeAssetId, + "@brief Inspector field type for Shapes\n\n" + "Editor use only.\n\n" + "@internal" +); + +void GuiInspectorTypeShapeAssetId::consoleInit() +{ + Parent::consoleInit(); + + ConsoleBaseType::getType(TypeShapeAssetId)->setInspectorFieldType("GuiInspectorTypeShapeAssetId"); +} diff --git a/Engine/source/T3D/assets/ShapeAsset.h b/Engine/source/T3D/assets/ShapeAsset.h index 621473b22..df2938105 100644 --- a/Engine/source/T3D/assets/ShapeAsset.h +++ b/Engine/source/T3D/assets/ShapeAsset.h @@ -129,8 +129,11 @@ public: inline StringTableEntry getShapeConstructorFile(void) const { return mConstructorFileName; }; static bool getAssetByFilename(StringTableEntry fileName, AssetPtr* shapeAsset); + static StringTableEntry getAssetIdByFilename(StringTableEntry fileName); static bool getAssetById(StringTableEntry assetId, AssetPtr* shapeAsset); + static StringTableEntry getNoShapeAssetId() { return StringTable->insert("Core_Rendering:noshape"); } + protected: virtual void onAssetRefresh(void); @@ -143,6 +146,7 @@ protected: }; DefineConsoleType(TypeShapeAssetPtr, S32) +DefineConsoleType(TypeShapeAssetId, String) //----------------------------------------------------------------------------- // TypeAssetId GuiInspectorField Class @@ -161,5 +165,14 @@ public: virtual bool updateRects(); }; +class GuiInspectorTypeShapeAssetId : public GuiInspectorTypeShapeAssetPtr +{ + typedef GuiInspectorTypeShapeAssetPtr Parent; +public: + + DECLARE_CONOBJECT(GuiInspectorTypeShapeAssetId); + static void consoleInit(); +}; + #endif diff --git a/Engine/source/T3D/tsStatic.cpp b/Engine/source/T3D/tsStatic.cpp index 1d48b8637..bf7dc6882 100644 --- a/Engine/source/T3D/tsStatic.cpp +++ b/Engine/source/T3D/tsStatic.cpp @@ -66,7 +66,7 @@ extern bool gEditingMission; IMPLEMENT_CO_NETOBJECT_V1(TSStatic); -ConsoleDocClass( TSStatic, +ConsoleDocClass(TSStatic, "@brief A static object derived from a 3D model file and placed within the game world.\n\n" "TSStatic is the most basic 3D shape in Torque. Unlike StaticShape it doesn't make use of " @@ -77,40 +77,43 @@ ConsoleDocClass( TSStatic, "a single ambient animation sequence to play when the object is first added to the scene.\n\n" "@tsexample\n" - "new TSStatic(Team1Base) {\n" - " shapeName = \"art/shapes/desertStructures/station01.dts\";\n" - " playAmbient = \"1\";\n" - " receiveSunLight = \"1\";\n" - " receiveLMLighting = \"1\";\n" - " useCustomAmbientLighting = \"0\";\n" - " customAmbientLighting = \"0 0 0 1\";\n" - " collisionType = \"Visible Mesh\";\n" - " decalType = \"Collision Mesh\";\n" - " allowPlayerStep = \"1\";\n" - " renderNormals = \"0\";\n" - " forceDetail = \"-1\";\n" - " position = \"315.18 -180.418 244.313\";\n" - " rotation = \"0 0 1 195.952\";\n" - " scale = \"1 1 1\";\n" - " isRenderEnabled = \"true\";\n" - " canSaveDynamicFields = \"1\";\n" - "};\n" + "new TSStatic(Team1Base) {\n" + " shapeName = \"art/shapes/desertStructures/station01.dts\";\n" + " playAmbient = \"1\";\n" + " receiveSunLight = \"1\";\n" + " receiveLMLighting = \"1\";\n" + " useCustomAmbientLighting = \"0\";\n" + " customAmbientLighting = \"0 0 0 1\";\n" + " collisionType = \"Visible Mesh\";\n" + " decalType = \"Collision Mesh\";\n" + " allowPlayerStep = \"1\";\n" + " renderNormals = \"0\";\n" + " forceDetail = \"-1\";\n" + " position = \"315.18 -180.418 244.313\";\n" + " rotation = \"0 0 1 195.952\";\n" + " scale = \"1 1 1\";\n" + " isRenderEnabled = \"true\";\n" + " canSaveDynamicFields = \"1\";\n" + "};\n" "@endtsexample\n" "@ingroup gameObjects\n" ); TSStatic::TSStatic() + : + cubeDescId(0), + reflectorDesc(NULL) { mNetFlags.set(Ghostable | ScopeAlways); mTypeMask |= StaticObjectType | StaticShapeObjectType; - mShapeName = ""; - mShapeInstance = NULL; + mShapeName = ""; + mShapeInstance = NULL; - mPlayAmbient = true; - mAmbientThread = NULL; + mPlayAmbient = true; + mAmbientThread = NULL; mAllowPlayerStep = false; @@ -122,10 +125,10 @@ TSStatic::TSStatic() mMeshCulling = false; mUseOriginSort = false; - mUseAlphaFade = false; - mAlphaFadeStart = 100.0f; - mAlphaFadeEnd = 150.0f; - mInvertAlphaFade = false; + mUseAlphaFade = false; + mAlphaFadeStart = 100.0f; + mAlphaFadeEnd = 150.0f; + mInvertAlphaFade = false; mAlphaFade = 1.0f; mPhysicsRep = NULL; @@ -150,31 +153,34 @@ TSStatic::~TSStatic() mConvexList = NULL; } -ImplementEnumType( TSMeshType, +ImplementEnumType(TSMeshType, "Type of mesh data available in a shape.\n" - "@ingroup gameObjects" ) - { TSStatic::None, "None", "No mesh data." }, + "@ingroup gameObjects") +{ + TSStatic::None, "None", "No mesh data." +}, { TSStatic::Bounds, "Bounds", "Bounding box of the shape." }, { TSStatic::CollisionMesh, "Collision Mesh", "Specifically desingated \"collision\" meshes." }, { TSStatic::VisibleMesh, "Visible Mesh", "Rendered mesh polygons." }, -EndImplementEnumType; + EndImplementEnumType; void TSStatic::initPersistFields() { addGroup("Shape"); - addProtectedField("shapeAsset", TypeShapeAssetPtr, Offset(mShapeAsset, TSStatic), - &TSStatic::_setShapeAsset, &defaultProtectedGetFn, - "The source shape asset."); + addProtectedField("shapeAsset", TypeShapeAssetId, Offset(mShapeAssetId, TSStatic), + &TSStatic::_setShapeAsset, &defaultProtectedGetFn, + "The source shape asset."); - addProtectedField("shapeName", TypeFilename, Offset( mShapeName, TSStatic ), &TSStatic::_setShape, &defaultProtectedGetFn, - "%Path and filename of the model file (.DTS, .DAE) to use for this TSStatic."/*, AbstractClassRep::FieldFlags::FIELD_HideInInspectors*/ ); + addProtectedField("shapeName", TypeShapeFilename, Offset(mShapeName, TSStatic), + &TSStatic::_setShapeName, &defaultProtectedGetFn, + "%Path and filename of the model file (.DTS, .DAE) to use for this TSStatic. Legacy field. Any loose files assigned here will attempt to be auto-imported in as an asset."); endGroup("Shape"); addGroup("Materials"); - addProtectedField( "skin", TypeRealString, Offset( mAppliedSkinName, TSStatic ), &_setFieldSkin, &_getFieldSkin, + addProtectedField("skin", TypeRealString, Offset(mAppliedSkinName, TSStatic), &_setFieldSkin, &_getFieldSkin, "@brief The skin applied to the shape.\n\n" "'Skinning' the shape effectively renames the material targets, allowing " @@ -198,82 +204,92 @@ void TSStatic::initPersistFields() "Material targets are only renamed if an existing Material maps to that " "name, or if there is a diffuse texture in the model folder with the same " - "name as the new target.\n\n" ); + "name as the new target.\n\n"); endGroup("Materials"); - + addGroup("Rendering"); - addField( "playAmbient", TypeBool, Offset( mPlayAmbient, TSStatic ), - "Enables automatic playing of the animation sequence named \"ambient\" (if it exists) when the TSStatic is loaded."); - addField( "meshCulling", TypeBool, Offset( mMeshCulling, TSStatic ), - "Enables detailed culling of meshes within the TSStatic. Should only be used " - "with large complex shapes like buildings which contain many submeshes." ); - addField( "originSort", TypeBool, Offset( mUseOriginSort, TSStatic ), - "Enables translucent sorting of the TSStatic by its origin instead of the bounds." ); - - addField("overrideColor", TypeColorF, Offset(mOverrideColor, TSStatic), - "@brief The skin applied to the shape.\n\n"); + addField("playAmbient", TypeBool, Offset(mPlayAmbient, TSStatic), + "Enables automatic playing of the animation sequence named \"ambient\" (if it exists) when the TSStatic is loaded."); + addField("meshCulling", TypeBool, Offset(mMeshCulling, TSStatic), + "Enables detailed culling of meshes within the TSStatic. Should only be used " + "with large complex shapes like buildings which contain many submeshes."); + addField("originSort", TypeBool, Offset(mUseOriginSort, TSStatic), + "Enables translucent sorting of the TSStatic by its origin instead of the bounds."); endGroup("Rendering"); + addGroup("Reflection"); + addField("cubeReflectorDesc", TypeRealString, Offset(cubeDescName, TSStatic), + "References a ReflectorDesc datablock that defines performance and quality properties for dynamic reflections.\n"); + endGroup("Reflection"); + addGroup("Collision"); - addField( "collisionType", TypeTSMeshType, Offset( mCollisionType, TSStatic ), - "The type of mesh data to use for collision queries." ); - addField( "decalType", TypeTSMeshType, Offset( mDecalType, TSStatic ), - "The type of mesh data used to clip decal polygons against." ); - addField( "allowPlayerStep", TypeBool, Offset( mAllowPlayerStep, TSStatic ), - "@brief Allow a Player to walk up sloping polygons in the TSStatic (based on the collisionType).\n\n" - "When set to false, the slightest bump will stop the player from walking on top of the object.\n"); - + addField("collisionType", TypeTSMeshType, Offset(mCollisionType, TSStatic), + "The type of mesh data to use for collision queries."); + addField("decalType", TypeTSMeshType, Offset(mDecalType, TSStatic), + "The type of mesh data used to clip decal polygons against."); + addField("allowPlayerStep", TypeBool, Offset(mAllowPlayerStep, TSStatic), + "@brief Allow a Player to walk up sloping polygons in the TSStatic (based on the collisionType).\n\n" + "When set to false, the slightest bump will stop the player from walking on top of the object.\n"); + endGroup("Collision"); - addGroup( "AlphaFade" ); - addField( "alphaFadeEnable", TypeBool, Offset(mUseAlphaFade, TSStatic), "Turn on/off Alpha Fade" ); - addField( "alphaFadeStart", TypeF32, Offset(mAlphaFadeStart, TSStatic), "Distance of start Alpha Fade" ); - addField( "alphaFadeEnd", TypeF32, Offset(mAlphaFadeEnd, TSStatic), "Distance of end Alpha Fade" ); - addField( "alphaFadeInverse", TypeBool, Offset(mInvertAlphaFade, TSStatic), "Invert Alpha Fade's Start & End Distance" ); - endGroup( "AlphaFade" ); + addGroup("AlphaFade"); + addField("alphaFadeEnable", TypeBool, Offset(mUseAlphaFade, TSStatic), "Turn on/off Alpha Fade"); + addField("alphaFadeStart", TypeF32, Offset(mAlphaFadeStart, TSStatic), "Distance of start Alpha Fade"); + addField("alphaFadeEnd", TypeF32, Offset(mAlphaFadeEnd, TSStatic), "Distance of end Alpha Fade"); + addField("alphaFadeInverse", TypeBool, Offset(mInvertAlphaFade, TSStatic), "Invert Alpha Fade's Start & End Distance"); + endGroup("AlphaFade"); addGroup("Debug"); - addField( "renderNormals", TypeF32, Offset( mRenderNormalScalar, TSStatic ), - "Debug rendering mode shows the normals for each point in the TSStatic's mesh." ); - addField( "forceDetail", TypeS32, Offset( mForceDetail, TSStatic ), - "Forces rendering to a particular detail level." ); + addField("renderNormals", TypeF32, Offset(mRenderNormalScalar, TSStatic), + "Debug rendering mode shows the normals for each point in the TSStatic's mesh."); + addField("forceDetail", TypeS32, Offset(mForceDetail, TSStatic), + "Forces rendering to a particular detail level."); endGroup("Debug"); addGroup("AFX"); - addField("ignoreZodiacs", TypeBool, Offset(mIgnoreZodiacs, TSStatic)); - addField("useGradientRange", TypeBool, Offset(mHasGradients, TSStatic)); - addField("gradientRange", TypePoint2F, Offset(mGradientRangeUser, TSStatic)); - addField("invertGradientRange", TypeBool, Offset(mInvertGradientRange, TSStatic)); + addField("ignoreZodiacs", TypeBool, Offset(mIgnoreZodiacs, TSStatic)); + addField("useGradientRange", TypeBool, Offset(mHasGradients, TSStatic)); + addField("gradientRange", TypePoint2F, Offset(mGradientRangeUser, TSStatic)); + addField("invertGradientRange", TypeBool, Offset(mInvertGradientRange, TSStatic)); endGroup("AFX"); Parent::initPersistFields(); } -bool TSStatic::_setShape(void* obj, const char* index, const char* data) +bool TSStatic::_setShapeAsset(void* obj, const char* index, const char* data) { TSStatic* ts = static_cast(obj);// ->setFile(FileName(data)); - if (ShapeAsset::getAssetByFilename(StringTable->insert(data), &ts->mShapeAsset)) + ts->mShapeAssetId = StringTable->insert(data); + + return ts->setShapeAsset(ts->mShapeAssetId); +} + +bool TSStatic::_setShapeName(void* obj, const char* index, const char* data) +{ + TSStatic* ts = static_cast(obj);// ->setFile(FileName(data)); + + StringTableEntry assetId = ShapeAsset::getAssetIdByFilename(StringTable->insert(data)); + if (assetId != StringTable->EmptyString()) { //Special exception case. If we've defaulted to the 'no shape' mesh, don't save it out, we'll retain the original ids/paths so it doesn't break //the TSStatic - - if (ts->mShapeAsset.getAssetId() != StringTable->insert("Core_Rendering:noshape")) + if (ts->setShapeAsset(assetId)) { - //ts->mShapeAssetId = ts->mShapeAsset.getAssetId(); - ts->mShapeName = StringTable->EmptyString(); + if (assetId == StringTable->insert("Core_Rendering:noShape")) + { + ts->mShapeName = data; + return true; + } + + return false; } - /*else - { - ts->mShapeAssetId = StringTable->EmptyString(); - }*/ - - ts->_createShape(); - } + } else { ts->mShapeAsset = StringTable->EmptyString(); @@ -282,26 +298,17 @@ bool TSStatic::_setShape(void* obj, const char* index, const char* data) return false; } -bool TSStatic::_setShapeAsset(void* obj, const char* index, const char* data) +bool TSStatic::_setFieldSkin(void* object, const char* index, const char* data) { - TSStatic* ts = static_cast(obj); - - ts->setShapeAsset(data); - + TSStatic* ts = static_cast(object); + if (ts) + ts->setSkinName(data); return false; } -bool TSStatic::_setFieldSkin( void *object, const char *index, const char *data ) +const char* TSStatic::_getFieldSkin(void* object, const char* data) { - TSStatic *ts = static_cast( object ); - if ( ts ) - ts->setSkinName( data ); - return false; -} - -const char *TSStatic::_getFieldSkin( void *object, const char *data ) -{ - TSStatic *ts = static_cast( object ); + TSStatic* ts = static_cast(object); return ts ? ts->mSkinNameHandle.getString() : ""; } @@ -310,7 +317,7 @@ void TSStatic::inspectPostApply() // Apply any transformations set in the editor Parent::inspectPostApply(); - if(isServerObject()) + if (isServerObject()) { setMaskBits(-1); prepCollision(); @@ -323,49 +330,57 @@ bool TSStatic::onAdd() { PROFILE_SCOPE(TSStatic_onAdd); - if ( isServerObject() ) + if (isServerObject()) { // Handle the old "usePolysoup" field SimFieldDictionary* fieldDict = getFieldDictionary(); - if ( fieldDict ) + if (fieldDict) { - StringTableEntry slotName = StringTable->insert( "usePolysoup" ); + StringTableEntry slotName = StringTable->insert("usePolysoup"); - SimFieldDictionary::Entry * entry = fieldDict->findDynamicField( slotName ); + SimFieldDictionary::Entry* entry = fieldDict->findDynamicField(slotName); - if ( entry ) + if (entry) { // Was "usePolysoup" set? - bool usePolysoup = dAtob( entry->value ); + bool usePolysoup = dAtob(entry->value); // "usePolysoup" maps to the new VisibleMesh type - if ( usePolysoup ) + if (usePolysoup) mCollisionType = VisibleMesh; // Remove the field in favor on the new "collisionType" field - fieldDict->setFieldValue( slotName, "" ); + fieldDict->setFieldValue(slotName, ""); } } } - if ( !Parent::onAdd() ) + if (!Parent::onAdd()) return false; // Setup the shape. - if ( !_createShape() ) + if (!_createShape()) { - Con::errorf( "TSStatic::onAdd() - Shape creation failed!" ); + Con::errorf("TSStatic::onAdd() - Shape creation failed!"); return false; } setRenderTransform(mObjToWorld); // Register for the resource change signal. - ResourceManager::get().getChangedSignal().notify( this, &TSStatic::_onResourceChanged ); + ResourceManager::get().getChangedSignal().notify(this, &TSStatic::_onResourceChanged); addToScene(); + if (isClientObject()) + { + mCubeReflector.unregisterReflector(); + + if (reflectorDesc) + mCubeReflector.registerReflector(this, reflectorDesc); + } + _updateShouldTick(); // Accumulation and environment mapping @@ -379,7 +394,7 @@ bool TSStatic::onAdd() bool TSStatic::setShapeAsset(const StringTableEntry shapeAssetId) { - if (ShapeAsset::getAssetById(StringTable->insert(shapeAssetId), &mShapeAsset)) + if (ShapeAsset::getAssetById(shapeAssetId, &mShapeAsset)) { //Special exception case. If we've defaulted to the 'no shape' mesh, don't save it out, we'll retain the original ids/paths so it doesn't break //the TSStatic @@ -390,12 +405,12 @@ bool TSStatic::setShapeAsset(const StringTableEntry shapeAssetId) _createShape(); + setMaskBits(-1); + return true; } - else - { - return false; - } + + return false; } bool TSStatic::_createShape() @@ -405,33 +420,32 @@ bool TSStatic::_createShape() mDecalDetails.clear(); mDecalDetailsPtr = 0; mLOSDetails.clear(); - SAFE_DELETE( mPhysicsRep ); - SAFE_DELETE( mShapeInstance ); + SAFE_DELETE(mPhysicsRep); + SAFE_DELETE(mShapeInstance); mAmbientThread = NULL; + mShape = NULL; - if (mShapeAsset.isNull()) + if(!mShapeAsset.isNull()) { - Con::errorf("[TSStatic] Failed to load shape asset."); + //Special-case handling, usually because we set noShape + mShape = mShapeAsset->getShapeResource(); + } + + if (!mShape) + { + Con::errorf("TSStatic::_createShape() - Shape Asset %s had no valid shape!", mShapeAsset.getAssetId()); return false; } - if(!mShapeAsset->getShapeResource()) - { - Con::errorf("TSStatic::_createShape() - Shape Asset had no valid shape!"); - return false; - } - - if ( isClientObject() && - !mShapeAsset->getShapeResource()->preloadMaterialList(mShapeAsset->getShapeFile()) && - NetConnection::filesWereDownloaded() ) + if (isClientObject() && + !mShape->preloadMaterialList(mShape.getPath()) && + NetConnection::filesWereDownloaded()) return false; - TSShape* shape = mShapeAsset->getShapeResource(); - - mObjBox = shape->mBounds; + mObjBox = mShape->mBounds; resetWorldBox(); - mShapeInstance = new TSShapeInstance(shape, isClientObject() ); + mShapeInstance = new TSShapeInstance(mShape, isClientObject()); if (isClientObject()) { mShapeInstance->cloneMaterialList(); @@ -439,7 +453,7 @@ bool TSStatic::_createShape() if (isClientObject()) mShapeInstance->cloneMaterialList(); - if( isGhost() ) + if (isGhost()) { // Reapply the current skin mAppliedSkinName = ""; @@ -449,16 +463,26 @@ bool TSStatic::_createShape() prepCollision(); // Find the "ambient" animation if it exists - S32 ambientSeq = shape->findSequence("ambient"); + S32 ambientSeq = mShape->findSequence("ambient"); - if ( ambientSeq > -1 && !mAmbientThread ) + if (ambientSeq > -1 && !mAmbientThread) mAmbientThread = mShapeInstance->addThread(); - if ( mAmbientThread ) - mShapeInstance->setSequence( mAmbientThread, ambientSeq, 0); + if (mAmbientThread) + mShapeInstance->setSequence(mAmbientThread, ambientSeq, 0); + + // Resolve CubeReflectorDesc. + if (cubeDescName.isNotEmpty()) + { + Sim::findObject(cubeDescName, reflectorDesc); + } + else if (cubeDescId > 0) + { + Sim::findObject(cubeDescId, reflectorDesc); + } //Set up the material slot vars for easy manipulation - S32 materialCount = shape->materialList->getMaterialNameList().size(); //mMeshAsset->getMaterialCount(); + S32 materialCount = mShape->materialList->getMaterialNameList().size(); //mMeshAsset->getMaterialCount(); if (isServerObject()) { @@ -466,7 +490,7 @@ bool TSStatic::_createShape() for (U32 i = 0; i < materialCount; i++) { - StringTableEntry materialname = StringTable->insert(shape->materialList->getMaterialName(i).c_str()); + StringTableEntry materialname = StringTable->insert(mShape->materialList->getMaterialName(i).c_str()); dSprintf(matFieldName, 128, "MaterialSlot%d", i); StringTableEntry matFld = StringTable->insert(matFieldName); @@ -528,13 +552,11 @@ void TSStatic::onDynamicModified(const char* slotName, const char* newValue) void TSStatic::prepCollision() { // Let the client know that the collision was updated - setMaskBits( UpdateCollisionMask ); + setMaskBits(UpdateCollisionMask); // Allow the ShapeInstance to prep its collision if it hasn't already if (mShapeInstance) mShapeInstance->prepCollision(); - else - return; // Cleanup any old collision data mCollisionDetails.clear(); @@ -543,24 +565,22 @@ void TSStatic::prepCollision() mLOSDetails.clear(); mConvexList->nukeList(); - TSShape* shape = mShapeAsset->getShapeResource(); - - if ( mCollisionType == CollisionMesh || mCollisionType == VisibleMesh ) + if (mCollisionType == CollisionMesh || mCollisionType == VisibleMesh) { - shape->findColDetails( mCollisionType == VisibleMesh, &mCollisionDetails, &mLOSDetails ); - if ( mDecalType == mCollisionType ) + mShape->findColDetails(mCollisionType == VisibleMesh, &mCollisionDetails, &mLOSDetails); + if (mDecalType == mCollisionType) { mDecalDetailsPtr = &mCollisionDetails; } - else if ( mDecalType == CollisionMesh || mDecalType == VisibleMesh ) + else if (mDecalType == CollisionMesh || mDecalType == VisibleMesh) { - shape->findColDetails( mDecalType == VisibleMesh, &mDecalDetails, 0 ); + mShape->findColDetails(mDecalType == VisibleMesh, &mDecalDetails, 0); mDecalDetailsPtr = &mDecalDetails; } } - else if ( mDecalType == CollisionMesh || mDecalType == VisibleMesh ) + else if (mDecalType == CollisionMesh || mDecalType == VisibleMesh) { - shape->findColDetails( mDecalType == VisibleMesh, &mDecalDetails, 0 ); + mShape->findColDetails(mDecalType == VisibleMesh, &mDecalDetails, 0); mDecalDetailsPtr = &mDecalDetails; } @@ -569,41 +589,39 @@ void TSStatic::prepCollision() void TSStatic::_updatePhysics() { - SAFE_DELETE( mPhysicsRep ); + SAFE_DELETE(mPhysicsRep); - if ( !PHYSICSMGR || mCollisionType == None ) + if (!PHYSICSMGR || mCollisionType == None) return; - TSShape* shape = mShapeAsset->getShapeResource(); - - PhysicsCollision *colShape = NULL; - if ( mCollisionType == Bounds ) + PhysicsCollision* colShape = NULL; + if (mCollisionType == Bounds) { - MatrixF offset( true ); - offset.setPosition(shape->center ); + MatrixF offset(true); + offset.setPosition(mShape->center); colShape = PHYSICSMGR->createCollision(); - colShape->addBox( getObjBox().getExtents() * 0.5f * mObjScale, offset ); + colShape->addBox(getObjBox().getExtents() * 0.5f * mObjScale, offset); } else - colShape = shape->buildColShape( mCollisionType == VisibleMesh, getScale() ); + colShape = mShape->buildColShape(mCollisionType == VisibleMesh, getScale()); - if ( colShape ) + if (colShape) { - PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" ); + PhysicsWorld* world = PHYSICSMGR->getWorld(isServerObject() ? "server" : "client"); mPhysicsRep = PHYSICSMGR->createBody(); - mPhysicsRep->init( colShape, 0, 0, this, world ); - mPhysicsRep->setTransform( getTransform() ); + mPhysicsRep->init(colShape, 0, 0, this, world); + mPhysicsRep->setTransform(getTransform()); } } void TSStatic::onRemove() { - SAFE_DELETE( mPhysicsRep ); + SAFE_DELETE(mPhysicsRep); // Accumulation - if ( isClientObject() && mShapeInstance ) + if (isClientObject() && mShapeInstance) { - if ( mShapeInstance->hasAccumulation() ) + if (mShapeInstance->hasAccumulation()) AccumulationVolume::removeObject(this); } @@ -612,42 +630,44 @@ void TSStatic::onRemove() removeFromScene(); // Remove the resource change signal. - ResourceManager::get().getChangedSignal().remove( this, &TSStatic::_onResourceChanged ); + ResourceManager::get().getChangedSignal().remove(this, &TSStatic::_onResourceChanged); delete mShapeInstance; mShapeInstance = NULL; mAmbientThread = NULL; + if (isClientObject()) + mCubeReflector.unregisterReflector(); Parent::onRemove(); } -void TSStatic::_onResourceChanged( const Torque::Path &path ) +void TSStatic::_onResourceChanged(const Torque::Path& path) { - if ( path != Path( mShapeName ) ) + if (path != Path(mShapeName)) return; - + _createShape(); _updateShouldTick(); } -void TSStatic::setSkinName( const char *name ) +void TSStatic::setSkinName(const char* name) { - if ( !isGhost() ) + if (!isGhost()) { - if ( name[0] != '\0' ) + if (name[0] != '\0') { // Use tags for better network performance // Should be a tag, but we'll convert to one if it isn't. - if ( name[0] == StringTagPrefixByte ) - mSkinNameHandle = NetStringHandle( U32(dAtoi(name + 1)) ); + if (name[0] == StringTagPrefixByte) + mSkinNameHandle = NetStringHandle(U32(dAtoi(name + 1))); else - mSkinNameHandle = NetStringHandle( name ); + mSkinNameHandle = NetStringHandle(name); } else mSkinNameHandle = NetStringHandle(); - setMaskBits( SkinMask ); + setMaskBits(SkinMask); } } @@ -691,33 +711,33 @@ void TSStatic::reSkin() } } -void TSStatic::processTick( const Move *move ) +void TSStatic::processTick(const Move* move) { - if ( isServerObject() && mPlayAmbient && mAmbientThread ) - mShapeInstance->advanceTime( TickSec, mAmbientThread ); + if (isServerObject() && mPlayAmbient && mAmbientThread) + mShapeInstance->advanceTime(TickSec, mAmbientThread); - if ( isMounted() ) + if (isMounted()) { - MatrixF mat( true ); - mMount.object->getMountTransform(mMount.node, mMount.xfm, &mat ); - setTransform( mat ); + MatrixF mat(true); + mMount.object->getMountTransform(mMount.node, mMount.xfm, &mat); + setTransform(mat); } } -void TSStatic::interpolateTick( F32 delta ) +void TSStatic::interpolateTick(F32 delta) { } -void TSStatic::advanceTime( F32 dt ) +void TSStatic::advanceTime(F32 dt) { - if ( mPlayAmbient && mAmbientThread ) - mShapeInstance->advanceTime( dt, mAmbientThread ); + if (mPlayAmbient && mAmbientThread) + mShapeInstance->advanceTime(dt, mAmbientThread); - if ( isMounted() ) + if (isMounted()) { - MatrixF mat( true ); - mMount.object->getRenderMountTransform( dt, mMount.node, mMount.xfm, &mat ); - setRenderTransform( mat ); + MatrixF mat(true); + mMount.object->getRenderMountTransform(dt, mMount.node, mMount.xfm, &mat); + setRenderTransform(mat); } } @@ -725,17 +745,17 @@ void TSStatic::_updateShouldTick() { bool shouldTick = (mPlayAmbient && mAmbientThread) || isMounted(); - if ( isTicking() != shouldTick ) - setProcessTick( shouldTick ); + if (isTicking() != shouldTick) + setProcessTick(shouldTick); } -void TSStatic::prepRenderImage( SceneRenderState* state ) +void TSStatic::prepRenderImage(SceneRenderState* state) { - if( !mShapeInstance ) + if (!mShapeInstance) return; Point3F cameraOffset; - getRenderTransform().getColumn(3,&cameraOffset); + getRenderTransform().getColumn(3, &cameraOffset); cameraOffset -= state->getDiffuseCameraPosition(); F32 dist = cameraOffset.len(); if (dist < 0.01f) @@ -771,23 +791,32 @@ void TSStatic::prepRenderImage( SceneRenderState* state ) } } - F32 invScale = (1.0f/getMax(getMax(mObjScale.x,mObjScale.y),mObjScale.z)); + F32 invScale = (1.0f / getMax(getMax(mObjScale.x, mObjScale.y), mObjScale.z)); - if ( mForceDetail == -1 ) - mShapeInstance->setDetailFromDistance( state, dist * invScale ); + // If we're currently rendering our own reflection we + // don't want to render ourselves into it. + if (mCubeReflector.isRendering()) + return; + + + if (mForceDetail == -1) + mShapeInstance->setDetailFromDistance(state, dist * invScale); else - mShapeInstance->setCurrentDetail( mForceDetail ); + mShapeInstance->setCurrentDetail(mForceDetail); - if ( mShapeInstance->getCurrentDetail() < 0 ) + if (mShapeInstance->getCurrentDetail() < 0) return; GFXTransformSaver saver; - + // Set up our TS render state. TSRenderState rdata; - rdata.setSceneState( state ); - rdata.setFadeOverride( 1.0f ); - rdata.setOriginSort( mUseOriginSort ); + rdata.setSceneState(state); + rdata.setFadeOverride(1.0f); + rdata.setOriginSort(mUseOriginSort); + + if (mCubeReflector.isEnabled()) + rdata.setCubemap(mCubeReflector.getCubemap()); // Acculumation rdata.setAccuTex(mAccuTex); @@ -795,100 +824,114 @@ void TSStatic::prepRenderImage( SceneRenderState* state ) // If we have submesh culling enabled then prepare // the object space frustum to pass to the shape. Frustum culler; - if ( mMeshCulling ) + if (mMeshCulling) { culler = state->getCullingFrustum(); - MatrixF xfm( true ); - xfm.scale( Point3F::One / getScale() ); - xfm.mul( getRenderWorldTransform() ); - xfm.mul( culler.getTransform() ); - culler.setTransform( xfm ); - rdata.setCuller( &culler ); + MatrixF xfm(true); + xfm.scale(Point3F::One / getScale()); + xfm.mul(getRenderWorldTransform()); + xfm.mul(culler.getTransform()); + culler.setTransform(xfm); + rdata.setCuller(&culler); } // We might have some forward lit materials // so pass down a query to gather lights. LightQuery query; - query.init( getWorldSphere() ); - rdata.setLightQuery( &query ); + query.init(getWorldSphere()); + rdata.setLightQuery(&query); MatrixF mat = getRenderTransform(); - mat.scale( mObjScale ); - GFX->setWorldMatrix( mat ); + mat.scale(mObjScale); + GFX->setWorldMatrix(mat); + + if (state->isDiffusePass() && mCubeReflector.isEnabled() && mCubeReflector.getOcclusionQuery()) + { + RenderPassManager* pass = state->getRenderPass(); + OccluderRenderInst* ri = pass->allocInst(); + + ri->type = RenderPassManager::RIT_Occluder; + ri->query = mCubeReflector.getOcclusionQuery(); + mObjToWorld.mulP(mObjBox.getCenter(), &ri->position); + ri->scale.set(mObjBox.getExtents()); + ri->orientation = pass->allocUniqueXform(mObjToWorld); + ri->isSphere = false; + state->getRenderPass()->addInst(ri); + } mShapeInstance->animate(); - if(mShapeInstance) + if (mShapeInstance) { if (mUseAlphaFade) { mShapeInstance->setAlphaAlways(mAlphaFade); S32 s = mShapeInstance->mMeshObjects.size(); - - for(S32 x = 0; x < s; x++) + + for (S32 x = 0; x < s; x++) { mShapeInstance->mMeshObjects[x].visible = mAlphaFade; } } } - mShapeInstance->render( rdata ); + mShapeInstance->render(rdata); #ifdef TORQUE_AFX_ENABLED if (!mIgnoreZodiacs && mDecalDetailsPtr != 0) afxZodiacMgr::renderPolysoupZodiacs(state, this); #endif - if ( mRenderNormalScalar > 0 ) + if (mRenderNormalScalar > 0) { - ObjectRenderInst *ri = state->getRenderPass()->allocInst(); - ri->renderDelegate.bind( this, &TSStatic::_renderNormals ); + ObjectRenderInst* ri = state->getRenderPass()->allocInst(); + ri->renderDelegate.bind(this, &TSStatic::_renderNormals); ri->type = RenderPassManager::RIT_Editor; - state->getRenderPass()->addInst( ri ); + state->getRenderPass()->addInst(ri); } } -void TSStatic::_renderNormals( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ) +void TSStatic::_renderNormals(ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat) { - PROFILE_SCOPE( TSStatic_RenderNormals ); + PROFILE_SCOPE(TSStatic_RenderNormals); GFXTransformSaver saver; MatrixF mat = getRenderTransform(); - mat.scale( mObjScale ); - GFX->multWorld( mat ); + mat.scale(mObjScale); + GFX->multWorld(mat); S32 dl = mShapeInstance->getCurrentDetail(); - mShapeInstance->renderDebugNormals( mRenderNormalScalar, dl ); + mShapeInstance->renderDebugNormals(mRenderNormalScalar, dl); } void TSStatic::onScaleChanged() { Parent::onScaleChanged(); - if ( mPhysicsRep ) + if (mPhysicsRep) { // If the editor is enabled delay the scale operation // by a few milliseconds so that we're not rebuilding // during an active scale drag operation. - if ( gEditingMission ) - mPhysicsRep->queueCallback( 500, Delegate( this, &TSStatic::_updatePhysics ) ); + if (gEditingMission) + mPhysicsRep->queueCallback(500, Delegate(this, &TSStatic::_updatePhysics)); else _updatePhysics(); } - setMaskBits( ScaleMask ); + setMaskBits(ScaleMask); } -void TSStatic::setTransform(const MatrixF & mat) +void TSStatic::setTransform(const MatrixF& mat) { Parent::setTransform(mat); - if ( !isMounted() ) - setMaskBits( TransformMask ); + if (!isMounted()) + setMaskBits(TransformMask); - if ( mPhysicsRep ) - mPhysicsRep->setTransform( mat ); + if (mPhysicsRep) + mPhysicsRep->setTransform(mat); // Accumulation - if ( isClientObject() && mShapeInstance ) + if (isClientObject() && mShapeInstance) { - if ( mShapeInstance->hasAccumulation() ) + if (mShapeInstance->hasAccumulation()) AccumulationVolume::updateObject(this); } @@ -897,31 +940,31 @@ void TSStatic::setTransform(const MatrixF & mat) setRenderTransform(mat); } -U32 TSStatic::packUpdate(NetConnection *con, U32 mask, BitStream *stream) +U32 TSStatic::packUpdate(NetConnection* con, U32 mask, BitStream* stream) { U32 retMask = Parent::packUpdate(con, mask, stream); - if ( stream->writeFlag( mask & TransformMask ) ) - mathWrite( *stream, getTransform() ); + if (stream->writeFlag(mask & TransformMask)) + mathWrite(*stream, getTransform()); - if ( stream->writeFlag( mask & ScaleMask ) ) + if (stream->writeFlag(mask & ScaleMask)) { // Only write one bit if the scale is one. - if ( stream->writeFlag( mObjScale != Point3F::One ) ) - mathWrite( *stream, mObjScale ); + if (stream->writeFlag(mObjScale != Point3F::One)) + mathWrite(*stream, mObjScale); } - if ( stream->writeFlag( mask & UpdateCollisionMask ) ) - stream->write( (U32)mCollisionType ); + if (stream->writeFlag(mask & UpdateCollisionMask)) + stream->write((U32)mCollisionType); - if ( stream->writeFlag( mask & SkinMask ) ) - con->packNetStringHandleU( stream, mSkinNameHandle ); + if (stream->writeFlag(mask & SkinMask)) + con->packNetStringHandleU(stream, mSkinNameHandle); if (stream->writeFlag(mask & AdvancedStaticOptionsMask)) { - if(mShapeAsset->isAssetValid()) - stream->writeString(mShapeAsset.getAssetId()); - + stream->writeString(mShapeAsset.getAssetId()); + stream->writeString(mShapeName); + stream->write((U32)mDecalType); stream->writeFlag(mAllowPlayerStep); @@ -935,12 +978,12 @@ U32 TSStatic::packUpdate(NetConnection *con, U32 mask, BitStream *stream) stream->writeFlag(mPlayAmbient); } - if ( stream->writeFlag(mUseAlphaFade) ) - { - stream->write(mAlphaFadeStart); - stream->write(mAlphaFadeEnd); - stream->write(mInvertAlphaFade); - } + if (stream->writeFlag(mUseAlphaFade)) + { + stream->write(mAlphaFadeStart); + stream->write(mAlphaFadeEnd); + stream->write(mInvertAlphaFade); + } stream->writeFlag(mIgnoreZodiacs); if (stream->writeFlag(mHasGradients)) @@ -949,9 +992,14 @@ U32 TSStatic::packUpdate(NetConnection *con, U32 mask, BitStream *stream) stream->write(mGradientRange.x); stream->write(mGradientRange.y); } - if ( mLightPlugin ) + if (mLightPlugin) retMask |= mLightPlugin->packUpdate(this, AdvancedStaticOptionsMask, con, mask, stream); + if (stream->writeFlag(reflectorDesc != NULL)) + { + stream->writeRangedU32(reflectorDesc->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast); + } + stream->write(mOverrideColor); if (stream->writeFlag(mask & MaterialMask)) @@ -972,42 +1020,42 @@ U32 TSStatic::packUpdate(NetConnection *con, U32 mask, BitStream *stream) return retMask; } -void TSStatic::unpackUpdate(NetConnection *con, BitStream *stream) +void TSStatic::unpackUpdate(NetConnection* con, BitStream* stream) { Parent::unpackUpdate(con, stream); - if ( stream->readFlag() ) // TransformMask + if (stream->readFlag()) // TransformMask { MatrixF mat; - mathRead( *stream, &mat ); + mathRead(*stream, &mat); setTransform(mat); setRenderTransform(mat); } - if ( stream->readFlag() ) // ScaleMask + if (stream->readFlag()) // ScaleMask { - if ( stream->readFlag() ) + if (stream->readFlag()) { VectorF scale; - mathRead( *stream, &scale ); - setScale( scale ); + mathRead(*stream, &scale); + setScale(scale); } else - setScale( Point3F::One ); + setScale(Point3F::One); } - if ( stream->readFlag() ) // UpdateCollisionMask + if (stream->readFlag()) // UpdateCollisionMask { U32 collisionType = CollisionMesh; - stream->read( &collisionType ); + stream->read(&collisionType); // Handle it if we have changed CollisionType's - if ( (MeshType)collisionType != mCollisionType ) + if ((MeshType)collisionType != mCollisionType) { mCollisionType = (MeshType)collisionType; - if ( isProperlyAdded() && mShapeInstance ) + if (isProperlyAdded() && mShapeInstance) prepCollision(); } } @@ -1026,7 +1074,9 @@ void TSStatic::unpackUpdate(NetConnection *con, BitStream *stream) { char buffer[256]; stream->readString(buffer); - mShapeAsset = StringTable->insert(buffer); + setShapeAsset(StringTable->insert(buffer)); + + mShapeName = stream->readSTString(); stream->read((U32*)&mDecalType); @@ -1038,14 +1088,16 @@ void TSStatic::unpackUpdate(NetConnection *con, BitStream *stream) stream->read(&mForceDetail); mPlayAmbient = stream->readFlag(); + + } - mUseAlphaFade = stream->readFlag(); + mUseAlphaFade = stream->readFlag(); if (mUseAlphaFade) { - stream->read(&mAlphaFadeStart); - stream->read(&mAlphaFadeEnd); - stream->read(&mInvertAlphaFade); + stream->read(&mAlphaFadeStart); + stream->read(&mAlphaFadeEnd); + stream->read(&mInvertAlphaFade); } mIgnoreZodiacs = stream->readFlag(); @@ -1056,11 +1108,16 @@ void TSStatic::unpackUpdate(NetConnection *con, BitStream *stream) stream->read(&mGradientRange.x); stream->read(&mGradientRange.y); } - if ( mLightPlugin ) + if (mLightPlugin) { mLightPlugin->unpackUpdate(this, con, stream); } + if (stream->readFlag()) + { + cubeDescId = stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast); + } + stream->read(&mOverrideColor); if (stream->readFlag()) @@ -1083,21 +1140,21 @@ void TSStatic::unpackUpdate(NetConnection *con, BitStream *stream) updateMaterials(); } - if ( isProperlyAdded() ) + if (isProperlyAdded()) _updateShouldTick(); set_special_typing(); } //---------------------------------------------------------------------------- -bool TSStatic::castRay(const Point3F &start, const Point3F &end, RayInfo* info) +bool TSStatic::castRay(const Point3F& start, const Point3F& end, RayInfo* info) { - if ( mCollisionType == None ) + if (mCollisionType == None) return false; - if ( !mShapeInstance ) + if (!mShapeInstance) return false; - if ( mCollisionType == Bounds ) + if (mCollisionType == Bounds) { F32 fst; if (!mObjBox.collideLine(start, end, &fst, &info->normal)) @@ -1105,7 +1162,7 @@ bool TSStatic::castRay(const Point3F &start, const Point3F &end, RayInfo* info) info->t = fst; info->object = this; - info->point.interpolate( start, end, fst ); + info->point.interpolate(start, end, fst); info->material = NULL; return true; } @@ -1116,11 +1173,11 @@ bool TSStatic::castRay(const Point3F &start, const Point3F &end, RayInfo* info) shortest.t = 1e8f; localInfo.generateTexCoord = info->generateTexCoord; - for ( U32 i = 0; i < mLOSDetails.size(); i++ ) + for (U32 i = 0; i < mLOSDetails.size(); i++) { - mShapeInstance->animate( mLOSDetails[i] ); + mShapeInstance->animate(mLOSDetails[i]); - if ( mShapeInstance->castRayOpcode( mLOSDetails[i], start, end, &localInfo ) ) + if (mShapeInstance->castRayOpcode(mLOSDetails[i], start, end, &localInfo)) { localInfo.object = this; @@ -1140,18 +1197,18 @@ bool TSStatic::castRay(const Point3F &start, const Point3F &end, RayInfo* info) return false; } -bool TSStatic::castRayRendered(const Point3F &start, const Point3F &end, RayInfo *info) +bool TSStatic::castRayRendered(const Point3F& start, const Point3F& end, RayInfo* info) { - if ( !mShapeInstance ) + if (!mShapeInstance) return false; // Cast the ray against the currently visible detail RayInfo localInfo; if (info && info->generateTexCoord) localInfo.generateTexCoord = true; - bool res = mShapeInstance->castRayOpcode( mShapeInstance->getCurrentDetail(), start, end, &localInfo ); + bool res = mShapeInstance->castRayOpcode(mShapeInstance->getCurrentDetail(), start, end, &localInfo); - if ( res ) + if (res) { *info = localInfo; info->object = this; @@ -1161,62 +1218,62 @@ bool TSStatic::castRayRendered(const Point3F &start, const Point3F &end, RayInfo return false; } -bool TSStatic::buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF &) +bool TSStatic::buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F& box, const SphereF&) { - if ( !mShapeInstance ) + if (!mShapeInstance) return false; // This is safe to set even if we're not outputing - polyList->setTransform( &mObjToWorld, mObjScale ); - polyList->setObject( this ); + polyList->setTransform(&mObjToWorld, mObjScale); + polyList->setObject(this); - if ( context == PLC_Export ) + if (context == PLC_Export) { // Use highest detail level S32 dl = 0; // Try to call on the client so we can export materials - if ( isServerObject() && getClientObject() ) - dynamic_cast(getClientObject())->mShapeInstance->buildPolyList( polyList, dl ); + if (isServerObject() && getClientObject()) + dynamic_cast(getClientObject())->mShapeInstance->buildPolyList(polyList, dl); else - mShapeInstance->buildPolyList( polyList, dl ); + mShapeInstance->buildPolyList(polyList, dl); } - else if ( context == PLC_Selection ) + else if (context == PLC_Selection) { // Use the last rendered detail level S32 dl = mShapeInstance->getCurrentDetail(); - mShapeInstance->buildPolyListOpcode( dl, polyList, box ); + mShapeInstance->buildPolyListOpcode(dl, polyList, box); } else { // Figure out the mesh type we're looking for. - MeshType meshType = ( context == PLC_Decal ) ? mDecalType : mCollisionType; + MeshType meshType = (context == PLC_Decal) ? mDecalType : mCollisionType; - if ( meshType == None ) + if (meshType == None) return false; - else if ( meshType == Bounds ) - polyList->addBox( mObjBox ); - else if ( meshType == VisibleMesh ) - mShapeInstance->buildPolyList( polyList, 0 ); + else if (meshType == Bounds) + polyList->addBox(mObjBox); + else if (meshType == VisibleMesh) + mShapeInstance->buildPolyList(polyList, 0); else if (context == PLC_Decal && mDecalDetailsPtr != 0) { - for ( U32 i = 0; i < mDecalDetailsPtr->size(); i++ ) - mShapeInstance->buildPolyListOpcode( (*mDecalDetailsPtr)[i], polyList, box ); + for (U32 i = 0; i < mDecalDetailsPtr->size(); i++) + mShapeInstance->buildPolyListOpcode((*mDecalDetailsPtr)[i], polyList, box); } else { // Everything else is done from the collision meshes // which may be built from either the visual mesh or // special collision geometry. - for ( U32 i = 0; i < mCollisionDetails.size(); i++ ) - mShapeInstance->buildPolyListOpcode( mCollisionDetails[i], polyList, box ); + for (U32 i = 0; i < mCollisionDetails.size(); i++) + mShapeInstance->buildPolyListOpcode(mCollisionDetails[i], polyList, box); } } return true; } -bool TSStatic::buildExportPolyList(ColladaUtils::ExportData* exportData, const Box3F &box, const SphereF &) +bool TSStatic::buildExportPolyList(ColladaUtils::ExportData* exportData, const Box3F& box, const SphereF&) { if (!mShapeInstance) return false; @@ -1308,16 +1365,16 @@ bool TSStatic::buildExportPolyList(ColladaUtils::ExportData* exportData, const B void TSStatic::buildConvex(const Box3F& box, Convex* convex) { - if ( mCollisionType == None ) + if (mCollisionType == None) return; - if ( mShapeInstance == NULL ) + if (mShapeInstance == NULL) return; // These should really come out of a pool mConvexList->collectGarbage(); - if ( mCollisionType == Bounds ) + if (mCollisionType == Bounds) { // Just return a box convex for the entire shape... Convex* cc = 0; @@ -1325,7 +1382,7 @@ void TSStatic::buildConvex(const Box3F& box, Convex* convex) for (CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext) { if (itr->mConvex->getType() == BoxConvexType && - itr->mConvex->getObject() == this) + itr->mConvex->getObject() == this) { cc = itr->mConvex; break; @@ -1350,47 +1407,37 @@ void TSStatic::buildConvex(const Box3F& box, Convex* convex) TSStaticPolysoupConvex::smCurObject = this; for (U32 i = 0; i < mCollisionDetails.size(); i++) - mShapeInstance->buildConvexOpcode( mObjToWorld, mObjScale, mCollisionDetails[i], box, convex, mConvexList ); + mShapeInstance->buildConvexOpcode(mObjToWorld, mObjScale, mCollisionDetails[i], box, convex, mConvexList); TSStaticPolysoupConvex::smCurObject = NULL; } } -Resource TSStatic::getShape() const -{ - if (mShapeAsset->isAssetValid()) - { - return mShapeAsset->getShapeResource(); - } - - return nullptr; -} - SceneObject* TSStaticPolysoupConvex::smCurObject = NULL; TSStaticPolysoupConvex::TSStaticPolysoupConvex() -: box( 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f ), - normal( 0.0f, 0.0f, 0.0f, 0.0f ), - idx( 0 ), - mesh( NULL ) + : box(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f), + normal(0.0f, 0.0f, 0.0f, 0.0f), + idx(0), + mesh(NULL) { mType = TSPolysoupConvexType; - for ( U32 i = 0; i < 4; ++i ) + for (U32 i = 0; i < 4; ++i) { - verts[i].set( 0.0f, 0.0f, 0.0f ); + verts[i].set(0.0f, 0.0f, 0.0f); } } Point3F TSStaticPolysoupConvex::support(const VectorF& vec) const { - F32 bestDot = mDot( verts[0], vec ); + F32 bestDot = mDot(verts[0], vec); - const Point3F *bestP = &verts[0]; - for(S32 i=1; i<4; i++) + const Point3F* bestP = &verts[0]; + for (S32 i = 1; i < 4; i++) { F32 newD = mDot(verts[i], vec); - if(newD > bestDot) + if (newD > bestDot) { bestDot = newD; bestP = &verts[i]; @@ -1403,8 +1450,8 @@ Point3F TSStaticPolysoupConvex::support(const VectorF& vec) const Box3F TSStaticPolysoupConvex::getBoundingBox() const { Box3F wbox = box; - wbox.minExtents.convolve( mObject->getScale() ); - wbox.maxExtents.convolve( mObject->getScale() ); + wbox.minExtents.convolve(mObject->getScale()); + wbox.maxExtents.convolve(mObject->getScale()); mObject->getTransform().mul(wbox); return wbox; } @@ -1415,18 +1462,18 @@ Box3F TSStaticPolysoupConvex::getBoundingBox(const MatrixF& mat, const Point3F& return box; } -void TSStaticPolysoupConvex::getPolyList(AbstractPolyList *list) +void TSStaticPolysoupConvex::getPolyList(AbstractPolyList* list) { // Transform the list into object space and set the pointer to the object - MatrixF i( mObject->getTransform() ); - Point3F iS( mObject->getScale() ); + MatrixF i(mObject->getTransform()); + Point3F iS(mObject->getScale()); list->setTransform(&i, iS); list->setObject(mObject); // Add only the original collision triangle - S32 base = list->addPoint(verts[0]); - list->addPoint(verts[2]); - list->addPoint(verts[1]); + S32 base = list->addPoint(verts[0]); + list->addPoint(verts[2]); + list->addPoint(verts[1]); list->begin(0, (U32)idx ^ (uintptr_t)mesh); list->vertex(base + 2); @@ -1436,7 +1483,7 @@ void TSStaticPolysoupConvex::getPolyList(AbstractPolyList *list) list->end(); } -void TSStaticPolysoupConvex::getFeatures(const MatrixF& mat,const VectorF& n, ConvexFeature* cf) +void TSStaticPolysoupConvex::getFeatures(const MatrixF& mat, const VectorF& n, ConvexFeature* cf) { cf->material = 0; cf->object = mObject; @@ -1458,83 +1505,83 @@ void TSStaticPolysoupConvex::getFeatures(const MatrixF& mat,const VectorF& n, Co // edges... cf->mEdgeList.increment(); - cf->mEdgeList.last().vertex[0] = firstVert+0; - cf->mEdgeList.last().vertex[1] = firstVert+1; + cf->mEdgeList.last().vertex[0] = firstVert + 0; + cf->mEdgeList.last().vertex[1] = firstVert + 1; cf->mEdgeList.increment(); - cf->mEdgeList.last().vertex[0] = firstVert+1; - cf->mEdgeList.last().vertex[1] = firstVert+2; + cf->mEdgeList.last().vertex[0] = firstVert + 1; + cf->mEdgeList.last().vertex[1] = firstVert + 2; cf->mEdgeList.increment(); - cf->mEdgeList.last().vertex[0] = firstVert+2; - cf->mEdgeList.last().vertex[1] = firstVert+0; + cf->mEdgeList.last().vertex[0] = firstVert + 2; + cf->mEdgeList.last().vertex[1] = firstVert + 0; cf->mEdgeList.increment(); - cf->mEdgeList.last().vertex[0] = firstVert+3; - cf->mEdgeList.last().vertex[1] = firstVert+0; + cf->mEdgeList.last().vertex[0] = firstVert + 3; + cf->mEdgeList.last().vertex[1] = firstVert + 0; cf->mEdgeList.increment(); - cf->mEdgeList.last().vertex[0] = firstVert+3; - cf->mEdgeList.last().vertex[1] = firstVert+1; + cf->mEdgeList.last().vertex[0] = firstVert + 3; + cf->mEdgeList.last().vertex[1] = firstVert + 1; cf->mEdgeList.increment(); - cf->mEdgeList.last().vertex[0] = firstVert+3; - cf->mEdgeList.last().vertex[1] = firstVert+2; + cf->mEdgeList.last().vertex[0] = firstVert + 3; + cf->mEdgeList.last().vertex[1] = firstVert + 2; // triangles... cf->mFaceList.increment(); cf->mFaceList.last().normal = PlaneF(tverts[2], tverts[1], tverts[0]); - cf->mFaceList.last().vertex[0] = firstVert+2; - cf->mFaceList.last().vertex[1] = firstVert+1; - cf->mFaceList.last().vertex[2] = firstVert+0; + cf->mFaceList.last().vertex[0] = firstVert + 2; + cf->mFaceList.last().vertex[1] = firstVert + 1; + cf->mFaceList.last().vertex[2] = firstVert + 0; cf->mFaceList.increment(); cf->mFaceList.last().normal = PlaneF(tverts[1], tverts[0], tverts[3]); - cf->mFaceList.last().vertex[0] = firstVert+1; - cf->mFaceList.last().vertex[1] = firstVert+0; - cf->mFaceList.last().vertex[2] = firstVert+3; + cf->mFaceList.last().vertex[0] = firstVert + 1; + cf->mFaceList.last().vertex[1] = firstVert + 0; + cf->mFaceList.last().vertex[2] = firstVert + 3; cf->mFaceList.increment(); cf->mFaceList.last().normal = PlaneF(tverts[2], tverts[1], tverts[3]); - cf->mFaceList.last().vertex[0] = firstVert+2; - cf->mFaceList.last().vertex[1] = firstVert+1; - cf->mFaceList.last().vertex[2] = firstVert+3; + cf->mFaceList.last().vertex[0] = firstVert + 2; + cf->mFaceList.last().vertex[1] = firstVert + 1; + cf->mFaceList.last().vertex[2] = firstVert + 3; cf->mFaceList.increment(); cf->mFaceList.last().normal = PlaneF(tverts[0], tverts[2], tverts[3]); - cf->mFaceList.last().vertex[0] = firstVert+0; - cf->mFaceList.last().vertex[1] = firstVert+2; - cf->mFaceList.last().vertex[2] = firstVert+3; + cf->mFaceList.last().vertex[0] = firstVert + 0; + cf->mFaceList.last().vertex[1] = firstVert + 2; + cf->mFaceList.last().vertex[2] = firstVert + 3; // All done! } -void TSStatic::onMount( SceneObject *obj, S32 node ) +void TSStatic::onMount(SceneObject* obj, S32 node) { Parent::onMount(obj, node); _updateShouldTick(); } -void TSStatic::onUnmount( SceneObject *obj, S32 node ) +void TSStatic::onUnmount(SceneObject* obj, S32 node) { - Parent::onUnmount( obj, node ); - setMaskBits( TransformMask ); + Parent::onUnmount(obj, node); + setMaskBits(TransformMask); _updateShouldTick(); } U32 TSStatic::getNumDetails() { - if (isServerObject() && getClientObject()) - { - TSStatic* clientShape = dynamic_cast(getClientObject()); - return clientShape->mShapeInstance->getNumDetails(); - } - return 0; + if (isServerObject() && getClientObject()) + { + TSStatic* clientShape = dynamic_cast(getClientObject()); + return clientShape->mShapeInstance->getNumDetails(); + } + return 0; }; void TSStatic::updateMaterials() { - if (mChangingMaterials.empty() || !mShapeAsset->getShapeResource()) + if (mChangingMaterials.empty() || !mShape) return; TSMaterialList* pMatList = mShapeInstance->getMaterialList(); @@ -1585,7 +1632,7 @@ void TSStatic::onInspect(GuiInspector* inspector) //Put the GameObject group before everything that'd be gameobject-effecting, for orginazational purposes GuiInspectorGroup* materialGroup = inspector->findExistentGroup(StringTable->insert("Materials")); GuiControl* stack = dynamic_cast(materialGroup->findObjectByInternalName(StringTable->insert("Stack"))); - + //Do this on both the server and client S32 materialCount = mShapeAsset->getShape()->materialList->getMaterialNameList().size(); //mMeshAsset->getMaterialCount(); @@ -1663,14 +1710,14 @@ void TSStatic::onInspect(GuiInspector* inspector) } } -DefineEngineMethod( TSStatic, getTargetName, const char*, ( S32 index ),(0), +DefineEngineMethod(TSStatic, getTargetName, const char*, (S32 index), (0), "Get the name of the indexed shape material.\n" "@param index index of the material to get (valid range is 0 - getTargetCount()-1).\n" "@return the name of the indexed material.\n" "@see getTargetCount()\n") { - TSStatic *obj = dynamic_cast< TSStatic* > ( object ); - if(obj) + TSStatic* obj = dynamic_cast (object); + if (obj) { // Try to use the client object (so we get the reskinned targets in the Material Editor) if ((TSStatic*)obj->getClientObject()) @@ -1682,13 +1729,13 @@ DefineEngineMethod( TSStatic, getTargetName, const char*, ( S32 index ),(0), return ""; } -DefineEngineMethod( TSStatic, getTargetCount, S32,(),, +DefineEngineMethod(TSStatic, getTargetCount, S32, (), , "Get the number of materials in the shape.\n" "@return the number of materials in the shape.\n" "@see getTargetName()\n") { - TSStatic *obj = dynamic_cast< TSStatic* > ( object ); - if(obj) + TSStatic* obj = dynamic_cast (object); + if (obj) { // Try to use the client object (so we get the reskinned targets in the Material Editor) if ((TSStatic*)obj->getClientObject()) @@ -1703,7 +1750,7 @@ DefineEngineMethod( TSStatic, getTargetCount, S32,(),, // This method is able to change materials per map to with others. The material that is being replaced is being mapped to // unmapped_mat as a part of this transition -DefineEngineMethod( TSStatic, changeMaterial, void, ( const char* mapTo, Material* oldMat, Material* newMat ),("",nullAsType(),nullAsType()), +DefineEngineMethod(TSStatic, changeMaterial, void, (const char* mapTo, Material* oldMat, Material* newMat), ("", nullAsType(), nullAsType()), "@brief Change one of the materials on the shape.\n\n" "This method changes materials per mapTo with others. The material that " @@ -1717,13 +1764,13 @@ DefineEngineMethod( TSStatic, changeMaterial, void, ( const char* mapTo, Materia "@param newMat the new Material to map\n\n" "@tsexample\n" - "// remap the first material in the shape\n" - "%mapTo = %obj.getTargetName( 0 );\n" - "%obj.changeMaterial( %mapTo, 0, MyMaterial );\n" - "@endtsexample\n" ) + "// remap the first material in the shape\n" + "%mapTo = %obj.getTargetName( 0 );\n" + "%obj.changeMaterial( %mapTo, 0, MyMaterial );\n" + "@endtsexample\n") { // if no valid new material, theres no reason for doing this - if( !newMat ) + if (!newMat) { Con::errorf("TSShape::changeMaterial failed: New material does not exist!"); return; @@ -1740,13 +1787,13 @@ DefineEngineMethod( TSStatic, changeMaterial, void, ( const char* mapTo, Materia } // Lets remap the old material off, so as to let room for our current material room to claim its spot - if( oldMat ) + if (oldMat) oldMat->mMapTo = String("unmapped_mat"); newMat->mMapTo = mapTo; // Map the material by name in the matmgr - MATMGR->mapMaterial( mapTo, newMat->getName() ); + MATMGR->mapMaterial(mapTo, newMat->getName()); // Replace instances with the new material being traded in. Lets make sure that we only // target the specific targets per inst, this is actually doing more than we thought @@ -1754,20 +1801,20 @@ DefineEngineMethod( TSStatic, changeMaterial, void, ( const char* mapTo, Materia shapeMaterialList->mMatInstList[matIndex] = newMat->createMatInstance(); // Finish up preparing the material instances for rendering - const GFXVertexFormat *flags = getGFXVertexFormat(); + const GFXVertexFormat* flags = getGFXVertexFormat(); FeatureSet features = MATMGR->getDefaultFeatures(); shapeMaterialList->getMaterialInst(matIndex)->init(features, flags); } -DefineEngineMethod( TSStatic, getModelFile, const char *, (),, +DefineEngineMethod(TSStatic, getModelFile, const char*, (), , "@brief Get the model filename used by this shape.\n\n" "@return the shape filename\n\n" "@tsexample\n" - "// Acquire the model filename used on this shape.\n" - "%modelFilename = %obj.getModelFile();\n" + "// Acquire the model filename used on this shape.\n" + "%modelFilename = %obj.getModelFile();\n" "@endtsexample\n" - ) +) { return object->getShapeFileName(); } @@ -1780,7 +1827,7 @@ void TSStatic::set_special_typing() mTypeMask &= ~InteriorLikeObjectType; } -void TSStatic::onStaticModified(const char* slotName, const char*newValue) +void TSStatic::onStaticModified(const char* slotName, const char* newValue) { #ifdef TORQUE_AFX_ENABLED if (slotName == afxZodiacData::GradientRangeSlot) @@ -1797,17 +1844,17 @@ void TSStatic::setSelectionFlags(U8 flags) { Parent::setSelectionFlags(flags); - if (!mShapeInstance || !isClientObject()) - return; - - if (!mShapeInstance->ownMaterialList()) - return; - - TSMaterialList* pMatList = mShapeInstance->getMaterialList(); - for (S32 j = 0; j < pMatList->size(); j++) - { - BaseMatInstance * bmi = pMatList->getMaterialInst(j); - bmi->setSelectionHighlighting(needsSelectionHighlighting()); - } + if (!mShapeInstance || !isClientObject()) + return; + + if (!mShapeInstance->ownMaterialList()) + return; + + TSMaterialList* pMatList = mShapeInstance->getMaterialList(); + for (S32 j = 0; j < pMatList->size(); j++) + { + BaseMatInstance* bmi = pMatList->getMaterialInst(j); + bmi->setSelectionHighlighting(needsSelectionHighlighting()); + } } diff --git a/Engine/source/T3D/tsStatic.h b/Engine/source/T3D/tsStatic.h index 98d0cf92a..a26e2b016 100644 --- a/Engine/source/T3D/tsStatic.h +++ b/Engine/source/T3D/tsStatic.h @@ -38,11 +38,16 @@ #include "core/resource.h" #endif #ifndef _NETSTRINGTABLE_H_ - #include "sim/netStringTable.h" +#include "sim/netStringTable.h" #endif #ifndef _TSSHAPE_H_ #include "ts/tsShape.h" #endif + +#ifndef _REFLECTOR_H_ +#include "scene/reflector.h" +#endif + #ifndef _ASSET_PTR_H_ #include "assets/assetPtr.h" #endif @@ -71,7 +76,7 @@ public: Point3F verts[4]; PlaneF normal; S32 idx; - TSMesh *mesh; + TSMesh* mesh; static SceneObject* smCurObject; @@ -81,7 +86,7 @@ public: Box3F getBoundingBox() const; Box3F getBoundingBox(const MatrixF& mat, const Point3F& scale) const; - void getFeatures(const MatrixF& mat,const VectorF& n, ConvexFeature* cf); + void getFeatures(const MatrixF& mat, const VectorF& n, ConvexFeature* cf); // This returns a list of convex faces to collide against void getPolyList(AbstractPolyList* list); @@ -98,25 +103,25 @@ class TSStatic : public SceneObject static U32 smUniqueIdentifier; - enum MaskBits + enum MaskBits { - TransformMask = Parent::NextFreeMask << 0, - AdvancedStaticOptionsMask = Parent::NextFreeMask << 1, - UpdateCollisionMask = Parent::NextFreeMask << 2, - SkinMask = Parent::NextFreeMask << 3, - MaterialMask = Parent::NextFreeMask << 4, - NextFreeMask = Parent::NextFreeMask << 5 + TransformMask = Parent::NextFreeMask << 0, + AdvancedStaticOptionsMask = Parent::NextFreeMask << 1, + UpdateCollisionMask = Parent::NextFreeMask << 2, + SkinMask = Parent::NextFreeMask << 3, + MaterialMask = Parent::NextFreeMask << 4, + NextFreeMask = Parent::NextFreeMask << 5 }; public: void setAlphaFade(bool enable, F32 start, F32 end, bool inverse) { - mUseAlphaFade = enable; - mAlphaFadeStart = start; - mAlphaFadeEnd = end; - mInvertAlphaFade = inverse; + mUseAlphaFade = enable; + mAlphaFadeStart = start; + mAlphaFadeEnd = end; + mInvertAlphaFade = inverse; } - + /// The different types of mesh data types enum MeshType { @@ -125,7 +130,7 @@ public: CollisionMesh = 2, ///< Specifically designated collision meshes VisibleMesh = 3 ///< Rendered mesh polygons }; - + protected: bool mUseAlphaFade; F32 mAlphaFadeStart; @@ -148,41 +153,47 @@ protected: // Collision void prepCollision(); - bool castRay(const Point3F &start, const Point3F &end, RayInfo* info); - bool castRayRendered(const Point3F &start, const Point3F &end, RayInfo* info); - bool buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF& sphere); - bool buildExportPolyList(ColladaUtils::ExportData* exportData, const Box3F &box, const SphereF &); + bool castRay(const Point3F& start, const Point3F& end, RayInfo* info); + bool castRayRendered(const Point3F& start, const Point3F& end, RayInfo* info); + bool buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F& box, const SphereF& sphere); + bool buildExportPolyList(ColladaUtils::ExportData* exportData, const Box3F& box, const SphereF&); void buildConvex(const Box3F& box, Convex* convex); bool setShapeAsset(const StringTableEntry shapeAssetId); bool _createShape(); - + void _updatePhysics(); - void _renderNormals( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ); + void _renderNormals(ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat); - void _onResourceChanged( const Torque::Path &path ); + void _onResourceChanged(const Torque::Path& path); // ProcessObject - virtual void processTick( const Move *move ); - virtual void interpolateTick( F32 delta ); - virtual void advanceTime( F32 dt ); + virtual void processTick(const Move* move); + virtual void interpolateTick(F32 delta); + virtual void advanceTime(F32 dt); virtual void onDynamicModified(const char* slotName, const char* newValue); /// Start or stop processing ticks depending on our state. void _updateShouldTick(); + String cubeDescName; + U32 cubeDescId; + ReflectorDesc* reflectorDesc; + CubeReflector mCubeReflector; + protected: - Convex *mConvexList; + Convex* mConvexList; StringTableEntry mShapeName; U32 mShapeHash; + Resource mShape; Vector mCollisionDetails; Vector mLOSDetails; - TSShapeInstance *mShapeInstance; + TSShapeInstance* mShapeInstance; AssetPtr mShapeAsset; StringTableEntry mShapeAssetId; @@ -191,7 +202,7 @@ protected: String mAppliedSkinName; bool mPlayAmbient; - TSThread* mAmbientThread; + TSThread* mAmbientThread; /// The type of mesh data to return for collision queries. MeshType mCollisionType; @@ -209,7 +220,7 @@ protected: /// model instead of the nearest point of the bounds. bool mUseOriginSort; - PhysicsBody *mPhysicsRep; + PhysicsBody* mPhysicsRep; LinearColorF mOverrideColor; @@ -224,36 +235,36 @@ public: DECLARE_CONOBJECT(TSStatic); static void initPersistFields(); - static bool _setShape(void* obj, const char* index, const char* data); static bool _setShapeAsset(void* obj, const char* index, const char* data); - static bool _setFieldSkin( void *object, const char* index, const char* data ); - static const char *_getFieldSkin( void *object, const char *data ); + static bool _setShapeName(void* obj, const char* index, const char* data); + static bool _setFieldSkin(void* object, const char* index, const char* data); + static const char* _getFieldSkin(void* object, const char* data); // Skinning - void setSkinName( const char *name ); + void setSkinName(const char* name); void reSkin(); // NetObject - U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream ); - void unpackUpdate( NetConnection *conn, BitStream *stream ); + U32 packUpdate(NetConnection* conn, U32 mask, BitStream* stream); + void unpackUpdate(NetConnection* conn, BitStream* stream); // SceneObject - void setTransform( const MatrixF &mat ); + void setTransform(const MatrixF& mat); void onScaleChanged(); - void prepRenderImage( SceneRenderState *state ); + void prepRenderImage(SceneRenderState* state); void inspectPostApply(); - virtual void onMount( SceneObject *obj, S32 node ); - virtual void onUnmount( SceneObject *obj, S32 node ); + virtual void onMount(SceneObject* obj, S32 node); + virtual void onUnmount(SceneObject* obj, S32 node); /// The type of mesh data use for collision queries. MeshType getCollisionType() const { return mCollisionType; } bool allowPlayerStep() const { return mAllowPlayerStep; } - Resource getShape() const; - StringTableEntry getShapeFileName() { return mShapeName; } + Resource getShape() const { return mShape; } + StringTableEntry getShapeFileName() { return mShapeName; } void setShapeFileName(StringTableEntry shapeName) { mShapeName = shapeName; } - + TSShapeInstance* getShapeInstance() const { return mShapeInstance; } U32 getNumDetails(); @@ -267,10 +278,10 @@ public: void updateMaterials(); private: - virtual void onStaticModified(const char* slotName, const char*newValue = NULL); + virtual void onStaticModified(const char* slotName, const char* newValue = NULL); protected: Vector mDecalDetails; - Vector* mDecalDetailsPtr; + Vector* mDecalDetailsPtr; public: bool mIgnoreZodiacs; bool mHasGradients; @@ -283,7 +294,7 @@ private: }; typedef TSStatic::MeshType TSMeshType; -DefineEnumType( TSMeshType ); +DefineEnumType(TSMeshType); #endif // _H_TSSTATIC diff --git a/Engine/source/ts/tsShapeConstruct.cpp b/Engine/source/ts/tsShapeConstruct.cpp index ac37ef3c8..40004e98b 100644 --- a/Engine/source/ts/tsShapeConstruct.cpp +++ b/Engine/source/ts/tsShapeConstruct.cpp @@ -390,7 +390,11 @@ TSShapeConstructor* TSShapeConstructor::findShapeConstructor(const FileName& pat for (S32 i = 0; i < group->size(); i++) { TSShapeConstructor* tss = dynamic_cast( group->at(i) ); - if ( tss->mShapePath.equal( path, String::NoCase ) ) + FileName shapePath = tss->mShapePath; + + char buf[1024]; + FileName fullShapePath = Platform::makeFullPathName(shapePath, buf, sizeof(buf)); + if (shapePath.equal( path, String::NoCase ) || fullShapePath.equal(path, String::NoCase)) return tss; } } diff --git a/Templates/BaseGame/game/tools/assetBrowser/main.cs b/Templates/BaseGame/game/tools/assetBrowser/main.cs index f8f575842..5f1ad1b4e 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/main.cs +++ b/Templates/BaseGame/game/tools/assetBrowser/main.cs @@ -101,6 +101,7 @@ function initializeAssetBrowser() exec("./scripts/assetTypes/folder.cs"); exec("./scripts/assetTypes/terrain.cs"); exec("./scripts/assetTypes/terrainMaterial.cs"); + exec("./scripts/assetTypes/datablockObjects.cs"); new ScriptObject( AssetBrowserPlugin ) { diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.cs index 95907a643..80668cfde 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.cs +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.cs @@ -278,7 +278,45 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName ) } else { - %fullPath = %moduleName !$= "" ? %moduleName @ "/" @ %asset : %asset; + //special-case entry + if(getFieldCount(%asset) > 1) + { + %specialType = getField(%asset,0); + + /*if(%specialType $= "Folder") + { + + } + else if(%specialType $= "Datablock") + { + %sdfasdgah = true; + }*/ + %assetType = %specialType; + %assetName = getField(%asset, 1); + %sdfasdgah = true; + + if(%assetType $= "Folder") + { + %fullPath = %moduleName !$= "" ? %moduleName @ "/" @ %assetName : %assetName; + %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 $= "Datablock") + { + %assetDesc = %assetName; + %assetDesc.assetType = %assetType; + } + } + /*%fullPath = %moduleName !$= "" ? %moduleName @ "/" @ %assetName : %assetName; %fullPath = strreplace(%fullPath, "/", "_"); if(isObject(%fullPath)) @@ -287,12 +325,12 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName ) %assetDesc = new ScriptObject(%fullPath); %assetDesc.dirPath = %moduleName; - %assetDesc.assetName = %asset; - %assetDesc.description = %moduleName @ "/" @ %asset; - %assetDesc.assetType = "Folder"; + %assetDesc.assetName = %assetName; + %assetDesc.description = %moduleName @ "/" @ %assetName; + %assetDesc.assetType = %assetType;*/ - %assetName = %asset; - %assetType = "Folder"; + //%assetName = %asset; + //%assetType = "Folder"; } %previewSize = %this.previewSize SPC %this.previewSize; @@ -425,7 +463,7 @@ function AssetBrowser::loadDirectories( %this ) } //Add Non-Asset Scripted Objects. Datablock, etc based - %category = getWord( %breadcrumbPath, 1 ); + /*%category = getWord( %breadcrumbPath, 1 ); %dataGroup = "DataBlockGroup"; if(%dataGroup.getCount() != 0) @@ -437,8 +475,14 @@ function AssetBrowser::loadDirectories( %this ) %obj = %dataGroup.getObject(%i); // echo ("Obj: " @ %obj.getName() @ " - " @ %obj.category ); - if ( %obj.category $= "" && %obj.category == 0 ) - continue; + //if ( %obj.category $= "" && %obj.category == 0 ) + // continue; + + %dbFilename = %obj.getFileName(); + %dbFilePath = filePath(%dbFilename); + + if(%breadcrumbPath $= %dbFilePath) + { //if ( %breadcrumbPath $= "" ) //{ @@ -456,8 +500,9 @@ function AssetBrowser::loadDirectories( %this ) { AssetBrowser-->filterTree.insertItem(%scriptedItem, %obj.getName()); }*/ - } - } + //} + //} + // } AssetPreviewArray.empty(); @@ -916,6 +961,9 @@ function AssetBrowser::doRebuildAssetArray(%this) AssetBrowser-->assetList.deleteAllObjects(); AssetPreviewArray.empty(); + if(isObject(%assetArray)) + %assetArray.delete(); + %assetArray = new ArrayObject(); //First, Query for our assets @@ -1032,12 +1080,12 @@ function AssetBrowser::doRebuildAssetArray(%this) if(%searchText !$= "Search Assets...") { if(strstr(strlwr(%folderName), strlwr(%searchText)) != -1) - %assetArray.add( %breadcrumbPath, %folderName ); + %assetArray.add( %breadcrumbPath, "Folder" TAB %folderName ); } else { //got it. - %assetArray.add( %breadcrumbPath, %folderName ); + %assetArray.add( %breadcrumbPath, "Folder" TAB %folderName ); } } } @@ -1046,32 +1094,36 @@ function AssetBrowser::doRebuildAssetArray(%this) %category = getWord( %breadcrumbPath, 1 ); %dataGroup = "DataBlockGroup"; - if(%dataGroup.getCount() != 0) + for ( %i = 0; %i < %dataGroup.getCount(); %i++ ) { - %scriptedItem = AssetBrowser-->filterTree.findItemByName("Scripted"); + %obj = %dataGroup.getObject(%i); + // echo ("Obj: " @ %obj.getName() @ " - " @ %obj.category ); - for ( %i = 0; %i < %dataGroup.getCount(); %i++ ) + //if ( %obj.category $= "" && %obj.category == 0 ) + // continue; + + %dbFilename = %obj.getFileName(); + %dbFilePath = filePath(%dbFilename); + + if(%breadcrumbPath $= %dbFilePath) { - %obj = %dataGroup.getObject(%i); - // echo ("Obj: " @ %obj.getName() @ " - " @ %obj.category ); + %dbName = %obj.getName(); + %assetArray.add( %breadcrumbPath, "Datablock" TAB %dbName ); - if ( %obj.category $= "" && %obj.category == 0 ) - continue; + /*%catItem = AssetBrowser-->filterTree.findItemByName(%obj.category); - /*if ( %breadcrumbPath $= "" ) - { - %ctrl = %this.findIconCtrl( %obj.category ); - if ( %ctrl == -1 ) - { - %this.addFolderIcon( %obj.category ); - } - } - else */ - if ( %breadcrumbPath $= %obj.category ) - { - AssetBrowser-->filterTree.insertItem(%scriptedItem, %obj.getName()); - } + if(%catItem == 0) + AssetBrowser-->filterTree.insertItem(%scriptedItem, %obj.category, "scripted");*/ + /*%ctrl = %this.findIconCtrl( %obj.category ); + if ( %ctrl == -1 ) + { + %this.addFolderIcon( %obj.category ); + }*/ } + /*else if ( %breadcrumbPath $= %obj.category ) + { + AssetBrowser-->filterTree.insertItem(%scriptedItem, %obj.getName()); + }*/ } AssetBrowser.currentPreviewPage = 0; diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImport.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImport.cs index 3a76a5ec4..163ddaa7b 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImport.cs +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImport.cs @@ -464,11 +464,15 @@ function importLooseFile(%filePath, %forceAutoImport) %assetItem.moduleName = %targetModule; + %assetName = %assetItem.assetName; + AssetBrowser.dirHandler.currentAddress = filePath(%filePath); //skip the refresh delay, we'll force it here ImportAssetWindow.doRefresh(); + ImportAssetItems.empty(); + if(ImportAssetWindow.hasImportIssues) return false; } @@ -673,7 +677,8 @@ function ImportAssetWindow::doRefresh(%this) %ImportActionSummary = %ImportActionSummary SPC %this.autoRenamedAssets @ " Auto Renamed|"; } - warn(%ImportActionSummary); + if(%ImportActionSummary !$= "") + warn(%ImportActionSummary); AssetImportSummarization.Text = %ImportActionSummary; @@ -1222,7 +1227,7 @@ function ImportAssetWindow::checkAssetsForCollision(%this, %assetItemToCheck, %a } } - return result; + return %result; } // diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImportConfigEditor.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImportConfigEditor.cs index 4975765d3..bd4ca3a30 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImportConfigEditor.cs +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetImportConfigEditor.cs @@ -23,6 +23,11 @@ function AssetImportConfigEditor::refresh(%this) ImportAssetConfigList.setSelected(0); } +function AssetImportConfigEditor::apply(%this) +{ + AssetImportSettings.write(); +} + function AssetImportConfigList::onSelect( %this, %id, %text ) { ImportOptionsConfigList.clearFields(); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/datablockObjects.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/datablockObjects.cs index e69de29bb..cf144c05d 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/datablockObjects.cs +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/datablockObjects.cs @@ -0,0 +1,127 @@ +function AssetBrowser::createNewDatablock(%this) +{ + AssetBrowser_newFolderNameTxt.text = "NewFolder"; + Canvas.pushDialog(AssetBrowser_newFolder); +} + +function AssetBrowser::doCreateNewDatablock(%this) +{ + %newFolderName = AssetBrowser_newFolderNameTxt.getText(); + + if(%newFolderName $= "") + %newFolderName = "NewFolder"; + + %newFolderIdx = ""; + %matched = true; + %newFolderPath = ""; + while(%matched == true) + { + %newFolderPath = AssetBrowser.dirHandler.currentAddress @ "/" @ %newFolderName @ %newFolderIdx; + if(!isDirectory(%newFolderPath)) + { + %matched = false; + } + else + { + %newFolderIdx++; + } + } + + //make a dummy file + %file = new FileObject(); + %file.openForWrite(%newFolderPath @ "/test"); + %file.close(); + + fileDelete(%newFolderPath @ "/test"); + + //refresh the directory + AssetBrowser.loadDirectories(); + + %this.navigateTo(%newFolderPath); +} + +function AssetBrowser::buildDatablockPreview(%this, %assetDef, %previewData) +{ + %previewData.assetName = %assetDef.assetName; + %previewData.assetPath = %assetDef.dirPath; + + %previewData.previewImage = "tools/assetBrowser/art/scriptIcon"; + + //%previewData.assetFriendlyName = %assetDef.assetName; + %previewData.assetDesc = %assetDef.description; + %previewData.tooltip = %assetDef.dirPath; + %previewData.doubleClickCommand = "AssetBrowser.schedule(10, \"navigateTo\",\""@ %assetDef.dirPath @ "/" @ %assetDef.assetName @"\");";//browseTo %assetDef.dirPath / %assetDef.assetName +} + +function AssetBrowser::renameDatablock(%this, %folderPath, %newFolderName) +{ + %fullPath = makeFullPath(%folderPath); + %newFullPath = makeFullPath(%folderPath); + + %fullPath = strreplace(%fullPath, "//", "/"); + + %count = getTokenCount(%fullPath, "/"); + %basePath = getTokens(%fullPath, "/", 0, %count-2); + %oldName = getToken(%fullPath, "/", %count-1); + + //We need to ensure that no files are 'active' while we try and clean up behind ourselves with the delete action + //so, we nix any assets active for the module, do the delete action on the old folder, and then re-acquire our assets. + //This will have the added benefit of updating paths for asset items + + %module = AssetBrowser.dirHandler.getModuleFromAddress(AssetBrowser.dirHandler.currentAddress); + %moduleId = %module.ModuleId; + + AssetDatabase.removeDeclaredAssets(%moduleId); + + %copiedSuccess = %this.dirHandler.copyDatablock(%fullPath, %basePath @ "/" @ %newFolderName); + %this.dirHandler.deleteDatablock(%fullPath); + + %this.loadDirectories(); + + AssetDatabase.addModuleDeclaredAssets(%moduleId); +} + +function AssetBrowser::moveDatablock(%this, %folderPath, %newFolderPath) +{ + %fullPath = makeFullPath(%folderPath); + %newFullPath = makeFullPath(%newFolderPath); + + %fullPath = strreplace(%fullPath, "//", "/"); + %newFullPath = strreplace(%newFullPath, "//", "/"); + + %count = getTokenCount(%fullPath, "/"); + %basePath = getTokens(%fullPath, "/", 0, %count-2); + %oldName = getToken(%fullPath, "/", %count-1); + + %copiedSuccess = %this.dirHandler.copyDatablock(%fullPath, %newFullPath); + %this.dirHandler.deleteDatablock(%fullPath); + + %this.loadDirectories(); + + //thrash the modules and reload them + %oldModule = %this.dirHandler.getModuleFromAddress(%folderPath); + %newModule = %this.dirHandler.getModuleFromAddress(%newFolderPath); + + //if we didn't move modules, then we don't need to do anything other than refresh the assets within it + if(%oldModule == %newModule) + { + //only do a refresh to update asset loose file paths + AssetDatabase.refreshAllAssets(); + } + else + { + //they're different moduels now, so we gotta unload/reload both + ModuleDatabase.unloadExplicit(%oldModule.getModuleId()); + ModuleDatabase.loadExplicit(%oldModule.getModuleId()); + + ModuleDatabase.unloadExplicit(%newModule.getModuleId()); + ModuleDatabase.loadExplicit(%newModule.getModuleId()); + } +} + +function AssetBrowser::deleteDatablock(%this, %folderPath) +{ + %this.dirHandler.deleteDatablock(%folderPath); + + %this.refresh(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.cs index ed74dbc90..28d8ac437 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.cs +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.cs @@ -43,6 +43,18 @@ function AssetBrowser::editMaterialAsset(%this, %assetDef) MaterialEditorGui.setActiveMaterial( %assetDef.materialDefinitionName ); AssetBrowser.hideDialog(); + + // + // + /*%assetDef.materialDefinitionName.reload(); + $Tools::materialEditorList = ""; + EWorldEditor.clearSelection(); + MaterialEditorGui.currentObject = 0; + MaterialEditorGui.currentMode = "asset"; + MaterialEditorGui.currentMaterial = %assetDef.materialDefinitionName; + MaterialEditorGui.setActiveMaterial( %assetDef.materialDefinitionName); + EditorGui.setEditor(MaterialEditorPlugin); + AssetBrowser.hideDialog();*/ } //Renames the asset @@ -424,7 +436,7 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData) %previewData.assetPath = %assetDef.scriptFile; //Lotta prepwork - %previewData.doubleClickCommand = %assetDef@".materialDefinitionName.reload(); " + /*%previewData.doubleClickCommand = %assetDef@".materialDefinitionName.reload(); " @ "$Tools::materialEditorList = \"\";" @ "EWorldEditor.clearSelection();" @ "MaterialEditorGui.currentObject = 0;" @@ -432,7 +444,9 @@ function AssetBrowser::buildMaterialAssetPreview(%this, %assetDef, %previewData) @ "MaterialEditorGui.currentMaterial = "@%assetDef@".materialDefinitionName;" @ "MaterialEditorGui.setActiveMaterial( "@%assetDef@".materialDefinitionName );" @ "EditorGui.setEditor(MaterialEditorPlugin); " - @ "AssetBrowser.hideDialog();"; + @ "AssetBrowser.hideDialog();";*/ + + %previewData.doubleClickCommand = "AssetBrowser.editAsset(" @ %assetDef @ ");"; %test = %assetDef.materialDefinitionName.diffuseMapAsset[0]; diff --git a/Templates/BaseGame/game/tools/settings.xml b/Templates/BaseGame/game/tools/settings.xml index d54773a33..fa508e139 100644 --- a/Templates/BaseGame/game/tools/settings.xml +++ b/Templates/BaseGame/game/tools/settings.xml @@ -1,218 +1,205 @@ - - 50 49 48 255 - 255 255 255 255 - 50 49 48 255 - 72 70 68 255 - 59 58 57 255 - 37 36 35 255 - 234 232 230 255 - 17 16 15 255 - 96 94 92 255 - 50 49 48 255 - 32 31 30 255 - 59 58 57 255 - 236 234 232 255 - 77 77 77 255 - 100 98 96 255 - 178 175 172 255 - 255 255 255 255 - 43 43 43 255 - 72 70 68 255 + + 0 0 1 + 255 255 255 255 + 5 + 0 255 0 255 + 255 0 0 255 + 10 tools/RPGDialogEditor/gui 1024 768 - - 1 - 1 - - 2 - 1 - 1 - 0 - 8 1 - 1 1 - - - ../../../Documentation/Torque 3D - Script Manual.chm - ../../../Documentation/Official Documentation.html - http://www.garagegames.com/products/torque-3d/documentation/user + 1 + 1 + 2 + 1 + 8 + 0 Categorized + + 0 + 0 + 0 + + + ../../../Documentation/Official Documentation.html + http://www.garagegames.com/products/torque-3d/documentation/user + ../../../Documentation/Torque 3D - Script Manual.chm + + + 1 + 1 + 0 - - 0 - 0 - 0 - - FPSGameplay:EmptyLevel,pbr:PbrMatTestLevel,FPSGameplay:EmptyTerrain,TTR:DasBootLevel - 1 - 6 - 50 - screenCenter - AssetWork_Debug.exe FPSGameplay:EmptyLevel - 1 Blank Level + 0 + AssetWork_Debug.exe + FPSGameplay:EmptyLevel,pbr:PbrMatTestLevel,FPSGameplay:EmptyTerrain,TTR:DasBootLevel + 50 WorldEditorInspectorPlugin Modern 40 - 0 - - 8 - 20 - 0 - 255 - 1 - - - ../../../Documentation/Official Documentation.html - http://www.garagegames.com/products/torque-3d/forums - ../../../Documentation/Torque 3D - Script Manual.chm - http://www.garagegames.com/products/torque-3d/documentation/user - - - 100 100 100 255 - 255 255 0 255 - 255 255 0 255 - 255 0 0 255 - 255 255 255 255 - 0 255 0 255 - 0 0 255 255 - - - tools/worldEditor/images/DefaultHandle - tools/worldEditor/images/SelectHandle - tools/worldEditor/images/LockedHandle - - - 1 - 102 102 102 100 - 1 - 51 51 51 100 - 255 255 255 100 + screenCenter + 6 + 1 + 1 + + 48 48 48 255 + 215 215 215 255 + 50 50 50 255 + 255 255 255 255 + 180 180 180 255 - 1 - 0 - 0 100 + 0 + 0.01 + 1 0 0 1 2 - 0.01 - - - 215 215 215 255 - 50 50 50 255 - 180 180 180 255 - 48 48 48 255 - 255 255 255 255 + 0 1 - 1 - 1 - 1 1 + 1 + 1 + 1 + + + tools/worldEditor/images/SelectHandle + tools/worldEditor/images/LockedHandle + tools/worldEditor/images/DefaultHandle + + + 1 + 8 + 20 + 0 + 255 + + + 0 0 255 255 + 255 255 0 255 + 100 100 100 255 + 0 255 0 255 + 255 255 0 255 + 255 255 255 255 + 255 0 0 255 + + + 102 102 102 100 + 1 + 51 51 51 100 + 255 255 255 100 + 1 + + + ../../../Documentation/Official Documentation.html + ../../../Documentation/Torque 3D - Script Manual.chm + http://www.garagegames.com/products/torque-3d/forums + http://www.garagegames.com/products/torque-3d/documentation/user Classic + + 1 + 255 255 255 255 + 45 + 0 + 0 0 0 100 + 1 + 1 + 0 + 135 + 1 + 0.1 + 1 + 180 180 180 255 + 40 40 + 1 + - 100 - 15 0.8 - 0 - 1 - 0 0.8 + 0 + 100 + 1 + 15 + 0 - 0 - 0 - 255 255 255 20 - 1 - 1 500 + 1 + 0 1 1 1 + 255 255 255 20 + 0 + 1 - - 255 0 0 255 - 5 + + Small + + 0 0 1 10 + 255 0 0 255 + DefaultRoadMaterialOther 0 255 0 255 - 255 255 255 255 - - - 1 - - - 1 - 1 - 0.1 - 135 - 180 180 180 255 - 45 - 1 - 40 40 - 1 - 1 - 0 - 255 255 255 255 - 0 - 1 - 0 0 0 100 - - - <AssetType>/ - <AssetType>/ - 1 - <AssetType>/<SpecialAssetTag>/ - <AssetType>/ - <AssetType>/OtherFolder/ - TestConfig - <AssetType>/<AssetName>/ - <AssetType>/<SpecialAssetTag>/ - <AssetType>/ - <AssetType>/ + DefaultRoadMaterialTop lowerHeight + 1 + ellipse + 1 40 40 40 40 - ellipse - 1 - 1 - 0.1 + 0 100 1.000000 0.833333 0.666667 0.500000 0.333333 0.166667 0.000000 - 0 - 1.000000 0.833333 0.666667 0.500000 0.333333 0.166667 0.000000 - 50 - 1 - 10 - 90 1 + 90 + 50 + 10 + 1.000000 0.833333 0.666667 0.500000 0.333333 0.166667 0.000000 + 1 + 0.1 + + <AssetType>/ + <AssetType>/ + 1 + TestConfig + <AssetType>/<AssetName>/ + <AssetType>/<SpecialAssetTag>/ + <AssetType>/ + <AssetType>/<SpecialAssetTag>/ + <AssetType>/ + <AssetType>/OtherFolder/ + <AssetType>/ + data/FPSGameplay/levels @@ -230,36 +217,49 @@ - - 255 0 0 255 - DefaultRoadMaterialTop - 0 255 0 255 - 10 - 0 0 1 - DefaultRoadMaterialOther - - - DefaultDecalRoadMaterial - 255 255 255 255 - 10 - 0 255 0 255 - - - AIPlayer - 1 - DefaultPlayerData - - - Grid_512_Orange - - 0 TestConfig + 1 small - - Small + + 1 + DefaultPlayerData + AIPlayer + + + 255 255 255 255 + DefaultDecalRoadMaterial + 0 255 0 255 + 10 + + + 96 94 92 255 + 100 98 96 255 + 234 232 230 255 + 59 58 57 255 + 50 49 48 255 + 50 49 48 255 + 32 31 30 255 + 17 16 15 255 + 59 58 57 255 + 50 49 48 255 + 77 77 77 255 + 43 43 43 255 + 72 70 68 255 + 178 175 172 255 + 72 70 68 255 + 37 36 35 255 + 236 234 232 255 + 255 255 255 255 + 255 255 255 255 + + + 1 + + + Grid_512_Orange diff --git a/Templates/BaseGame/game/tools/shapeEditor/main.cs b/Templates/BaseGame/game/tools/shapeEditor/main.cs index c511c245b..dd0100c4c 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/main.cs +++ b/Templates/BaseGame/game/tools/shapeEditor/main.cs @@ -151,6 +151,13 @@ function ShapeEditorPlugin::openShapeAsset(%this, %assetDef) %this.open(%this.selectedAssetDef.fileName); } +function ShapeEditorPlugin::openShapeAssetId(%this, %assetId) +{ + %this.selectedAssetDef = AssetDatabase.acquireAsset(%assetId); + //%this.selectedAssetDef = %assetDef; + %this.open(%this.selectedAssetDef.fileName); +} + function ShapeEditorPlugin::open(%this, %filename) { if ( !%this.isActivated )