diff --git a/Engine/source/CMakeLists.txt b/Engine/source/CMakeLists.txt index b800d7981..f5ff160b7 100644 --- a/Engine/source/CMakeLists.txt +++ b/Engine/source/CMakeLists.txt @@ -150,6 +150,12 @@ endif (TORQUE_OPENGL) # Handle terrain torqueAddSourceDirectories("terrain") +# Handle theora +if (TORQUE_THEORA) + torqueAddSourceDirectories("core/ogg") + torqueAddSourceDirectories("gui/theora") +endif(TORQUE_THEORA) + if (WIN32 AND TORQUE_D3D11) torqueAddSourceDirectories("terrain/hlsl") endif (WIN32 AND TORQUE_D3D11) @@ -337,6 +343,10 @@ addDef(TORQUE_ENABLE_ASSERTS "Debug;RelWithDebInfo") addDef(TORQUE_DEBUG_GFX_MODE "RelWithDebInfo") addDef(TORQUE_OGGVORBIS) +if (TORQUE_THEORA) + addDef(TORQUE_OGGTHEORA) +endif(TORQUE_THEORA) + if(NOT TORQUE_SDL) filterOut("platform/nativeDialogs/fileDialog.cpp" ) endif() @@ -430,6 +440,8 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON) foreach (TORQUE_LIBRARY ${TORQUE_LINK_LIBRARIES}) set_target_properties(${TORQUE_LIBRARY} PROPERTIES FOLDER "Libraries") + # remove warnings from 3rd parties. + target_compile_options(${TORQUE_LIBRARY} PRIVATE "-w") endforeach() target_compile_definitions(${TORQUE_APP_NAME} PUBLIC ${TORQUE_COMPILE_DEFINITIONS}) diff --git a/Engine/source/T3D/fx/particleEmitter.h b/Engine/source/T3D/fx/particleEmitter.h index 49a11c906..b11e53ce8 100644 --- a/Engine/source/T3D/fx/particleEmitter.h +++ b/Engine/source/T3D/fx/particleEmitter.h @@ -238,7 +238,7 @@ class ParticleEmitter : public GameBase const LinearColorF &ambientColor, ParticleVertexType *lVerts ); - inline void setupOriented( Particle *part, + void setupOriented( Particle *part, const Point3F &camPos, const LinearColorF &ambientColor, ParticleVertexType *lVerts ); diff --git a/Engine/source/T3D/guiObjectView.cpp b/Engine/source/T3D/guiObjectView.cpp index 1fb8451f5..9dfc13a5d 100644 --- a/Engine/source/T3D/guiObjectView.cpp +++ b/Engine/source/T3D/guiObjectView.cpp @@ -91,7 +91,7 @@ IMPLEMENT_CALLBACK( GuiObjectView, onMouseLeave, void, (),(), GuiObjectView::GuiObjectView() : mMouseState( None ), mLastMousePoint( 0, 0 ), - mModel( NULL ), + mModelInstance(NULL), mMaxOrbitDist( 5.0f ), mMinOrbitDist( 0.0f ), mCameraRotation( 0.0f, 0.0f, 0.0f ), @@ -99,13 +99,13 @@ GuiObjectView::GuiObjectView() mCameraSpeed( 0.01f ), mMountNode( -1 ), mMountNodeName( "mount0" ), - mMountedModel( NULL ), + mMountedModelInstance( NULL ), mAnimationSeq( -1 ), mRunThread( NULL ), mLastRenderTime( 0 ), mLight( NULL ), mLightColor( 1.0f, 1.0f, 1.0f ), - mLightAmbient( 0.5f, 0.5f, 0.5f ), + mLightAmbient( 1.0f, 1.0f, 1.0f ), mLightDirection( 0.f, 0.707f, -0.707f ) { mCameraMatrix.identity(); @@ -117,16 +117,14 @@ GuiObjectView::GuiObjectView() // By default don't do dynamic reflection // updates for this viewport. mReflectPriority = 0.0f; + INIT_ASSET(Model); + INIT_ASSET(MountedModel); } //------------------------------------------------------------------------------ GuiObjectView::~GuiObjectView() { - if( mModel ) - SAFE_DELETE( mModel ); - if( mMountedModel ) - SAFE_DELETE( mMountedModel ); if( mLight ) SAFE_DELETE( mLight ); } @@ -136,13 +134,10 @@ GuiObjectView::~GuiObjectView() void GuiObjectView::initPersistFields() { docsURL; - addGroup( "Model" ); - - addField( "shapeFile", TypeStringFilename, Offset( mModelName, GuiObjectView ), - "The object model shape file to show in the view." ); + addGroup( "Model" ); + INITPERSISTFIELD_SHAPEASSET(Model, GuiObjectView, "The source shape asset."); addField( "skin", TypeRealString, Offset( mSkinName, GuiObjectView ), - "The skin to use on the object model." ); - + "The skin to use on the object model." ); endGroup( "Model" ); addGroup( "Animation" ); @@ -152,10 +147,8 @@ void GuiObjectView::initPersistFields() endGroup( "Animation" ); - addGroup( "Mounting" ); - - addField( "mountedShapeFile", TypeStringFilename, Offset( mMountedModelName, GuiObjectView ), - "Optional shape file to mount on the primary model (e.g. weapon)." ); + addGroup( "Mounting" ); + INITPERSISTFIELD_SHAPEASSET(MountedModel, GuiObjectView, "The mounted shape asset."); addField( "mountedSkin", TypeRealString, Offset( mMountSkinName, GuiObjectView ), "Skin name used on mounted shape file." ); addField( "mountedNode", TypeRealString, Offset( mMountNodeName, GuiObjectView ), @@ -197,9 +190,7 @@ void GuiObjectView::onStaticModified( StringTableEntry slotName, const char* new { Parent::onStaticModified( slotName, newValue ); - static StringTableEntry sShapeFile = StringTable->insert( "shapeFile" ); static StringTableEntry sSkin = StringTable->insert( "skin" ); - static StringTableEntry sMountedShapeFile = StringTable->insert( "mountedShapeFile" ); static StringTableEntry sMountedSkin = StringTable->insert( "mountedSkin" ); static StringTableEntry sMountedNode = StringTable->insert( "mountedNode" ); static StringTableEntry sLightColor = StringTable->insert( "lightColor" ); @@ -211,12 +202,8 @@ void GuiObjectView::onStaticModified( StringTableEntry slotName, const char* new static StringTableEntry sCameraRotation = StringTable->insert( "cameraRotation" ); static StringTableEntry sAnimSequence = StringTable->insert( "animSequence" ); - if( slotName == sShapeFile ) - setObjectModel( String( mModelName ) ); - else if( slotName == sSkin ) + if( slotName == sSkin ) setSkin( String( mSkinName ) ); - else if( slotName == sMountedShapeFile ) - setMountedObject( String( mMountedModelName ) ); else if( slotName == sMountedSkin ) setMountSkin( String( mMountSkinName ) ); else if( slotName == sMountedNode ) @@ -325,7 +312,7 @@ void GuiObjectView::setObjectAnimation( S32 index ) mAnimationSeq = index; mAnimationSeqName = String(); - if( mModel ) + if(mModelInstance) _initAnimation(); } @@ -336,107 +323,123 @@ void GuiObjectView::setObjectAnimation( const String& sequenceName ) mAnimationSeq = -1; mAnimationSeqName = sequenceName; - if( mModel ) + if(mModelInstance) _initAnimation(); } //------------------------------------------------------------------------------ -void GuiObjectView::setObjectModel( const String& modelName ) +bool GuiObjectView::setObjectModel( const String& modelName ) { - SAFE_DELETE( mModel ); mRunThread = 0; - mModelName = String::EmptyString; - - // Load the shape. - Resource< TSShape > model = ResourceManager::get().load( modelName ); - if( !model ) + // Load the shape. + _setModel(modelName); + if( !getModelResource()) { Con::warnf( "GuiObjectView::setObjectModel - Failed to load model '%s'", modelName.c_str() ); - return; + return false; } - + + if (!getModelResource()->preloadMaterialList(getModelResource().getPath())) return false; + // Instantiate it. - mModel = new TSShapeInstance( model, true ); - mModelName = modelName; + mModelInstance = new TSShapeInstance(getModelResource(), true ); + mModelInstance->resetMaterialList(); + mModelInstance->cloneMaterialList(); if( !mSkinName.isEmpty() ) - mModel->reSkin( mSkinName ); + mModelInstance->reSkin( mSkinName ); + TSMaterialList* pMatList = mModelInstance->getMaterialList(); + pMatList->setTextureLookupPath(mModelAsset->getShapeFileName()); + mModelInstance->initMaterialList(); // Initialize camera values. - mOrbitPos = mModel->getShape()->center; - mMinOrbitDist = mModel->getShape()->mRadius; + mOrbitPos = getModelResource()->center; + mMinOrbitDist = getModelResource()->mRadius; // Initialize animation. _initAnimation(); _initMount(); + return true; +} + +void GuiObjectView::onModelChanged() +{ + } //------------------------------------------------------------------------------ void GuiObjectView::setSkin( const String& name ) { - if( mModel ) - mModel->reSkin( name, mSkinName ); + if(mModelInstance) + mModelInstance->reSkin( name, mSkinName ); mSkinName = name; } + //------------------------------------------------------------------------------ -void GuiObjectView::setMountSkin( const String& name ) +bool GuiObjectView::setMountedObject( const String& modelName ) { - if( mMountedModel ) - mMountedModel->reSkin( name, mMountSkinName ); - + // Load the model. + _setMountedModel(modelName); + if (!getMountedModelResource()) + { + Con::warnf("GuiObjectView::setMountedObject - Failed to load model '%s'", modelName.c_str()); + return false; + } + + if (!getMountedModelResource()->preloadMaterialList(getMountedModelResource().getPath())) return false; + + mMountedModelInstance = new TSShapeInstance(getMountedModelResource(), true); + mMountedModelInstance->resetMaterialList(); + mMountedModelInstance->cloneMaterialList(); + + if( !mMountSkinName.isEmpty() ) + mMountedModelInstance->reSkin( mMountSkinName ); + + mMountedModelInstance->initMaterialList(); + + if(mMountedModelInstance) + _initMount(); + return true; +} + +void GuiObjectView::onMountedModelChanged() +{ + +} + +//------------------------------------------------------------------------------ + +void GuiObjectView::setMountSkin(const String& name) +{ + if (mMountedModelInstance) + mMountedModelInstance->reSkin(name, mMountSkinName); + mMountSkinName = name; } //------------------------------------------------------------------------------ -void GuiObjectView::setMountNode( S32 index ) +void GuiObjectView::setMountNode(S32 index) { - setMountNode( String::ToString( "mount%i", index ) ); + setMountNode(String::ToString("mount%i", index)); } //------------------------------------------------------------------------------ -void GuiObjectView::setMountNode( const String& name ) +void GuiObjectView::setMountNode(const String& name) { mMountNodeName = name; - - if( mModel ) - _initMount(); -} -//------------------------------------------------------------------------------ - -void GuiObjectView::setMountedObject( const String& modelName ) -{ - SAFE_DELETE( mMountedModel ); - mMountedModelName = String::EmptyString; - - // Load the model. - - Resource< TSShape > model = ResourceManager::get().load( modelName ); - if( !model ) - { - Con::warnf( "GuiObjectView::setMountedObject - Failed to load object model '%s'", - modelName.c_str() ); - return; - } - - mMountedModel = new TSShapeInstance( model, true ); - mMountedModelName = modelName; - - if( !mMountSkinName.isEmpty() ) - mMountedModel->reSkin( mMountSkinName ); - - if( mModel ) + if (mModelInstance) _initMount(); } @@ -483,7 +486,7 @@ void GuiObjectView::onMouseLeave( const GuiEvent & event ) void GuiObjectView::renderWorld( const RectI& updateRect ) { - if( !mModel ) + if( !mModelInstance) return; GFXTransformSaver _saveTransforms; @@ -538,26 +541,26 @@ void GuiObjectView::renderWorld( const RectI& updateRect ) // Render primary model. - if( mModel ) + if(mModelInstance) { if( mRunThread ) { - mModel->advanceTime( dt / 1000.f, mRunThread ); - mModel->animate(); + mModelInstance->advanceTime( dt / 1000.f, mRunThread ); + mModelInstance->animate(); } - mModel->render( rdata ); + mModelInstance->render( rdata ); } // Render mounted model. - if( mMountedModel && mMountNode != -1 ) + if( mMountedModelInstance && mMountNode != -1 ) { GFX->pushWorldMatrix(); - GFX->multWorld( mModel->mNodeTransforms[ mMountNode ] ); + GFX->multWorld(mModelInstance->mNodeTransforms[ mMountNode ] ); GFX->multWorld( mMountTransform ); - mMountedModel->render( rdata ); + mMountedModelInstance->render( rdata ); GFX->popWorldMatrix(); } @@ -620,7 +623,7 @@ void GuiObjectView::setLightDirection( const Point3F& direction ) void GuiObjectView::_initAnimation() { - AssertFatal( mModel, "GuiObjectView::_initAnimation - No model loaded!" ); + AssertFatal(getModelResource(), "GuiObjectView::_initAnimation - No model loaded!" ); if( mAnimationSeqName.isEmpty() && mAnimationSeq == -1 ) return; @@ -629,7 +632,7 @@ void GuiObjectView::_initAnimation() if( !mAnimationSeqName.isEmpty() ) { - mAnimationSeq = mModel->getShape()->findSequence( mAnimationSeqName ); + mAnimationSeq = getModelResource()->findSequence( mAnimationSeqName ); if( mAnimationSeq == -1 ) { @@ -646,7 +649,7 @@ void GuiObjectView::_initAnimation() if( mAnimationSeq != -1 ) { - if( mAnimationSeq >= mModel->getShape()->sequences.size() ) + if( mAnimationSeq >= getModelResource()->sequences.size() ) { Con::errorf( "GuiObjectView::_initAnimation - Sequence '%i' out of range for model '%s'", mAnimationSeq, @@ -658,9 +661,9 @@ void GuiObjectView::_initAnimation() } if( !mRunThread ) - mRunThread = mModel->addThread(); + mRunThread = mModelInstance->addThread(); - mModel->setSequence( mRunThread, mAnimationSeq, 0.f ); + mModelInstance->setSequence( mRunThread, mAnimationSeq, 0.f ); } mLastRenderTime = Platform::getVirtualMilliseconds(); @@ -670,9 +673,9 @@ void GuiObjectView::_initAnimation() void GuiObjectView::_initMount() { - AssertFatal( mModel, "GuiObjectView::_initMount - No model loaded!" ); + AssertFatal(mModelInstance, "GuiObjectView::_initMount - No model loaded!" ); - if( !mMountedModel ) + if( !mModelInstance) return; mMountTransform.identity(); @@ -681,7 +684,7 @@ void GuiObjectView::_initMount() if( !mMountNodeName.isEmpty() ) { - mMountNode = mModel->getShape()->findNode( mMountNodeName ); + mMountNode = getModelResource()->findNode( mMountNodeName ); if( mMountNode == -1 ) { Con::errorf( "GuiObjectView::_initMount - No node '%s' on '%s'", @@ -695,7 +698,7 @@ void GuiObjectView::_initMount() // Make sure mount node is valid. - if( mMountNode != -1 && mMountNode >= mModel->getShape()->nodes.size() ) + if( mMountNode != -1 && mMountNode >= getModelResource()->nodes.size() ) { Con::errorf( "GuiObjectView::_initMount - Mount node index '%i' out of range for '%s'", mMountNode, @@ -708,11 +711,11 @@ void GuiObjectView::_initMount() // Look up node on the mounted model from // which to mount to the primary model's node. - - S32 mountPoint = mMountedModel->getShape()->findNode( "mountPoint" ); + if (!getMountedModelResource()) return; + S32 mountPoint = getMountedModelResource()->findNode( "mountPoint" ); if( mountPoint != -1 ) { - mMountedModel->getShape()->getNodeWorldTransform( mountPoint, &mMountTransform ), + getMountedModelResource()->getNodeWorldTransform(mountPoint, &mMountTransform), mMountTransform.inverse(); } } @@ -733,12 +736,12 @@ DefineEngineMethod( GuiObjectView, getModel, const char*, (),, "@return Name of the displayed model.\n\n" "@see GuiControl") { - return Con::getReturnBuffer( object->getModelName() ); + return Con::getReturnBuffer( object->getModel() ); } //----------------------------------------------------------------------------- -DefineEngineMethod( GuiObjectView, setModel, void, (const char* shapeName),, +DefineEngineMethod( GuiObjectView, setModel, bool, (const char* shapeName),, "@brief Sets the model to be displayed in this control.\n\n" "@param shapeName Name of the model to display.\n" "@tsexample\n" @@ -749,7 +752,7 @@ DefineEngineMethod( GuiObjectView, setModel, void, (const char* shapeName),, "@endtsexample\n\n" "@see GuiControl") { - object->setObjectModel( shapeName ); + return object->setObjectModel( shapeName ); } //----------------------------------------------------------------------------- @@ -763,7 +766,7 @@ DefineEngineMethod( GuiObjectView, getMountedModel, const char*, (),, "@return Name of the mounted model.\n\n" "@see GuiControl") { - return Con::getReturnBuffer( object->getMountedModelName() ); + return Con::getReturnBuffer( object->getMountedModel() ); } //----------------------------------------------------------------------------- diff --git a/Engine/source/T3D/guiObjectView.h b/Engine/source/T3D/guiObjectView.h index ff84ff111..faeb06531 100644 --- a/Engine/source/T3D/guiObjectView.h +++ b/Engine/source/T3D/guiObjectView.h @@ -69,12 +69,17 @@ class GuiObjectView : public GuiTSCtrl /// @name Model /// @{ - /// Name of the model loaded for display. - StringTableEntry mModelName; - - /// Model being displayed in the view. - TSShapeInstance* mModel; - + ///Model loaded for display. + DECLARE_SHAPEASSET(GuiObjectView, Model, onModelChanged); + static bool _setModelData(void* obj, const char* index, const char* data)\ + { + bool ret = false; + GuiObjectView* object = static_cast(obj); + ret = object->setObjectModel(StringTable->insert(data)); + return ret; + } + void onModelChanged(); + TSShapeInstance* mModelInstance; /// Name of skin to use on model. String mSkinName; @@ -103,8 +108,17 @@ class GuiObjectView : public GuiTSCtrl /// @name Mounting /// @{ - /// Name of model to mount to the primary model. - String mMountedModelName; + ///Model to mount to the primary model. + DECLARE_SHAPEASSET(GuiObjectView, MountedModel, onMountedModelChanged); + static bool _setMountedModelData(void* obj, const char* index, const char* data)\ + { + bool ret = false; + GuiObjectView* object = static_cast(obj); + ret = object->setMountedObject(StringTable->insert(data)); + return ret; + } + void onMountedModelChanged(); + TSShapeInstance* mMountedModelInstance; /// String mMountSkinName; @@ -114,9 +128,6 @@ class GuiObjectView : public GuiTSCtrl /// Name of node to mount the secondary model to. Unset by default. String mMountNodeName; - - /// Model mounted as an image to the primary model. - TSShapeInstance* mMountedModel; /// MatrixF mMountTransform; @@ -173,13 +184,7 @@ class GuiObjectView : public GuiTSCtrl /// @name Model /// @{ - - /// - const String& getModelName() const { return mModelName; } - - /// Return the instance of the model being rendered in the view. - TSShapeInstance* getModel() const { return mModel; } - + /// Return the name of the skin used on the primary model. const String& getSkin() const { return mSkinName; } @@ -187,7 +192,7 @@ class GuiObjectView : public GuiTSCtrl void setSkin( const String& name ); /// Set the model to show in this view. - void setObjectModel( const String& modelName ); + bool setObjectModel( const String& modelName ); /// @} @@ -206,13 +211,7 @@ class GuiObjectView : public GuiTSCtrl /// @name Mounting /// @{ - - /// Return the model mounted to the current primary model; NULL if none. - TSShapeInstance* getMountedModel() const { return mMountedModel; } - - /// - const String& getMountedModelName() const { return mMountedModelName; } - + /// Return the name of the skin used on the mounted model. const String& getMountSkin() const { return mMountSkinName; } @@ -226,7 +225,7 @@ class GuiObjectView : public GuiTSCtrl void setMountNode( const String& nodeName ); /// - void setMountedObject( const String& modelName ); + bool setMountedObject( const String& modelName ); /// @} diff --git a/Engine/source/T3D/lighting/reflectionProbe.cpp b/Engine/source/T3D/lighting/reflectionProbe.cpp index f993b795c..57f6e9485 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.cpp +++ b/Engine/source/T3D/lighting/reflectionProbe.cpp @@ -184,6 +184,10 @@ void ReflectionProbe::initPersistFields() "@note Only works for shadow mapped lights.\n\n" "@ingroup Lighting"); + Con::addVariable("$Probes::Capturing", TypeBool, &RenderProbeMgr::smBakeReflectionProbes, + "Toggles probe rendering capture state.\n\n" + "@ingroup Lighting"); + Con::addVariable("$Light::renderPreviewProbes", TypeBool, &ReflectionProbe::smRenderPreviewProbes, "Toggles rendering of light frustums when the light is selected in the editor.\n\n" "@note Only works for shadow mapped lights.\n\n" @@ -793,7 +797,9 @@ void ReflectionProbe::bake() if (mReflectionModeType != BakedCubemap) return; + PROBEMGR->preBake(); PROBEMGR->bakeProbe(this); + PROBEMGR->postBake(); setMaskBits(-1); } @@ -823,7 +829,7 @@ void ReflectionProbe::createEditorResources() void ReflectionProbe::prepRenderImage(SceneRenderState *state) { - if (!mEnabled || (!RenderProbeMgr::smRenderReflectionProbes && !dStrcmp(Con::getVariable("$Probes::Capturing", "0"),"1"))) + if (!mEnabled || (!RenderProbeMgr::smRenderReflectionProbes || RenderProbeMgr::smBakeReflectionProbes)) return; Point3F distVec = getRenderPosition() - state->getCameraPosition(); diff --git a/Engine/source/console/persistenceManager.cpp b/Engine/source/console/persistenceManager.cpp index b7dfb97f5..630dad448 100644 --- a/Engine/source/console/persistenceManager.cpp +++ b/Engine/source/console/persistenceManager.cpp @@ -1358,7 +1358,7 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj const AbstractClassRep::Field* f = &list[i]; // Skip the special field types. - if ( f->type >= AbstractClassRep::ARCFirstCustomField ) + if ( f->type >= AbstractClassRep::ARCFirstCustomField || f->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors)) continue; for(U32 j = 0; S32(j) < f->elementCount; j++) diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index 0b887cb08..38780df02 100644 --- a/Engine/source/console/simObject.cpp +++ b/Engine/source/console/simObject.cpp @@ -328,7 +328,7 @@ void SimObject::writeFields(Stream &stream, U32 tabStop) const AbstractClassRep::Field* f = &list[i]; // Skip the special field types. - if ( f->type >= AbstractClassRep::ARCFirstCustomField ) + if ( f->type >= AbstractClassRep::ARCFirstCustomField || f->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors)) continue; for(U32 j = 0; S32(j) < f->elementCount; j++) @@ -924,7 +924,7 @@ void SimObject::assignFieldsFrom(SimObject *parent) continue; // Skip the special field types. - if ( f->type >= AbstractClassRep::ARCFirstCustomField ) + if ( f->type >= AbstractClassRep::ARCFirstCustomField || f->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors)) continue; // Skip certain fields that we don't want to see copied so we don't @@ -3266,7 +3266,7 @@ DefineEngineMethod( SimObject, getFieldCount, S32, (),, f = &list[i]; // The special field types do not need to be counted. - if ( f->type >= AbstractClassRep::ARCFirstCustomField ) + if ( f->type >= AbstractClassRep::ARCFirstCustomField || f->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors)) numDummyEntries++; } @@ -3291,7 +3291,7 @@ DefineEngineMethod( SimObject, getField, const char*, ( S32 index ),, f = &list[i]; // The special field types can be skipped. - if ( f->type >= AbstractClassRep::ARCFirstCustomField ) + if ( f->type >= AbstractClassRep::ARCFirstCustomField || f->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors)) continue; if(currentField == index) diff --git a/Engine/source/console/simSerialize.cpp b/Engine/source/console/simSerialize.cpp index 6a7a84b17..c87033265 100644 --- a/Engine/source/console/simSerialize.cpp +++ b/Engine/source/console/simSerialize.cpp @@ -48,7 +48,7 @@ bool SimObject::writeObject(Stream *stream) for(itr = fieldList.begin();itr != fieldList.end();itr++) { - if( itr->type >= AbstractClassRep::ARCFirstCustomField ) + if( itr->type >= AbstractClassRep::ARCFirstCustomField || itr->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors)) { numFields--; continue; diff --git a/Engine/source/environment/scatterSky.cpp b/Engine/source/environment/scatterSky.cpp index 9869bf4a7..0d7bb727b 100644 --- a/Engine/source/environment/scatterSky.cpp +++ b/Engine/source/environment/scatterSky.cpp @@ -921,6 +921,13 @@ void ScatterSky::_initMoon() features.removeFeature(MFT_ReflectionProbes); features.addFeature(MFT_isBackground); mMoonMatInst = MATMGR->createMatInstance(mMoonMatAsset->getMaterialDefinitionName(), features, getGFXVertexFormat()); + + GFXStateBlockDesc desc; + desc.setBlend(true); + desc.setAlphaTest(true); + desc.setZReadWrite(true, false); + mMoonMatInst->addStateBlockDesc(desc); + mMoonMatInst->init(features, getGFXVertexFormat()); } } diff --git a/Engine/source/environment/skySphere.cpp b/Engine/source/environment/skySphere.cpp index 2b755722d..7f8cf6618 100644 --- a/Engine/source/environment/skySphere.cpp +++ b/Engine/source/environment/skySphere.cpp @@ -183,7 +183,7 @@ void SkySphere::prepRenderImage(SceneRenderState* state) ObjectRenderInst* ri = state->getRenderPass()->allocInst(); ri->renderDelegate.bind(this, &SkySphere::_renderObject); ri->type = RenderPassManager::RIT_Sky; - ri->defaultKey = 9; + ri->defaultKey = 10; ri->defaultKey2 = 0; state->getRenderPass()->addInst(ri); } @@ -196,10 +196,7 @@ void SkySphere::_renderObject(ObjectRenderInst* ri, SceneRenderState* state, Bas GFX->setVertexBuffer(mVB); MatrixF worldMat = MatrixF::Identity; - worldMat.setPosition(Point3F( - state->getCameraPosition().x, - state->getCameraPosition().y, - state->getCameraPosition().z)); + worldMat.setPosition(state->getCameraPosition()); SceneData sgData; sgData.init(state); @@ -602,7 +599,7 @@ void SkySphere::_initMaterial() desc.setCullMode(GFXCullNone); desc.setBlend(true); desc.setZReadWrite(true, false); - desc.zFunc = GFXCmpLessEqual; + desc.zFunc = GFXCmpGreaterEqual; mMatInstance->addStateBlockDesc(desc); // Also disable lighting on the skysphere material by default. diff --git a/Engine/source/environment/sun.cpp b/Engine/source/environment/sun.cpp index c7ffefa05..615337a1f 100644 --- a/Engine/source/environment/sun.cpp +++ b/Engine/source/environment/sun.cpp @@ -41,6 +41,7 @@ #include "materials/baseMatInstance.h" #include "materials/sceneData.h" #include "math/util/matrixSet.h" +#include "materials/materialFeatureTypes.h" IMPLEMENT_CO_NETOBJECT_V1(Sun); @@ -454,7 +455,21 @@ void Sun::_initCorona() if (mCoronaMaterialAsset.notNull()) { - mCoronaMatInst = MATMGR->createMatInstance(mCoronaMaterialAsset->getMaterialDefinitionName(), MATMGR->getDefaultFeatures(), getGFXVertexFormat()); + FeatureSet features = MATMGR->getDefaultFeatures(); + features.removeFeature(MFT_RTLighting); + features.removeFeature(MFT_Visibility); + features.removeFeature(MFT_ReflectionProbes); + features.addFeature(MFT_isBackground); + features.addFeature(MFT_VertLit); + + mCoronaMatInst = MATMGR->createMatInstance(mCoronaMaterialAsset->getMaterialDefinitionName(), features, getGFXVertexFormat()); + + GFXStateBlockDesc desc; + desc.setBlend(true); + desc.setAlphaTest(true); + desc.setZReadWrite(true, false); + mCoronaMatInst->addStateBlockDesc(desc); + mCoronaMatInst->init(features, getGFXVertexFormat()); } } diff --git a/Engine/source/gfx/gl/gfxGLShader.cpp b/Engine/source/gfx/gl/gfxGLShader.cpp index 8595a96d4..c8366ed56 100644 --- a/Engine/source/gfx/gl/gfxGLShader.cpp +++ b/Engine/source/gfx/gl/gfxGLShader.cpp @@ -1109,9 +1109,12 @@ bool GFXGLShader::initShader( const Torque::Path &file, return false; } - if ( !_loadShaderFromStream( activeShader, file, &stream, macros ) ) + if (!_loadShaderFromStream(activeShader, file, &stream, macros)) + { + if (smLogErrors) + Con::errorf("GFXGLShader::initShader - unable to load shader from stream: '%s'.", file.getFullPath().c_str()); return false; - + } GLint compile; glGetShaderiv(activeShader, GL_COMPILE_STATUS, &compile); @@ -1119,17 +1122,13 @@ bool GFXGLShader::initShader( const Torque::Path &file, U32 logLength = 0; glGetShaderiv(activeShader, GL_INFO_LOG_LENGTH, (GLint*)&logLength); - GLint compileStatus = GL_TRUE; if ( logLength ) { FrameAllocatorMarker fam; char* log = (char*)fam.alloc(logLength); glGetShaderInfoLog(activeShader, logLength, NULL, log); - // Always print errors - glGetShaderiv( activeShader, GL_COMPILE_STATUS, &compileStatus ); - - if ( compileStatus == GL_FALSE ) + if (compile == GL_FALSE ) { if ( smLogErrors ) { @@ -1141,7 +1140,7 @@ bool GFXGLShader::initShader( const Torque::Path &file, Con::warnf( "Program %s: %s", file.getFullPath().c_str(), log ); } - return compileStatus != GL_FALSE; + return compile != GL_FALSE; } /// Returns our list of shader constants, the material can get this and just set the constants it knows about diff --git a/Engine/source/gfx/video/theoraTexture.cpp b/Engine/source/gfx/video/theoraTexture.cpp index 1b85837b7..e69958d80 100644 --- a/Engine/source/gfx/video/theoraTexture.cpp +++ b/Engine/source/gfx/video/theoraTexture.cpp @@ -59,7 +59,7 @@ /// Profile for the video texture. GFX_ImplementTextureProfile( GFXTheoraTextureProfile, GFXTextureProfile::DiffuseMap, - GFXTextureProfile::NoMipmap | GFXTextureProfile::Dynamic, + GFXTextureProfile::NoMipmap | GFXTextureProfile::Dynamic | GFXTextureProfile::PreserveSize, GFXTextureProfile::NONE ); diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index 0f1ce87f6..954d199e2 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -59,6 +59,8 @@ RenderProbeMgr *RenderProbeMgr::smProbeManager = NULL; // This variable is a global toggle on if reflection probes should be rendered or not bool RenderProbeMgr::smRenderReflectionProbes = true; +bool RenderProbeMgr::smBakeReflectionProbes = false; + // This variable defines the maximum draw distance of a probe. F32 RenderProbeMgr::smMaxProbeDrawDistance = 100; @@ -500,19 +502,50 @@ void RenderProbeMgr::reloadTextures() void RenderProbeMgr::preBake() { - Con::setVariable("$Probes::Capturing", "1"); + RenderProbeMgr::smBakeReflectionProbes = true; + GFXShader::addGlobalMacro("CAPTURING", String("1")); + + //Con::setVariable("$Probes::Capturing", "1"); mRenderMaximumNumOfLights = AdvancedLightBinManager::smMaximumNumOfLights; mRenderUseLightFade = AdvancedLightBinManager::smUseLightFade; AdvancedLightBinManager::smMaximumNumOfLights = -1; AdvancedLightBinManager::smUseLightFade = false; + + //kickstart rendering + LightManager* lm = LIGHTMGR; + if (lm) + { + SceneManager* sm = lm->getSceneManager(); + if (sm && sm->getContainer() == &gClientContainer) + { + lm->deactivate(); + lm->activate(sm); + } + } } + void RenderProbeMgr::postBake() { - Con::setVariable("$Probes::Capturing", "0"); + RenderProbeMgr::smBakeReflectionProbes = false; + GFXShader::addGlobalMacro("CAPTURING", String("0")); + //Con::setVariable("$Probes::Capturing", "0"); AdvancedLightBinManager::smMaximumNumOfLights = mRenderMaximumNumOfLights; AdvancedLightBinManager::smUseLightFade = mRenderUseLightFade; + + //kickstart rendering + LightManager* lm = LIGHTMGR; + if (lm) + { + SceneManager* sm = lm->getSceneManager(); + if (sm && sm->getContainer() == &gClientContainer) + { + lm->deactivate(); + lm->activate(sm); + } + } } + void RenderProbeMgr::bakeProbe(ReflectionProbe* probe) { GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE); @@ -520,8 +553,6 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe) Con::warnf("RenderProbeMgr::bakeProbe() - Beginning bake!"); U32 startMSTime = Platform::getRealMilliseconds(); - preBake(); - String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/"); U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64); U32 prefilterMipLevels = mLog2(F32(resolution)) + 1; @@ -641,7 +672,6 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe) if (!renderWithProbes) RenderProbeMgr::smRenderReflectionProbes = probeRenderState; - postBake(); cubeRefl.unregisterReflector(); @@ -845,7 +875,7 @@ void RenderProbeMgr::render( SceneRenderState *state ) _setupPerFrameParameters(state); // Early out if nothing to draw. - if ((!RenderProbeMgr::smRenderReflectionProbes && !dStrcmp(Con::getVariable("$Probes::Capturing", "0"), "1")) || (!mHasSkylight && mProbeData.effectiveProbeCount == 0)) + if (!RenderProbeMgr::smRenderReflectionProbes || (!mHasSkylight && mProbeData.effectiveProbeCount == 0)) { getProbeArrayEffect()->setSkip(true); mActiveProbes.clear(); @@ -875,9 +905,6 @@ void RenderProbeMgr::render( SceneRenderState *state ) String probePerFrame = Con::getVariable("$pref::MaxProbesPerFrame", "8"); mProbeArrayEffect->setShaderMacro("MAX_PROBES", probePerFrame); - String probeCapturing = Con::getVariable("$Probes::Capturing", "0"); - mProbeArrayEffect->setShaderMacro("CAPTURING", probeCapturing); - mProbeArrayEffect->setTexture(3, mBRDFTexture); mProbeArrayEffect->setCubemapArrayTexture(4, mPrefilterArray); mProbeArrayEffect->setCubemapArrayTexture(5, mIrradianceArray); @@ -953,11 +980,15 @@ void RenderProbeMgr::render( SceneRenderState *state ) DefineEngineMethod(RenderProbeMgr, bakeProbe, void, (ReflectionProbe* probe), (nullAsType< ReflectionProbe*>()), "@brief Bakes the cubemaps for a reflection probe\n\n.") { + object->preBake(); if(probe != nullptr) object->bakeProbe(probe); + object->postBake(); } DefineEngineMethod(RenderProbeMgr, bakeProbes, void, (),, "@brief Iterates over all reflection probes in the scene and bakes their cubemaps\n\n.") { + object->preBake(); object->bakeProbes(); + object->postBake(); } diff --git a/Engine/source/renderInstance/renderProbeMgr.h b/Engine/source/renderInstance/renderProbeMgr.h index 4f64eaf95..94b8f7167 100644 --- a/Engine/source/renderInstance/renderProbeMgr.h +++ b/Engine/source/renderInstance/renderProbeMgr.h @@ -357,6 +357,7 @@ public: /// static bool smRenderReflectionProbes; + static bool smBakeReflectionProbes; //============================================================================= // Utility functions for processing and setting up the probes for rendering //============================================================================= diff --git a/Engine/source/scene/reflector.cpp b/Engine/source/scene/reflector.cpp index 09c03e426..7117bc8ff 100644 --- a/Engine/source/scene/reflector.cpp +++ b/Engine/source/scene/reflector.cpp @@ -355,6 +355,9 @@ void CubeReflector::updateFace( const ReflectParams ¶ms, U32 faceidx, Point3 // store current matrices GFXTransformSaver saver; + F32 detailAdjustBackup = TSShapeInstance::smDetailAdjust; + TSShapeInstance::smDetailAdjust *= mDesc->detailAdjust; + // set projection to 90 degrees vertical and horizontal F32 left, right, top, bottom; MathUtils::makeFrustum( &left, &right, &top, &bottom, M_HALFPI_F, 1.0f, mDesc->nearDist ); @@ -437,6 +440,7 @@ void CubeReflector::updateFace( const ReflectParams ¶ms, U32 faceidx, Point3 // Clean up. mRenderTarget->resolve(); + TSShapeInstance::smDetailAdjust = detailAdjustBackup; } F32 CubeReflector::calcFaceScore( const ReflectParams ¶ms, U32 faceidx ) diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl index f430c0e35..723a62511 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl @@ -66,6 +66,10 @@ uniform vec4 albedo; #define DEBUGVIZ_CONTRIB 0 #endif +#ifndef CAPTURE_LIGHT_FLOOR +#define CAPTURE_LIGHT_FLOOR 0.04 +#endif + vec3 getDistanceVectorToPlane( vec3 origin, vec3 direction, vec4 plane ) { float denum = dot( plane.xyz, direction.xyz ); @@ -234,7 +238,7 @@ vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight) vec3 Fr = D * F * Vis; #if CAPTURING == 1 - return saturate(mix(Fd + Fr,surface.f0,surface.metalness)); + return mix(Fd + Fr, surface.baseColor.rgb, surface.metalness); #else return Fd + Fr; #endif @@ -243,23 +247,38 @@ vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight) vec3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float shadow) { - vec3 factor = lightColor * max(surfaceToLight.NdotL * shadow * lightIntensity, 0.0f); +#if CAPTURING == 1 + float lightfloor = CAPTURE_LIGHT_FLOOR; +#else + float lightfloor = 0.0; +#endif + vec3 factor = lightColor * max(surfaceToLight.NdotL * shadow * lightIntensity, lightfloor); return evaluateStandardBRDF(surface,surfaceToLight) * factor; } vec3 getPunctualLight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float radius, float shadow) { +#if CAPTURING == 1 + float lightfloor = CAPTURE_LIGHT_FLOOR; +#else + float lightfloor = 0.0; +#endif float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); - vec3 factor = lightColor * max(surfaceToLight.NdotL * shadow * lightIntensity * attenuation, 0.0f); + vec3 factor = lightColor * max(surfaceToLight.NdotL * shadow * lightIntensity * attenuation, lightfloor); return evaluateStandardBRDF(surface,surfaceToLight) * factor; } vec3 getSpotlight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float radius, vec3 lightDir, vec2 lightSpotParams, float shadow) { +#if CAPTURING == 1 + float lightfloor = CAPTURE_LIGHT_FLOOR; +#else + float lightfloor = 0.0; +#endif float attenuation = 1.0f; attenuation *= getDistanceAtt(surfaceToLight.Lu, radius); attenuation *= getSpotAngleAtt(-surfaceToLight.L, lightDir, lightSpotParams.xy); - vec3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, 0.0f) ; + vec3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, lightfloor); return evaluateStandardBRDF(surface,surfaceToLight) * factor; } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl index a2004bd4d..3ec490af1 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl @@ -68,6 +68,10 @@ uniform float4 albedo; #define DEBUGVIZ_CONTRIB 0 #endif +#ifndef CAPTURE_LIGHT_FLOOR +#define CAPTURE_LIGHT_FLOOR 0.04 +#endif + inline float3 getDistanceVectorToPlane( float3 origin, float3 direction, float4 plane ) { float denum = dot( plane.xyz, direction.xyz ); @@ -235,7 +239,7 @@ float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight) float3 Fr = D * F * Vis; #if CAPTURING == 1 - return saturate(lerp(Fd + Fr,surface.f0,surface.metalness)); + return lerp(Fd + Fr,surface.baseColor.rgb,surface.metalness); #else return Fd + Fr; #endif @@ -244,25 +248,41 @@ float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight) float3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float shadow) { - float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity, 0.0f) ; +#if CAPTURING == 1 + float lightfloor = CAPTURE_LIGHT_FLOOR; +#else + float lightfloor = 0.0; +#endif + float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity, lightfloor) ; return evaluateStandardBRDF(surface,surfaceToLight) * factor; } float3 getPunctualLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float radius, float shadow) { +#if CAPTURING == 1 + float lightfloor = CAPTURE_LIGHT_FLOOR; +#else + float lightfloor = 0.0; +#endif float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); - float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, 0.0f) ; + float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, lightfloor) ; return evaluateStandardBRDF(surface,surfaceToLight) * factor; } float3 getSpotlight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float radius, float3 lightDir, float2 lightSpotParams, float shadow) { +#if CAPTURING == 1 + float lightfloor = CAPTURE_LIGHT_FLOOR; +#else + float lightfloor = 0.0; +#endif float attenuation = 1.0f; attenuation *= getDistanceAtt(surfaceToLight.Lu, radius); attenuation *= getSpotAngleAtt(-surfaceToLight.L, lightDir, lightSpotParams.xy); - float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, 0.0f) ; + float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, lightfloor) ; return evaluateStandardBRDF(surface,surfaceToLight) * factor; } + float computeSpecOcclusion( float NdotV , float AO , float roughness ) { return saturate (pow( abs(NdotV + AO) , exp2 ( -16.0f * roughness - 1.0f )) - 1.0f + AO ); diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl index 1a2be0d2a..d83ee249a 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl @@ -86,7 +86,7 @@ vec3 ImportanceSampleGGX(vec2 Xi, vec3 N) vec3 prefilterEnvMap(vec3 R) { - int sampleCount = resolution*2; + int sampleCount = 1024; vec3 N = R; vec3 V = R; float totalWeight = 0.0; @@ -107,7 +107,7 @@ vec3 prefilterEnvMap(vec3 R) float HdotV = max(dot(H, V), 0.0); float pdf = D * NdotH / (4.0 * HdotV) + 0.0001; - float saTexel = 4.0 * M_PI_F / float(6.0 * sampleCount * sampleCount); + float saTexel = 4.0 * M_PI_F / float(6.0 * resolution * resolution); float saSample = 1.0 / (float(sampleCount) * pdf + 0.0001); float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel); diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl index fbacdadc9..b1f485e91 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl @@ -88,7 +88,7 @@ float3 ImportanceSampleGGX(float2 Xi, float3 N) float4 prefilterEnvMap(float3 R) { - int sampleCount = resolution*2; + int sampleCount = 1024; float3 N = R; float3 V = R; float totalWeight = 0.0; @@ -109,7 +109,7 @@ float4 prefilterEnvMap(float3 R) float HdotV = max(dot(H, V), 0.0); float pdf = D * NdotH / (4.0 * HdotV) + 0.0001; - float saTexel = 4.0 * M_PI_F / (6.0 * sampleCount * sampleCount); + float saTexel = 4.0 * M_PI_F / (6.0 * resolution * resolution); float saSample = 1.0 / (float(sampleCount) * pdf + 0.0001); float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel); diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorUndo.ed.tscript b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorUndo.ed.tscript index ba75ee7a0..e94c4d91d 100644 --- a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorUndo.ed.tscript +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorUndo.ed.tscript @@ -20,6 +20,8 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +//command variable feilds. do not trip them by unsetting or resetting these +$undoIgnoreList = "docsURL EditPosOffset Bake EditPostEffects selectAll sync Prototype"; //--------------------------------------------------------------------------------------------- @@ -451,6 +453,15 @@ function GenericUndoAction::undo(%this) for(%j = 0; %j < getWordCount(%fieldNames); %j++) { %field = getWord(%fieldNames, %j); + %skip = false; + for(%k = 0; %k < getWordCount($undoIgnoreList); %k++) + { + if(%field $= getWord(%fieldNames, %k)) //specialty field, we can't 'undo' it + %skip = true; + } + if (%skip) + continue; + %object.setFieldValue(%field, %this.fieldValues[%object, %field]); } // null out the fields in the null list @@ -469,7 +480,6 @@ function GenericUndoAction::undo(%this) function GenericUndoAction::redo(%this) { - // set the objects to the new values // set the objects to the new values // scan through our objects %objectList = %this.objectIdList; @@ -481,6 +491,15 @@ function GenericUndoAction::redo(%this) for(%j = 0; %j < getWordCount(%fieldNames); %j++) { %field = getWord(%fieldNames, %j); + %skip = false; + for(%k = 0; %k < getWordCount($undoIgnoreList); %k++) + { + if(%field $= getWord(%fieldNames, %k)) //specialty field, we can't 'redo' it + %skip = true; + } + if (%skip) + continue; + %object.setFieldValue(%field, %this.newFieldValues[%object, %field]); } // null out the fields in the null list diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript index c0beb15f7..6cfdb0350 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript @@ -286,10 +286,7 @@ function doEditorResetDefaultLevel() function EditorSaveMissionMenu() { - if(EditorGui.saveAs) - AssetBrowser.setupCreateNewAsset("LevelAsset", AssetBrowser.selectedModule, "EditorSaveMissionAs"); - else - EditorSaveMission(); + EditorSaveMission(); } function EditorSaveMission() @@ -387,6 +384,8 @@ function EditorSaveMission() function EditorSaveMissionAs( %levelAsset ) { + EditorGui.saveAs = true; + AssetBrowser.setupCreateNewAsset("LevelAsset", AssetBrowser.selectedModule,""); // If we didn't get passed a new mission name then // prompt the user for one. if ( %levelAsset $= "" ) diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.tscript index 92cefad74..5b21e0630 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.tscript @@ -142,7 +142,7 @@ function EditorGui::buildMenus(%this) %fileMenu.appendItem("Open Recent" TAB RecentLevelsPopupMenu); %fileMenu.appendItem("-"); %fileMenu.appendItem("Save Level" TAB %cmdCtrl SPC "S" TAB "EditorSaveMissionMenu();"); - %fileMenu.appendItem("Save Level As..." TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"LevelAsset\", AssetBrowser.selectedModule, \"EditorSaveMissionAs\");"); + %fileMenu.appendItem("Save Level As..." TAB "" TAB "EditorSaveMissionAs();"); %fileMenu.appendItem("-"); %fileMenu.appendItem("Save Current Scene as Editor Default" TAB "" TAB "EditorSaveAsDefaultLevel();"); %fileMenu.appendItem("Reset Editor Default" TAB "" TAB "EditorResetDefaultLevel();");