diff --git a/Engine/source/forest/glsl/windDeformationGLSL.cpp b/Engine/source/forest/glsl/windDeformationGLSL.cpp index ae32b51f7..9c9ed6f42 100644 --- a/Engine/source/forest/glsl/windDeformationGLSL.cpp +++ b/Engine/source/forest/glsl/windDeformationGLSL.cpp @@ -60,7 +60,7 @@ MODULE_END; WindDeformationGLSL::WindDeformationGLSL() - : mDep( "shaders/common/gl/wind.glsl" ) + : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/wind.glsl" )) { addDependency( &mDep ); } diff --git a/Engine/source/forest/hlsl/windDeformationHLSL.cpp b/Engine/source/forest/hlsl/windDeformationHLSL.cpp index 24acf769a..08bce353e 100644 --- a/Engine/source/forest/hlsl/windDeformationHLSL.cpp +++ b/Engine/source/forest/hlsl/windDeformationHLSL.cpp @@ -60,7 +60,7 @@ MODULE_END; WindDeformationHLSL::WindDeformationHLSL() - : mDep( "shaders/common/wind.hlsl" ) + : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/wind.hlsl" )) { addDependency( &mDep ); } diff --git a/Engine/source/gfx/D3D11/gfxD3D11Device.cpp b/Engine/source/gfx/D3D11/gfxD3D11Device.cpp index fd2e2e58b..16440eb64 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Device.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11Device.cpp @@ -670,8 +670,8 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type) //shader model 4.0 is enough for the generic shaders const char* shaderModel = "4.0"; shaderData = new ShaderData(); - shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/colorV.hlsl"); - shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/colorP.hlsl"); + shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/colorV.hlsl")); + shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/colorP.hlsl")); shaderData->setField("pixVersion", shaderModel); shaderData->registerObject(); mGenericShader[GSColor] = shaderData->getShader(); @@ -680,8 +680,8 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type) Sim::getRootGroup()->addObject(shaderData); shaderData = new ShaderData(); - shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/modColorTextureV.hlsl"); - shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/modColorTextureP.hlsl"); + shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/modColorTextureV.hlsl")); + shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/modColorTextureP.hlsl")); shaderData->setField("pixVersion", shaderModel); shaderData->registerObject(); mGenericShader[GSModColorTexture] = shaderData->getShader(); @@ -690,8 +690,8 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type) Sim::getRootGroup()->addObject(shaderData); shaderData = new ShaderData(); - shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/addColorTextureV.hlsl"); - shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/addColorTextureP.hlsl"); + shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/addColorTextureV.hlsl")); + shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/addColorTextureP.hlsl")); shaderData->setField("pixVersion", shaderModel); shaderData->registerObject(); mGenericShader[GSAddColorTexture] = shaderData->getShader(); @@ -700,8 +700,8 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type) Sim::getRootGroup()->addObject(shaderData); shaderData = new ShaderData(); - shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/textureV.hlsl"); - shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/textureP.hlsl"); + shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/textureV.hlsl")); + shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/textureP.hlsl")); shaderData->setField("pixVersion", shaderModel); shaderData->registerObject(); mGenericShader[GSTexture] = shaderData->getShader(); diff --git a/Engine/source/gfx/D3D9/gfxD3D9Device.cpp b/Engine/source/gfx/D3D9/gfxD3D9Device.cpp index 4f23d7a7d..05c3474dc 100644 --- a/Engine/source/gfx/D3D9/gfxD3D9Device.cpp +++ b/Engine/source/gfx/D3D9/gfxD3D9Device.cpp @@ -154,8 +154,8 @@ inline void GFXD3D9Device::setupGenericShaders( GenericShaderType type /* = GSCo ShaderData *shaderData; shaderData = new ShaderData(); - shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/colorV.hlsl"); - shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/colorP.hlsl"); + shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/colorV.hlsl")); + shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/colorP.hlsl")); shaderData->setField("pixVersion", "3.0"); shaderData->registerObject(); mGenericShader[GSColor] = shaderData->getShader(); @@ -164,8 +164,8 @@ inline void GFXD3D9Device::setupGenericShaders( GenericShaderType type /* = GSCo Sim::getRootGroup()->addObject(shaderData); shaderData = new ShaderData(); - shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/modColorTextureV.hlsl"); - shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/modColorTextureP.hlsl"); + shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/modColorTextureV.hlsl")); + shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/modColorTextureP.hlsl")); shaderData->setSamplerName("$diffuseMap", 0); shaderData->setField("pixVersion", "3.0"); shaderData->registerObject(); @@ -175,8 +175,8 @@ inline void GFXD3D9Device::setupGenericShaders( GenericShaderType type /* = GSCo Sim::getRootGroup()->addObject(shaderData); shaderData = new ShaderData(); - shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/addColorTextureV.hlsl"); - shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/addColorTextureP.hlsl"); + shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/addColorTextureV.hlsl")); + shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/addColorTextureP.hlsl")); shaderData->setSamplerName("$diffuseMap", 0); shaderData->setField("pixVersion", "3.0"); shaderData->registerObject(); @@ -186,8 +186,8 @@ inline void GFXD3D9Device::setupGenericShaders( GenericShaderType type /* = GSCo Sim::getRootGroup()->addObject(shaderData); shaderData = new ShaderData(); - shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/textureV.hlsl"); - shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/textureP.hlsl"); + shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/textureV.hlsl")); + shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/textureP.hlsl")); shaderData->setSamplerName("$diffuseMap", 0); shaderData->setField("pixVersion", "3.0"); shaderData->registerObject(); diff --git a/Engine/source/gfx/gfxTextureManager.cpp b/Engine/source/gfx/gfxTextureManager.cpp index 781e0daa2..e9a3e57d4 100644 --- a/Engine/source/gfx/gfxTextureManager.cpp +++ b/Engine/source/gfx/gfxTextureManager.cpp @@ -42,9 +42,9 @@ using namespace Torque; S32 GFXTextureManager::smTextureReductionLevel = 0; -String GFXTextureManager::smMissingTexturePath("core/art/missingTexture"); -String GFXTextureManager::smUnavailableTexturePath("core/art/unavailable"); -String GFXTextureManager::smWarningTexturePath("core/art/warnmat"); +String GFXTextureManager::smMissingTexturePath(Con::getVariable("$Core::MissingTexturePath")); +String GFXTextureManager::smUnavailableTexturePath(Con::getVariable("$Core::UnAvailableTexturePath")); +String GFXTextureManager::smWarningTexturePath(Con::getVariable("$Core::WarningTexturePath")); GFXTextureManager::EventSignal GFXTextureManager::smEventSignal; diff --git a/Engine/source/gfx/gl/gfxGLDevice.cpp b/Engine/source/gfx/gl/gfxGLDevice.cpp index ce22f16a1..bc348671b 100644 --- a/Engine/source/gfx/gl/gfxGLDevice.cpp +++ b/Engine/source/gfx/gl/gfxGLDevice.cpp @@ -780,8 +780,8 @@ void GFXGLDevice::setupGenericShaders( GenericShaderType type ) ShaderData *shaderData; shaderData = new ShaderData(); - shaderData->setField("OGLVertexShaderFile", "shaders/common/fixedFunction/gl/colorV.glsl"); - shaderData->setField("OGLPixelShaderFile", "shaders/common/fixedFunction/gl/colorP.glsl"); + shaderData->setField("OGLVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/colorV.glsl")); + shaderData->setField("OGLPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/colorP.glsl")); shaderData->setField("pixVersion", "2.0"); shaderData->registerObject(); mGenericShader[GSColor] = shaderData->getShader(); @@ -790,8 +790,8 @@ void GFXGLDevice::setupGenericShaders( GenericShaderType type ) Sim::getRootGroup()->addObject(shaderData); shaderData = new ShaderData(); - shaderData->setField("OGLVertexShaderFile", "shaders/common/fixedFunction/gl/modColorTextureV.glsl"); - shaderData->setField("OGLPixelShaderFile", "shaders/common/fixedFunction/gl/modColorTextureP.glsl"); + shaderData->setField("OGLVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/modColorTextureV.glsl")); + shaderData->setField("OGLPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/modColorTextureP.glsl")); shaderData->setSamplerName("$diffuseMap", 0); shaderData->setField("pixVersion", "2.0"); shaderData->registerObject(); @@ -801,8 +801,8 @@ void GFXGLDevice::setupGenericShaders( GenericShaderType type ) Sim::getRootGroup()->addObject(shaderData); shaderData = new ShaderData(); - shaderData->setField("OGLVertexShaderFile", "shaders/common/fixedFunction/gl/addColorTextureV.glsl"); - shaderData->setField("OGLPixelShaderFile", "shaders/common/fixedFunction/gl/addColorTextureP.glsl"); + shaderData->setField("OGLVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/addColorTextureV.glsl")); + shaderData->setField("OGLPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/addColorTextureP.glsl")); shaderData->setSamplerName("$diffuseMap", 0); shaderData->setField("pixVersion", "2.0"); shaderData->registerObject(); @@ -812,8 +812,8 @@ void GFXGLDevice::setupGenericShaders( GenericShaderType type ) Sim::getRootGroup()->addObject(shaderData); shaderData = new ShaderData(); - shaderData->setField("OGLVertexShaderFile", "shaders/common/fixedFunction/gl/textureV.glsl"); - shaderData->setField("OGLPixelShaderFile", "shaders/common/fixedFunction/gl/textureP.glsl"); + shaderData->setField("OGLVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/textureV.glsl")); + shaderData->setField("OGLPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/gl/textureP.glsl")); shaderData->setSamplerName("$diffuseMap", 0); shaderData->setField("pixVersion", "2.0"); shaderData->registerObject(); diff --git a/Engine/source/materials/shaderData.cpp b/Engine/source/materials/shaderData.cpp index 829bbbbb1..29c379ed7 100644 --- a/Engine/source/materials/shaderData.cpp +++ b/Engine/source/materials/shaderData.cpp @@ -48,10 +48,10 @@ ConsoleDocClass( ShaderData, "// Used for the procedural clould system\n" "singleton ShaderData( CloudLayerShader )\n" "{\n" - " DXVertexShaderFile = \"shaders/common/cloudLayerV.hlsl\";\n" - " DXPixelShaderFile = \"shaders/common/cloudLayerP.hlsl\";\n" - " OGLVertexShaderFile = \"shaders/common/gl/cloudLayerV.glsl\";\n" - " OGLPixelShaderFile = \"shaders/common/gl/cloudLayerP.glsl\";\n" + " DXVertexShaderFile = $Core::CommonShaderPath @ \"/cloudLayerV.hlsl\";\n" + " DXPixelShaderFile = $Core::CommonShaderPath @ \"/cloudLayerP.hlsl\";\n" + " OGLVertexShaderFile = $Core::CommonShaderPath @ \"/gl/cloudLayerV.glsl\";\n" + " OGLPixelShaderFile = $Core::CommonShaderPath @ \"/gl/cloudLayerP.glsl\";\n" " pixVersion = 2.0;\n" "};\n" "@endtsexample\n\n" @@ -109,8 +109,8 @@ void ShaderData::initPersistFields() "@tsexample\n" "singleton ShaderData( FlashShader )\n" "{\n" - "DXVertexShaderFile = \"shaders/common/postFx/flashV.hlsl\";\n" - "DXPixelShaderFile = \"shaders/common/postFx/flashP.hlsl\";\n\n" + "DXVertexShaderFile = $shaderGen::cachePath @ \"/postFx/flashV.hlsl\";\n" + "DXPixelShaderFile = $shaderGen::cachePath @ \"/postFx/flashP.hlsl\";\n\n" " //Define setting the color of WHITE_COLOR.\n" "defines = \"WHITE_COLOR=float4(1.0,1.0,1.0,0.0)\";\n\n" "pixVersion = 2.0\n" diff --git a/Engine/source/postFx/postEffect.cpp b/Engine/source/postFx/postEffect.cpp index 7e4a6fed8..65cb69d20 100644 --- a/Engine/source/postFx/postEffect.cpp +++ b/Engine/source/postFx/postEffect.cpp @@ -411,10 +411,6 @@ bool PostEffect::onAdd() texFilename[0] == '#' ) continue; - // If '/', then path is specified, open normally - if ( texFilename[0] != '/' ) - texFilename = scriptPath.getFullPath() + '/' + texFilename; - // Try to load the texture. bool success = mTextures[i].set( texFilename, &PostFxTextureProfile, avar( "%s() - (line %d)", __FUNCTION__, __LINE__ ) ); if (!success) diff --git a/Engine/source/shaderGen/GLSL/bumpGLSL.cpp b/Engine/source/shaderGen/GLSL/bumpGLSL.cpp index bc11a156f..020107b57 100644 --- a/Engine/source/shaderGen/GLSL/bumpGLSL.cpp +++ b/Engine/source/shaderGen/GLSL/bumpGLSL.cpp @@ -236,7 +236,7 @@ void BumpFeatGLSL::setTexData( Material::StageData &stageDat, ParallaxFeatGLSL::ParallaxFeatGLSL() - : mIncludeDep( "shaders/common/gl/torque.glsl" ) + : mIncludeDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl" )) { addDependency( &mIncludeDep ); } diff --git a/Engine/source/shaderGen/GLSL/pixSpecularGLSL.cpp b/Engine/source/shaderGen/GLSL/pixSpecularGLSL.cpp index 2ecb56df6..192641775 100644 --- a/Engine/source/shaderGen/GLSL/pixSpecularGLSL.cpp +++ b/Engine/source/shaderGen/GLSL/pixSpecularGLSL.cpp @@ -30,7 +30,7 @@ PixelSpecularGLSL::PixelSpecularGLSL() - : mDep( "shaders/common/gl/lighting.glsl" ) + : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/lighting.glsl" )) { addDependency( &mDep ); } diff --git a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp index cabedc14c..0a7ec2159 100644 --- a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp +++ b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp @@ -830,7 +830,7 @@ Var* ShaderFeatureGLSL::addOutDetailTexCoord( Vector &compon //**************************************************************************** DiffuseMapFeatGLSL::DiffuseMapFeatGLSL() -: mTorqueDep("shaders/common/gl/torque.glsl") +: mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl")) { addDependency(&mTorqueDep); } @@ -1975,7 +1975,7 @@ void ReflectCubeFeatGLSL::setTexData( Material::StageData &stageDat, //**************************************************************************** RTLightingFeatGLSL::RTLightingFeatGLSL() - : mDep( "shaders/common/gl/lighting.glsl" ) + : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/lighting.glsl" )) { addDependency( &mDep ); } @@ -2190,7 +2190,7 @@ ShaderFeature::Resources RTLightingFeatGLSL::getResources( const MaterialFeature //**************************************************************************** FogFeatGLSL::FogFeatGLSL() - : mFogDep( "shaders/common/gl/torque.glsl" ) + : mFogDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl" )) { addDependency( &mFogDep ); } @@ -2321,7 +2321,7 @@ ShaderFeature::Resources FogFeatGLSL::getResources( const MaterialFeatureData &f //**************************************************************************** VisibilityFeatGLSL::VisibilityFeatGLSL() - : mTorqueDep( "shaders/common/gl/torque.glsl" ) + : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl" )) { addDependency( &mTorqueDep ); } @@ -2487,7 +2487,7 @@ void RenderTargetZeroGLSL::processPix( Vector &componentList, //**************************************************************************** HDROutGLSL::HDROutGLSL() - : mTorqueDep( "shaders/common/gl/torque.glsl" ) + : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl" )) { addDependency( &mTorqueDep ); } @@ -2508,7 +2508,7 @@ void HDROutGLSL::processPix( Vector &componentList, #include "T3D/fx/groundCover.h" FoliageFeatureGLSL::FoliageFeatureGLSL() -: mDep( "shaders/common/gl/foliage.glsl" ) +: mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/foliage.glsl" )) { addDependency( &mDep ); } @@ -2654,7 +2654,7 @@ void ParticleNormalFeatureGLSL::processVert(Vector &componentL //**************************************************************************** ImposterVertFeatureGLSL::ImposterVertFeatureGLSL() - : mDep( "shaders/common/gl/imposter.glsl" ) + : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/imposter.glsl" )) { addDependency( &mDep ); } diff --git a/Engine/source/shaderGen/GLSL/shaderGenGLSL.cpp b/Engine/source/shaderGen/GLSL/shaderGenGLSL.cpp index 6e068c7cf..d5556cb1f 100644 --- a/Engine/source/shaderGen/GLSL/shaderGenGLSL.cpp +++ b/Engine/source/shaderGen/GLSL/shaderGenGLSL.cpp @@ -37,8 +37,8 @@ void ShaderGenPrinterGLSL::printShaderHeader( Stream& stream ) stream.write( dStrlen(header1), header1 ); // Cheap HLSL compatibility. - const char* header3 = "#include \"shaders/common/gl/hlslCompat.glsl\"\r\n"; - stream.write( dStrlen(header3), header3 ); + String header3 = String("#include \"") + String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/hlslCompat.glsl\"\r\n"); + stream.write(dStrlen(header3), header3.c_str()); const char* header4 = "\r\n"; stream.write( dStrlen(header4), header4 ); diff --git a/Engine/source/shaderGen/HLSL/bumpHLSL.cpp b/Engine/source/shaderGen/HLSL/bumpHLSL.cpp index f6beb4cfc..79ea27714 100644 --- a/Engine/source/shaderGen/HLSL/bumpHLSL.cpp +++ b/Engine/source/shaderGen/HLSL/bumpHLSL.cpp @@ -268,7 +268,7 @@ void BumpFeatHLSL::setTexData( Material::StageData &stageDat, ParallaxFeatHLSL::ParallaxFeatHLSL() - : mIncludeDep( "shaders/common/torque.hlsl" ) + : mIncludeDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl" )) { addDependency( &mIncludeDep ); } diff --git a/Engine/source/shaderGen/HLSL/pixSpecularHLSL.cpp b/Engine/source/shaderGen/HLSL/pixSpecularHLSL.cpp index b5a5a98b1..3a794a394 100644 --- a/Engine/source/shaderGen/HLSL/pixSpecularHLSL.cpp +++ b/Engine/source/shaderGen/HLSL/pixSpecularHLSL.cpp @@ -30,7 +30,7 @@ PixelSpecularHLSL::PixelSpecularHLSL() - : mDep( "shaders/common/lighting.hlsl" ) + : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/lighting.hlsl" )) { addDependency( &mDep ); } diff --git a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp index 6e8a08347..8690ae610 100644 --- a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp +++ b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp @@ -853,7 +853,7 @@ Var* ShaderFeatureHLSL::addOutDetailTexCoord( Vector &compon //**************************************************************************** DiffuseMapFeatHLSL::DiffuseMapFeatHLSL() -: mTorqueDep("shaders/common/torque.hlsl") +: mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl")) { addDependency(&mTorqueDep); } @@ -2168,7 +2168,7 @@ void ReflectCubeFeatHLSL::setTexData( Material::StageData &stageDat, //**************************************************************************** RTLightingFeatHLSL::RTLightingFeatHLSL() - : mDep( "shaders/common/lighting.hlsl" ) + : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/lighting.hlsl" )) { addDependency( &mDep ); } @@ -2383,7 +2383,7 @@ ShaderFeature::Resources RTLightingFeatHLSL::getResources( const MaterialFeature //**************************************************************************** FogFeatHLSL::FogFeatHLSL() - : mFogDep( "shaders/common/torque.hlsl" ) + : mFogDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl" )) { addDependency( &mFogDep ); } @@ -2514,7 +2514,7 @@ ShaderFeature::Resources FogFeatHLSL::getResources( const MaterialFeatureData &f //**************************************************************************** VisibilityFeatHLSL::VisibilityFeatHLSL() - : mTorqueDep( "shaders/common/torque.hlsl" ) + : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl" )) { addDependency( &mTorqueDep ); } @@ -2681,7 +2681,7 @@ void RenderTargetZeroHLSL::processPix( Vector &componentList, //**************************************************************************** HDROutHLSL::HDROutHLSL() - : mTorqueDep( "shaders/common/torque.hlsl" ) + : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl" )) { addDependency( &mTorqueDep ); } @@ -2702,7 +2702,7 @@ void HDROutHLSL::processPix( Vector &componentList, #include "T3D/fx/groundCover.h" FoliageFeatureHLSL::FoliageFeatureHLSL() -: mDep( "shaders/common/foliage.hlsl" ) +: mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/foliage.hlsl" )) { addDependency( &mDep ); } @@ -2848,7 +2848,7 @@ void ParticleNormalFeatureHLSL::processVert(Vector &componentL //**************************************************************************** ImposterVertFeatureHLSL::ImposterVertFeatureHLSL() - : mDep( "shaders/common/imposter.hlsl" ) + : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/imposter.hlsl" )) { addDependency( &mDep ); } diff --git a/Engine/source/terrain/glsl/terrFeatureGLSL.cpp b/Engine/source/terrain/glsl/terrFeatureGLSL.cpp index f40776b80..193f9587c 100644 --- a/Engine/source/terrain/glsl/terrFeatureGLSL.cpp +++ b/Engine/source/terrain/glsl/terrFeatureGLSL.cpp @@ -70,7 +70,7 @@ MODULE_END; TerrainFeatGLSL::TerrainFeatGLSL() - : mTorqueDep( "shaders/common/gl/torque.glsl" ) + : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl" )) { addDependency( &mTorqueDep ); } @@ -297,8 +297,8 @@ U32 TerrainBaseMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) co } TerrainDetailMapFeatGLSL::TerrainDetailMapFeatGLSL() - : mTorqueDep( "shaders/common/gl/torque.glsl" ), - mTerrainDep( "shaders/common/terrain/terrain.glsl" ) + : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl" )), + mTerrainDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/terrain/terrain.glsl" )) { addDependency( &mTorqueDep ); @@ -667,8 +667,8 @@ U32 TerrainDetailMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) TerrainMacroMapFeatGLSL::TerrainMacroMapFeatGLSL() - : mTorqueDep( "shaders/common/gl/torque.glsl" ), - mTerrainDep( "shaders/common/terrain/terrain.glsl" ) + : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/gl/torque.glsl" )), + mTerrainDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/terrain/terrain.glsl" )) { addDependency( &mTorqueDep ); diff --git a/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp b/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp index 9bd77b664..74fdd417b 100644 --- a/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp +++ b/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp @@ -69,7 +69,7 @@ MODULE_END; TerrainFeatHLSL::TerrainFeatHLSL() - : mTorqueDep( "shaders/common/torque.hlsl" ) + : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl" )) { addDependency( &mTorqueDep ); } @@ -315,8 +315,8 @@ U32 TerrainBaseMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) co } TerrainDetailMapFeatHLSL::TerrainDetailMapFeatHLSL() - : mTorqueDep( "shaders/common/torque.hlsl" ), - mTerrainDep( "shaders/common/terrain/terrain.hlsl" ) + : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl" )), + mTerrainDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/terrain/terrain.hlsl" )) { addDependency( &mTorqueDep ); @@ -692,8 +692,8 @@ U32 TerrainDetailMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) TerrainMacroMapFeatHLSL::TerrainMacroMapFeatHLSL() - : mTorqueDep( "shaders/common/torque.hlsl" ), - mTerrainDep( "shaders/common/terrain/terrain.hlsl" ) + : mTorqueDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/torque.hlsl" )), + mTerrainDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/terrain/terrain.hlsl" )) { addDependency( &mTorqueDep ); diff --git a/Templates/BaseGame/BaseGame.cmake b/Templates/BaseGame/BaseGame.cmake new file mode 100644 index 000000000..8b0a6700a --- /dev/null +++ b/Templates/BaseGame/BaseGame.cmake @@ -0,0 +1 @@ +# Project-specific Cmake configurations go here \ No newline at end of file diff --git a/Templates/BaseGame/DeleteCachedDTSs.bat b/Templates/BaseGame/DeleteCachedDTSs.bat new file mode 100644 index 000000000..8f0dc258e --- /dev/null +++ b/Templates/BaseGame/DeleteCachedDTSs.bat @@ -0,0 +1 @@ +for /R %%a IN (*.dae) do IF EXIST "%%~pna.cached.dts" del "%%~pna.cached.dts" diff --git a/Templates/BaseGame/DeleteCachedDTSs.command b/Templates/BaseGame/DeleteCachedDTSs.command new file mode 100644 index 000000000..f497316e0 --- /dev/null +++ b/Templates/BaseGame/DeleteCachedDTSs.command @@ -0,0 +1,15 @@ +#!/bin/sh + +cd "`dirname "$0"`" + +for i in $(find . -type f \( -iname "*.dae" \)) +do + len=$((${#i} - 4)) + file=${i:0:$len}.cached.dts + if [ -e $file ] + then + echo "Removing ${file}" + rm $file + fi +done + diff --git a/Templates/BaseGame/DeleteDSOs.bat b/Templates/BaseGame/DeleteDSOs.bat new file mode 100644 index 000000000..42228e4b3 --- /dev/null +++ b/Templates/BaseGame/DeleteDSOs.bat @@ -0,0 +1,6 @@ +for /R %%a IN (*.cs) do IF EXIST "%%a.dso" del "%%a.dso" +for /R %%a IN (*.cs) do IF EXIST "%%a.edso" del "%%a.edso" +for /R %%a IN (*.gui) do IF EXIST "%%a.dso" del "%%a.dso" +for /R %%a IN (*.gui) do IF EXIST "%%a.edso" del "%%a.edso" +for /R %%a IN (*.ts) do IF EXIST "%%a.dso" del "%%a.dso" +for /R %%a IN (*.ts) do IF EXIST "%%a.edso" del "%%a.edso" diff --git a/Templates/BaseGame/DeleteDSOs.command b/Templates/BaseGame/DeleteDSOs.command new file mode 100644 index 000000000..f6e805a31 --- /dev/null +++ b/Templates/BaseGame/DeleteDSOs.command @@ -0,0 +1,19 @@ +#!/bin/sh + +cd "`dirname "$0"`" + +for i in $(find . -type f \( -iname "*.cs" \)) +do + file=${i}.dso + if [ -e $file ] + then + echo "Removing ${file}" + rm $file + fi + file=${i}.edso + if [ -e $file ] + then + echo "Removing ${file}" + rm $file + fi +done diff --git a/Templates/BaseGame/DeletePrefs.bat b/Templates/BaseGame/DeletePrefs.bat new file mode 100644 index 000000000..e61988210 --- /dev/null +++ b/Templates/BaseGame/DeletePrefs.bat @@ -0,0 +1,6 @@ +del /s prefs.cs +del /s config.cs +del /s banlist.cs +del /s config.cs.dso +del /s prefs.cs.dso +del /s banlist.cs.dso diff --git a/Templates/BaseGame/DeletePrefs.command b/Templates/BaseGame/DeletePrefs.command new file mode 100644 index 000000000..43961562f --- /dev/null +++ b/Templates/BaseGame/DeletePrefs.command @@ -0,0 +1,3 @@ +#!/bin/sh + +find "`dirname "$0"`" -type f \( -name "prefs.cs" -or -name "config.cs" -or -name "banlist.cs" -or -name "prefs.cs.dso" -or -name "config.cs.dso" -or -name "banlist.cs.dso" \) -exec rm {} \; diff --git a/Templates/BaseGame/cleanShaders.bat b/Templates/BaseGame/cleanShaders.bat new file mode 100644 index 000000000..047b30d21 --- /dev/null +++ b/Templates/BaseGame/cleanShaders.bat @@ -0,0 +1,7 @@ +REM Delete procedural shaders + +del /q /a:-R game\shaders\procedural\*.* + +REM Delete dumped shader disassembly files + +del /q /s /a:-R *_dis.txt \ No newline at end of file diff --git a/Templates/BaseGame/cleanShaders.command b/Templates/BaseGame/cleanShaders.command new file mode 100644 index 000000000..93cebdcea --- /dev/null +++ b/Templates/BaseGame/cleanShaders.command @@ -0,0 +1,4 @@ +#!/bin/sh + +cd "`dirname "$0"`" +rm -rf game/shaders/procedural/*.* diff --git a/Templates/BaseGame/game/Template.torsion.exports b/Templates/BaseGame/game/Template.torsion.exports new file mode 100644 index 000000000..c6a971eb4 --- /dev/null +++ b/Templates/BaseGame/game/Template.torsion.exports @@ -0,0 +1 @@ + diff --git a/Templates/BaseGame/game/core/audio.cs b/Templates/BaseGame/game/core/audio.cs new file mode 100644 index 000000000..a5932de8f --- /dev/null +++ b/Templates/BaseGame/game/core/audio.cs @@ -0,0 +1,436 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Source groups. +//----------------------------------------------------------------------------- + +singleton SFXDescription( AudioMaster ); +singleton SFXSource( AudioChannelMaster ) +{ + description = AudioMaster; +}; + +singleton SFXDescription( AudioChannel ) +{ + sourceGroup = AudioChannelMaster; +}; + +singleton SFXSource( AudioChannelDefault ) +{ + description = AudioChannel; +}; +singleton SFXSource( AudioChannelGui ) +{ + description = AudioChannel; +}; +singleton SFXSource( AudioChannelEffects ) +{ + description = AudioChannel; +}; +singleton SFXSource( AudioChannelMessages ) +{ + description = AudioChannel; +}; +singleton SFXSource( AudioChannelMusic ) +{ + description = AudioChannel; +}; + +// Set default playback states of the channels. + +AudioChannelMaster.play(); +AudioChannelDefault.play(); + +AudioChannelGui.play(); +AudioChannelMusic.play(); +AudioChannelMessages.play(); + +// Stop in-game effects channels. +AudioChannelEffects.stop(); + +//----------------------------------------------------------------------------- +// Master SFXDescriptions. +//----------------------------------------------------------------------------- + +// Master description for interface audio. +singleton SFXDescription( AudioGui ) +{ + volume = 1.0; + sourceGroup = AudioChannelGui; +}; + +// Master description for game effects audio. +singleton SFXDescription( AudioEffect ) +{ + volume = 1.0; + sourceGroup = AudioChannelEffects; +}; + +// Master description for audio in notifications. +singleton SFXDescription( AudioMessage ) +{ + volume = 1.0; + sourceGroup = AudioChannelMessages; +}; + +// Master description for music. +singleton SFXDescription( AudioMusic ) +{ + volume = 1.0; + sourceGroup = AudioChannelMusic; +}; + +//----------------------------------------------------------------------------- +// SFX Functions. +//----------------------------------------------------------------------------- + +/// This initializes the sound system device from +/// the defaults in the $pref::SFX:: globals. +function sfxStartup() +{ + echo( "\nsfxStartup..." ); + + // If we have a provider set, try initialize a device now. + + if( $pref::SFX::provider !$= "" ) + { + if( sfxInit() ) + return; + else + { + // Force auto-detection. + $pref::SFX::autoDetect = true; + } + } + + // If enabled autodetect a safe device. + + if( ( !isDefined( "$pref::SFX::autoDetect" ) || $pref::SFX::autoDetect ) && + sfxAutodetect() ) + return; + + // Failure. + + error( " Failed to initialize device!\n\n" ); + + $pref::SFX::provider = ""; + $pref::SFX::device = ""; + + return; +} + + +/// This initializes the sound system device from +/// the defaults in the $pref::SFX:: globals. +function sfxInit() +{ + // If already initialized, shut down the current device first. + + if( sfxGetDeviceInfo() !$= "" ) + sfxShutdown(); + + // Start it up! + %maxBuffers = $pref::SFX::useHardware ? -1 : $pref::SFX::maxSoftwareBuffers; + if ( !sfxCreateDevice( $pref::SFX::provider, $pref::SFX::device, $pref::SFX::useHardware, %maxBuffers ) ) + return false; + + // This returns a tab seperated string with + // the initialized system info. + %info = sfxGetDeviceInfo(); + $pref::SFX::provider = getField( %info, 0 ); + $pref::SFX::device = getField( %info, 1 ); + $pref::SFX::useHardware = getField( %info, 2 ); + %useHardware = $pref::SFX::useHardware ? "Yes" : "No"; + %maxBuffers = getField( %info, 3 ); + + echo( " Provider: " @ $pref::SFX::provider ); + echo( " Device: " @ $pref::SFX::device ); + echo( " Hardware: " @ %useHardware ); + echo( " Max Buffers: " @ %maxBuffers ); + echo( " " ); + + if( isDefined( "$pref::SFX::distanceModel" ) ) + sfxSetDistanceModel( $pref::SFX::distanceModel ); + if( isDefined( "$pref::SFX::dopplerFactor" ) ) + sfxSetDopplerFactor( $pref::SFX::dopplerFactor ); + if( isDefined( "$pref::SFX::rolloffFactor" ) ) + sfxSetRolloffFactor( $pref::SFX::rolloffFactor ); + + // Restore master volume. + + sfxSetMasterVolume( $pref::SFX::masterVolume ); + + // Restore channel volumes. + + for( %channel = 0; %channel <= 8; %channel ++ ) + sfxSetChannelVolume( %channel, $pref::SFX::channelVolume[ %channel ] ); + + return true; +} + + +/// Destroys the current sound system device. +function sfxShutdown() +{ + // Store volume prefs. + + $pref::SFX::masterVolume = sfxGetMasterVolume(); + + for( %channel = 0; %channel <= 8; %channel ++ ) + $pref::SFX::channelVolume[ %channel ] = sfxGetChannelVolume( %channel ); + + // We're assuming here that a null info + // string means that no device is loaded. + if( sfxGetDeviceInfo() $= "" ) + return; + + sfxDeleteDevice(); +} + + +/// Determines which of the two SFX providers is preferable. +function sfxCompareProvider( %providerA, %providerB ) +{ + if( %providerA $= %providerB ) + return 0; + + switch$( %providerA ) + { + // Always prefer FMOD over anything else. + case "FMOD": + return 1; + + // Prefer OpenAL over anything but FMOD. + case "OpenAL": + if( %providerB $= "FMOD" ) + return -1; + else + return 1; + + // choose XAudio over DirectSound + case "XAudio": + if( %providerB $= "FMOD" || %providerB $= "OpenAL" ) + return -1; + else + return 0; + + case "DirectSound": + if( %providerB !$= "FMOD" && %providerB !$= "OpenAL" && %providerB !$= "XAudio" ) + return 1; + else + return -1; + + default: + return -1; + } +} + + +/// Try to detect and initalize the best SFX device available. +function sfxAutodetect() +{ + // Get all the available devices. + + %devices = sfxGetAvailableDevices(); + + // Collect and sort the devices by preferentiality. + + %deviceTrySequence = new ArrayObject(); + %bestMatch = -1; + %count = getRecordCount( %devices ); + for( %i = 0; %i < %count; %i ++ ) + { + %info = getRecord( %devices, %i ); + %provider = getField( %info, 0 ); + + %deviceTrySequence.push_back( %provider, %info ); + } + + %deviceTrySequence.sortfkd( "sfxCompareProvider" ); + + // Try the devices in order. + + %count = %deviceTrySequence.count(); + for( %i = 0; %i < %count; %i ++ ) + { + %provider = %deviceTrySequence.getKey( %i ); + %info = %deviceTrySequence.getValue( %i ); + + $pref::SFX::provider = %provider; + $pref::SFX::device = getField( %info, 1 ); + $pref::SFX::useHardware = getField( %info, 2 ); + + // By default we've decided to avoid hardware devices as + // they are buggy and prone to problems. + $pref::SFX::useHardware = false; + + if( sfxInit() ) + { + $pref::SFX::autoDetect = false; + %deviceTrySequence.delete(); + return true; + } + } + + // Found no suitable device. + + error( "sfxAutodetect - Could not initialize a valid SFX device." ); + + $pref::SFX::provider = ""; + $pref::SFX::device = ""; + $pref::SFX::useHardware = ""; + + %deviceTrySequence.delete(); + + return false; +} + + +//----------------------------------------------------------------------------- +// Backwards-compatibility with old channel system. +//----------------------------------------------------------------------------- + +// Volume channel IDs for backwards-compatibility. + +$GuiAudioType = 1; // Interface. +$SimAudioType = 2; // Game. +$MessageAudioType = 3; // Notifications. +$MusicAudioType = 4; // Music. + +$AudioChannels[ 0 ] = AudioChannelDefault; +$AudioChannels[ $GuiAudioType ] = AudioChannelGui; +$AudioChannels[ $SimAudioType ] = AudioChannelEffects; +$AudioChannels[ $MessageAudioType ] = AudioChannelMessages; +$AudioChannels[ $MusicAudioType ] = AudioChannelMusic; + +function sfxOldChannelToGroup( %channel ) +{ + return $AudioChannels[ %channel ]; +} + +function sfxGroupToOldChannel( %group ) +{ + %id = %group.getId(); + for( %i = 0;; %i ++ ) + if( !isObject( $AudioChannels[ %i ] ) ) + return -1; + else if( $AudioChannels[ %i ].getId() == %id ) + return %i; + + return -1; +} + +function sfxSetMasterVolume( %volume ) +{ + AudioChannelMaster.setVolume( %volume ); +} + +function sfxGetMasterVolume( %volume ) +{ + return AudioChannelMaster.getVolume(); +} + +function sfxStopAll( %channel ) +{ + // Don't stop channel itself since that isn't quite what the function + // here intends. + + %channel = sfxOldChannelToGroup( %channel ); + if (isObject(%channel)) + { + foreach( %source in %channel ) + %source.stop(); + } +} + +function sfxGetChannelVolume( %channel ) +{ + %obj = sfxOldChannelToGroup( %channel ); + if( isObject( %obj ) ) + return %obj.getVolume(); +} + +function sfxSetChannelVolume( %channel, %volume ) +{ + %obj = sfxOldChannelToGroup( %channel ); + if( isObject( %obj ) ) + %obj.setVolume( %volume ); +} + +/*singleton SimSet( SFXPausedSet ); + + +/// Pauses the playback of active sound sources. +/// +/// @param %channels An optional word list of channel indices or an empty +/// string to pause sources on all channels. +/// @param %pauseSet An optional SimSet which is filled with the paused +/// sources. If not specified the global SfxSourceGroup +/// is used. +/// +/// @deprecated +/// +function sfxPause( %channels, %pauseSet ) +{ + // Did we get a set to populate? + if ( !isObject( %pauseSet ) ) + %pauseSet = SFXPausedSet; + + %count = SFXSourceSet.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %source = SFXSourceSet.getObject( %i ); + + %channel = sfxGroupToOldChannel( %source.getGroup() ); + if( %channels $= "" || findWord( %channels, %channel ) != -1 ) + { + %source.pause(); + %pauseSet.add( %source ); + } + } +} + + +/// Resumes the playback of paused sound sources. +/// +/// @param %pauseSet An optional SimSet which contains the paused sound +/// sources to be resumed. If not specified the global +/// SfxSourceGroup is used. +/// @deprecated +/// +function sfxResume( %pauseSet ) +{ + if ( !isObject( %pauseSet ) ) + %pauseSet = SFXPausedSet; + + %count = %pauseSet.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %source = %pauseSet.getObject( %i ); + %source.play(); + } + + // Clear our pause set... the caller is left + // to clear his own if he passed one. + %pauseSet.clear(); +}*/ diff --git a/Templates/BaseGame/game/core/canvas.cs b/Templates/BaseGame/game/core/canvas.cs new file mode 100644 index 000000000..b38cdccca --- /dev/null +++ b/Templates/BaseGame/game/core/canvas.cs @@ -0,0 +1,162 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function createCanvas(%windowTitle) +{ + if ($isDedicated) + { + GFXInit::createNullDevice(); + return true; + } + + // Create the Canvas + $GameCanvas = new GuiCanvas(Canvas) + { + displayWindow = $platform !$= "windows"; + }; + + // Set the window title + if (isObject(Canvas)) + { + Canvas.setWindowTitle(%windowTitle @ " - " @ $pref::Video::displayDevice); + configureCanvas(); + } + else + { + error("Canvas creation failed. Shutting down."); + quit(); + } +} + +// Constants for referencing video resolution preferences +$WORD::RES_X = 0; +$WORD::RES_Y = 1; +$WORD::FULLSCREEN = 2; +$WORD::BITDEPTH = 3; +$WORD::REFRESH = 4; +$WORD::AA = 5; + +function configureCanvas() +{ + // Setup a good default if we don't have one already. + if ($pref::Video::Resolution $= "") + $pref::Video::Resolution = "800 600"; + if ($pref::Video::FullScreen $= "") + $pref::Video::FullScreen = false; + if ($pref::Video::BitDepth $= "") + $pref::Video::BitDepth = "32"; + if ($pref::Video::RefreshRate $= "") + $pref::Video::RefreshRate = "60"; + if ($pref::Video::AA $= "") + $pref::Video::AA = "4"; + + %resX = $pref::Video::Resolution.x; + %resY = $pref::Video::Resolution.y; + %fs = $pref::Video::FullScreen; + %bpp = $pref::Video::BitDepth; + %rate = $pref::Video::RefreshRate; + %aa = $pref::Video::AA; + + if($cliFullscreen !$= "") { + %fs = $cliFullscreen; + $cliFullscreen = ""; + } + + echo("--------------"); + echo("Attempting to set resolution to \"" @ %resX SPC %resY SPC %fs SPC %bpp SPC %rate SPC %aa @ "\""); + + %deskRes = getDesktopResolution(); + %deskResX = getWord(%deskRes, $WORD::RES_X); + %deskResY = getWord(%deskRes, $WORD::RES_Y); + %deskResBPP = getWord(%deskRes, 2); + + // We shouldn't be getting this any more but just in case... + if (%bpp $= "Default") + %bpp = %deskResBPP; + + // Make sure we are running at a valid resolution + if (%fs $= "0" || %fs $= "false") + { + // Windowed mode has to use the same bit depth as the desktop + %bpp = %deskResBPP; + + // Windowed mode also has to run at a smaller resolution than the desktop + if ((%resX >= %deskResX) || (%resY >= %deskResY)) + { + warn("Warning: The requested windowed resolution is equal to or larger than the current desktop resolution. Attempting to find a better resolution"); + + %resCount = Canvas.getModeCount(); + for (%i = (%resCount - 1); %i >= 0; %i--) + { + %testRes = Canvas.getMode(%i); + %testResX = getWord(%testRes, $WORD::RES_X); + %testResY = getWord(%testRes, $WORD::RES_Y); + %testBPP = getWord(%testRes, $WORD::BITDEPTH); + + if (%testBPP != %bpp) + continue; + + if ((%testResX < %deskResX) && (%testResY < %deskResY)) + { + // This will work as our new resolution + %resX = %testResX; + %resY = %testResY; + + warn("Warning: Switching to \"" @ %resX SPC %resY SPC %bpp @ "\""); + + break; + } + } + } + } + + $pref::Video::Resolution = %resX SPC %resY; + $pref::Video::FullScreen = %fs; + $pref::Video::BitDepth = %bpp; + $pref::Video::RefreshRate = %rate; + $pref::Video::AA = %aa; + + if (%fs == 1 || %fs $= "true") + %fsLabel = "Yes"; + else + %fsLabel = "No"; + + echo("Accepted Mode: " NL + "--Resolution : " @ %resX SPC %resY NL + "--Full Screen : " @ %fsLabel NL + "--Bits Per Pixel : " @ %bpp NL + "--Refresh Rate : " @ %rate NL + "--AA TypeXLevel : " @ %aa NL + "--------------"); + + // Actually set the new video mode + Canvas.setVideoMode(%resX, %resY, %fs, %bpp, %rate, %aa); + + commandToServer('setClientAspectRatio', %resX, %resY); + + // AA piggybacks on the AA setting in $pref::Video::mode. + // We need to parse the setting between AA modes, and then it's level + // It's formatted as AATypexAALevel + // So, FXAAx4 or MLAAx2 + if ( isObject( FXAA_PostEffect ) ) + FXAA_PostEffect.isEnabled = ( %aa > 0 ) ? true : false; +} diff --git a/Templates/BaseGame/game/core/console/console.gui b/Templates/BaseGame/game/core/console/console.gui new file mode 100644 index 000000000..8c6c7f63a --- /dev/null +++ b/Templates/BaseGame/game/core/console/console.gui @@ -0,0 +1,51 @@ +new GuiControl(ConsoleDlg) { + profile = "GuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiConsoleEditCtrl(ConsoleEntry) { + profile = "ConsoleTextEditProfile"; + horizSizing = "width"; + vertSizing = "top"; + position = "0 462"; + extent = "640 18"; + minExtent = "8 8"; + visible = "1"; + altCommand = "ConsoleEntry::eval();"; + helpTag = "0"; + maxLength = "255"; + historySize = "40"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "1"; + useSiblingScroller = "1"; + }; + new GuiScrollCtrl() { + internalName = "Scroll"; + profile = "ConsoleScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 462"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOn"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiConsole( ConsoleMessageLogView ) { + profile = "GuiConsoleProfile"; + position = "0 0"; + }; + }; +}; diff --git a/Templates/BaseGame/game/core/console/main.cs b/Templates/BaseGame/game/core/console/main.cs new file mode 100644 index 000000000..b36dafd24 --- /dev/null +++ b/Templates/BaseGame/game/core/console/main.cs @@ -0,0 +1,108 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +exec("./profiles.cs"); +exec("./console.gui"); + +GlobalActionMap.bind("keyboard", "tilde", "toggleConsole"); + +function ConsoleEntry::eval() +{ + %text = trim(ConsoleEntry.getValue()); + if(%text $= "") + return; + + // If it's missing a trailing () and it's not a variable, + // append the parentheses. + if(strpos(%text, "(") == -1 && !isDefined(%text)) { + if(strpos(%text, "=") == -1 && strpos(%text, " ") == -1) { + if(strpos(%text, "{") == -1 && strpos(%text, "}") == -1) { + %text = %text @ "()"; + } + } + } + + // Append a semicolon if need be. + %pos = strlen(%text) - 1; + if(strpos(%text, ";", %pos) == -1 && strpos(%text, "}") == -1) { + %text = %text @ ";"; + } + + // Turn off warnings for assigning from void + // and evaluate the snippet. + if(!isDefined("$Con::warnVoidAssignment")) + %oldWarnVoidAssignment = true; + else + %oldWarnVoidAssignment = $Con::warnVoidAssignment; + $Con::warnVoidAssignment = false; + + echo("==>" @ %text); + if( !startsWith(%text, "function ") + && !startsWith(%text, "datablock ") + && !startsWith(%text, "foreach(") + && !startsWith(%text, "foreach$(") + && !startsWith(%text, "if(") + && !startsWith(%text, "while(") + && !startsWith(%text, "for(") + && !startsWith(%text, "switch(") + && !startsWith(%text, "switch$(")) + eval("%result = " @ %text); + else + eval(%text); + $Con::warnVoidAssignment = %oldWarnVoidAssignment; + + ConsoleEntry.setValue(""); + + // Echo result. + if(%result !$= "") + echo(%result); +} + +function ToggleConsole(%make) +{ + if (%make) { + if (ConsoleDlg.isAwake()) { + // Deactivate the console. + Canvas.popDialog(ConsoleDlg); + } else { + Canvas.pushDialog(ConsoleDlg, 99); + } + } +} + +function ConsoleDlg::hideWindow(%this) +{ + %this-->Scroll.setVisible(false); +} + +function ConsoleDlg::showWindow(%this) +{ + %this-->Scroll.setVisible(true); +} + +function ConsoleDlg::setAlpha( %this, %alpha) +{ + if (%alpha $= "") + ConsoleScrollProfile.fillColor = $ConsoleDefaultFillColor; + else + ConsoleScrollProfile.fillColor = getWords($ConsoleDefaultFillColor, 0, 2) SPC %alpha * 255.0; +} diff --git a/Templates/BaseGame/game/core/console/profiles.cs b/Templates/BaseGame/game/core/console/profiles.cs new file mode 100644 index 000000000..b83dd4fa7 --- /dev/null +++ b/Templates/BaseGame/game/core/console/profiles.cs @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +if(!isObject(GuiConsoleProfile)) +new GuiControlProfile(GuiConsoleProfile) +{ + fontType = ($platform $= "macos") ? "Monaco" : "Lucida Console"; + fontSize = ($platform $= "macos") ? 13 : 12; + fontColor = "255 255 255"; + fontColorHL = "0 255 255"; + fontColorNA = "255 0 0"; + fontColors[6] = "100 100 100"; + fontColors[7] = "100 100 0"; + fontColors[8] = "0 0 100"; + fontColors[9] = "0 100 0"; + category = "Core"; +}; + +if(!isObject(GuiConsoleTextProfile)) +new GuiControlProfile(GuiConsoleTextProfile) +{ + fontColor = "0 0 0"; + autoSizeWidth = true; + autoSizeHeight = true; + textOffset = "2 2"; + opaque = true; + fillColor = "255 255 255"; + border = true; + borderThickness = 1; + borderColor = "0 0 0"; + category = "Core"; +}; + +if(!isObject(ConsoleScrollProfile)) +new GuiControlProfile(ConsoleScrollProfile : GuiScrollProfile) +{ + opaque = true; + fillColor = "0 0 0 175"; + border = 1; + //borderThickness = 0; + borderColor = "0 0 0"; + category = "Core"; +}; + +if(!isObject(ConsoleTextEditProfile)) +new GuiControlProfile(ConsoleTextEditProfile : GuiTextEditProfile) +{ + fillColor = "242 241 240 255"; + fillColorHL = "255 255 255"; + category = "Core"; +}; diff --git a/Templates/BaseGame/game/core/cursor.cs b/Templates/BaseGame/game/core/cursor.cs new file mode 100644 index 000000000..f71bc023a --- /dev/null +++ b/Templates/BaseGame/game/core/cursor.cs @@ -0,0 +1,102 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//--------------------------------------------------------------------------------------------- +// Cursor toggle functions. +//--------------------------------------------------------------------------------------------- +$cursorControlled = true; +function showCursor() +{ + if ($cursorControlled) + lockMouse(false); + Canvas.cursorOn(); +} + +function hideCursor() +{ + if ($cursorControlled) + lockMouse(true); + Canvas.cursorOff(); +} + +//--------------------------------------------------------------------------------------------- +// In the CanvasCursor package we add some additional functionality to the built-in GuiCanvas +// class, of which the global Canvas object is an instance. In this case, the behavior we want +// is for the cursor to automatically display, except when the only guis visible want no +// cursor - usually the in game interface. +//--------------------------------------------------------------------------------------------- +package CanvasCursorPackage +{ + +//--------------------------------------------------------------------------------------------- +// checkCursor +// The checkCursor method iterates through all the root controls on the canvas checking each +// ones noCursor property. If the noCursor property exists as anything other than false or an +// empty string on every control, the cursor will be hidden. +//--------------------------------------------------------------------------------------------- +function GuiCanvas::checkCursor(%this) +{ + %count = %this.getCount(); + for(%i = 0; %i < %count; %i++) + { + %control = %this.getObject(%i); + if ((%control.noCursor $= "") || !%control.noCursor) + { + showCursor(); + return; + } + } + // If we get here, every control requested a hidden cursor, so we oblige. + hideCursor(); +} + +//--------------------------------------------------------------------------------------------- +// The following functions override the GuiCanvas defaults that involve changing the content +// of the Canvas. Basically, all we are doing is adding a call to checkCursor to each one. +//--------------------------------------------------------------------------------------------- +function GuiCanvas::setContent(%this, %ctrl) +{ + Parent::setContent(%this, %ctrl); + %this.checkCursor(); +} + +function GuiCanvas::pushDialog(%this, %ctrl, %layer, %center) +{ + Parent::pushDialog(%this, %ctrl, %layer, %center); + %this.checkCursor(); +} + +function GuiCanvas::popDialog(%this, %ctrl) +{ + Parent::popDialog(%this, %ctrl); + %this.checkCursor(); +} + +function GuiCanvas::popLayer(%this, %layer) +{ + Parent::popLayer(%this, %layer); + %this.checkCursor(); +} + +}; + +activatePackage(CanvasCursorPackage); diff --git a/Templates/BaseGame/game/core/fonts/Arial 10 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial 10 (ansi).uft new file mode 100644 index 000000000..2b5649500 Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial 10 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/fonts/Arial 12 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial 12 (ansi).uft new file mode 100644 index 000000000..67a177016 Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial 12 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/fonts/Arial 14 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial 14 (ansi).uft new file mode 100644 index 000000000..a5fc4ef5f Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial 14 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/fonts/Arial 16 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial 16 (ansi).uft new file mode 100644 index 000000000..058fbb305 Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial 16 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/fonts/Arial 36 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial 36 (ansi).uft new file mode 100644 index 000000000..968441ce3 Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial 36 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/fonts/Arial Bold 14 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial Bold 14 (ansi).uft new file mode 100644 index 000000000..60d7b0227 Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial Bold 14 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/fonts/Arial Bold 16 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial Bold 16 (ansi).uft new file mode 100644 index 000000000..f1f94acb3 Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial Bold 16 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/fonts/Arial Bold 18 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial Bold 18 (ansi).uft new file mode 100644 index 000000000..c93889322 Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial Bold 18 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/fonts/ArialBold 14 (ansi).uft b/Templates/BaseGame/game/core/fonts/ArialBold 14 (ansi).uft new file mode 100644 index 000000000..08d83901e Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/ArialBold 14 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/fonts/ArialItalic 14 (ansi).uft b/Templates/BaseGame/game/core/fonts/ArialItalic 14 (ansi).uft new file mode 100644 index 000000000..d718df5ce Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/ArialItalic 14 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/fonts/Lucida Console 12 (ansi).uft b/Templates/BaseGame/game/core/fonts/Lucida Console 12 (ansi).uft new file mode 100644 index 000000000..bd148fa9b Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Lucida Console 12 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/gfxData/clouds.cs b/Templates/BaseGame/game/core/gfxData/clouds.cs new file mode 100644 index 000000000..00d56d6d3 --- /dev/null +++ b/Templates/BaseGame/game/core/gfxData/clouds.cs @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// CloudLayer +//------------------------------------------------------------------------------ + +singleton ShaderData( CloudLayerShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/cloudLayerV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/cloudLayerP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/cloudLayerV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/cloudLayerP.glsl"; + + samplerNames[0] = "$normalHeightMap"; + + pixVersion = 2.0; +}; + +//------------------------------------------------------------------------------ +// BasicClouds +//------------------------------------------------------------------------------ + +singleton ShaderData( BasicCloudsShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/basicCloudsV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/basicCloudsP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/basicCloudsV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/basicCloudsP.glsl"; + + samplerNames[0] = "$diffuseMap"; + + pixVersion = 2.0; +}; diff --git a/Templates/BaseGame/game/core/gfxData/commonMaterialData.cs b/Templates/BaseGame/game/core/gfxData/commonMaterialData.cs new file mode 100644 index 000000000..c5d8ef5bc --- /dev/null +++ b/Templates/BaseGame/game/core/gfxData/commonMaterialData.cs @@ -0,0 +1,79 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Anim flag settings - must match material.h +// These cannot be enumed through script becuase it cannot +// handle the "|" operation for combining them together +// ie. Scroll | Wave does not work. +//----------------------------------------------------------------------------- +$scroll = 1; +$rotate = 2; +$wave = 4; +$scale = 8; +$sequence = 16; + + +// Common stateblock definitions +new GFXSamplerStateData(SamplerClampLinear) +{ + textureColorOp = GFXTOPModulate; + addressModeU = GFXAddressClamp; + addressModeV = GFXAddressClamp; + addressModeW = GFXAddressClamp; + magFilter = GFXTextureFilterLinear; + minFilter = GFXTextureFilterLinear; + mipFilter = GFXTextureFilterLinear; +}; + +new GFXSamplerStateData(SamplerClampPoint) +{ + textureColorOp = GFXTOPModulate; + addressModeU = GFXAddressClamp; + addressModeV = GFXAddressClamp; + addressModeW = GFXAddressClamp; + magFilter = GFXTextureFilterPoint; + minFilter = GFXTextureFilterPoint; + mipFilter = GFXTextureFilterPoint; +}; + +new GFXSamplerStateData(SamplerWrapLinear) +{ + textureColorOp = GFXTOPModulate; + addressModeU = GFXTextureAddressWrap; + addressModeV = GFXTextureAddressWrap; + addressModeW = GFXTextureAddressWrap; + magFilter = GFXTextureFilterLinear; + minFilter = GFXTextureFilterLinear; + mipFilter = GFXTextureFilterLinear; +}; + +new GFXSamplerStateData(SamplerWrapPoint) +{ + textureColorOp = GFXTOPModulate; + addressModeU = GFXTextureAddressWrap; + addressModeV = GFXTextureAddressWrap; + addressModeW = GFXTextureAddressWrap; + magFilter = GFXTextureFilterPoint; + minFilter = GFXTextureFilterPoint; + mipFilter = GFXTextureFilterPoint; +}; diff --git a/Templates/BaseGame/game/core/gfxData/scatterSky.cs b/Templates/BaseGame/game/core/gfxData/scatterSky.cs new file mode 100644 index 000000000..5add01d8b --- /dev/null +++ b/Templates/BaseGame/game/core/gfxData/scatterSky.cs @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +new GFXStateBlockData( ScatterSkySBData ) +{ + cullMode = "GFXCullNone"; + + zDefined = true; + zEnable = true; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampLinear; + vertexColorEnable = true; +}; + +singleton ShaderData( ScatterSkyShaderData ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/scatterSkyV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/scatterSkyP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/scatterSkyV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/scatterSkyP.glsl"; + + samplerNames[0] = "$nightSky"; + + pixVersion = 2.0; +}; diff --git a/Templates/BaseGame/game/core/gfxData/shaders.cs b/Templates/BaseGame/game/core/gfxData/shaders.cs new file mode 100644 index 000000000..5f733abd0 --- /dev/null +++ b/Templates/BaseGame/game/core/gfxData/shaders.cs @@ -0,0 +1,140 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// This file contains shader data necessary for various engine utility functions +//----------------------------------------------------------------------------- + + +singleton ShaderData( ParticlesShaderData ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/particlesV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/particlesP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/particlesV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/particlesP.glsl"; + + samplerNames[0] = "$diffuseMap"; + samplerNames[1] = "$prepassTex"; + samplerNames[2] = "$paraboloidLightMap"; + + pixVersion = 2.0; +}; + +singleton ShaderData( OffscreenParticleCompositeShaderData ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/particleCompositeV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/particleCompositeP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/particleCompositeV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/particleCompositeP.glsl"; + + samplerNames[0] = "$colorSource"; + samplerNames[1] = "$edgeSource"; + + pixVersion = 2.0; +}; + +//----------------------------------------------------------------------------- +// Planar Reflection +//----------------------------------------------------------------------------- +new ShaderData( ReflectBump ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/planarReflectBumpV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/planarReflectBumpP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/planarReflectBumpV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/planarReflectBumpP.glsl"; + + samplerNames[0] = "$diffuseMap"; + samplerNames[1] = "$refractMap"; + samplerNames[2] = "$bumpMap"; + + pixVersion = 2.0; +}; + +new ShaderData( Reflect ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/planarReflectV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/planarReflectP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/planarReflectV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/planarReflectP.glsl"; + + samplerNames[0] = "$diffuseMap"; + samplerNames[1] = "$refractMap"; + + pixVersion = 1.4; +}; + +//----------------------------------------------------------------------------- +// fxFoliageReplicator +//----------------------------------------------------------------------------- +new ShaderData( fxFoliageReplicatorShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/fxFoliageReplicatorV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/fxFoliageReplicatorP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/fxFoliageReplicatorV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/fxFoliageReplicatorP.glsl"; + + samplerNames[0] = "$diffuseMap"; + samplerNames[1] = "$alphaMap"; + + pixVersion = 1.4; +}; + +singleton ShaderData( VolumetricFogPrePassShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogPreV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogPreP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogPreV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogPreP.glsl"; + + pixVersion = 3.0; +}; +singleton ShaderData( VolumetricFogShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogP.glsl"; + + samplerNames[0] = "$prepassTex"; + samplerNames[1] = "$depthBuffer"; + samplerNames[2] = "$frontBuffer"; + samplerNames[3] = "$density"; + + pixVersion = 3.0; +}; +singleton ShaderData( VolumetricFogReflectionShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogPreV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogRefl.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogPreV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogRefl.glsl"; + + pixVersion = 3.0; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/core/gfxData/terrainBlock.cs b/Templates/BaseGame/game/core/gfxData/terrainBlock.cs new file mode 100644 index 000000000..69802b1da --- /dev/null +++ b/Templates/BaseGame/game/core/gfxData/terrainBlock.cs @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +/// Used when generating the blended base texture. +singleton ShaderData( TerrainBlendShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/terrain/blendV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/terrain/blendP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/terrain/gl/blendV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/terrain/gl/blendP.glsl"; + + samplerNames[0] = "layerTex"; + samplerNames[1] = "textureMap"; + + pixVersion = 2.0; +}; diff --git a/Templates/BaseGame/game/core/gfxData/water.cs b/Templates/BaseGame/game/core/gfxData/water.cs new file mode 100644 index 000000000..a7332d0c4 --- /dev/null +++ b/Templates/BaseGame/game/core/gfxData/water.cs @@ -0,0 +1,208 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + + +//----------------------------------------------------------------------------- +// Water +//----------------------------------------------------------------------------- + +singleton ShaderData( WaterShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/water/waterV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/water/waterP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/water/gl/waterV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/water/gl/waterP.glsl"; + + samplerNames[0] = "$bumpMap"; // noise + samplerNames[1] = "$prepassTex"; // #prepass + samplerNames[2] = "$reflectMap"; // $reflectbuff + samplerNames[3] = "$refractBuff"; // $backbuff + samplerNames[4] = "$skyMap"; // $cubemap + samplerNames[5] = "$foamMap"; // foam + samplerNames[6] = "$depthGradMap"; // depthMap ( color gradient ) + + pixVersion = 3.0; +}; + +new GFXSamplerStateData(WaterSampler) +{ + textureColorOp = GFXTOPModulate; + addressModeU = GFXAddressWrap; + addressModeV = GFXAddressWrap; + addressModeW = GFXAddressWrap; + magFilter = GFXTextureFilterLinear; + minFilter = GFXTextureFilterAnisotropic; + mipFilter = GFXTextureFilterLinear; + maxAnisotropy = 4; +}; + +singleton GFXStateBlockData( WaterStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = WaterSampler; // noise + samplerStates[1] = SamplerClampPoint; // #prepass + samplerStates[2] = SamplerClampLinear; // $reflectbuff + samplerStates[3] = SamplerClampPoint; // $backbuff + samplerStates[4] = SamplerWrapLinear; // $cubemap + samplerStates[5] = SamplerWrapLinear; // foam + samplerStates[6] = SamplerClampLinear; // depthMap ( color gradient ) + cullDefined = true; + cullMode = "GFXCullCCW"; +}; + +singleton GFXStateBlockData( UnderWaterStateBlock : WaterStateBlock ) +{ + cullMode = "GFXCullCW"; +}; + +singleton CustomMaterial( WaterMat ) +{ + sampler["prepassTex"] = "#prepass"; + sampler["reflectMap"] = "$reflectbuff"; + sampler["refractBuff"] = "$backbuff"; + // These samplers are set in code not here. + // This is to allow different WaterObject instances + // to use this same material but override these textures + // per instance. + //sampler["bumpMap"] = ""; + //sampler["skyMap"] = ""; + //sampler["foamMap"] = ""; + //sampler["depthGradMap"] = ""; + + shader = WaterShader; + stateBlock = WaterStateBlock; + version = 3.0; + + useAnisotropic[0] = true; +}; + +//----------------------------------------------------------------------------- +// Underwater +//----------------------------------------------------------------------------- + +singleton ShaderData( UnderWaterShader : WaterShader ) +{ + defines = "UNDERWATER"; +}; + +singleton CustomMaterial( UnderwaterMat ) +{ + // These samplers are set in code not here. + // This is to allow different WaterObject instances + // to use this same material but override these textures + // per instance. + //sampler["bumpMap"] = "core/art/water/noise02"; + //sampler["foamMap"] = "core/art/water/foam"; + + sampler["prepassTex"] = "#prepass"; + sampler["refractBuff"] = "$backbuff"; + + shader = UnderWaterShader; + stateBlock = UnderWaterStateBlock; + specular = "0.75 0.75 0.75 1.0"; + specularPower = 48.0; + version = 3.0; +}; + +//----------------------------------------------------------------------------- +// Basic Water +//----------------------------------------------------------------------------- + +singleton ShaderData( WaterBasicShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/water/waterBasicV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/water/waterBasicP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/water/gl/waterBasicV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/water/gl/waterBasicP.glsl"; + + samplerNames[0] = "$bumpMap"; + samplerNames[2] = "$reflectMap"; + samplerNames[3] = "$refractBuff"; + samplerNames[4] = "$skyMap"; + samplerNames[5] = "$depthGradMap"; + + pixVersion = 2.0; +}; + +singleton GFXStateBlockData( WaterBasicStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = WaterSampler; // noise + samplerStates[2] = SamplerClampLinear; // $reflectbuff + samplerStates[3] = SamplerClampPoint; // $backbuff + samplerStates[4] = SamplerWrapLinear; // $cubemap + cullDefined = true; + cullMode = "GFXCullCCW"; +}; + +singleton GFXStateBlockData( UnderWaterBasicStateBlock : WaterBasicStateBlock ) +{ + cullMode = "GFXCullCW"; +}; + +singleton CustomMaterial( WaterBasicMat ) +{ + // These samplers are set in code not here. + // This is to allow different WaterObject instances + // to use this same material but override these textures + // per instance. + //sampler["bumpMap"] = "core/art/water/noise02"; + //sampler["skyMap"] = "$cubemap"; + + //sampler["prepassTex"] = "#prepass"; + sampler["reflectMap"] = "$reflectbuff"; + sampler["refractBuff"] = "$backbuff"; + + cubemap = NewLevelSkyCubemap; + shader = WaterBasicShader; + stateBlock = WaterBasicStateBlock; + version = 2.0; +}; + +//----------------------------------------------------------------------------- +// Basic UnderWater +//----------------------------------------------------------------------------- + +singleton ShaderData( UnderWaterBasicShader : WaterBasicShader) +{ + defines = "UNDERWATER"; +}; + +singleton CustomMaterial( UnderwaterBasicMat ) +{ + // These samplers are set in code not here. + // This is to allow different WaterObject instances + // to use this same material but override these textures + // per instance. + //sampler["bumpMap"] = "core/art/water/noise02"; + //samplers["skyMap"] = "$cubemap"; + + //sampler["prepassTex"] = "#prepass"; + sampler["refractBuff"] = "$backbuff"; + + shader = UnderWaterBasicShader; + stateBlock = UnderWaterBasicStateBlock; + version = 2.0; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/core/gfxprofile/D3D9.ATITechnologiesInc.cs b/Templates/BaseGame/game/core/gfxprofile/D3D9.ATITechnologiesInc.cs new file mode 100644 index 000000000..10c6bdf5b --- /dev/null +++ b/Templates/BaseGame/game/core/gfxprofile/D3D9.ATITechnologiesInc.cs @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// ATI Vendor Profile Script +// +// This script is responsible for setting global +// capability strings based on the nVidia vendor. + +if(GFXCardProfiler::getVersion() < 64.44) +{ + $GFX::OutdatedDrivers = true; + $GFX::OutdatedDriversLink = "You can get newer drivers here.."; +} +else +{ + $GFX::OutdatedDrivers = false; +} diff --git a/Templates/BaseGame/game/core/gfxprofile/D3D9.NVIDIA.GeForce8600.cs b/Templates/BaseGame/game/core/gfxprofile/D3D9.NVIDIA.GeForce8600.cs new file mode 100644 index 000000000..328788dac --- /dev/null +++ b/Templates/BaseGame/game/core/gfxprofile/D3D9.NVIDIA.GeForce8600.cs @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// nVidia Vendor Profile Script +// +// This script is responsible for setting global +// capability strings based on the nVidia vendor. + +if(GFXCardProfiler::getVersion() < 1.2) +{ + $GFX::OutdatedDrivers = true; + $GFX::OutdatedDriversLink = "You can get newer drivers here.."; +} +else +{ + $GFX::OutdatedDrivers = false; +} diff --git a/Templates/BaseGame/game/core/gfxprofile/D3D9.NVIDIA.QuadroFXGo1000.cs b/Templates/BaseGame/game/core/gfxprofile/D3D9.NVIDIA.QuadroFXGo1000.cs new file mode 100644 index 000000000..5681b2f6d --- /dev/null +++ b/Templates/BaseGame/game/core/gfxprofile/D3D9.NVIDIA.QuadroFXGo1000.cs @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// nVidia Vendor Profile Script +// +// This script is responsible for setting global +// capability strings based on the nVidia vendor. + +if(GFXCardProfiler::getVersion() < 53.82) +{ + $GFX::OutdatedDrivers = true; + $GFX::OutdatedDriversLink = "You can get newer drivers here.."; +} +else +{ + $GFX::OutdatedDrivers = false; +} + +// Silly card has trouble with this! +GFXCardProfiler::setCapability("autoMipmapLevel", false); diff --git a/Templates/BaseGame/game/core/gfxprofile/D3D9.NVIDIA.cs b/Templates/BaseGame/game/core/gfxprofile/D3D9.NVIDIA.cs new file mode 100644 index 000000000..b33b8d5d3 --- /dev/null +++ b/Templates/BaseGame/game/core/gfxprofile/D3D9.NVIDIA.cs @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// nVidia Vendor Profile Script +// +// This script is responsible for setting global +// capability strings based on the nVidia vendor. + +if(GFXCardProfiler::getVersion() < 56.72) +{ + $GFX::OutdatedDrivers = true; + $GFX::OutdatedDriversLink = "You can get newer drivers here.."; +} +else +{ + $GFX::OutdatedDrivers = false; +} diff --git a/Templates/BaseGame/game/core/gfxprofile/D3D9.cs b/Templates/BaseGame/game/core/gfxprofile/D3D9.cs new file mode 100644 index 000000000..e1e299341 --- /dev/null +++ b/Templates/BaseGame/game/core/gfxprofile/D3D9.cs @@ -0,0 +1,26 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Direct3D 9 Renderer Profile Script +// +// This script is responsible for setting global +// capability strings based on the D3D9 renderer type. \ No newline at end of file diff --git a/Templates/BaseGame/game/core/globals.cs b/Templates/BaseGame/game/core/globals.cs new file mode 100644 index 000000000..d730d63a4 --- /dev/null +++ b/Templates/BaseGame/game/core/globals.cs @@ -0,0 +1,102 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +// DInput keyboard, mouse, and joystick prefs +// ---------------------------------------------------------------------------- + +$pref::Input::MouseEnabled = 1; +$pref::Input::LinkMouseSensitivity = 1; +$pref::Input::KeyboardEnabled = 1; +$pref::Input::KeyboardTurnSpeed = 0.1; +$pref::Input::JoystickEnabled = 0; + +// ---------------------------------------------------------------------------- +// Video Preferences +// ---------------------------------------------------------------------------- + +// Set directory paths for various data or default images. +$pref::Video::ProfilePath = "core/gfxprofile"; +$pref::Video::missingTexturePath = "core/images/missingTexture.png"; +$pref::Video::unavailableTexturePath = "core/images/unavailable.png"; +$pref::Video::warningTexturePath = "core/images/warnMat.dds"; + +$pref::Video::disableVerticalSync = 1; +$pref::Video::mode = "800 600 false 32 60 4"; +$pref::Video::defaultFenceCount = 0; + +// This disables the hardware FSAA/MSAA so that we depend completely on the FXAA +// post effect which works on all cards and in deferred mode. Note that the new +// Intel Hybrid graphics on laptops will fail to initialize when hardware AA is +// enabled... so you've been warned. +$pref::Video::disableHardwareAA = true; + +$pref::Video::disableNormalmapping = false; +$pref::Video::disablePixSpecular = false; +$pref::Video::disableCubemapping = false; +$pref::Video::disableParallaxMapping = false; + +// The number of mipmap levels to drop on loaded textures to reduce video memory +// usage. It will skip any textures that have been defined as not allowing down +// scaling. +$pref::Video::textureReductionLevel = 0; + +$pref::Video::defaultAnisotropy = 1; +//$pref::Video::Gamma = 1.0; + +/// AutoDetect graphics quality levels the next startup. +$pref::Video::autoDetect = 1; + +// ---------------------------------------------------------------------------- +// Shader stuff +// ---------------------------------------------------------------------------- + +// This is the path used by ShaderGen to cache procedural shaders. If left +// blank ShaderGen will only cache shaders to memory and not to disk. +$shaderGen::cachePath = ""; + +// Uncomment to disable ShaderGen, useful when debugging +//$ShaderGen::GenNewShaders = false; + +// Uncomment to dump disassembly for any shader that is compiled to disk. These +// will appear as shadername_dis.txt in the same path as the shader file. +//$gfx::disassembleAllShaders = true; + +// ---------------------------------------------------------------------------- +// Lighting and shadowing +// ---------------------------------------------------------------------------- + +// Uncomment to enable AdvancedLighting on the Mac (T3D 2009 Beta 3) +//$pref::machax::enableAdvancedLighting = true; + +$sceneLighting::cacheSize = 20000; +$sceneLighting::purgeMethod = "lastCreated"; +$sceneLighting::cacheLighting = 1; + +$pref::Shadows::textureScalar = 1.0; +$pref::Shadows::disable = false; + +// Sets the shadow filtering mode. +// None - Disables filtering. +// SoftShadow - Does a simple soft shadow +// SoftShadowHighQuality +$pref::Shadows::filterMode = "SoftShadow"; diff --git a/Templates/BaseGame/game/core/helperFunctions.cs b/Templates/BaseGame/game/core/helperFunctions.cs new file mode 100644 index 000000000..8559eda88 --- /dev/null +++ b/Templates/BaseGame/game/core/helperFunctions.cs @@ -0,0 +1,528 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------ +// Check if a script file exists, compiled or not. +function isScriptFile(%path) +{ + if( isFile(%path @ ".dso") || isFile(%path) ) + return true; + + return false; +} + +function loadMaterials() +{ + // Load any materials files for which we only have DSOs. + + for( %file = findFirstFile( "*/materials.cs.dso" ); + %file !$= ""; + %file = findNextFile( "*/materials.cs.dso" )) + { + // Only execute, if we don't have the source file. + %csFileName = getSubStr( %file, 0, strlen( %file ) - 4 ); + if( !isFile( %csFileName ) ) + exec( %csFileName ); + } + + // Load all source material files. + + for( %file = findFirstFile( "*/materials.cs" ); + %file !$= ""; + %file = findNextFile( "*/materials.cs" )) + { + exec( %file ); + } + + // Load all materials created by the material editor if + // the folder exists + if( IsDirectory( "materialEditor" ) ) + { + for( %file = findFirstFile( "materialEditor/*.cs.dso" ); + %file !$= ""; + %file = findNextFile( "materialEditor/*.cs.dso" )) + { + // Only execute, if we don't have the source file. + %csFileName = getSubStr( %file, 0, strlen( %file ) - 4 ); + if( !isFile( %csFileName ) ) + exec( %csFileName ); + } + + for( %file = findFirstFile( "materialEditor/*.cs" ); + %file !$= ""; + %file = findNextFile( "materialEditor/*.cs" )) + { + exec( %file ); + } + } +} + +function reloadMaterials() +{ + reloadTextures(); + loadMaterials(); + reInitMaterials(); +} + +function loadDatablockFiles( %datablockFiles, %recurse ) +{ + if ( %recurse ) + { + recursiveLoadDatablockFiles( %datablockFiles, 9999 ); + return; + } + + %count = %datablockFiles.count(); + for ( %i=0; %i < %count; %i++ ) + { + %file = %datablockFiles.getKey( %i ); + if ( !isFile(%file @ ".dso") && !isFile(%file) ) + continue; + + exec( %file ); + } + + // Destroy the incoming list. + //%datablockFiles.delete(); +} + +function recursiveLoadDatablockFiles( %datablockFiles, %previousErrors ) +{ + %reloadDatablockFiles = new ArrayObject(); + + // Keep track of the number of datablocks that + // failed during this pass. + %failedDatablocks = 0; + + // Try re-executing the list of datablock files. + %count = %datablockFiles.count(); + for ( %i=0; %i < %count; %i++ ) + { + %file = %datablockFiles.getKey( %i ); + if ( !isFile(%file @ ".dso") && !isFile(%file) ) + continue; + + // Start counting copy constructor creation errors. + $Con::objectCopyFailures = 0; + + exec( %file ); + + // If errors occured then store this file for re-exec later. + if ( $Con::objectCopyFailures > 0 ) + { + %reloadDatablockFiles.add( %file ); + %failedDatablocks = %failedDatablocks + $Con::objectCopyFailures; + } + } + + // Clear the object copy failure counter so that + // we get console error messages again. + $Con::objectCopyFailures = -1; + + // Delete the old incoming list... we're done with it. + //%datablockFiles.delete(); + + // If we still have datablocks to retry. + %newCount = %reloadDatablockFiles.count(); + if ( %newCount > 0 ) + { + // If the datablock failures have not been reduced + // from the last pass then we must have a real syntax + // error and not just a bad dependancy. + if ( %previousErrors > %failedDatablocks ) + recursiveLoadDatablockFiles( %reloadDatablockFiles, %failedDatablocks ); + + else + { + // Since we must have real syntax errors do one + // last normal exec to output error messages. + loadDatablockFiles( %reloadDatablockFiles, false ); + } + + return; + } + + // Cleanup the empty reload list. + %reloadDatablockFiles.delete(); +} + +function getPrefpath() +{ + %temp = getUserHomeDirectory(); + echo(%temp); + if(!isDirectory(%temp)) + { + %temp = getUserDataDirectory(); + echo(%temp); + if(!isDirectory(%temp)) + { + $prefpath = "data"; + } + else + { + //put it in appdata/roaming + $prefpath = %temp @ "/" @ $appName @ "/preferences"; + } + } + else + { + //put it in user/documents + $prefPath = %temp @ "/" @ $appName @ "/preferences"; + } + return $prefPath; +} + +function updateTSShapeLoadProgress(%progress, %msg) +{ + // Check if the loading GUI is visible and use that instead of the + // separate import progress GUI if possible + if ( isObject(LoadingGui) && LoadingGui.isAwake() ) + { + // Save/Restore load progress at the start/end of the import process + if ( %progress == 0 ) + { + ColladaImportProgress.savedProgress = LoadingProgress.getValue(); + ColladaImportProgress.savedText = LoadingProgressTxt.getValue(); + + ColladaImportProgress.msgPrefix = "Importing " @ %msg; + %msg = "Reading file into memory..."; + } + else if ( %progress == 1.0 ) + { + LoadingProgress.setValue( ColladaImportProgress.savedProgress ); + LoadingProgressTxt.setValue( ColladaImportProgress.savedText ); + } + + %msg = ColladaImportProgress.msgPrefix @ ": " @ %msg; + + %progressCtrl = LoadingProgress; + %textCtrl = LoadingProgressTxt; + } + else + { + //it's probably the editors using it + if(isFunction("updateToolTSShapeLoadProgress")) + { + updateToolTSShapeLoadProgress(%progress, %msg); + } + } + + // Update progress indicators + if (%progress == 0) + { + %progressCtrl.setValue(0.001); + %textCtrl.setText(%msg); + } + else if (%progress != 1.0) + { + %progressCtrl.setValue(%progress); + %textCtrl.setText(%msg); + } + + Canvas.repaint(33); +} + +/// A helper function which will return the ghosted client object +/// from a server object when connected to a local server. +function serverToClientObject( %serverObject ) +{ + assert( isObject( LocalClientConnection ), "serverToClientObject() - No local client connection found!" ); + assert( isObject( ServerConnection ), "serverToClientObject() - No server connection found!" ); + + %ghostId = LocalClientConnection.getGhostId( %serverObject ); + if ( %ghostId == -1 ) + return 0; + + return ServerConnection.resolveGhostID( %ghostId ); +} + +//---------------------------------------------------------------------------- +// Debug commands +//---------------------------------------------------------------------------- + +function netSimulateLag( %msDelay, %packetLossPercent ) +{ + if ( %packetLossPercent $= "" ) + %packetLossPercent = 0; + + commandToServer( 'NetSimulateLag', %msDelay, %packetLossPercent ); +} + +//Various client functions + +function validateDatablockName(%name) +{ + // remove whitespaces at beginning and end + %name = trim( %name ); + + // remove numbers at the beginning + %numbers = "0123456789"; + while( strlen(%name) > 0 ) + { + // the first character + %firstChar = getSubStr( %name, 0, 1 ); + // if the character is a number remove it + if( strpos( %numbers, %firstChar ) != -1 ) + { + %name = getSubStr( %name, 1, strlen(%name) -1 ); + %name = ltrim( %name ); + } + else + break; + } + + // replace whitespaces with underscores + %name = strreplace( %name, " ", "_" ); + + // remove any other invalid characters + %invalidCharacters = "-+*/%$&§=()[].?\"#,;!~<>|°^{}"; + %name = stripChars( %name, %invalidCharacters ); + + if( %name $= "" ) + %name = "Unnamed"; + + return %name; +} + +//-------------------------------------------------------------------------- +// Finds location of %word in %text, starting at %start. Works just like strPos +//-------------------------------------------------------------------------- + +function wordPos(%text, %word, %start) +{ + if (%start $= "") %start = 0; + + if (strpos(%text, %word, 0) == -1) return -1; + %count = getWordCount(%text); + if (%start >= %count) return -1; + for (%i = %start; %i < %count; %i++) + { + if (getWord( %text, %i) $= %word) return %i; + } + return -1; +} + +//-------------------------------------------------------------------------- +// Finds location of %field in %text, starting at %start. Works just like strPos +//-------------------------------------------------------------------------- + +function fieldPos(%text, %field, %start) +{ + if (%start $= "") %start = 0; + + if (strpos(%text, %field, 0) == -1) return -1; + %count = getFieldCount(%text); + if (%start >= %count) return -1; + for (%i = %start; %i < %count; %i++) + { + if (getField( %text, %i) $= %field) return %i; + } + return -1; +} + +//-------------------------------------------------------------------------- +// returns the text in a file with "\n" at the end of each line +//-------------------------------------------------------------------------- + +function loadFileText( %file) +{ + %fo = new FileObject(); + %fo.openForRead(%file); + %text = ""; + while(!%fo.isEOF()) + { + %text = %text @ %fo.readLine(); + if (!%fo.isEOF()) %text = %text @ "\n"; + } + + %fo.delete(); + return %text; +} + +function setValueSafe(%dest, %val) +{ + %cmd = %dest.command; + %alt = %dest.altCommand; + %dest.command = ""; + %dest.altCommand = ""; + + %dest.setValue(%val); + + %dest.command = %cmd; + %dest.altCommand = %alt; +} + +function shareValueSafe(%source, %dest) +{ + setValueSafe(%dest, %source.getValue()); +} + +function shareValueSafeDelay(%source, %dest, %delayMs) +{ + schedule(%delayMs, 0, shareValueSafe, %source, %dest); +} + + +//------------------------------------------------------------------------------ +// An Aggregate Control is a plain GuiControl that contains other controls, +// which all share a single job or represent a single value. +//------------------------------------------------------------------------------ + +// AggregateControl.setValue( ) propagates the value to any control that has an +// internal name. +function AggregateControl::setValue(%this, %val, %child) +{ + for(%i = 0; %i < %this.getCount(); %i++) + { + %obj = %this.getObject(%i); + if( %obj == %child ) + continue; + + if(%obj.internalName !$= "") + setValueSafe(%obj, %val); + } +} + +// AggregateControl.getValue() uses the value of the first control that has an +// internal name, if it has not cached a value via .setValue +function AggregateControl::getValue(%this) +{ + for(%i = 0; %i < %this.getCount(); %i++) + { + %obj = %this.getObject(%i); + if(%obj.internalName !$= "") + { + //error("obj = " @ %obj.getId() @ ", " @ %obj.getName() @ ", " @ %obj.internalName ); + //error(" value = " @ %obj.getValue()); + return %obj.getValue(); + } + } +} + +// AggregateControl.updateFromChild( ) is called by child controls to propagate +// a new value, and to trigger the onAction() callback. +function AggregateControl::updateFromChild(%this, %child) +{ + %val = %child.getValue(); + if(%val == mCeil(%val)){ + %val = mCeil(%val); + }else{ + if ( %val <= -100){ + %val = mCeil(%val); + }else if ( %val <= -10){ + %val = mFloatLength(%val, 1); + }else if ( %val < 0){ + %val = mFloatLength(%val, 2); + }else if ( %val >= 1000){ + %val = mCeil(%val); + }else if ( %val >= 100){ + %val = mFloatLength(%val, 1); + }else if ( %val >= 10){ + %val = mFloatLength(%val, 2); + }else if ( %val > 0){ + %val = mFloatLength(%val, 3); + } + } + %this.setValue(%val, %child); + %this.onAction(); +} + +// default onAction stub, here only to prevent console spam warnings. +function AggregateControl::onAction(%this) +{ +} + +// call a method on all children that have an internalName and that implement the method. +function AggregateControl::callMethod(%this, %method, %args) +{ + for(%i = 0; %i < %this.getCount(); %i++) + { + %obj = %this.getObject(%i); + if(%obj.internalName !$= "" && %obj.isMethod(%method)) + eval(%obj @ "." @ %method @ "( " @ %args @ " );"); + } + +} + +// A function used in order to easily parse the MissionGroup for classes . I'm pretty +// sure at this point the function can be easily modified to search the any group as well. +function parseMissionGroup( %className, %childGroup ) +{ + if( getWordCount( %childGroup ) == 0) + %currentGroup = "MissionGroup"; + else + %currentGroup = %childGroup; + + for(%i = 0; %i < (%currentGroup).getCount(); %i++) + { + if( (%currentGroup).getObject(%i).getClassName() $= %className ) + return true; + + if( (%currentGroup).getObject(%i).getClassName() $= "SimGroup" ) + { + if( parseMissionGroup( %className, (%currentGroup).getObject(%i).getId() ) ) + return true; + } + } +} + +// A variation of the above used to grab ids from the mission group based on classnames +function parseMissionGroupForIds( %className, %childGroup ) +{ + if( getWordCount( %childGroup ) == 0) + %currentGroup = "MissionGroup"; + else + %currentGroup = %childGroup; + + for(%i = 0; %i < (%currentGroup).getCount(); %i++) + { + if( (%currentGroup).getObject(%i).getClassName() $= %className ) + %classIds = %classIds @ (%currentGroup).getObject(%i).getId() @ " "; + + if( (%currentGroup).getObject(%i).getClassName() $= "SimGroup" ) + %classIds = %classIds @ parseMissionGroupForIds( %className, (%currentGroup).getObject(%i).getId()); + } + return trim( %classIds ); +} + +//------------------------------------------------------------------------------ +// Altered Version of TGB's QuickEditDropDownTextEditCtrl +//------------------------------------------------------------------------------ + +function QuickEditDropDownTextEditCtrl::onRenameItem( %this ) +{ +} + +function QuickEditDropDownTextEditCtrl::updateFromChild( %this, %ctrl ) +{ + if( %ctrl.internalName $= "PopUpMenu" ) + { + %this->TextEdit.setText( %ctrl.getText() ); + } + else if ( %ctrl.internalName $= "TextEdit" ) + { + %popup = %this->PopupMenu; + %popup.changeTextById( %popup.getSelected(), %ctrl.getText() ); + %this.onRenameItem(); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/images/button.png b/Templates/BaseGame/game/core/images/button.png new file mode 100644 index 000000000..1c7361e25 Binary files /dev/null and b/Templates/BaseGame/game/core/images/button.png differ diff --git a/Templates/BaseGame/game/core/images/checkbox.png b/Templates/BaseGame/game/core/images/checkbox.png new file mode 100644 index 000000000..46e0ac959 Binary files /dev/null and b/Templates/BaseGame/game/core/images/checkbox.png differ diff --git a/Templates/BaseGame/game/core/images/group-border.png b/Templates/BaseGame/game/core/images/group-border.png new file mode 100644 index 000000000..61234ae1f Binary files /dev/null and b/Templates/BaseGame/game/core/images/group-border.png differ diff --git a/Templates/BaseGame/game/core/images/inactive-overlay.png b/Templates/BaseGame/game/core/images/inactive-overlay.png new file mode 100644 index 000000000..feab83209 Binary files /dev/null and b/Templates/BaseGame/game/core/images/inactive-overlay.png differ diff --git a/Templates/BaseGame/game/core/images/loadingbar.png b/Templates/BaseGame/game/core/images/loadingbar.png new file mode 100644 index 000000000..34f594403 Binary files /dev/null and b/Templates/BaseGame/game/core/images/loadingbar.png differ diff --git a/Templates/BaseGame/game/core/images/materials.cs b/Templates/BaseGame/game/core/images/materials.cs new file mode 100644 index 000000000..2441947e6 --- /dev/null +++ b/Templates/BaseGame/game/core/images/materials.cs @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton Material( BlankWhite ) +{ + diffuseMap[0] = "data/art/white"; + mapTo = "white"; + materialTag0 = "Miscellaneous"; +}; + +singleton Material( Empty ) +{ +}; + +singleton Material(WarningMaterial) { + detailMap[0] = "missingTexture"; + diffuseColor[0] = "25 16 0"; + emissive[0] = false; + translucent = false; +}; diff --git a/Templates/BaseGame/game/core/images/missingTexture.png b/Templates/BaseGame/game/core/images/missingTexture.png new file mode 100644 index 000000000..80a7874da Binary files /dev/null and b/Templates/BaseGame/game/core/images/missingTexture.png differ diff --git a/Templates/BaseGame/game/core/images/scrollBar.png b/Templates/BaseGame/game/core/images/scrollBar.png new file mode 100644 index 000000000..e8c34dc85 Binary files /dev/null and b/Templates/BaseGame/game/core/images/scrollBar.png differ diff --git a/Templates/BaseGame/game/core/images/textEdit.png b/Templates/BaseGame/game/core/images/textEdit.png new file mode 100644 index 000000000..5a65fac3c Binary files /dev/null and b/Templates/BaseGame/game/core/images/textEdit.png differ diff --git a/Templates/BaseGame/game/core/images/thumbHighlightButton.png b/Templates/BaseGame/game/core/images/thumbHighlightButton.png new file mode 100644 index 000000000..9d83b75f3 Binary files /dev/null and b/Templates/BaseGame/game/core/images/thumbHighlightButton.png differ diff --git a/Templates/BaseGame/game/core/images/unavailable.png b/Templates/BaseGame/game/core/images/unavailable.png new file mode 100644 index 000000000..9d818a376 Binary files /dev/null and b/Templates/BaseGame/game/core/images/unavailable.png differ diff --git a/Templates/BaseGame/game/core/images/warnMat.dds b/Templates/BaseGame/game/core/images/warnMat.dds new file mode 100644 index 000000000..ea99dcbd7 Binary files /dev/null and b/Templates/BaseGame/game/core/images/warnMat.dds differ diff --git a/Templates/BaseGame/game/core/images/window.png b/Templates/BaseGame/game/core/images/window.png new file mode 100644 index 000000000..d9e8006e4 Binary files /dev/null and b/Templates/BaseGame/game/core/images/window.png differ diff --git a/Templates/BaseGame/game/core/lighting.cs b/Templates/BaseGame/game/core/lighting.cs new file mode 100644 index 000000000..9ece7d1a0 --- /dev/null +++ b/Templates/BaseGame/game/core/lighting.cs @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function initLightingSystems(%manager) +{ + echo( "\nInitializing Lighting Systems" ); + + // First exec the scripts for the different light managers + // in the lighting folder. + %pattern = "./lighting/*/init.cs"; + %file = findFirstFile( %pattern ); + if ( %file $= "" ) + { + // Try for DSOs next. + %pattern = "./lighting/*/init.cs.dso"; + %file = findFirstFile( %pattern ); + } + + while( %file !$= "" ) + { + exec( %file ); + %file = findNextFile( %pattern ); + } + + // Try the perfered one first. + %success = setLightManager(%manager); + + // Did we completely fail to initialize a light manager? + if (!%success) + { + // If we completely failed to initialize a light + // manager then the 3d scene cannot be rendered. + quitWithErrorMessage( "Failed to set a light manager!" ); + } +} + +//--------------------------------------------------------------------------------------------- + +function onLightManagerActivate( %lmName ) +{ + // Call activation callbacks. + %activateNewFn = "onActivate" @ getWord( %lmName, 0 ) @ "LM"; + if( isFunction( %activateNewFn ) ) + eval( %activateNewFn @ "();" ); +} + +//--------------------------------------------------------------------------------------------- + +function onLightManagerDeactivate( %lmName ) +{ + // Call deactivation callback. + %deactivateOldFn = "onDeactivate" @ getWord( %lmName, 0 ) @ "LM"; + if( isFunction( %deactivateOldFn ) ) + eval( %deactivateOldFn @ "();" ); +} diff --git a/Templates/BaseGame/game/core/lighting/advanced/deferredShading.cs b/Templates/BaseGame/game/core/lighting/advanced/deferredShading.cs new file mode 100644 index 000000000..3ea6baebc --- /dev/null +++ b/Templates/BaseGame/game/core/lighting/advanced/deferredShading.cs @@ -0,0 +1,147 @@ +singleton ShaderData( ClearGBufferShader ) +{ + DXVertexShaderFile = "data/shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "data/shaders/common/lighting/advanced/deferredClearGBufferP.hlsl"; + + OGLVertexShaderFile = "data/shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "data/shaders/common/lighting/advanced/gl/deferredClearGBufferP.glsl"; + + pixVersion = 2.0; +}; + +singleton ShaderData( DeferredColorShader ) +{ + DXVertexShaderFile = "data/shaders/common/lighting/advanced/deferredClearGBufferV.hlsl"; + DXPixelShaderFile = "data/shaders/common/lighting/advanced/deferredColorShaderP.hlsl"; + + OGLVertexShaderFile = "data/shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "data/shaders/common/lighting/advanced/gl/deferredColorShaderP.glsl"; + + pixVersion = 2.0; +}; + +// Primary Deferred Shader +new GFXStateBlockData( AL_DeferredShadingState : PFX_DefaultStateBlock ) +{ + cullMode = GFXCullNone; + + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendSrcAlpha; + blendDest = GFXBlendInvSrcAlpha; + + samplersDefined = true; + samplerStates[0] = SamplerWrapLinear; + samplerStates[1] = SamplerWrapLinear; + samplerStates[2] = SamplerWrapLinear; + samplerStates[3] = SamplerWrapLinear; +}; + +new ShaderData( AL_DeferredShader ) +{ + DXVertexShaderFile = "data/shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "data/shaders/common/lighting/advanced/deferredShadingP.hlsl"; + + OGLVertexShaderFile = "data/shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "data/shaders/common/lighting/advanced/gl/deferredShadingP.glsl"; + + samplerNames[0] = "colorBufferTex"; + samplerNames[1] = "lightPrePassTex"; + samplerNames[2] = "matInfoTex"; + samplerNames[3] = "prepassTex"; + + pixVersion = 2.0; +}; + +singleton PostEffect( AL_DeferredShading ) +{ + renderTime = "PFXAfterBin"; + renderBin = "SkyBin"; + shader = AL_DeferredShader; + stateBlock = AL_DeferredShadingState; + texture[0] = "#color"; + texture[1] = "#lightinfo"; + texture[2] = "#matinfo"; + texture[3] = "#prepass"; + + target = "$backBuffer"; + renderPriority = 10000; + allowReflectPass = true; +}; + +// Debug Shaders. +new ShaderData( AL_ColorBufferShader ) +{ + DXVertexShaderFile = "data/shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "data/shaders/common/lighting/advanced/dbgColorBufferP.hlsl"; + + OGLVertexShaderFile = "data/shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "data/shaders/common/lighting/advanced/gl/dbgColorBufferP.glsl"; + + samplerNames[0] = "colorBufferTex"; + pixVersion = 2.0; +}; + +singleton PostEffect( AL_ColorBufferVisualize ) +{ + shader = AL_ColorBufferShader; + stateBlock = AL_DefaultVisualizeState; + texture[0] = "#color"; + target = "$backBuffer"; + renderPriority = 9999; +}; + +/// Toggles the visualization of the AL lighting specular power buffer. +function toggleColorBufferViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_ColorBufferShaderVar = AL_ColorBufferVisualize.isEnabled() ? false : true; + AL_ColorBufferVisualize.toggle(); + } + else if ( %enable ) + { + AL_DeferredShading.disable(); + AL_ColorBufferVisualize.enable(); + } + else if ( !%enable ) + { + AL_ColorBufferVisualize.disable(); + AL_DeferredShading.enable(); + } +} + +new ShaderData( AL_SpecMapShader ) +{ + DXVertexShaderFile = "data/shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "data/shaders/common/lighting/advanced/dbgSpecMapVisualizeP.hlsl"; + + OGLVertexShaderFile = "data/shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "data/shaders/common/lighting/advanced/gl/dbgSpecMapVisualizeP.glsl"; + + samplerNames[0] = "matinfoTex"; + pixVersion = 2.0; +}; + +singleton PostEffect( AL_SpecMapVisualize ) +{ + shader = AL_SpecMapShader; + stateBlock = AL_DefaultVisualizeState; + texture[0] = "#matinfo"; + target = "$backBuffer"; + renderPriority = 9999; +}; + +/// Toggles the visualization of the AL lighting specular power buffer. +function toggleSpecMapViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_SpecMapShaderVar = AL_SpecMapVisualize.isEnabled() ? false : true; + AL_SpecMapVisualize.toggle(); + } + else if ( %enable ) + AL_SpecMapVisualize.enable(); + else if ( !%enable ) + AL_SpecMapVisualize.disable(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/lighting/advanced/depthviz.png b/Templates/BaseGame/game/core/lighting/advanced/depthviz.png new file mode 100644 index 000000000..12991ed5c Binary files /dev/null and b/Templates/BaseGame/game/core/lighting/advanced/depthviz.png differ diff --git a/Templates/BaseGame/game/core/lighting/advanced/init.cs b/Templates/BaseGame/game/core/lighting/advanced/init.cs new file mode 100644 index 000000000..0b585aa03 --- /dev/null +++ b/Templates/BaseGame/game/core/lighting/advanced/init.cs @@ -0,0 +1,80 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +/////////////////////////////////////////////////////////////////////////////// +// Default Prefs + +/* +$pref::LightManager::sgAtlasMaxDynamicLights = "16"; +$pref::LightManager::sgDynamicShadowDetailSize = "0"; +$pref::LightManager::sgDynamicShadowQuality = "0"; +$pref::LightManager::sgLightingProfileAllowShadows = "1"; +$pref::LightManager::sgLightingProfileQuality = "0"; +$pref::LightManager::sgMaxBestLights = "10"; +$pref::LightManager::sgMultipleDynamicShadows = "1"; +$pref::LightManager::sgShowCacheStats = "0"; +$pref::LightManager::sgUseBloom = ""; +$pref::LightManager::sgUseDRLHighDynamicRange = "0"; +$pref::LightManager::sgUseDynamicRangeLighting = "0"; +$pref::LightManager::sgUseDynamicShadows = "1"; +$pref::LightManager::sgUseToneMapping = ""; +*/ + +exec( "./shaders.cs" ); +exec( "./lightViz.cs" ); +exec( "./shadowViz.cs" ); +exec( "./shadowViz.gui" ); +exec( "./deferredShading.cs" ); + +function onActivateAdvancedLM() +{ + // Don't allow the offscreen target on OSX. + if ( $platform $= "macos" ) + return; + + // On the Xbox360 we know what will be enabled so don't do any trickery to + // disable MSAA + if ( $platform $= "xenon" ) + return; + + // Enable the offscreen target so that AL will work + // with MSAA back buffers and for HDR rendering. + AL_FormatToken.enable(); + + // Activate Deferred Shading + AL_DeferredShading.enable(); +} + +function onDeactivateAdvancedLM() +{ + // Disable the offscreen render target. + AL_FormatToken.disable(); + + // Deactivate Deferred Shading + AL_DeferredShading.disable(); +} + +function setAdvancedLighting() +{ + setLightManager( "Advanced Lighting" ); +} + diff --git a/Templates/BaseGame/game/core/lighting/advanced/lightViz.cs b/Templates/BaseGame/game/core/lighting/advanced/lightViz.cs new file mode 100644 index 000000000..75184c16f --- /dev/null +++ b/Templates/BaseGame/game/core/lighting/advanced/lightViz.cs @@ -0,0 +1,294 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +new GFXStateBlockData( AL_DepthVisualizeState ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; // depth + samplerStates[1] = SamplerClampLinear; // viz color lookup +}; + +new GFXStateBlockData( AL_DefaultVisualizeState ) +{ + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendSrcAlpha; + blendDest = GFXBlendInvSrcAlpha; + + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; // #prepass + samplerStates[1] = SamplerClampLinear; // depthviz +}; + +new ShaderData( AL_DepthVisualizeShader ) +{ + DXVertexShaderFile = "data/shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "data/shaders/common/lighting/advanced/dbgDepthVisualizeP.hlsl"; + + OGLVertexShaderFile = "data/shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "data/shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl"; + + samplerNames[0] = "prepassTex"; + samplerNames[1] = "depthViz"; + + pixVersion = 2.0; +}; + +singleton PostEffect( AL_DepthVisualize ) +{ + shader = AL_DepthVisualizeShader; + stateBlock = AL_DefaultVisualizeState; + texture[0] = "#prepass"; + texture[1] = "core/lighting/advanced/depthviz"; + target = "$backBuffer"; + renderPriority = 9999; +}; + +function AL_DepthVisualize::onEnabled( %this ) +{ + AL_NormalsVisualize.disable(); + AL_LightColorVisualize.disable(); + AL_LightSpecularVisualize.disable(); + $AL_NormalsVisualizeVar = false; + $AL_LightColorVisualizeVar = false; + $AL_LightSpecularVisualizeVar = false; + + return true; +} + +new ShaderData( AL_GlowVisualizeShader ) +{ + DXVertexShaderFile = "data/shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "data/shaders/common/lighting/advanced/dbgGlowVisualizeP.hlsl"; + + OGLVertexShaderFile = "data/shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "data/shaders/common/lighting/advanced/gl/dbgGlowVisualizeP.glsl"; + + samplerNames[0] = "glowBuffer"; + pixVersion = 2.0; +}; + +singleton PostEffect( AL_GlowVisualize ) +{ + shader = AL_GlowVisualizeShader; + stateBlock = AL_DefaultVisualizeState; + texture[0] = "#glowbuffer"; + target = "$backBuffer"; + renderPriority = 9999; +}; + +new ShaderData( AL_NormalsVisualizeShader ) +{ + DXVertexShaderFile = "data/shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "data/shaders/common/lighting/advanced/dbgNormalVisualizeP.hlsl"; + + OGLVertexShaderFile = "data/shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "data/shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl"; + + samplerNames[0] = "prepassTex"; + + pixVersion = 2.0; +}; + +singleton PostEffect( AL_NormalsVisualize ) +{ + shader = AL_NormalsVisualizeShader; + stateBlock = AL_DefaultVisualizeState; + texture[0] = "#prepass"; + target = "$backBuffer"; + renderPriority = 9999; +}; + +function AL_NormalsVisualize::onEnabled( %this ) +{ + AL_DepthVisualize.disable(); + AL_LightColorVisualize.disable(); + AL_LightSpecularVisualize.disable(); + $AL_DepthVisualizeVar = false; + $AL_LightColorVisualizeVar = false; + $AL_LightSpecularVisualizeVar = false; + + return true; +} + + + +new ShaderData( AL_LightColorVisualizeShader ) +{ + DXVertexShaderFile = "data/shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "data/shaders/common/lighting/advanced/dbgLightColorVisualizeP.hlsl"; + + OGLVertexShaderFile = "data/shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "data/shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl"; + + samplerNames[0] = "lightPrePassTex"; + + pixVersion = 2.0; +}; + +singleton PostEffect( AL_LightColorVisualize ) +{ + shader = AL_LightColorVisualizeShader; + stateBlock = AL_DefaultVisualizeState; + texture[0] = "#lightinfo"; + target = "$backBuffer"; + renderPriority = 9999; +}; + +function AL_LightColorVisualize::onEnabled( %this ) +{ + AL_NormalsVisualize.disable(); + AL_DepthVisualize.disable(); + AL_LightSpecularVisualize.disable(); + $AL_NormalsVisualizeVar = false; + $AL_DepthVisualizeVar = false; + $AL_LightSpecularVisualizeVar = false; + + return true; +} + + +new ShaderData( AL_LightSpecularVisualizeShader ) +{ + DXVertexShaderFile = "data/shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "data/shaders/common/lighting/advanced/dbgLightSpecularVisualizeP.hlsl"; + + OGLVertexShaderFile = "data/shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "data/shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl"; + + samplerNames[0] = "lightPrePassTex"; + + pixVersion = 2.0; +}; + +singleton PostEffect( AL_LightSpecularVisualize ) +{ + shader = AL_LightSpecularVisualizeShader; + stateBlock = AL_DefaultVisualizeState; + texture[0] = "#lightinfo"; + target = "$backBuffer"; + renderPriority = 9999; +}; + +function AL_LightSpecularVisualize::onEnabled( %this ) +{ + AL_NormalsVisualize.disable(); + AL_DepthVisualize.disable(); + AL_LightColorVisualize.disable(); + $AL_NormalsVisualizeVar = false; + $AL_DepthVisualizeVar = false; + $AL_LightColorVisualizeVar = false; + + return true; +} + +/// Toggles the visualization of the AL depth buffer. +function toggleDepthViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_DepthVisualizeVar = AL_DepthVisualize.isEnabled() ? false : true; + AL_DepthVisualize.toggle(); + } + else if ( %enable ) + AL_DepthVisualize.enable(); + else if ( !%enable ) + AL_DepthVisualize.disable(); +} + +/// Toggles the visualization of the AL depth buffer. +function toggleGlowViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_GlowVisualizeVar = AL_GlowVisualize.isEnabled() ? false : true; + AL_GlowVisualize.toggle(); + } + else if ( %enable ) + AL_GlowVisualize.enable(); + else if ( !%enable ) + AL_GlowVisualize.disable(); +} + +/// Toggles the visualization of the AL normals buffer. +function toggleNormalsViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_NormalsVisualizeVar = AL_NormalsVisualize.isEnabled() ? false : true; + AL_NormalsVisualize.toggle(); + } + else if ( %enable ) + AL_NormalsVisualize.enable(); + else if ( !%enable ) + AL_NormalsVisualize.disable(); +} + +/// Toggles the visualization of the AL lighting color buffer. +function toggleLightColorViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_LightColorVisualizeVar = AL_LightColorVisualize.isEnabled() ? false : true; + AL_LightColorVisualize.toggle(); + } + else if ( %enable ) + AL_LightColorVisualize.enable(); + else if ( !%enable ) + AL_LightColorVisualize.disable(); +} + +/// Toggles the visualization of the AL lighting specular power buffer. +function toggleLightSpecularViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_LightSpecularVisualizeVar = AL_LightSpecularVisualize.isEnabled() ? false : true; + AL_LightSpecularVisualize.toggle(); + } + else if ( %enable ) + AL_LightSpecularVisualize.enable(); + else if ( !%enable ) + AL_LightSpecularVisualize.disable(); +} + +function toggleBackbufferViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_BackbufferVisualizeVar = AL_DeferredShading.isEnabled() ? true : false; + AL_DeferredShading.toggle(); + } + else if ( %enable ) + AL_DeferredShading.disable(); + else if ( !%enable ) + AL_DeferredShading.enable(); +} diff --git a/Templates/BaseGame/game/core/lighting/advanced/shaders.cs b/Templates/BaseGame/game/core/lighting/advanced/shaders.cs new file mode 100644 index 000000000..6cf97f810 --- /dev/null +++ b/Templates/BaseGame/game/core/lighting/advanced/shaders.cs @@ -0,0 +1,276 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +// Vector Light State +new GFXStateBlockData( AL_VectorLightState ) +{ + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendOne; + blendDest = GFXBlendOne; + blendOp = GFXBlendOpAdd; + + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; // G-buffer + mSamplerNames[0] = "prePassBuffer"; + samplerStates[1] = SamplerClampPoint; // Shadow Map (Do not change this to linear, as all cards can not filter equally.) + mSamplerNames[1] = "shadowMap"; + samplerStates[2] = SamplerClampPoint; // Shadow Map (Do not change this to linear, as all cards can not filter equally.) + mSamplerNames[2] = "dynamicShadowMap"; + samplerStates[3] = SamplerClampLinear; // SSAO Mask + mSamplerNames[3] = "ssaoMask"; + samplerStates[4] = SamplerWrapPoint; // Random Direction Map + + cullDefined = true; + cullMode = GFXCullNone; + + stencilDefined = true; + stencilEnable = true; + stencilFailOp = GFXStencilOpKeep; + stencilZFailOp = GFXStencilOpKeep; + stencilPassOp = GFXStencilOpKeep; + stencilFunc = GFXCmpLess; + stencilRef = 0; +}; + +// Vector Light Material +new ShaderData( AL_VectorLightShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/farFrustumQuadV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/vectorLightP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/farFrustumQuadV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/vectorLightP.glsl"; + + samplerNames[0] = "$prePassBuffer"; + samplerNames[1] = "$shadowMap"; + samplerNames[2] = "$dynamicShadowMap"; + samplerNames[3] = "$ssaoMask"; + samplerNames[4] = "$gTapRotationTex"; + samplerNames[5] = "$lightBuffer"; + samplerNames[6] = "$colorBuffer"; + samplerNames[7] = "$matInfoBuffer"; + + pixVersion = 3.0; +}; + +new CustomMaterial( AL_VectorLightMaterial ) +{ + shader = AL_VectorLightShader; + stateBlock = AL_VectorLightState; + + sampler["prePassBuffer"] = "#prepass"; + sampler["shadowMap"] = "$dynamiclight"; + sampler["dynamicShadowMap"] = "$dynamicShadowMap"; + sampler["ssaoMask"] = "#ssaoMask"; + sampler["lightBuffer"] = "#lightinfo"; + sampler["colorBuffer"] = "#color"; + sampler["matInfoBuffer"] = "#matinfo"; + + target = "lightinfo"; + + pixVersion = 3.0; +}; + +//------------------------------------------------------------------------------ + +// Convex-geometry light states +new GFXStateBlockData( AL_ConvexLightState ) +{ + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendOne; + blendDest = GFXBlendOne; + blendOp = GFXBlendOpAdd; + + zDefined = true; + zEnable = true; + zWriteEnable = false; + zFunc = GFXCmpGreaterEqual; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; // G-buffer + mSamplerNames[0] = "prePassBuffer"; + samplerStates[1] = SamplerClampPoint; // Shadow Map (Do not use linear, these are perspective projections) + mSamplerNames[1] = "shadowMap"; + samplerStates[2] = SamplerClampPoint; // Shadow Map (Do not use linear, these are perspective projections) + mSamplerNames[2] = "dynamicShadowMap"; + samplerStates[3] = SamplerClampLinear; // Cookie Map + samplerStates[4] = SamplerWrapPoint; // Random Direction Map + + cullDefined = true; + cullMode = GFXCullCW; + + stencilDefined = true; + stencilEnable = true; + stencilFailOp = GFXStencilOpKeep; + stencilZFailOp = GFXStencilOpKeep; + stencilPassOp = GFXStencilOpKeep; + stencilFunc = GFXCmpLess; + stencilRef = 0; +}; + +// Point Light Material +new ShaderData( AL_PointLightShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/convexGeometryV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/pointLightP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/convexGeometryV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/pointLightP.glsl"; + + samplerNames[0] = "$prePassBuffer"; + samplerNames[1] = "$shadowMap"; + samplerNames[2] = "$dynamicShadowMap"; + samplerNames[3] = "$cookieMap"; + samplerNames[4] = "$gTapRotationTex"; + samplerNames[5] = "$lightBuffer"; + samplerNames[6] = "$colorBuffer"; + samplerNames[7] = "$matInfoBuffer"; + + pixVersion = 3.0; +}; + +new CustomMaterial( AL_PointLightMaterial ) +{ + shader = AL_PointLightShader; + stateBlock = AL_ConvexLightState; + + sampler["prePassBuffer"] = "#prepass"; + sampler["shadowMap"] = "$dynamiclight"; + sampler["dynamicShadowMap"] = "$dynamicShadowMap"; + sampler["cookieMap"] = "$dynamiclightmask"; + sampler["lightBuffer"] = "#lightinfo"; + sampler["colorBuffer"] = "#color"; + sampler["matInfoBuffer"] = "#matinfo"; + + target = "lightinfo"; + + pixVersion = 3.0; +}; + +// Spot Light Material +new ShaderData( AL_SpotLightShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/convexGeometryV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/spotLightP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/convexGeometryV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/spotLightP.glsl"; + + samplerNames[0] = "$prePassBuffer"; + samplerNames[1] = "$shadowMap"; + samplerNames[2] = "$dynamicShadowMap"; + samplerNames[3] = "$cookieMap"; + samplerNames[4] = "$gTapRotationTex"; + samplerNames[5] = "$lightBuffer"; + samplerNames[6] = "$colorBuffer"; + samplerNames[7] = "$matInfoBuffer"; + + pixVersion = 3.0; +}; + +new CustomMaterial( AL_SpotLightMaterial ) +{ + shader = AL_SpotLightShader; + stateBlock = AL_ConvexLightState; + + sampler["prePassBuffer"] = "#prepass"; + sampler["shadowMap"] = "$dynamiclight"; + sampler["dynamicShadowMap"] = "$dynamicShadowMap"; + sampler["cookieMap"] = "$dynamiclightmask"; + sampler["lightBuffer"] = "#lightinfo"; + sampler["colorBuffer"] = "#color"; + sampler["matInfoBuffer"] = "#matinfo"; + + target = "lightinfo"; + + pixVersion = 3.0; +}; + +/// This material is used for generating prepass +/// materials for objects that do not have materials. +new Material( AL_DefaultPrePassMaterial ) +{ + // We need something in the first pass else it + // won't create a proper material instance. + // + // We use color here because some objects may not + // have texture coords in their vertex format... + // for example like terrain. + // + diffuseColor[0] = "1 1 1 1"; +}; + +/// This material is used for generating shadow +/// materials for objects that do not have materials. +new Material( AL_DefaultShadowMaterial ) +{ + // We need something in the first pass else it + // won't create a proper material instance. + // + // We use color here because some objects may not + // have texture coords in their vertex format... + // for example like terrain. + // + diffuseColor[0] = "1 1 1 1"; + + // This is here mostly for terrain which uses + // this material to create its shadow material. + // + // At sunset/sunrise the sun is looking thru + // backsides of the terrain which often are not + // closed. By changing the material to be double + // sided we avoid holes in the shadowed geometry. + // + doubleSided = true; +}; + +// Particle System Point Light Material +new ShaderData( AL_ParticlePointLightShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/particlePointLightV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/particlePointLightP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/convexGeometryV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/pointLightP.glsl"; + + samplerNames[0] = "$prePassBuffer"; + + pixVersion = 3.0; +}; + +new CustomMaterial( AL_ParticlePointLightMaterial ) +{ + shader = AL_ParticlePointLightShader; + stateBlock = AL_ConvexLightState; + + sampler["prePassBuffer"] = "#prepass"; + target = "lightinfo"; + + pixVersion = 3.0; +}; diff --git a/Templates/BaseGame/game/core/lighting/advanced/shadowViz.cs b/Templates/BaseGame/game/core/lighting/advanced/shadowViz.cs new file mode 100644 index 000000000..c91ae83e8 --- /dev/null +++ b/Templates/BaseGame/game/core/lighting/advanced/shadowViz.cs @@ -0,0 +1,116 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +new ShaderData( AL_ShadowVisualizeShader ) +{ + DXVertexShaderFile = "data/shaders/common/guiMaterialV.hlsl"; + DXPixelShaderFile = "data/shaders/common/lighting/advanced/dbgShadowVisualizeP.hlsl"; + + OGLVertexShaderFile = "data/shaders/common/gl/guiMaterialV.glsl"; + OGLPixelShaderFile = "data/shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl"; + + samplerNames[0] = "$shadowMap"; + samplerNames[1] = "$depthViz"; + + pixVersion = 2.0; +}; + +new CustomMaterial( AL_ShadowVisualizeMaterial ) +{ + shader = AL_ShadowVisualizeShader; + stateBlock = AL_DepthVisualizeState; + + sampler["shadowMap"] = "#AL_ShadowVizTexture"; + sampler["depthViz"] = "depthviz"; + + pixVersion = 2.0; +}; + +singleton GuiControlProfile( AL_ShadowLabelTextProfile ) +{ + fontColor = "0 0 0"; + autoSizeWidth = true; + autoSizeHeight = true; + justify = "left"; + fontSize = 14; +}; + +/// Toggles the visualization of the pre-pass lighting buffer. +function toggleShadowViz() +{ + if ( AL_ShadowVizOverlayCtrl.isAwake() ) + { + setShadowVizLight( 0 ); + Canvas.popDialog( AL_ShadowVizOverlayCtrl ); + } + else + { + Canvas.pushDialog( AL_ShadowVizOverlayCtrl, 100 ); + _setShadowVizLight( EWorldEditor.getSelectedObject( 0 ) ); + } +} + +/// Called from the WorldEditor when an object is selected. +function _setShadowVizLight( %light, %force ) +{ + if ( !AL_ShadowVizOverlayCtrl.isAwake() ) + return; + + if ( AL_ShadowVizOverlayCtrl.isLocked() && !%force ) + return; + + // Resolve the object to the client side. + if ( isObject( %light ) ) + { + %clientLight = serverToClientObject( %light ); + %sizeAndAspect = setShadowVizLight( %clientLight ); + } + + AL_ShadowVizOverlayCtrl-->MatCtrl.setMaterial( "AL_ShadowVisualizeMaterial" ); + + %text = "ShadowViz"; + if ( isObject( %light ) ) + %text = %text @ " : " @ getWord( %sizeAndAspect, 0 ) @ " x " @ getWord( %sizeAndAspect, 1 ); + + AL_ShadowVizOverlayCtrl-->WindowCtrl.text = %text; +} + +/// For convenience, push the viz dialog and set the light manually from the console. +function showShadowVizForLight( %light ) +{ + if ( !AL_ShadowVizOverlayCtrl.isAwake() ) + Canvas.pushDialog( AL_ShadowVizOverlayCtrl, 100 ); + _setShadowVizLight( %light, true ); +} + +// Prevent shadowViz from changing lights in response to editor selection +// events until unlock is called. The only way a vis light will change while locked +// is if showShadowVizForLight is explicitly called by the user. +function lockShadowViz() +{ + AL_ShadowVizOverlayCtrl.islocked = true; +} + +function unlockShadowViz() +{ + AL_ShadowVizOverlayCtrl.islocked = false; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/lighting/advanced/shadowViz.gui b/Templates/BaseGame/game/core/lighting/advanced/shadowViz.gui new file mode 100644 index 000000000..05c1a8926 --- /dev/null +++ b/Templates/BaseGame/game/core/lighting/advanced/shadowViz.gui @@ -0,0 +1,78 @@ +//--------------------------------------------------------------------------------------------- +// Torque 3D +// Copyright (C) GarageGames.com, Inc. +//--------------------------------------------------------------------------------------------- + +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AL_ShadowVizOverlayCtrl) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiModelessDialogProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + noCursor = true; + + new GuiWindowCtrl() { + internalName = "WindowCtrl"; + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "50 50"; + Extent = "347 209"; + MinExtent = "150 100"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "1"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "ShadowViz"; + closeCommand = "toggleShadowViz();"; + + new GuiMaterialCtrl() { + internalName = "MatCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "3 23"; + Extent = "341 181"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "2 2 2 2"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + materialName = "AL_ShadowVisualizeMaterial"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/core/lighting/basic/init.cs b/Templates/BaseGame/game/core/lighting/basic/init.cs new file mode 100644 index 000000000..e5fe350f5 --- /dev/null +++ b/Templates/BaseGame/game/core/lighting/basic/init.cs @@ -0,0 +1,92 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +exec( "./shadowFilter.cs" ); + +singleton GFXStateBlockData( BL_ProjectedShadowSBData ) +{ + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendDestColor; + blendDest = GFXBlendZero; + + zDefined = true; + zEnable = true; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + vertexColorEnable = true; +}; + +singleton ShaderData( BL_ProjectedShadowShaderData ) +{ + DXVertexShaderFile = "data/shaders/common/projectedShadowV.hlsl"; + DXPixelShaderFile = "data/shaders/common/projectedShadowP.hlsl"; + + OGLVertexShaderFile = "data/shaders/common/gl/projectedShadowV.glsl"; + OGLPixelShaderFile = "data/shaders/common/gl/projectedShadowP.glsl"; + + samplerNames[0] = "inputTex"; + + pixVersion = 2.0; +}; + +singleton CustomMaterial( BL_ProjectedShadowMaterial ) +{ + sampler["inputTex"] = "$miscbuff"; + + shader = BL_ProjectedShadowShaderData; + stateBlock = BL_ProjectedShadowSBData; + version = 2.0; + forwardLit = true; +}; + +function onActivateBasicLM() +{ + // If HDR is enabled... enable the special format token. + if ( $platform !$= "macos" && HDRPostFx.isEnabled ) + AL_FormatToken.enable(); + + // Create render pass for projected shadow. + new RenderPassManager( BL_ProjectedShadowRPM ); + + // Create the mesh bin and add it to the manager. + %meshBin = new RenderMeshMgr(); + BL_ProjectedShadowRPM.addManager( %meshBin ); + + // Add both to the root group so that it doesn't + // end up in the MissionCleanup instant group. + RootGroup.add( BL_ProjectedShadowRPM ); + RootGroup.add( %meshBin ); +} + +function onDeactivateBasicLM() +{ + // Delete the pass manager which also deletes the bin. + BL_ProjectedShadowRPM.delete(); +} + +function setBasicLighting() +{ + setLightManager( "Basic Lighting" ); +} diff --git a/Templates/BaseGame/game/core/lighting/basic/shadowFilter.cs b/Templates/BaseGame/game/core/lighting/basic/shadowFilter.cs new file mode 100644 index 000000000..cf2788e5f --- /dev/null +++ b/Templates/BaseGame/game/core/lighting/basic/shadowFilter.cs @@ -0,0 +1,76 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +singleton ShaderData( BL_ShadowFilterShaderV ) +{ + DXVertexShaderFile = "data/shaders/common/lighting/basic/shadowFilterV.hlsl"; + DXPixelShaderFile = "data/shaders/common/lighting/basic/shadowFilterP.hlsl"; + + OGLVertexShaderFile = "data/shaders/common/lighting/basic/gl/shadowFilterV.glsl"; + OGLPixelShaderFile = "data/shaders/common/lighting/basic/gl/shadowFilterP.glsl"; + + samplerNames[0] = "$diffuseMap"; + + defines = "BLUR_DIR=float2(1.0,0.0)"; + + pixVersion = 2.0; +}; + +singleton ShaderData( BL_ShadowFilterShaderH : BL_ShadowFilterShaderV ) +{ + defines = "BLUR_DIR=float2(0.0,1.0)"; +}; + + +singleton GFXStateBlockData( BL_ShadowFilterSB : PFX_DefaultStateBlock ) +{ + colorWriteDefined=true; + colorWriteRed=false; + colorWriteGreen=false; + colorWriteBlue=false; + blendDefined = true; + blendEnable = true; +}; + +// NOTE: This is ONLY used in Basic Lighting, and +// only directly by the ProjectedShadow. It is not +// meant to be manually enabled like other PostEffects. +singleton PostEffect( BL_ShadowFilterPostFx ) +{ + // Blur vertically + shader = BL_ShadowFilterShaderV; + stateBlock = PFX_DefaultStateBlock; + targetClear = "PFXTargetClear_OnDraw"; + targetClearColor = "0 0 0 0"; + texture[0] = "$inTex"; + target = "$outTex"; + + // Blur horizontal + new PostEffect() + { + shader = BL_ShadowFilterShaderH; + stateBlock = PFX_DefaultStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + }; +}; diff --git a/Templates/BaseGame/game/core/lighting/shadowMaps/init.cs b/Templates/BaseGame/game/core/lighting/shadowMaps/init.cs new file mode 100644 index 000000000..eaa46cae7 --- /dev/null +++ b/Templates/BaseGame/game/core/lighting/shadowMaps/init.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +new ShaderData(BlurDepthShader) +{ + DXVertexShaderFile = "data/shaders/common/lighting/shadowMap/boxFilterV.hlsl"; + DXPixelShaderFile = "data/shaders/common/lighting/shadowMap/boxFilterP.hlsl"; + + OGLVertexShaderFile = "data/shaders/common/lighting/shadowMap/gl/boxFilterV.glsl"; + OGLPixelShaderFile = "data/shaders/common/lighting/shadowMap/gl/boxFilterP.glsl"; + pixVersion = 2.0; +}; diff --git a/Templates/BaseGame/game/core/main.cs b/Templates/BaseGame/game/core/main.cs new file mode 100644 index 000000000..d5c7bf45b --- /dev/null +++ b/Templates/BaseGame/game/core/main.cs @@ -0,0 +1,95 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +// Initialize core sub system functionality such as audio, the Canvas, PostFX, +// rendermanager, light managers, etc. +// +// Note that not all of these need to be initialized before the client, although +// the audio should and the canvas definitely needs to be. I've put things here +// to distinguish between the purpose and functionality of the various client +// scripts. Game specific script isn't needed until we reach the shell menus +// and start a game or connect to a server. We get the various subsystems ready +// to go, and then use initClient() to handle the rest of the startup sequence. +// +// If this is too convoluted we can reduce this complexity after futher testing +// to find exactly which subsystems should be readied before kicking things off. +// ---------------------------------------------------------------------------- + +//We need to hook the missing/warn material stuff early, so do it here +$Core::MissingTexturePath = "core/images/missingTexture"; +$Core::UnAvailableTexturePath = "core/images/unavailable"; +$Core::WarningTexturePath = "core/images/warnMat"; +$Core::CommonShaderPath = "data/shaders/common"; + +/// This is the path used by ShaderGen to cache procedural +/// shaders. If left blank ShaderGen will only cache shaders +/// to memory and not to disk. +$shaderGen::cachePath = "data/shaders"; + +exec("./helperFunctions.cs"); + +// We need some of the default GUI profiles in order to get the canvas and +// other aspects of the GUI system ready. +exec("./profiles.cs"); + +//This is a bit of a shortcut, but we'll load the client's default settings to ensure all the prefs get initialized correctly +%prefPath = getPrefpath(); +if ( isFile( %prefPath @ "/clientPrefs.cs" ) ) + exec( %prefPath @ "/clientPrefs.cs" ); +else + exec("data/defaults.cs"); + +%der = $pref::Video::displayDevice; + +// Initialization of the various subsystems requires some of the preferences +// to be loaded... so do that first. +exec("./globals.cs"); + +exec("./canvas.cs"); +exec("./cursor.cs"); + +exec("./renderManager.cs"); +exec("./lighting.cs"); + +exec("./audio.cs"); +exec("./sfx/audioAmbience.cs"); +exec("./sfx/audioData.cs"); +exec("./sfx/audioDescriptions.cs"); +exec("./sfx/audioEnvironments.cs"); +exec("./sfx/audioStates.cs"); + +exec("./parseArgs.cs"); + +// Materials and Shaders for rendering various object types +exec("./gfxData/commonMaterialData.cs"); +exec("./gfxData/shaders.cs"); +exec("./gfxData/terrainBlock.cs"); +exec("./gfxData/water.cs"); +exec("./gfxData/scatterSky.cs"); +exec("./gfxData/clouds.cs"); + +// Initialize all core post effects. +exec("./postFx.cs"); + +// Seed the random number generator. +setRandomSeed(); \ No newline at end of file diff --git a/Templates/BaseGame/game/core/parseArgs.cs b/Templates/BaseGame/game/core/parseArgs.cs new file mode 100644 index 000000000..811cee00c --- /dev/null +++ b/Templates/BaseGame/game/core/parseArgs.cs @@ -0,0 +1,392 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Support functions used to manage the directory list +function pushFront(%list, %token, %delim) +{ + if (%list !$= "") + return %token @ %delim @ %list; + return %token; +} + +function pushBack(%list, %token, %delim) +{ + if (%list !$= "") + return %list @ %delim @ %token; + return %token; +} + +function popFront(%list, %delim) +{ + return nextToken(%list, unused, %delim); +} + +function parseArgs() +{ + for ($i = 1; $i < $Game::argc ; $i++) + { + $arg = $Game::argv[$i]; + $nextArg = $Game::argv[$i+1]; + $hasNextArg = $Game::argc - $i > 1; + $logModeSpecified = false; + + // Check for dedicated run + /*if( stricmp($arg,"-dedicated") == 0 ) + { + $userDirs = $defaultGame; + $dirCount = 1; + $isDedicated = true; + }*/ + + switch$ ($arg) + { + //-------------------- + case "-dedicated": + $userDirs = $defaultGame; + $dirCount = 1; + $isDedicated = true; + $Server::Dedicated = true; + enableWinConsole(true); + $argUsed[%i]++; + + //-------------------- + case "-mission": + $argUsed[%i]++; + if ($hasNextArg) + { + $missionArg = $nextArg; + $argUsed[%i+1]++; + %i++; + } + else + error("Error: Missing Command Line argument. Usage: -mission "); + + //-------------------- + case "-connect": + $argUsed[%i]++; + if ($hasNextArg) + { + $JoinGameAddress = $nextArg; + $argUsed[%i+1]++; + %i++; + } + else + error("Error: Missing Command Line argument. Usage: -connect "); + + + //-------------------- + case "-log": + $argUsed[$i]++; + if ($hasNextArg) + { + // Turn on console logging + if ($nextArg != 0) + { + // Dump existing console to logfile first. + $nextArg += 4; + } + setLogMode($nextArg); + $logModeSpecified = true; + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -log "); + + //-------------------- + case "-dir": + $argUsed[$i]++; + if ($hasNextArg) + { + // Append the mod to the end of the current list + $userDirs = strreplace($userDirs, $nextArg, ""); + $userDirs = pushFront($userDirs, $nextArg, ";"); + $argUsed[$i+1]++; + $i++; + $dirCount++; + } + else + error("Error: Missing Command Line argument. Usage: -dir "); + + //-------------------- + // changed the default behavior of this command line arg. It now + // defaults to ONLY loading the game, not tools + // default auto-run already loads in tools --SRZ 11/29/07 + case "-game": + $argUsed[$i]++; + if ($hasNextArg) + { + // Set the selected dir --NOTE: we no longer allow tools with this argument + /* + if( $isDedicated ) + { + $userDirs = $nextArg; + $dirCount = 1; + } + else + { + $userDirs = "tools;" @ $nextArg; + $dirCount = 2; + } + */ + $userDirs = $nextArg; + $dirCount = 1; + $argUsed[$i+1]++; + $i++; + error($userDirs); + } + else + error("Error: Missing Command Line argument. Usage: -game "); + + //-------------------- + case "-console": + enableWinConsole(true); + $argUsed[$i]++; + + //-------------------- + case "-jSave": + $argUsed[$i]++; + if ($hasNextArg) + { + echo("Saving event log to journal: " @ $nextArg); + saveJournal($nextArg); + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -jSave "); + + //-------------------- + case "-jPlay": + $argUsed[$i]++; + if ($hasNextArg) + { + playJournal($nextArg); + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -jPlay "); + + //-------------------- + case "-jPlayToVideo": + $argUsed[$i]++; + if ($hasNextArg) + { + $VideoCapture::journalName = $nextArg; + $VideoCapture::captureFromJournal = true; + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -jPlayToVideo "); + + //-------------------- + case "-vidCapFile": + $argUsed[$i]++; + if ($hasNextArg) + { + $VideoCapture::fileName = $nextArg; + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -vidCapFile "); + + //-------------------- + case "-vidCapFPS": + $argUsed[$i]++; + if ($hasNextArg) + { + $VideoCapture::fps = $nextArg; + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -vidCapFPS "); + + //-------------------- + case "-vidCapEncoder": + $argUsed[$i]++; + if ($hasNextArg) + { + $VideoCapture::encoder = $nextArg; + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -vidCapEncoder "); + + //-------------------- + case "-vidCapWidth": + $argUsed[$i]++; + if ($hasNextArg) + { + $videoCapture::width = $nextArg; + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -vidCapWidth "); + + //-------------------- + case "-vidCapHeight": + $argUsed[$i]++; + if ($hasNextArg) + { + $videoCapture::height = $nextArg; + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -vidCapHeight "); + + //-------------------- + case "-level": + $argUsed[$i]++; + if ($hasNextArg) + { + %hasExt = strpos($nextArg, ".mis"); + if(%hasExt == -1) + { + $levelToLoad = $nextArg @ " "; + + for(%i = $i + 2; %i < $Game::argc; %i++) + { + $arg = $Game::argv[%i]; + %hasExt = strpos($arg, ".mis"); + + if(%hasExt == -1) + { + $levelToLoad = $levelToLoad @ $arg @ " "; + } else + { + $levelToLoad = $levelToLoad @ $arg; + break; + } + } + } + else + { + $levelToLoad = $nextArg; + } + + $argUsed[$i+1]++; + $i++; + } + else + error("Error: Missing Command Line argument. Usage: -level "); + + //------------------- + case "-worldeditor": + $startWorldEditor = true; + $argUsed[$i]++; + + //------------------- + case "-guieditor": + $startGUIEditor = true; + $argUsed[$i]++; + + //------------------- + case "-help": + $displayHelp = true; + $argUsed[$i]++; + + //------------------- + case "-compileAll": + $compileAll = true; + $argUsed[$i]++; + + //------------------- + case "-compileTools": + $compileTools = true; + $argUsed[$i]++; + + //------------------- + case "-genScript": + $genScript = true; + $argUsed[$i]++; + + case "-fullscreen": + $cliFullscreen = true; + $argUsed[%i]++; + + case "-windowed": + $cliFullscreen = false; + $argUsed[%i]++; + + case "-openGL": + $pref::Video::displayDevice = "OpenGL"; + $argUsed[%i]++; + + case "-directX": + $pref::Video::displayDevice = "D3D"; + $argUsed[%i]++; + + case "-autoVideo": + $pref::Video::displayDevice = ""; + $argUsed[%i]++; + + case "-prefs": + $argUsed[%i]++; + if ($hasNextArg) { + exec($nextArg, true, true); + $argUsed[%i+1]++; + %i++; + } + else + error("Error: Missing Command Line argument. Usage: -prefs "); + + + //------------------- + default: + $argUsed[$i]++; + if($userDirs $= "") + $userDirs = $arg; + } + } + + //----------------------------------------------- + // Play journal to video file? + if ($VideoCapture::captureFromJournal && $VideoCapture::journalName !$= "") + { + if ($VideoCapture::fileName $= "") + $VideoCapture::fileName = $VideoCapture::journalName; + + if ($VideoCapture::encoder $= "") + $VideoCapture::encoder = "THEORA"; + + if ($VideoCapture::fps $= "") + $VideoCapture::fps = 30; + + if ($videoCapture::width $= "") + $videoCapture::width = 0; + + if ($videoCapture::height $= "") + $videoCapture::height = 0; + + playJournalToVideo( $VideoCapture::journalName, $VideoCapture::fileName, + $VideoCapture::encoder, $VideoCapture::fps, + $videoCapture::width SPC $videoCapture::height ); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/postFx.cs b/Templates/BaseGame/game/core/postFx.cs new file mode 100644 index 000000000..bb57edcb0 --- /dev/null +++ b/Templates/BaseGame/game/core/postFx.cs @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton ShaderData( PFX_PassthruShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/passthruP.hlsl"; + +// OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; +// OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/gl/passthruP.glsl"; + + samplerNames[0] = "$inputTex"; + + pixVersion = 2.0; +}; + +function PostEffect::inspectVars( %this ) +{ + %name = %this.getName(); + %globals = "$" @ %name @ "::*"; + inspectVars( %globals ); +} + +function PostEffect::viewDisassembly( %this ) +{ + %file = %this.dumpShaderDisassembly(); + + if ( %file $= "" ) + { + echo( "PostEffect::viewDisassembly - no shader disassembly found." ); + } + else + { + echo( "PostEffect::viewDisassembly - shader disassembly file dumped ( " @ %file @ " )." ); + openFile( %file ); + } +} + +// Return true if we really want the effect enabled. +// By default this is the case. +function PostEffect::onEnabled( %this ) +{ + return true; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/profiles.cs b/Templates/BaseGame/game/core/profiles.cs new file mode 100644 index 000000000..fa9d9b72a --- /dev/null +++ b/Templates/BaseGame/game/core/profiles.cs @@ -0,0 +1,226 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Set font cache path if it doesn't already exist. +if($Gui::fontCacheDirectory $= "") +{ + $Gui::fontCacheDirectory = expandFilename("./fonts"); +} + +// ---------------------------------------------------------------------------- +// GuiDefaultProfile is a special profile that all other profiles inherit +// defaults from. It must exist. +// ---------------------------------------------------------------------------- + +if(!isObject(GuiDefaultProfile)) +new GuiControlProfile (GuiDefaultProfile) +{ + tab = false; + canKeyFocus = false; + hasBitmapArray = false; + mouseOverSelected = false; + + // fill color + opaque = false; + fillColor = "242 241 240"; + fillColorHL ="228 228 235"; + fillColorSEL = "98 100 137"; + fillColorNA = "255 255 255 "; + + // border color + border = 0; + borderColor = "100 100 100"; + borderColorHL = "50 50 50 50"; + borderColorNA = "75 75 75"; + + // font + fontType = "Arial"; + fontSize = 14; + fontCharset = ANSI; + + fontColor = "0 0 0"; + fontColorHL = "0 0 0"; + fontColorNA = "0 0 0"; + fontColorSEL= "255 255 255"; + + // bitmap information + bitmap = ""; + bitmapBase = ""; + textOffset = "0 0"; + + // used by guiTextControl + modal = true; + justify = "left"; + autoSizeWidth = false; + autoSizeHeight = false; + returnTab = false; + numbersOnly = false; + cursorColor = "0 0 0 255"; +}; + +if(!isObject(GuiToolTipProfile)) +new GuiControlProfile (GuiToolTipProfile) +{ + // fill color + fillColor = "239 237 222"; + + // border color + borderColor = "138 134 122"; + + // font + fontType = "Arial"; + fontSize = 14; + fontColor = "0 0 0"; + + category = "Core"; +}; + +if(!isObject(GuiWindowProfile)) +new GuiControlProfile (GuiWindowProfile) +{ + opaque = false; + border = 2; + fillColor = "242 241 240"; + fillColorHL = "221 221 221"; + fillColorNA = "200 200 200"; + fontColor = "50 50 50"; + fontColorHL = "0 0 0"; + bevelColorHL = "255 255 255"; + bevelColorLL = "0 0 0"; + text = "untitled"; + bitmap = "./images/window"; + textOffset = "8 4"; + hasBitmapArray = true; + justify = "left"; + category = "Core"; +}; + + +if(!isObject(GuiTextEditProfile)) +new GuiControlProfile(GuiTextEditProfile) +{ + opaque = true; + bitmap = "./images/textEdit"; + hasBitmapArray = true; + border = -2; + fillColor = "242 241 240 0"; + fillColorHL = "255 255 255"; + fontColor = "0 0 0"; + fontColorHL = "255 255 255"; + fontColorSEL = "98 100 137"; + fontColorNA = "200 200 200"; + textOffset = "4 2"; + autoSizeWidth = false; + autoSizeHeight = true; + justify = "left"; + tab = true; + canKeyFocus = true; + category = "Core"; +}; + +if(!isObject(GuiScrollProfile)) +new GuiControlProfile(GuiScrollProfile) +{ + opaque = true; + fillcolor = "255 255 255"; + fontColor = "0 0 0"; + fontColorHL = "150 150 150"; + border = true; + bitmap = "./images/scrollBar"; + hasBitmapArray = true; + category = "Core"; +}; + +if(!isObject(GuiOverlayProfile)) +new GuiControlProfile(GuiOverlayProfile) +{ + opaque = true; + fontColor = "0 0 0"; + fontColorHL = "255 255 255"; + fillColor = "0 0 0 100"; + category = "Core"; +}; + +if(!isObject(GuiCheckBoxProfile)) +new GuiControlProfile(GuiCheckBoxProfile) +{ + opaque = false; + fillColor = "232 232 232"; + border = false; + borderColor = "100 100 100"; + fontSize = 14; + fontColor = "20 20 20"; + fontColorHL = "80 80 80"; + fontColorNA = "200 200 200"; + fixedExtent = true; + justify = "left"; + bitmap = "./images/checkbox"; + hasBitmapArray = true; + category = "Tools"; +}; + +if( !isObject( GuiProgressProfile ) ) +new GuiControlProfile( GuiProgressProfile ) +{ + opaque = false; + fillColor = "0 162 255 200"; + border = true; + borderColor = "50 50 50 200"; + category = "Core"; +}; + +if( !isObject( GuiProgressBitmapProfile ) ) +new GuiControlProfile( GuiProgressBitmapProfile ) +{ + border = false; + hasBitmapArray = true; + bitmap = "./images/loadingbar"; + category = "Core"; +}; + +if( !isObject( GuiProgressTextProfile ) ) +new GuiControlProfile( GuiProgressTextProfile ) +{ + fontSize = "14"; + fontType = "Arial"; + fontColor = "0 0 0"; + justify = "center"; + category = "Core"; +}; + +if( !isObject( GuiButtonProfile ) ) +new GuiControlProfile( GuiButtonProfile ) +{ + opaque = true; + border = true; + + fontColor = "50 50 50"; + fontColorHL = "0 0 0"; + fontColorNA = "200 200 200"; + //fontColorSEL ="0 0 0"; + fixedExtent = false; + justify = "center"; + canKeyFocus = false; + bitmap = "./images/button"; + hasBitmapArray = false; + category = "Core"; +}; diff --git a/Templates/BaseGame/game/core/renderManager.cs b/Templates/BaseGame/game/core/renderManager.cs new file mode 100644 index 000000000..f719ad1f0 --- /dev/null +++ b/Templates/BaseGame/game/core/renderManager.cs @@ -0,0 +1,125 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function initRenderManager() +{ + assert( !isObject( DiffuseRenderPassManager ), "initRenderManager() - DiffuseRenderPassManager already initialized!" ); + + new RenderPassManager( DiffuseRenderPassManager ); + + // This token, and the associated render managers, ensure that driver MSAA + // does not get used for Advanced Lighting renders. The 'AL_FormatResolve' + // PostEffect copies the result to the backbuffer. + new RenderFormatToken(AL_FormatToken) + { + enabled = "false"; + + format = getBestHDRFormat(); + depthFormat = "GFXFormatD24S8"; + aaLevel = 0; // -1 = match backbuffer + + // The contents of the back buffer before this format token is executed + // is provided in $inTex + copyEffect = "AL_FormatCopy"; + + // The contents of the render target created by this format token is + // provided in $inTex + resolveEffect = "AL_FormatCopy"; + }; + DiffuseRenderPassManager.addManager( new RenderPassStateBin() { renderOrder = 0.001; stateToken = AL_FormatToken; } ); + + // We really need to fix the sky to render after all the + // meshes... but that causes issues in reflections. + DiffuseRenderPassManager.addManager( new RenderObjectMgr(SkyBin) { bintype = "Sky"; renderOrder = 0.1; processAddOrder = 0.1; } ); + + //DiffuseRenderPassManager.addManager( new RenderVistaMgr() { bintype = "Vista"; renderOrder = 0.15; processAddOrder = 0.15; } ); + + DiffuseRenderPassManager.addManager( new RenderObjectMgr(BeginBin) { bintype = "Begin"; renderOrder = 0.2; processAddOrder = 0.2; } ); + // Normal mesh rendering. + DiffuseRenderPassManager.addManager( new RenderTerrainMgr(TerrainBin) { renderOrder = 0.4; processAddOrder = 0.4; basicOnly = true; } ); + DiffuseRenderPassManager.addManager( new RenderMeshMgr(MeshBin) { bintype = "Mesh"; renderOrder = 0.5; processAddOrder = 0.5; basicOnly = true; } ); + DiffuseRenderPassManager.addManager( new RenderImposterMgr(ImposterBin) { renderOrder = 0.56; processAddOrder = 0.56; } ); + DiffuseRenderPassManager.addManager( new RenderObjectMgr(ObjectBin) { bintype = "Object"; renderOrder = 0.6; processAddOrder = 0.6; } ); + + DiffuseRenderPassManager.addManager( new RenderObjectMgr(ShadowBin) { bintype = "Shadow"; renderOrder = 0.7; processAddOrder = 0.7; } ); + DiffuseRenderPassManager.addManager( new RenderMeshMgr(DecalRoadBin) { bintype = "DecalRoad"; renderOrder = 0.8; processAddOrder = 0.8; } ); + DiffuseRenderPassManager.addManager( new RenderMeshMgr(DecalBin) { bintype = "Decal"; renderOrder = 0.81; processAddOrder = 0.81; } ); + DiffuseRenderPassManager.addManager( new RenderOcclusionMgr(OccluderBin){ bintype = "Occluder"; renderOrder = 0.9; processAddOrder = 0.9; } ); + + // We now render translucent objects that should handle + // their own fogging and lighting. + + // Note that the fog effect is triggered before this bin. + DiffuseRenderPassManager.addManager( new RenderObjectMgr(ObjTranslucentBin) { bintype = "ObjectTranslucent"; renderOrder = 1.0; processAddOrder = 1.0; } ); + + DiffuseRenderPassManager.addManager( new RenderObjectMgr(WaterBin) { bintype = "Water"; renderOrder = 1.2; processAddOrder = 1.2; } ); + DiffuseRenderPassManager.addManager( new RenderObjectMgr(FoliageBin) { bintype = "Foliage"; renderOrder = 1.3; processAddOrder = 1.3; } ); + DiffuseRenderPassManager.addManager( new RenderParticleMgr(ParticleBin) { renderOrder = 1.35; processAddOrder = 1.35; } ); + DiffuseRenderPassManager.addManager( new RenderTranslucentMgr(TranslucentBin){ renderOrder = 1.4; processAddOrder = 1.4; } ); + + DiffuseRenderPassManager.addManager(new RenderObjectMgr(FogBin){ bintype = "ObjectVolumetricFog"; renderOrder = 1.45; processAddOrder = 1.45; } ); + + // Note that the GlowPostFx is triggered after this bin. + DiffuseRenderPassManager.addManager( new RenderGlowMgr(GlowBin) { renderOrder = 1.5; processAddOrder = 1.5; } ); + + // We render any editor stuff from this bin. Note that the HDR is + // completed before this bin to keep editor elements from tone mapping. + DiffuseRenderPassManager.addManager( new RenderObjectMgr(EditorBin) { bintype = "Editor"; renderOrder = 1.6; processAddOrder = 1.6; } ); + + // Resolve format change token last. + DiffuseRenderPassManager.addManager( new RenderPassStateBin(FinalBin) { renderOrder = 1.7; stateToken = AL_FormatToken; } ); +} + +/// This is the Default PostFX state block. Put here to prevent any missing object +/// errors for below dependencies +singleton GFXStateBlockData( PFX_DefaultStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; +}; + +/// This post effect is used to copy data from the non-MSAA back-buffer to the +/// device back buffer (which could be MSAA). It must be declared here so that +/// it is initialized when 'AL_FormatToken' is initialzed. +singleton GFXStateBlockData( AL_FormatTokenState : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; +}; + +singleton PostEffect( AL_FormatCopy ) +{ + // This PostEffect is used by 'AL_FormatToken' directly. It is never added to + // the PostEffectManager. Do not call enable() on it. + isEnabled = false; + allowReflectPass = true; + + shader = PFX_PassthruShader; + stateBlock = AL_FormatTokenState; + + texture[0] = "$inTex"; + target = "$backbuffer"; +}; diff --git a/Templates/BaseGame/game/core/sfx/audioAmbience.cs b/Templates/BaseGame/game/core/sfx/audioAmbience.cs new file mode 100644 index 000000000..8c2bf270c --- /dev/null +++ b/Templates/BaseGame/game/core/sfx/audioAmbience.cs @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton SFXAmbience( AudioAmbienceDefault ) +{ + environment = AudioEnvOff; +}; + +singleton SFXAmbience( AudioAmbienceOutside ) +{ + environment = AudioEnvPlain; + states[ 0 ] = AudioLocationOutside; +}; + +singleton SFXAmbience( AudioAmbienceInside ) +{ + environment = AudioEnvRoom; + states[ 0 ] = AudioLocationInside; +}; + +singleton SFXAmbience( AudioAmbienceUnderwater ) +{ + environment = AudioEnvUnderwater; + states[ 0 ] = AudioLocationUnderwater; +}; diff --git a/Templates/BaseGame/game/core/sfx/audioData.cs b/Templates/BaseGame/game/core/sfx/audioData.cs new file mode 100644 index 000000000..8584ce50e --- /dev/null +++ b/Templates/BaseGame/game/core/sfx/audioData.cs @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Game specific audio descriptions. Always declare SFXDescription's (the type of sound) +// before SFXProfile's (the sound itself) when creating new ones + +singleton SFXDescription(BulletFireDesc : AudioEffect ) +{ + isLooping = false; + is3D = true; + ReferenceDistance = 10.0; + MaxDistance = 60.0; +}; + +singleton SFXDescription(BulletImpactDesc : AudioEffect ) +{ + isLooping = false; + is3D = true; + ReferenceDistance = 10.0; + MaxDistance = 30.0; + volume = 0.4; + pitch = 1.4; +}; diff --git a/Templates/BaseGame/game/core/sfx/audioDescriptions.cs b/Templates/BaseGame/game/core/sfx/audioDescriptions.cs new file mode 100644 index 000000000..d682461cf --- /dev/null +++ b/Templates/BaseGame/game/core/sfx/audioDescriptions.cs @@ -0,0 +1,143 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Always declare SFXDescription's (the type of sound) before SFXProfile's (the +// sound itself) when creating new ones + +//----------------------------------------------------------------------------- +// 3D Sounds +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Single shot sounds +//----------------------------------------------------------------------------- + +singleton SFXDescription( AudioDefault3D : AudioEffect ) +{ + is3D = true; + ReferenceDistance = 20.0; + MaxDistance = 100.0; +}; + +singleton SFXDescription( AudioSoft3D : AudioEffect ) +{ + is3D = true; + ReferenceDistance = 20.0; + MaxDistance = 100.0; + volume = 0.4; +}; + +singleton SFXDescription( AudioClose3D : AudioEffect ) +{ + is3D = true; + ReferenceDistance = 10.0; + MaxDistance = 60.0; +}; + +singleton SFXDescription( AudioClosest3D : AudioEffect ) +{ + is3D = true; + ReferenceDistance = 5.0; + MaxDistance = 10.0; +}; + +//----------------------------------------------------------------------------- +// Looping sounds +//----------------------------------------------------------------------------- + +singleton SFXDescription( AudioDefaultLoop3D : AudioEffect ) +{ + isLooping = true; + is3D = true; + ReferenceDistance = 20.0; + MaxDistance = 100.0; +}; + +singleton SFXDescription( AudioCloseLoop3D : AudioEffect ) +{ + isLooping = true; + is3D = true; + ReferenceDistance = 18.0; + MaxDistance = 25.0; +}; + +singleton SFXDescription( AudioClosestLoop3D : AudioEffect ) +{ + isLooping = true; + is3D = true; + ReferenceDistance = 5.0; + MaxDistance = 10.0; +}; + +//----------------------------------------------------------------------------- +// 2d sounds +//----------------------------------------------------------------------------- + +// Used for non-looping environmental sounds (like power on, power off) +singleton SFXDescription( Audio2D : AudioEffect ) +{ + isLooping = false; +}; + +// Used for Looping Environmental Sounds +singleton SFXDescription( AudioLoop2D : AudioEffect ) +{ + isLooping = true; +}; + +singleton SFXDescription( AudioStream2D : AudioEffect ) +{ + isStreaming = true; +}; +singleton SFXDescription( AudioStreamLoop2D : AudioEffect ) +{ + isLooping = true; + isStreaming = true; +}; + +//----------------------------------------------------------------------------- +// Music +//----------------------------------------------------------------------------- + +singleton SFXDescription( AudioMusic2D : AudioMusic ) +{ + isStreaming = true; +}; + +singleton SFXDescription( AudioMusicLoop2D : AudioMusic ) +{ + isLooping = true; + isStreaming = true; +}; + +singleton SFXDescription( AudioMusic3D : AudioMusic ) +{ + isStreaming = true; + is3D = true; +}; + +singleton SFXDescription( AudioMusicLoop3D : AudioMusic ) +{ + isStreaming = true; + is3D = true; + isLooping = true; +}; diff --git a/Templates/BaseGame/game/core/sfx/audioEnvironments.cs b/Templates/BaseGame/game/core/sfx/audioEnvironments.cs new file mode 100644 index 000000000..671825b6b --- /dev/null +++ b/Templates/BaseGame/game/core/sfx/audioEnvironments.cs @@ -0,0 +1,916 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Reverb environment presets. +// +// For customized presets, best derive from one of these presets. + +singleton SFXEnvironment( AudioEnvOff ) +{ + envSize = "7.5"; + envDiffusion = "1.0"; + room = "-10000"; + roomHF = "-10000"; + roomLF = "0"; + decayTime = "1.0"; + decayHFRatio = "1.0"; + decayLFRatio = "1.0"; + reflections = "-2602"; + reflectionsDelay = "0.007"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "200"; + reverbDelay = "0.011"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "0.0"; + density = "0.0"; + flags = 0x33; +}; + +singleton SFXEnvironment( AudioEnvGeneric ) +{ + envSize = "7.5"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-100"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.83"; + decayLFRatio = "1.0"; + reflections = "-2602"; + reflectionsDelay = "0.007"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "200"; + reverbDelay = "0.011"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvRoom ) +{ + envSize = "1.9"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-454"; + roomLF = "0"; + decayTime = "0.4"; + decayHFRatio = "0.83"; + decayLFRatio = "1.0"; + reflections = "-1646"; + reflectionsDelay = "0.002"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "53"; + reverbDelay = "0.003"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvPaddedCell ) +{ + envSize = "1.4"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-6000"; + roomLF = "0"; + decayTime = "0.17"; + decayHFRatio = "0.1"; + decayLFRatio = "1.0"; + reflections = "-1204"; + reflectionsDelay = "0.001"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "207"; + reverbDelay = "0.002"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvBathroom ) +{ + envSize = "1.4"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-1200"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.54"; + decayLFRatio = "1.0"; + reflections = "-370"; + reflectionsDelay = "0.007"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "1030"; + reverbDelay = "0.011"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "60.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvLivingRoom ) +{ + envSize = "2.5"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-6000"; + roomLF = "0"; + decayTime = "0.5"; + decayHFRatio = "0.1"; + decayLFRatio = "1.0"; + reflections = "-1376"; + reflectionsDelay = "0.003"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-1104"; + reverbDelay = "0.004"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvStoneRoom ) +{ + envSize = "11.6"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "300"; + roomLF = "0"; + decayTime = "2.31"; + decayHFRatio = "0.64"; + decayLFRatio = "1.0"; + reflections = "-711"; + reflectionsDelay = "0.012"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "83"; + reverbDelay = "0.017"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "-5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvAuditorium ) +{ + envSize = "21.6"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-476"; + roomLF = "0"; + decayTime = "4.32"; + decayHFRatio = "0.59"; + decayLFRatio = "1.0"; + reflections = "1"; + reflectionsDelay = "0.02"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-289"; + reverbDelay = "0.03"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvConcertHall ) +{ + envSize = "19.6"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-500"; + roomLF = "0"; + decayTime = "3.92"; + decayHFRatio = "0.7"; + decayLFRatio = "1.0"; + reflections = "-1230"; + reflectionsDelay = "0.02"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-2"; + reverbDelay = "0.029"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvCave ) +{ + envSize = "14.6"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "0"; + roomLF = "0"; + decayTime = "2.91"; + decayHFRatio = "1.3"; + decayLFRatio = "1.0"; + reflections = "-602"; + reflectionsDelay = "0.015"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-302"; + reverbDelay = "0.022"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x1f; +}; + +singleton SFXEnvironment( AudioEnvArena ) +{ + envSize = "36.2f"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-698"; + roomLF = "0"; + decayTime = "7.24"; + decayHFRatio = "0.33"; + decayLFRatio = "1.0"; + reflections = "-1166"; + reflectionsDelay = "0.02"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "16"; + reverbDelay = "0.03"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvHangar ) +{ + envSize = "50.3"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-1000"; + roomLF = "0"; + decayTime = "10.05"; + decayHFRatio = "0.23"; + decayLFRatio = "1.0"; + reflections = "-602"; + reflectionsDelay = "0.02"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "198"; + reverbDelay = "0.03"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvCarpettedHallway ) +{ + envSize = "1.9"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-4000"; + roomLF = "0"; + decayTime = "0.3"; + decayHFRatio = "0.1"; + decayLFRatio = "1.0"; + reflections = "-1831"; + reflectionsDelay = "0.002"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-1630"; + reverbDelay = "0.03"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvHallway ) +{ + envSize = "1.8"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-300"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.59"; + decayLFRatio = "1.0"; + reflections = "-1219"; + reflectionsDelay = "0.007"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "441"; + reverbDelay = "0.011"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvStoneCorridor ) +{ + envSize = "13.5"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-237"; + roomLF = "0"; + decayTime = "2.7"; + decayHFRatio = "0.79"; + decayLFRatio = "1.0"; + reflections = "-1214"; + reflectionsDelay = "0.013"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "395"; + reverbDelay = "0.02"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvAlley ) +{ + envSize = "7.5"; + envDiffusion = "0.3"; + room = "-1000"; + roomHF = "-270"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.86"; + decayLFRatio = "1.0"; + reflections = "-1204"; + reflectionsDelay = "0.007"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-4"; + reverbDelay = "0.011"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.125"; + echoDepth = "0.95"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvForest ) +{ + envSize = "38.0"; + envDiffusion = "0.3"; + room = "-1000"; + roomHF = "-3300"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.54"; + decayLFRatio = "1.0"; + reflections = "-2560"; + reflectionsDelay = "0.162"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-229"; + reverbDelay = "0.088"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.125"; + echoDepth = "1.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "79.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvCity ) +{ + envSize = "7.5"; + envDiffusion = "0.5"; + room = "-1000"; + roomHF = "-800"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.67"; + decayLFRatio = "1.0"; + reflections = "-2273"; + reflectionsDelay = "0.007"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-1691"; + reverbDelay = "0.011"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "50.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvMountains ) +{ + envSize = "100.0"; + envDiffusion = "0.27"; + room = "-1000"; + roomHF = "-2500"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.21"; + decayLFRatio = "1.0"; + reflections = "-2780"; + reflectionsDelay = "0.3"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-1434"; + reverbDelay = "0.1"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "1.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "27.0"; + density = "100.0"; + flags = 0x1f; +}; + +singleton SFXEnvironment( AudioEnvQuary ) +{ + envSize = "17.5"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-1000"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.83"; + decayLFRatio = "1.0"; + reflections = "-10000"; + reflectionsDelay = "0.061"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "500"; + reverbDelay = "0.025"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.125"; + echoDepth = "0.7"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvPlain ) +{ + envSize = "42.5"; + envDiffusion = "0.21"; + room = "-1000"; + roomHF = "-2000"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.5"; + decayLFRatio = "1.0"; + reflections = "-2466"; + reflectionsDelay = "0.179"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-1926"; + reverbDelay = "0.1"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "1.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "21.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvParkingLot ) +{ + envSize = "8.3"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "0"; + roomLF = "0"; + decayTime = "1.65"; + decayHFRatio = "1.5"; + decayLFRatio = "1.0"; + reflections = "-1363"; + reflectionsDelay = "0.008"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-1153"; + reverbDelay = "0.012"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x1f; +}; + +singleton SFXEnvironment( AudioEnvSewerPipe ) +{ + envSize = "1.7"; + envDiffusion = "0.8"; + room = "-1000"; + roomHF = "-1000"; + roomLF = "0"; + decayTime = "2.81"; + decayHFRatio = "0.14"; + decayLFRatio = "1.0"; + reflections = "429"; + reflectionsDelay = "0.014"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "1023"; + reverbDelay = "0.21"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "0.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "80.0"; + density = "60.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvUnderwater ) +{ + envSize = "1.8"; + envDiffusion = "1.0"; + room = "-1000"; + roomHF = "-4000"; + roomLF = "0"; + decayTime = "1.49"; + decayHFRatio = "0.1"; + decayLFRatio = "1.0"; + reflections = "-449"; + reflectionsDelay = "0.007"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "1700"; + reverbDelay = "0.011"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "1.18"; + modulationDepth = "0.348"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x3f; +}; + +singleton SFXEnvironment( AudioEnvDrugged ) +{ + envSize = "1.9"; + envDiffusion = "0.5"; + room = "-1000"; + roomHF = "0"; + roomLF = "0"; + decayTime = "8.39"; + decayHFRatio = "1.39"; + decayLFRatio = "1.0"; + reflections = "-115"; + reflectionsDelay = "0.002"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "985"; + reverbDelay = "0.03"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "0.25"; + modulationDepth = "1.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x1f; +}; + +singleton SFXEnvironment( AudioEnvDizzy ) +{ + envSize = "1.8"; + envDiffusion = "0.6"; + room = "-1000.0"; + roomHF = "-400"; + roomLF = "0"; + decayTime = "17.23"; + decayHFRatio = "0.56"; + decayLFRatio = "1.0"; + reflections = "-1713"; + reflectionsDelay = "0.02"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "-613"; + reverbDelay = "0.03"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "1.0"; + modulationTime = "0.81"; + modulationDepth = "0.31"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x1f; +}; + +singleton SFXEnvironment( AudioEnvPsychotic ) +{ + envSize = "1.0"; + envDiffusion = "0.5"; + room = "-1000"; + roomHF = "-151"; + roomLF = "0"; + decayTime = "7.56"; + decayHFRatio = "0.91"; + decayLFRatio = "1.0"; + reflections = "-626"; + reflectionsDelay = "0.02"; + reflectionsPan[ 0 ] = "0.0"; + reflectionsPan[ 1 ] = "0.0"; + reflectionsPan[ 2 ] = "0.0"; + reverb = "774"; + reverbDelay = "0.03"; + reverbPan[ 0 ] = "0.0"; + reverbPan[ 1 ] = "0.0"; + reverbPan[ 2 ] = "0.0"; + echoTime = "0.25"; + echoDepth = "0.0"; + modulationTime = "4.0"; + modulationDepth = "1.0"; + airAbsorptionHF = "-5.0"; + HFReference = "5000.0"; + LFReference = "250.0"; + roomRolloffFactor = "0.0"; + diffusion = "100.0"; + density = "100.0"; + flags = 0x1f; +}; diff --git a/Templates/BaseGame/game/core/sfx/audioStates.cs b/Templates/BaseGame/game/core/sfx/audioStates.cs new file mode 100644 index 000000000..3ab55cf78 --- /dev/null +++ b/Templates/BaseGame/game/core/sfx/audioStates.cs @@ -0,0 +1,158 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Some state presets. + + +/// Return the first active SFXState in the given SimSet/SimGroup. +function sfxGetActiveStateInGroup( %group ) +{ + %count = %group.getCount(); + for( %i = 0; %i < %count; %i ++ ) + { + %obj = %group.getObject( %i ); + if( !%obj.isMemberOfClass( "SFXState" ) ) + continue; + + if( %obj.isActive() ) + return %obj; + } + + return 0; +} + + +//----------------------------------------------------------------------------- +// Special audio state that will always and only be active when no other +// state is active. Useful for letting slots apply specifically when no +// other slot in a list applies. + +singleton SFXState( AudioStateNone ) {}; + +AudioStateNone.activate(); + +function SFXState::onActivate( %this ) +{ + if( %this.getId() != AudioStateNone.getId() ) + AudioStateNone.disable(); +} + +function SFXState::onDeactivate( %this ) +{ + if( %this.getId() != AudioStateNone.getId() ) + AudioStateNone.enable(); +} + +//----------------------------------------------------------------------------- +// AudioStateExclusive class. +// +// Automatically deactivates sibling SFXStates in its parent SimGroup +// when activated. + +function AudioStateExclusive::onActivate( %this ) +{ + Parent::onActivate( %this ); + + %group = %this.parentGroup; + %count = %group.getCount(); + + for( %i = 0; %i < %count; %i ++ ) + { + %obj = %group.getObject( %i ); + + if( %obj != %this && %obj.isMemberOfClass( "SFXState" ) && %obj.isActive() ) + %obj.deactivate(); + } +} + +//----------------------------------------------------------------------------- +// Location-dependent states. + +singleton SimGroup( AudioLocation ); + +/// State when the listener is outside. +singleton SFXState( AudioLocationOutside ) +{ + parentGroup = AudioLocation; + className = "AudioStateExclusive"; +}; + +/// State when the listener is submerged. +singleton SFXState( AudioLocationUnderwater ) +{ + parentGroup = AudioLocation; + className = "AudioStateExclusive"; +}; + +/// State when the listener is indoors. +singleton SFXState( AudioLocationInside ) +{ + parentGroup = AudioLocation; + className = "AudioStateExclusive"; +}; + +/// Return the currently active SFXState in AudioLocation. +function sfxGetLocation() +{ + return sfxGetActiveStateInGroup( AudioLocation ); +} + +//----------------------------------------------------------------------------- +// Mood-dependent states. + +singleton SimGroup( AudioMood ); + +singleton SFXState( AudioMoodNeutral ) +{ + parentGroup = AudioMood; + className = "AudioStateExclusive"; +}; + +singleton SFXState( AudioMoodAggressive ) +{ + parentGroup = AudioMood; + className = "AudioStateExclusive"; +}; + +singleton SFXState( AudioMoodTense ) +{ + parentGroup = AudioMood; + className = "AudioStateExclusive"; +}; + +singleton SFXState( AudioMoodVictory ) +{ + parentGroup = AudioMood; + className = "AudioStateExclusive"; +}; + +singleton SFXState( AudioMoodCalm ) +{ + parentGroup = AudioMood; + className = "AudioStateExclusive"; +}; + +/// Return the currently active SFXState in AudioMood. +function sfxGetMood() +{ + return sfxGetActiveStateInGroup( AudioMood ); +} diff --git a/Templates/BaseGame/game/data/clientServer/ClientServer.cs b/Templates/BaseGame/game/data/clientServer/ClientServer.cs new file mode 100644 index 000000000..3cf7aaa55 --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/ClientServer.cs @@ -0,0 +1,112 @@ + +// The general flow of a gane - server's creation, loading and hosting clients, and then destruction is as follows: + +// First, a client will always create a server in the event that they want to host a single player +// game. Torque3D treats even single player connections as a soft multiplayer game, with some stuff +// in the networking short-circuited to sidestep around lag and packet transmission times. + +// initServer() is called, loading the default server scripts. +// After that, if this is a dedicated server session, initDedicated() is called, otherwise initClient is called +// to prep a playable client session. + +// When a local game is started - a listen server - via calling StartGame() a server is created and then the client is +// connected to it via createAndConnectToLocalServer(). + +function ClientServer::create( %this ) +{ + echo("\n--------- Initializing Directory: scripts ---------"); + exec( "./scripts/client/client.cs" ); + exec( "./scripts/server/server.cs" ); + + $Game::MissionGroup = "MissionGroup"; + + initServer(); + + %dbList = new ArrayObject(DatablockFilesList); + + // Start up in either client, or dedicated server mode + if ($Server::Dedicated) + { + initDedicated(); + } + else + { + initClient(); + } +} + +function ClientServer::destroy( %this ) +{ + // Ensure that we are disconnected and/or the server is destroyed. + // This prevents crashes due to the SceneGraph being deleted before + // the objects it contains. + if ($Server::Dedicated) + destroyServer(); + else + disconnect(); + + // Destroy the physics plugin. + physicsDestroy(); + + sfxShutdown(); + + echo("Exporting client prefs"); + %prefPath = getPrefpath(); + export("$pref::*", %prefPath @ "/clientPrefs.cs", false); + + echo("Exporting server prefs"); + export("$Pref::Server::*", %prefPath @ "/serverPrefs.cs", false); + BanList::Export(%prefPath @ "/banlist.cs"); +} + +//----------------------------------------------------------------------------- +function StartGame( %mission, %hostingType ) +{ + if( %mission $= "" ) + { + %id = CL_levelList.getSelectedId(); + %mission = getField(CL_levelList.getRowTextById(%id), 1); + //error("Cannot start a level with no level selected!"); + } + + if (%hostingType !$= "") + { + %serverType = %hostingType; + } + else + { + if ($pref::HostMultiPlayer) + %serverType = "MultiPlayer"; + else + %serverType = "SinglePlayer"; + } + + // Show the loading screen immediately. + if ( isObject( LoadingGui ) ) + { + Canvas.setContent("LoadingGui"); + LoadingProgress.setValue(1); + LoadingProgressTxt.setValue("LOADING MISSION FILE"); + Canvas.repaint(); + } + + createAndConnectToLocalServer( %serverType, %mission ); +} + +function JoinGame( %serverIndex ) +{ + // The server info index is stored in the row along with the + // rest of displayed info. + if( setServerInfo( %serverIndex ) ) + { + Canvas.setContent("LoadingGui"); + LoadingProgress.setValue(1); + LoadingProgressTxt.setValue("WAITING FOR SERVER"); + Canvas.repaint(); + + %conn = new GameConnection(ServerConnection); + %conn.setConnectArgs($pref::Player::Name); + %conn.setJoinPassword($Client::Password); + %conn.connect($ServerInfo::Address); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/clientServer/ClientServer.module b/Templates/BaseGame/game/data/clientServer/ClientServer.module new file mode 100644 index 000000000..05c70a90d --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/ClientServer.module @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/Templates/BaseGame/game/data/clientServer/scripts/client/client.cs b/Templates/BaseGame/game/data/clientServer/scripts/client/client.cs new file mode 100644 index 000000000..0b18d81aa --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/scripts/client/client.cs @@ -0,0 +1,29 @@ +function initClient() +{ + echo("\n--------- Initializing " @ $appName @ ": Client Scripts ---------"); + + // Make sure this variable reflects the correct state. + $Server::Dedicated = false; + + // Game information used to query the master server + $Client::GameTypeQuery = $appName; + $Client::MissionTypeQuery = "Any"; + + exec( "data/clientServer/scripts/client/message.cs" ); + exec( "data/clientServer/scripts/client/connectionToServer.cs" ); + exec( "data/clientServer/scripts/client/levelDownload.cs" ); + exec( "data/clientServer/scripts/client/levelLoad.cs" ); + + //load prefs + %prefPath = getPrefpath(); + if ( isFile( %prefPath @ "/clientPrefs.cs" ) ) + exec( %prefPath @ "/clientPrefs.cs" ); + else + exec( "data/defaults.cs" ); + + loadMaterials(); + + // Copy saved script prefs into C++ code. + setDefaultFov( $pref::Player::defaultFov ); + setZoomSpeed( $pref::Player::zoomSpeed ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/clientServer/scripts/client/connectionToServer.cs b/Templates/BaseGame/game/data/clientServer/scripts/client/connectionToServer.cs new file mode 100644 index 000000000..693c7fff7 --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/scripts/client/connectionToServer.cs @@ -0,0 +1,130 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Functions dealing with connecting to a server + +//---------------------------------------------------------------------------- +// GameConnection client callbacks +//---------------------------------------------------------------------------- +// Called on the new connection object after connect() succeeds. +function GameConnection::onConnectionAccepted(%this) +{ + // Startup the physX world on the client before any + // datablocks and objects are ghosted over. + physicsInitWorld( "client" ); +} + +function GameConnection::initialControlSet(%this) +{ + echo ("*** Initial Control Object"); + + // The first control object has been set by the server + // and we are now ready to go. + + // first check if the editor is active + if (!isToolBuild() || !isMethod("Editor", "checkActiveLoadDone") || !Editor::checkActiveLoadDone()) + { + if (Canvas.getContent() != PlayGui.getId()) + Canvas.setContent(PlayGui); + } +} + +function GameConnection::onControlObjectChange(%this) +{ + echo ("*** Control Object Changed"); + + // Reset the current FOV to match the new object + // and turn off any current zoom. + resetCurrentFOV(); + turnOffZoom(); +} + +function GameConnection::onConnectionError(%this, %msg) +{ + // General connection error, usually raised by ghosted objects + // initialization problems, such as missing files. We'll display + // the server's connection error message. + disconnectedCleanup(); + MessageBoxOK( "DISCONNECT", $ServerConnectionErrorMessage @ " (" @ %msg @ ")" ); +} + +//----------------------------------------------------------------------------- +// Server connection error +//----------------------------------------------------------------------------- +addMessageCallback( 'MsgConnectionError', handleConnectionErrorMessage ); + +function handleConnectionErrorMessage(%msgType, %msgString, %msgError) +{ + // On connect the server transmits a message to display if there + // are any problems with the connection. Most connection errors + // are game version differences, so hopefully the server message + // will tell us where to get the latest version of the game. + $ServerConnectionErrorMessage = %msgError; +} + +//----------------------------------------------------------------------------- +// Disconnect +//----------------------------------------------------------------------------- + +function disconnect() +{ + // We need to stop the client side simulation + // else physics resources will not cleanup properly. + physicsStopSimulation( "client" ); + + // Delete the connection if it's still there. + if (isObject(ServerConnection)) + ServerConnection.delete(); + + disconnectedCleanup(); + + // Call destroyServer in case we're hosting + destroyServer(); +} + +function disconnectedCleanup() +{ + // End mission, if it's running. + + if( $Client::missionRunning ) + clientEndMission(); + + // Disable mission lighting if it's going, this is here + // in case we're disconnected while the mission is loading. + + $lightingMission = false; + $sceneLighting::terminateLighting = true; + + // Back to the launch screen + if (isObject( MainMenuGui )) + Canvas.setContent( MainMenuGui ); + + // Before we destroy the client physics world + // make sure all ServerConnection objects are deleted. + if(isObject(ServerConnection)) + { + ServerConnection.deleteAllObjects(); + } + + // We can now delete the client physics simulation. + physicsDestroyWorld( "client" ); +} diff --git a/Templates/BaseGame/game/data/clientServer/scripts/client/levelDownload.cs b/Templates/BaseGame/game/data/clientServer/scripts/client/levelDownload.cs new file mode 100644 index 000000000..dd70e31ea --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/scripts/client/levelDownload.cs @@ -0,0 +1,185 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Mission Loading +// The client portion of the client/server mission loading process +//----------------------------------------------------------------------------- +//-------------------------------------------------------------------------- +// Loading Phases: +// Phase 1: Transmit Datablocks +// Transmit targets +// Phase 2: Transmit Ghost Objects +// Phase 3: Start Game +// +// The server invokes the client MissionStartPhase[1-3] function to request +// permission to start each phase. When a client is ready for a phase, +// it responds with MissionStartPhase[1-3]Ack. + +//---------------------------------------------------------------------------- +// Phase 1 +//---------------------------------------------------------------------------- +function clientCmdMissionStartPhase1(%seq, %missionName) +{ + // These need to come after the cls. + echo ("*** New Mission: " @ %missionName); + echo ("*** Phase 1: Download Datablocks & Targets"); + + //Prep the postFX stuff + // Load the post effect presets for this mission. + %path = filePath( %missionName ) @ "/" @ fileBase( %missionName ) @ $PostFXManager::fileExtension; + + if ( isScriptFile( %path ) ) + { + postFXManager::loadPresetHandler( %path ); + } + else + { + PostFXManager::settingsApplyDefaultPreset(); + } + + onMissionDownloadPhase("LOADING DATABLOCKS"); + + commandToServer('MissionStartPhase1Ack', %seq); +} + +function onDataBlockObjectReceived(%index, %total) +{ + onMissionDownloadProgress(%index / %total); +} + +//---------------------------------------------------------------------------- +// Phase 2 +//---------------------------------------------------------------------------- +function clientCmdMissionStartPhase2(%seq,%missionName) +{ + onPhaseComplete(); + echo ("*** Phase 2: Download Ghost Objects"); + + onMissionDownloadPhase("LOADING OBJECTS"); + + commandToServer('MissionStartPhase2Ack', %seq); +} + +function onGhostAlwaysStarted(%ghostCount) +{ + $ghostCount = %ghostCount; + $ghostsRecvd = 0; +} + +function onGhostAlwaysObjectReceived() +{ + $ghostsRecvd++; + onMissionDownloadProgress($ghostsRecvd / $ghostCount); +} + +//---------------------------------------------------------------------------- +// Phase 3 +//---------------------------------------------------------------------------- +function clientCmdMissionStartPhase3(%seq,%missionName) +{ + onPhaseComplete(); + StartClientReplication(); + StartFoliageReplication(); + + // Load the static mission decals. + if(isFile(%missionName @ ".decals")) + decalManagerLoad( %missionName @ ".decals" ); + + echo ("*** Phase 3: Mission Lighting"); + $MSeq = %seq; + $Client::MissionFile = %missionName; + + // Need to light the mission before we are ready. + // The sceneLightingComplete function will complete the handshake + // once the scene lighting is done. + if (lightScene("sceneLightingComplete", "")) + { + echo("Lighting mission...."); + schedule(1, 0, "updateLightingProgress"); + + onMissionDownloadPhase("LIGHTING MISSION"); + + $lightingMission = true; + } +} + +function updateLightingProgress() +{ + onMissionDownloadProgress($SceneLighting::lightingProgress); + if ($lightingMission) + $lightingProgressThread = schedule(1, 0, "updateLightingProgress"); +} + +function sceneLightingComplete() +{ + echo("Mission lighting done"); + $lightingMission = false; + + onPhaseComplete("STARTING MISSION"); + + // The is also the end of the mission load cycle. + commandToServer('MissionStartPhase3Ack', $MSeq); +} + +//---------------------------------------------------------------------------- +// Helper functions +//---------------------------------------------------------------------------- +function connect(%server) +{ + %conn = new GameConnection(ServerConnection); + RootGroup.add(ServerConnection); + %conn.setConnectArgs($pref::Player::Name); + %conn.setJoinPassword($Client::Password); + %conn.connect(%server); +} + +function onMissionDownloadPhase(%phase) +{ + if ( !isObject( LoadingProgress ) ) + return; + + LoadingProgress.setValue(0); + LoadingProgressTxt.setValue(%phase); + Canvas.repaint(); +} + +function onMissionDownloadProgress(%progress) +{ + if ( !isObject( LoadingProgress ) ) + return; + + LoadingProgress.setValue(%progress); + Canvas.repaint(33); +} + +function onPhaseComplete(%text) +{ + if ( !isObject( LoadingProgress ) ) + return; + + if(%text !$= "") + LoadingProgressTxt.setValue(%text); + + LoadingProgress.setValue( 1 ); + Canvas.repaint(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/clientServer/scripts/client/levelLoad.cs b/Templates/BaseGame/game/data/clientServer/scripts/client/levelLoad.cs new file mode 100644 index 000000000..c3fd04280 --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/scripts/client/levelLoad.cs @@ -0,0 +1,92 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +// Whether the local client is currently running a mission. +$Client::missionRunning = false; + +// Sequence number for currently running mission. +$Client::missionSeq = -1; + + +// Called when mission is started. +function clientStartMission() +{ + // The client recieves a mission start right before + // being dropped into the game. + physicsStartSimulation( "client" ); + + // Start game audio effects channels. + + AudioChannelEffects.play(); + + // Create client mission cleanup group. + + new SimGroup( ClientMissionCleanup ); + + // Done. + + $Client::missionRunning = true; +} + +// Called when mission is ended (either through disconnect or +// mission end client command). +function clientEndMission() +{ + // Stop physics simulation on client. + physicsStopSimulation( "client" ); + + // Stop game audio effects channels. + + AudioChannelEffects.stop(); + + // Delete all the decals. + decalManagerClear(); + + // Delete client mission cleanup group. + if( isObject( ClientMissionCleanup ) ) + ClientMissionCleanup.delete(); + + clearClientPaths(); + + // Done. + $Client::missionRunning = false; +} + +//---------------------------------------------------------------------------- +// Mission start / end events sent from the server +//---------------------------------------------------------------------------- + +function clientCmdMissionStart(%seq) +{ + clientStartMission(); + $Client::missionSeq = %seq; +} + +function clientCmdMissionEnd( %seq ) +{ + if( $Client::missionRunning && $Client::missionSeq == %seq ) + { + clientEndMission(); + $Client::missionSeq = -1; + } +} diff --git a/Templates/BaseGame/game/data/clientServer/scripts/client/message.cs b/Templates/BaseGame/game/data/clientServer/scripts/client/message.cs new file mode 100644 index 000000000..c532d50d9 --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/scripts/client/message.cs @@ -0,0 +1,94 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// Functions that process commands sent from the server. + +// Game event descriptions, which may or may not include text messages, can be +// sent using the message* functions in core/scripts/server/message.cs. Those +// functions do commandToClient with the tag ServerMessage, which invokes the +// function below. + +// For ServerMessage messages, the client can install callbacks that will be +// run, according to the "type" of the message. + +function clientCmdServerMessage(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10) +{ + // Get the message type; terminates at any whitespace. + %tag = getWord(%msgType, 0); + + // First see if there is a callback installed that doesn't have a type; + // if so, that callback is always executed when a message arrives. + for (%i = 0; (%func = $MSGCB["", %i]) !$= ""; %i++) { + call(%func, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10); + } + + // Next look for a callback for this particular type of ServerMessage. + if (%tag !$= "") { + for (%i = 0; (%func = $MSGCB[%tag, %i]) !$= ""; %i++) { + call(%func, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10); + } + } +} + +// Called by the client to install a callback for a particular type of +// ServerMessage. +function addMessageCallback(%msgType, %func) +{ + for (%i = 0; (%afunc = $MSGCB[%msgType, %i]) !$= ""; %i++) { + // If it already exists as a callback for this type, + // nothing to do. + if (%afunc $= %func) { + return; + } + } + // Set it up. + $MSGCB[%msgType, %i] = %func; +} + +// The following is the callback that will be executed for every ServerMessage, +// because we're going to install it without a specified type. Any type- +// specific callbacks will be executed afterward. + +// This just invokes onServerMessage, which can be overridden by the game +function onServerMessage(%a, %b, %c, %d, %e, %f, %g, %h, %i) +{ + echo("onServerMessage: "); + if(%a !$= "") echo(" +- a: " @ %a); + if(%b !$= "") echo(" +- b: " @ %b); + if(%c !$= "") echo(" +- c: " @ %c); + if(%d !$= "") echo(" +- d: " @ %d); + if(%e !$= "") echo(" +- e: " @ %e); + if(%f !$= "") echo(" +- f: " @ %f); + if(%g !$= "") echo(" +- g: " @ %g); + if(%h !$= "") echo(" +- h: " @ %h); + if(%i !$= "") echo(" +- i: " @ %i); +} + +function defaultMessageCallback(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10) +{ + onServerMessage(detag(%msgString)); +} + +// Register that default message handler now. +addMessageCallback("", defaultMessageCallback); diff --git a/Templates/BaseGame/game/data/clientServer/scripts/server/audio.cs b/Templates/BaseGame/game/data/clientServer/scripts/server/audio.cs new file mode 100644 index 000000000..67b2fbf5e --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/scripts/server/audio.cs @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- + +function ServerPlay2D(%profile) +{ + // Play the given sound profile on every client. + // The sounds will be transmitted as an event, not attached to any object. + for(%idx = 0; %idx < ClientGroup.getCount(); %idx++) + ClientGroup.getObject(%idx).play2D(%profile); +} + +function ServerPlay3D(%profile,%transform) +{ + // Play the given sound profile at the given position on every client + // The sound will be transmitted as an event, not attached to any object. + for(%idx = 0; %idx < ClientGroup.getCount(); %idx++) + ClientGroup.getObject(%idx).play3D(%profile,%transform); +} + diff --git a/Templates/BaseGame/game/data/clientServer/scripts/server/commands.cs b/Templates/BaseGame/game/data/clientServer/scripts/server/commands.cs new file mode 100644 index 000000000..85a08cc47 --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/scripts/server/commands.cs @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Misc. server commands avialable to clients +//----------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// Debug commands +//---------------------------------------------------------------------------- + +function serverCmdNetSimulateLag( %client, %msDelay, %packetLossPercent ) +{ + if ( %client.isAdmin ) + %client.setSimulatedNetParams( %packetLossPercent / 100.0, %msDelay ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/clientServer/scripts/server/connectionToClient.cs b/Templates/BaseGame/game/data/clientServer/scripts/server/connectionToClient.cs new file mode 100644 index 000000000..c3a4a3e26 --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/scripts/server/connectionToClient.cs @@ -0,0 +1,161 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// This script function is called before a client connection +// is accepted. Returning "" will accept the connection, +// anything else will be sent back as an error to the client. +// All the connect args are passed also to onConnectRequest +// +function GameConnection::onConnectRequest( %client, %netAddress, %name ) +{ + echo("Connect request from: " @ %netAddress); + if($Server::PlayerCount >= $pref::Server::MaxPlayers) + return "CR_SERVERFULL"; + return ""; +} + +//----------------------------------------------------------------------------- +// This script function is the first called on a client accept +function GameConnection::onConnect( %this, %clientData ) +{ + // Send down the connection error info, the client is responsible for + // displaying this message if a connection error occurs. + messageClient(%this, 'MsgConnectionError', "", $Pref::Server::ConnectionError); + + // Send mission information to the client + sendLoadInfoToClient(%this); + + // Simulated client lag for testing... + // %client.setSimulatedNetParams(0.1, 30); + + // Get the client's unique id: + // %authInfo = %client.getAuthInfo(); + // %client.guid = getField(%authInfo, 3); + %this.guid = 0; + addToServerGuidList(%this.guid); + + // Set admin status + if (%this.getAddress() $= "local") + { + %this.isAdmin = true; + %this.isSuperAdmin = true; + } + else + { + %this.isAdmin = false; + %this.isSuperAdmin = false; + } + + echo("CADD: "@ %this @" "@ %this.getAddress()); + + // If the mission is running, go ahead download it to the client + if ($missionRunning) + { + %this.loadMission(); + } + else if ($Server::LoadFailMsg !$= "") + { + messageClient(%this, 'MsgLoadFailed', $Server::LoadFailMsg); + } + + %this.connectData = %clientData; + + $Server::PlayerCount++; +} + +//----------------------------------------------------------------------------- +// A player's name could be obtained from the auth server, but for +// now we use the one passed from the client. +// %realName = getField( %authInfo, 0 ); +// +function GameConnection::setPlayerName(%client,%name) +{ + %client.sendGuid = 0; + + // Minimum length requirements + %name = trim( strToPlayerName( %name ) ); + if ( strlen( %name ) < 3 ) + %name = "Poser"; + + // Make sure the alias is unique, we'll hit something eventually + if (!isNameUnique(%name)) + { + %isUnique = false; + for (%suffix = 1; !%isUnique; %suffix++) { + %nameTry = %name @ "." @ %suffix; + %isUnique = isNameUnique(%nameTry); + } + %name = %nameTry; + } + + // Tag the name with the "smurf" color: + %client.nameBase = %name; + %client.playerName = addTaggedString("\cp\c8" @ %name @ "\co"); +} + +function isNameUnique(%name) +{ + %count = ClientGroup.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %test = ClientGroup.getObject( %i ); + %rawName = stripChars( detag( getTaggedString( %test.playerName ) ), "\cp\co\c6\c7\c8\c9" ); + if ( strcmp( %name, %rawName ) == 0 ) + return false; + } + return true; +} + +//----------------------------------------------------------------------------- +// This function is called when a client drops for any reason +// +function GameConnection::onDrop(%client, %reason) +{ + if($missionRunning) + theLevelInfo.onClientLeaveGame(); + + removeFromServerGuidList( %client.guid ); + + $Server::PlayerCount--; +} + +//----------------------------------------------------------------------------- + +function GameConnection::startMission(%this) +{ + // Inform the client the mission starting + commandToClient(%this, 'MissionStart', $missionSequence); +} + + +function GameConnection::endMission(%this) +{ + // Inform the client the mission is done. Note that if this is + // called as part of the server destruction routine, the client will + // actually never see this comment since the client connection will + // be destroyed before another round of command processing occurs. + // In this case, the client will only see the disconnect from the server + // and should manually trigger a mission cleanup. + commandToClient(%this, 'MissionEnd', $missionSequence); +} diff --git a/Templates/BaseGame/game/data/clientServer/scripts/server/defaults.cs b/Templates/BaseGame/game/data/clientServer/scripts/server/defaults.cs new file mode 100644 index 000000000..28f54b841 --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/scripts/server/defaults.cs @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//Firstly, set up our standard server prefs + +// List of master servers to query, each one is tried in order +// until one responds +$Pref::Server::RegionMask = 2; +$pref::Master[0] = "2:master.garagegames.com:28002"; + +// Information about the server +$Pref::Server::Name = "Torque 3D Server"; +$Pref::Server::Info = "This is a Torque 3D server."; + +// The connection error message is transmitted to the client immediatly +// on connection, if any further error occures during the connection +// process, such as network traffic mismatch, or missing files, this error +// message is display. This message should be replaced with information +// usefull to the client, such as the url or ftp address of where the +// latest version of the game can be obtained. +$Pref::Server::ConnectionError = + "You do not have the correct version of "@$appName@" or "@ + "the related art needed to play on this server, please contact "@ + "the server administrator."; + +// The network port is also defined by the client, this value +// overrides pref::net::port for dedicated servers +$Pref::Server::Port = 28000; + +// If the password is set, clients must provide it in order +// to connect to the server +$Pref::Server::Password = ""; + +// Password for admin clients +$Pref::Server::AdminPassword = ""; + +// Misc server settings. +$Pref::Server::MaxPlayers = 64; +$Pref::Server::TimeLimit = 20; // In minutes +$Pref::Server::KickBanTime = 300; // specified in seconds +$Pref::Server::BanTime = 1800; // specified in seconds +$Pref::Server::FloodProtectionEnabled = 1; +$Pref::Server::MaxChatLen = 120; \ No newline at end of file diff --git a/Templates/BaseGame/game/data/clientServer/scripts/server/levelDownload.cs b/Templates/BaseGame/game/data/clientServer/scripts/server/levelDownload.cs new file mode 100644 index 000000000..a598ee04f --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/scripts/server/levelDownload.cs @@ -0,0 +1,171 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Mission Loading +// The server portion of the client/server mission loading process +//----------------------------------------------------------------------------- +//-------------------------------------------------------------------------- +// Loading Phases: +// Phase 1: Transmit Datablocks +// Transmit targets +// Phase 2: Transmit Ghost Objects +// Phase 3: Start Game +// +// The server invokes the client MissionStartPhase[1-3] function to request +// permission to start each phase. When a client is ready for a phase, +// it responds with MissionStartPhase[1-3]Ack. + +//---------------------------------------------------------------------------- +// Phase 1 +//---------------------------------------------------------------------------- +function GameConnection::loadMission(%this) +{ + // Send over the information that will display the server info + // when we learn it got there, we'll send the data blocks + %this.currentPhase = 0; + if (%this.isAIControlled()) + { + // Cut to the chase... + theLevelInfo.onEnterGame(%this); + } + else + { + commandToClient(%this, 'MissionStartPhase1', $missionSequence, $Server::MissionFile); + + echo("*** Sending mission load to client: " @ $Server::MissionFile); + } +} + +function serverCmdMissionStartPhase1Ack(%client, %seq) +{ + // Make sure to ignore calls from a previous mission load + if (%seq != $missionSequence || !$MissionRunning || %client.currentPhase != 0) + return; + + %client.currentPhase = 1; + + // Start with the CRC + %client.setMissionCRC( $missionCRC ); + + // Send over the datablocks... + // OnDataBlocksDone will get called when have confirmation + // that they've all been received. + %client.transmitDataBlocks($missionSequence); +} + +function GameConnection::onDataBlocksDone( %this, %missionSequence ) +{ + // Make sure to ignore calls from a previous mission load + if (%missionSequence != $missionSequence || %this.currentPhase != 1) + return; + + %this.currentPhase = 1.5; + + // On to the next phase + commandToClient(%this, 'MissionStartPhase2', $missionSequence, $Server::MissionFile); +} + +//---------------------------------------------------------------------------- +// Phase 2 +//---------------------------------------------------------------------------- +function serverCmdMissionStartPhase2Ack(%client, %seq) +{ + // Make sure to ignore calls from a previous mission load + if (%seq != $missionSequence || !$MissionRunning || %client.currentPhase != 1.5) + return; + + %client.currentPhase = 2; + + // Update mod paths, this needs to get there before the objects. + %client.transmitPaths(); + + // Start ghosting objects to the client + %client.activateGhosting(); +} + +function GameConnection::clientWantsGhostAlwaysRetry(%client) +{ + if($MissionRunning) + %client.activateGhosting(); +} + +function GameConnection::onGhostAlwaysFailed(%client) +{ +} + +function GameConnection::onGhostAlwaysObjectsReceived(%client) +{ + // Ready for next phase. + commandToClient(%client, 'MissionStartPhase3', $missionSequence, $Server::MissionFile); +} + +//---------------------------------------------------------------------------- +// Phase 3 +//---------------------------------------------------------------------------- +function serverCmdMissionStartPhase3Ack(%client, %seq) +{ + // Make sure to ignore calls from a previous mission load + if(%seq != $missionSequence || !$MissionRunning || %client.currentPhase != 2) + return; + + %client.currentPhase = 3; + + // Server is ready to drop into the game + + //Have any special game-play handling here + if(theLevelInfo.isMethod("onClientEnterGame")) + { + theLevelInfo.onClientEnterGame(%client); + } + else + { + //No Game mode class for the level info, so just spawn a default camera + // Set the control object to the default camera + if (!isObject(%client.camera)) + { + if(!isObject(Observer)) + { + datablock CameraData(Observer) + { + mode = "Observer"; + }; + } + + if (isDefined("$Game::DefaultCameraClass")) + %client.camera = spawnObject("Camera", Observer); + } + + // If we have a camera then set up some properties + if (isObject(%client.camera)) + { + MissionCleanup.add( %this.camera ); + %client.camera.scopeToClient(%client); + + %client.setControlObject(%client.camera); + + %client.camera.setTransform("0 0 1 0 0 0 0"); + } + } + + %client.startMission(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/clientServer/scripts/server/levelInfo.cs b/Templates/BaseGame/game/data/clientServer/scripts/server/levelInfo.cs new file mode 100644 index 000000000..51df91204 --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/scripts/server/levelInfo.cs @@ -0,0 +1,197 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Loading info is text displayed on the client side while the mission +// is being loaded. This information is extracted from the mission file +// and sent to each the client as it joins. +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// clearLoadInfo +// +// Clears the mission info stored +//------------------------------------------------------------------------------ +function clearLoadInfo() +{ + if (isObject(theLevelInfo)) + theLevelInfo.delete(); +} + +//------------------------------------------------------------------------------ +// buildLoadInfo +// +// Extract the map description from the .mis file +//------------------------------------------------------------------------------ +function buildLoadInfo( %mission ) +{ + clearLoadInfo(); + + %infoObject = ""; + %file = new FileObject(); + + if ( %file.openForRead( %mission ) ) { + %inInfoBlock = false; + + while ( !%file.isEOF() ) { + %line = %file.readLine(); + %line = trim( %line ); + + if( %line $= "new ScriptObject(MissionInfo) {" ) + %inInfoBlock = true; + else if( %line $= "new LevelInfo(theLevelInfo) {" ) + %inInfoBlock = true; + else if( %inInfoBlock && %line $= "};" ) { + %inInfoBlock = false; + %infoObject = %infoObject @ %line; + break; + } + + if( %inInfoBlock ) + %infoObject = %infoObject @ %line @ " "; + } + + %file.close(); + } + else + error("Level file " @ %mission @ " not found."); + + // Will create the object "MissionInfo" + eval( %infoObject ); + %file.delete(); +} + +//------------------------------------------------------------------------------ +// dumpLoadInfo +// +// Echo the mission information to the console +//------------------------------------------------------------------------------ +function dumpLoadInfo() +{ + echo( "Level Name: " @ theLevelInfo.name ); + echo( "Level Description:" ); + + for( %i = 0; theLevelInfo.desc[%i] !$= ""; %i++ ) + echo (" " @ theLevelInfo.desc[%i]); +} + +//------------------------------------------------------------------------------ +// sendLoadInfoToClient +// +// Sends mission description to the client +//------------------------------------------------------------------------------ +function sendLoadInfoToClient( %client ) +{ + messageClient( %client, 'MsgLoadInfo', "", theLevelInfo.levelName ); + + // Send Mission Description a line at a time + for( %i = 0; theLevelInfo.desc[%i] !$= ""; %i++ ) + messageClient( %client, 'MsgLoadDescripition', "", theLevelInfo.desc[%i] ); + + messageClient( %client, 'MsgLoadInfoDone' ); +} + +// A function used in order to easily parse the MissionGroup for classes . I'm pretty +// sure at this point the function can be easily modified to search the any group as well. +function parseMissionGroup( %className, %childGroup ) +{ + if( getWordCount( %childGroup ) == 0) + %currentGroup = "MissionGroup"; + else + %currentGroup = %childGroup; + + for(%i = 0; %i < (%currentGroup).getCount(); %i++) + { + if( (%currentGroup).getObject(%i).getClassName() $= %className ) + return true; + + if( (%currentGroup).getObject(%i).getClassName() $= "SimGroup" ) + { + if( parseMissionGroup( %className, (%currentGroup).getObject(%i).getId() ) ) + return true; + } + } +} + +// +function parseMissionGroupForIds( %className, %childGroup ) +{ + if( getWordCount( %childGroup ) == 0) + %currentGroup = $Game::MissionGroup; + else + %currentGroup = %childGroup; + + for(%i = 0; %i < (%currentGroup).getCount(); %i++) + { + if( (%currentGroup).getObject(%i).getClassName() $= %className ) + %classIds = %classIds @ (%currentGroup).getObject(%i).getId() @ " "; + + if( (%currentGroup).getObject(%i).getClassName() $= "SimGroup" ) + %classIds = %classIds @ parseMissionGroupForIds( %className, (%currentGroup).getObject(%i).getId()); + } + return %classIds; +} + +function getLevelInfo( %missionFile ) +{ + clearLoadInfo(); + + %file = new FileObject(); + + %LevelInfoObject = ""; + + if ( %file.openForRead( %missionFile ) ) { + %inInfoBlock = false; + + while ( !%file.isEOF() ) { + %line = %file.readLine(); + %line = trim( %line ); + + if( %line $= "new ScriptObject(LevelInfo) {" ) + %inInfoBlock = true; + else if( %line $= "new LevelInfo(theLevelInfo) {" ) + %inInfoBlock = true; + else if( %inInfoBlock && %line $= "};" ) { + %inInfoBlock = false; + %LevelInfoObject = %LevelInfoObject @ %line; + break; + } + + if( %inInfoBlock ) + %LevelInfoObject = %LevelInfoObject @ %line @ " "; + } + + %file.close(); + } + %file.delete(); + + if( %LevelInfoObject !$= "" ) + { + %LevelInfoObject = "%LevelInfoObject = " @ %LevelInfoObject; + eval( %LevelInfoObject ); + + return %LevelInfoObject; + } + + // Didn't find our LevelInfo + return 0; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/clientServer/scripts/server/levelLoad.cs b/Templates/BaseGame/game/data/clientServer/scripts/server/levelLoad.cs new file mode 100644 index 000000000..92801318d --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/scripts/server/levelLoad.cs @@ -0,0 +1,181 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Mission Loading +// The server portion of the client/server mission loading process +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// Server mission loading +//----------------------------------------------------------------------------- +// On every mission load except the first, there is a pause after +// the initial mission info is downloaded to the client. +$MissionLoadPause = 5000; + +//----------------------------------------------------------------------------- +//This is the first call made by the server to kick the loading process off +function loadMission( %missionName, %isFirstMission ) +{ + endMission(); + echo("*** LOADING MISSION: " @ %missionName); + echo("*** Stage 1 load"); + + // increment the mission sequence (used for ghost sequencing) + $missionSequence++; + $missionRunning = false; + $Server::MissionFile = %missionName; + $Server::LoadFailMsg = ""; + + // Extract mission info from the mission file, + // including the display name and stuff to send + // to the client. + buildLoadInfo( %missionName ); + + // Download mission info to the clients + %count = ClientGroup.getCount(); + for( %cl = 0; %cl < %count; %cl++ ) + { + %client = ClientGroup.getObject( %cl ); + + if (!%client.isAIControlled()) + sendLoadInfoToClient(%client); + } + + // Now that we've sent the LevelInfo to the clients + // clear it so that it won't conflict with the actual + // LevelInfo loaded in the level + clearLoadInfo(); + + // if this isn't the first mission, allow some time for the server + // to transmit information to the clients: + if( %isFirstMission || $Server::ServerType $= "SinglePlayer" ) + loadMissionStage2(); + else + schedule( $MissionLoadPause, ServerGroup, loadMissionStage2 ); +} + +//----------------------------------------------------------------------------- + +function loadMissionStage2() +{ + echo("*** Stage 2 load"); + + // Create the mission group off the ServerGroup + $instantGroup = ServerGroup; + + // Make sure the mission exists + %file = $Server::MissionFile; + + if( !isFile( %file ) ) + { + $Server::LoadFailMsg = "Could not find mission \"" @ %file @ "\""; + } + else + { + // Calculate the mission CRC. The CRC is used by the clients + // to caching mission lighting. + $missionCRC = getFileCRC( %file ); + + // Exec the mission. The MissionGroup (loaded components) is added to the ServerGroup + exec(%file); + + if( !isObject(MissionGroup) ) + { + $Server::LoadFailMsg = "No 'MissionGroup' found in mission \"" @ %file @ "\"."; + } + } + + if( $Server::LoadFailMsg !$= "" ) + { + // Inform clients that are already connected + for (%clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++) + messageClient(ClientGroup.getObject(%clientIndex), 'MsgLoadFailed', $Server::LoadFailMsg); + return; + } + + // Set mission name. + if( isObject( theLevelInfo ) ) + $Server::MissionName = theLevelInfo.levelName; + + // Mission cleanup group. This is where run time components will reside. The MissionCleanup + // group will be added to the ServerGroup. + new SimGroup( MissionCleanup ); + + // Make the MissionCleanup group the place where all new objects will automatically be added. + $instantGroup = MissionCleanup; + + // Construct MOD paths + pathOnMissionLoadDone(); + + // Mission loading done... + echo("*** Mission loaded"); + + // Start all the clients in the mission + $missionRunning = true; + for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) + ClientGroup.getObject(%clientIndex).loadMission(); + + // Go ahead and launch the game + if(TheLevelInfo.isMethod("onMissionStart")) + TheLevelInfo.onMissionStart(); +} + +function endMission() +{ + if (!isObject( MissionGroup )) + return; + + echo("*** ENDING MISSION"); + + // Inform the game code we're done. + TheLevelInfo.onMissionEnded(); + + // Inform the clients + for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) { + // clear ghosts and paths from all clients + %cl = ClientGroup.getObject( %clientIndex ); + %cl.endMission(); + %cl.resetGhosting(); + %cl.clearPaths(); + } + + // Delete everything + MissionGroup.delete(); + MissionCleanup.delete(); + + clearServerPaths(); +} + +function resetMission() +{ + echo("*** MISSION RESET"); + + // Remove any temporary mission objects + MissionCleanup.delete(); + $instantGroup = ServerGroup; + new SimGroup( MissionCleanup ); + $instantGroup = MissionCleanup; + + clearServerPaths(); + // + TheLevelInfo.onMissionReset(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/clientServer/scripts/server/message.cs b/Templates/BaseGame/game/data/clientServer/scripts/server/message.cs new file mode 100644 index 000000000..ebb1165aa --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/scripts/server/message.cs @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +function messageClient(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) +{ + commandToClient(%client, 'ServerMessage', %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); +} + +function messageAll(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) +{ + %count = ClientGroup.getCount(); + for(%cl = 0; %cl < %count; %cl++) + { + %client = ClientGroup.getObject(%cl); + messageClient(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); + } +} + +function messageAllExcept(%client, %team, %msgtype, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13) +{ + //can exclude a client, a team or both. A -1 value in either field will ignore that exclusion, so + //messageAllExcept(-1, -1, $Mesblah, 'Blah!'); will message everyone (since there shouldn't be a client -1 or client on team -1). + %count = ClientGroup.getCount(); + for(%cl= 0; %cl < %count; %cl++) + { + %recipient = ClientGroup.getObject(%cl); + if((%recipient != %client) && (%recipient.team != %team)) + messageClient(%recipient, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/clientServer/scripts/server/server.cs b/Templates/BaseGame/game/data/clientServer/scripts/server/server.cs new file mode 100644 index 000000000..f45c6fe67 --- /dev/null +++ b/Templates/BaseGame/game/data/clientServer/scripts/server/server.cs @@ -0,0 +1,291 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function initServer() +{ + echo("\n--------- Initializing " @ $appName @ ": Server Scripts ---------"); + + //load prefs + %prefPath = getPrefpath(); + if ( isFile( %prefPath @ "/serverPrefs.cs" ) ) + exec( %prefPath @ "/serverPrefs.cs" ); + else + exec( "data/clientServer/scripts/server/defaults.cs" ); + + exec( "data/clientServer/scripts/server/audio.cs" ); + exec( "data/clientServer/scripts/server/commands.cs" ); + exec( "data/clientServer/scripts/server/message.cs" ); + exec( "data/clientServer/scripts/server/levelDownload.cs" ); + exec( "data/clientServer/scripts/server/levelLoad.cs" ); + exec( "data/clientServer/scripts/server/levelInfo.cs" ); + exec( "data/clientServer/scripts/server/connectionToClient.cs" ); + + // Server::Status is returned in the Game Info Query and represents the + // current status of the server. This string sould be very short. + $Server::Status = "Unknown"; + + // Turn on testing/debug script functions + $Server::TestCheats = false; + + // Specify where the mission files are. + $Server::MissionFileSpec = "data/levels/*.mis"; +} + +//----------------------------------------------------------------------------- +function initDedicated() +{ + enableWinConsole(true); + echo("\n--------- Starting Dedicated Server ---------"); + + // Make sure this variable reflects the correct state. + $Server::Dedicated = true; + + // The server isn't started unless a mission has been specified. + if ($missionArg !$= "") { + createServer("MultiPlayer", $missionArg); + } + else + echo("No mission specified (use -mission filename)"); +} + +/// Attempt to find an open port to initialize the server with +function portInit(%port) +{ + %failCount = 0; + while(%failCount < 10 && !setNetPort(%port)) + { + echo("Port init failed on port " @ %port @ " trying next port."); + %port++; %failCount++; + } +} + +/// Create a server of the given type, load the given level, and then +/// create a local client connection to the server. +// +/// @return true if successful. +function createAndConnectToLocalServer( %serverType, %level ) +{ + if( !createServer( %serverType, %level ) ) + return false; + + %conn = new GameConnection( ServerConnection ); + RootGroup.add( ServerConnection ); + + %conn.setConnectArgs( $pref::Player::Name ); + %conn.setJoinPassword( $Client::Password ); + + %result = %conn.connectLocal(); + if( %result !$= "" ) + { + %conn.delete(); + destroyServer(); + + return false; + } + + return true; +} + +/// Create a server with either a "SinglePlayer" or "MultiPlayer" type +/// Specify the level to load on the server +function createServer(%serverType, %level) +{ + // Increase the server session number. This is used to make sure we're + // working with the server session we think we are. + $Server::Session++; + + if (%level $= "") + { + error("createServer(): level name unspecified"); + return false; + } + + // Make sure our level name is relative so that it can send + // across the network correctly + %level = makeRelativePath(%level, getWorkingDirectory()); + + destroyServer(); + + $missionSequence = 0; + $Server::PlayerCount = 0; + $Server::ServerType = %serverType; + $Server::LoadFailMsg = ""; + $Physics::isSinglePlayer = true; + + // Setup for multi-player, the network must have been + // initialized before now. + if (%serverType $= "MultiPlayer") + { + $Physics::isSinglePlayer = false; + + echo("Starting multiplayer mode"); + + // Make sure the network port is set to the correct pref. + portInit($Pref::Server::Port); + allowConnections(true); + + if ($pref::Net::DisplayOnMaster !$= "Never" ) + schedule(0,0,startHeartbeat); + } + + // Let the game initialize some things now that the + // the server has been created + onServerCreated(); + + loadMission(%level, true); + + $Game::running = true; + + return true; +} + +function onServerCreated() +{ + // Server::GameType is sent to the master server. + // This variable should uniquely identify your game and/or mod. + $Server::GameType = $appName; + + // Server::MissionType sent to the master server. Clients can + // filter servers based on mission type. + // $Server::MissionType = "Deathmatch"; + + // GameStartTime is the sim time the game started. Used to calculated + // game elapsed time. + $Game::StartTime = 0; + + // Create the server physics world. + physicsInitWorld( "server" ); + + physicsStartSimulation("server"); + + %cnt = DatablockFilesList.count(); + + loadDatablockFiles( DatablockFilesList, true ); + + %cnt = DatablockFilesList.count(); + + // Keep track of when the game started + $Game::StartTime = $Sim::Time; +} + +/// Shut down the server +function destroyServer() +{ + $Server::ServerType = ""; + $Server::Running = false; + + allowConnections(false); + stopHeartbeat(); + $missionRunning = false; + + // End any running levels and shut down the physics sim + onServerDestroyed(); + + physicsDestroy(); + + // Delete all the server objects + if (isObject(ServerGroup)) + ServerGroup.delete(); + + // Delete all the connections: + while (ClientGroup.getCount()) + { + %client = ClientGroup.getObject(0); + %client.delete(); + } + + $Server::GuidList = ""; + + // Delete all the data blocks... + deleteDataBlocks(); + + // Save any server settings + echo( "Exporting server prefs..." ); + export( "$Pref::Server::*", "data/clientServer/scripts/server/prefs.cs", false ); + + // Increase the server session number. This is used to make sure we're + // working with the server session we think we are. + $Server::Session++; +} + +function onServerDestroyed() +{ + physicsStopSimulation("server"); + + if (!isObject( MissionGroup )) + return; + + echo("*** ENDING MISSION"); + + // Inform the game code we're done. + if(TheLevelInfo.isMethod("onMissionEnded")) + TheLevelInfo.onMissionEnded(); + + // Inform the clients + for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) { + // clear ghosts and paths from all clients + %cl = ClientGroup.getObject( %clientIndex ); + %cl.endMission(); + %cl.resetGhosting(); + %cl.clearPaths(); + } + + // Delete everything + MissionGroup.delete(); + MissionCleanup.delete(); + + clearServerPaths(); +} + +/// Guid list maintenance functions +function addToServerGuidList( %guid ) +{ + %count = getFieldCount( $Server::GuidList ); + for ( %i = 0; %i < %count; %i++ ) + { + if ( getField( $Server::GuidList, %i ) == %guid ) + return; + } + + $Server::GuidList = $Server::GuidList $= "" ? %guid : $Server::GuidList TAB %guid; +} + +function removeFromServerGuidList( %guid ) +{ + %count = getFieldCount( $Server::GuidList ); + for ( %i = 0; %i < %count; %i++ ) + { + if ( getField( $Server::GuidList, %i ) == %guid ) + { + $Server::GuidList = removeField( $Server::GuidList, %i ); + return; + } + } +} + +/// When the server is queried for information, the value of this function is +/// returned as the status field of the query packet. This information is +/// accessible as the ServerInfo::State variable. +function onServerInfoQuery() +{ + return "Doing Ok"; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/defaults.cs b/Templates/BaseGame/game/data/defaults.cs new file mode 100644 index 000000000..ea7ee6a19 --- /dev/null +++ b/Templates/BaseGame/game/data/defaults.cs @@ -0,0 +1,218 @@ +$pref::Player::Name = "Visitor"; +$pref::Player::defaultFov = 75; +$pref::Player::zoomSpeed = 0; + +$pref::Net::LagThreshold = 400; +$pref::Net::Port = 28000; + +$pref::HudMessageLogSize = 40; +$pref::ChatHudLength = 1; + +$pref::Input::LinkMouseSensitivity = 1; +// DInput keyboard, mouse, and joystick prefs +$pref::Input::KeyboardEnabled = 1; +$pref::Input::MouseEnabled = 1; +$pref::Input::JoystickEnabled = 0; +$pref::Input::KeyboardTurnSpeed = 0.1; +$pref::Input::invertVerticalMouse = false; +$pref::Input::VertMouseSensitivity = 1; +$pref::Input::HorzMouseSensitivity = 1; +$pref::Input::RollMouseSensitivity = 1; +$pref::Input::ZoomVertMouseSensitivity = 0.3; +$pref::Input::ZoomHorzMouseSensitivity = 0.3; + +$sceneLighting::cacheSize = 20000; +$sceneLighting::purgeMethod = "lastCreated"; +$sceneLighting::cacheLighting = 1; + +$pref::Video::displayDevice = "D3D9"; +$pref::Video::disableVerticalSync = 1; +$pref::Video::Resolution = "1024 768"; +$pref::Video::FullScreen = false; +$pref::Video::BitDepth = "32"; +$pref::Video::RefreshRate = "60"; +$pref::Video::AA = "4"; +$pref::Video::defaultFenceCount = 0; +$pref::Video::screenShotSession = 0; +$pref::Video::screenShotFormat = "PNG"; + +/// This disables the hardware FSAA/MSAA so that +/// we depend completely on the FXAA post effect +/// which works on all cards and in deferred mode. +/// +/// Note the new Intel Hybrid graphics on laptops +/// will fail to initialize when hardware AA is +/// enabled... so you've been warned. +/// +$pref::Video::disableHardwareAA = true; + +$pref::Video::disableNormalmapping = false; + +$pref::Video::disablePixSpecular = false; + +$pref::Video::disableCubemapping = false; + +/// +$pref::Video::disableParallaxMapping = false; + +$pref::Video::Gamma = 2.2; +$pref::Video::Contrast = 1.0; +$pref::Video::Brightness = 0; + +/// The perfered light manager to use at startup. If blank +/// or if the selected one doesn't work on this platfom it +/// will try the defaults below. +$pref::lightManager = ""; + +/// This is the default list of light managers ordered from +/// most to least desirable for initialization. +$lightManager::defaults = "Advanced Lighting"; + +/// A scale to apply to the camera view distance +/// typically used for tuning performance. +$pref::camera::distanceScale = 1.0; + +/// Causes the system to do a one time autodetect +/// of an SFX provider and device at startup if the +/// provider is unset. +$pref::SFX::autoDetect = true; + +/// The sound provider to select at startup. Typically +/// this is DirectSound, OpenAL, or XACT. There is also +/// a special Null provider which acts normally, but +/// plays no sound. +$pref::SFX::provider = ""; + +/// The sound device to select from the provider. Each +/// provider may have several different devices. +$pref::SFX::device = "OpenAL"; + +/// If true the device will try to use hardware buffers +/// and sound mixing. If not it will use software. +$pref::SFX::useHardware = false; + +/// If you have a software device you have a +/// choice of how many software buffers to +/// allow at any one time. More buffers cost +/// more CPU time to process and mix. +$pref::SFX::maxSoftwareBuffers = 16; + +/// This is the playback frequency for the primary +/// sound buffer used for mixing. Although most +/// providers will reformat on the fly, for best +/// quality and performance match your sound files +/// to this setting. +$pref::SFX::frequency = 44100; + +/// This is the playback bitrate for the primary +/// sound buffer used for mixing. Although most +/// providers will reformat on the fly, for best +/// quality and performance match your sound files +/// to this setting. +$pref::SFX::bitrate = 32; + +/// The overall system volume at startup. Note that +/// you can only scale volume down, volume does not +/// get louder than 1. +$pref::SFX::masterVolume = 0.8; + +/// The startup sound channel volumes. These are +/// used to control the overall volume of different +/// classes of sounds. +$pref::SFX::channelVolume1 = 1; +$pref::SFX::channelVolume2 = 1; +$pref::SFX::channelVolume3 = 1; +$pref::SFX::channelVolume4 = 1; +$pref::SFX::channelVolume5 = 1; +$pref::SFX::channelVolume6 = 1; +$pref::SFX::channelVolume7 = 1; +$pref::SFX::channelVolume8 = 1; + +$pref::SFX::channelVolume[1] = 1; +$pref::SFX::channelVolume[2] = 1; +$pref::SFX::channelVolume[3] = 1; +$pref::SFX::channelVolume[4] = 1; + +$pref::PostEffect::PreferedHDRFormat = "GFXFormatR8G8B8A8"; + +/// This is an scalar which can be used to reduce the +/// reflection textures on all objects to save fillrate. +$pref::Reflect::refractTexScale = 1.0; + +/// This is the total frame in milliseconds to budget for +/// reflection rendering. If your CPU bound and have alot +/// of smaller reflection surfaces try reducing this time. +$pref::Reflect::frameLimitMS = 10; + +/// Set true to force all water objects to use static cubemap reflections. +$pref::Water::disableTrueReflections = false; + +// A global LOD scalar which can reduce the overall density of placed GroundCover. +$pref::GroundCover::densityScale = 1.0; + +/// An overall scaler on the lod switching between DTS models. +/// Smaller numbers makes the lod switch sooner. +$pref::TS::detailAdjust = 1.0; + +/// +$pref::Decals::enabled = true; + +/// +$pref::Decals::lifeTimeScale = "1"; + +/// The number of mipmap levels to drop on loaded textures +/// to reduce video memory usage. +/// +/// It will skip any textures that have been defined as not +/// allowing down scaling. +/// +$pref::Video::textureReductionLevel = 0; + +/// +$pref::Shadows::textureScalar = 1.0; + +/// +$pref::Shadows::disable = false; + +/// Sets the shadow filtering mode. +/// +/// None - Disables filtering. +/// +/// SoftShadow - Does a simple soft shadow +/// +/// SoftShadowHighQuality +/// +$pref::Shadows::filterMode = "SoftShadow"; + +/// +$pref::Video::defaultAnisotropy = 1; + +/// Radius in meters around the camera that ForestItems are affected by wind. +/// Note that a very large number with a large number of items is not cheap. +$pref::windEffectRadius = 25; + +/// AutoDetect graphics quality levels the next startup. +$pref::Video::autoDetect = 1; + +$PostFXManager::Settings::EnableDOF = "0"; +$PostFXManager::Settings::DOF::BlurCurveFar = ""; +$PostFXManager::Settings::DOF::BlurCurveNear = ""; +$PostFXManager::Settings::DOF::BlurMax = ""; +$PostFXManager::Settings::DOF::BlurMin = ""; +$PostFXManager::Settings::DOF::EnableAutoFocus = ""; +$PostFXManager::Settings::DOF::EnableDOF = ""; +$PostFXManager::Settings::DOF::FocusRangeMax = ""; +$PostFXManager::Settings::DOF::FocusRangeMin = ""; + +$PostFXManager::Settings::EnableLightRays = "0"; +$PostFXManager::Settings::LightRays::brightScalar = "0.75"; +$PostFXManager::Settings::LightRays::decay = "1.0"; +$PostFXManager::Settings::LightRays::density = "0.94"; +$PostFXManager::Settings::LightRays::numSamples = "40"; +$PostFXManager::Settings::LightRays::weight = "5.65"; + +$PostFXManager::Settings::EnableDOF = 1; +$pref::PostFX::EnableVignette = 1; +$pref::PostFX::EnableLightRays = 1; +$pref::PostFX::EnableHDR = 1; +$pref::PostFX::EnableSSAO = 1; \ No newline at end of file diff --git a/Templates/BaseGame/game/data/postFX/art/AreaMap33.dds b/Templates/BaseGame/game/data/postFX/art/AreaMap33.dds new file mode 100644 index 000000000..e01982a94 Binary files /dev/null and b/Templates/BaseGame/game/data/postFX/art/AreaMap33.dds differ diff --git a/Templates/BaseGame/game/data/postFX/art/caustics_1.png b/Templates/BaseGame/game/data/postFX/art/caustics_1.png new file mode 100644 index 000000000..49821ad0f Binary files /dev/null and b/Templates/BaseGame/game/data/postFX/art/caustics_1.png differ diff --git a/Templates/BaseGame/game/data/postFX/art/caustics_2.png b/Templates/BaseGame/game/data/postFX/art/caustics_2.png new file mode 100644 index 000000000..99097fa0e Binary files /dev/null and b/Templates/BaseGame/game/data/postFX/art/caustics_2.png differ diff --git a/Templates/BaseGame/game/data/postFX/art/noise.png b/Templates/BaseGame/game/data/postFX/art/noise.png new file mode 100644 index 000000000..ebff74256 Binary files /dev/null and b/Templates/BaseGame/game/data/postFX/art/noise.png differ diff --git a/Templates/BaseGame/game/data/postFX/art/null_color_ramp.png b/Templates/BaseGame/game/data/postFX/art/null_color_ramp.png new file mode 100644 index 000000000..5f5a52186 Binary files /dev/null and b/Templates/BaseGame/game/data/postFX/art/null_color_ramp.png differ diff --git a/Templates/BaseGame/game/data/postFX/postFX.cs b/Templates/BaseGame/game/data/postFX/postFX.cs new file mode 100644 index 000000000..4b443ea97 --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/postFX.cs @@ -0,0 +1,45 @@ + +// The general flow of a gane - server's creation, loading and hosting clients, and then destruction is as follows: + +// First, a client will always create a server in the event that they want to host a single player +// game. Torque3D treats even single player connections as a soft multiplayer game, with some stuff +// in the networking short-circuited to sidestep around lag and packet transmission times. + +// initServer() is called, loading the default server scripts. +// After that, if this is a dedicated server session, initDedicated() is called, otherwise initClient is called +// to prep a playable client session. + +// When a local game is started - a listen server - via calling StartGame() a server is created and then the client is +// connected to it via createAndConnectToLocalServer(). + +function PostFX::create( %this ) +{ + echo("\n--------- Initializing PostFX Directory: scripts ---------"); + + // Start up in either client, or dedicated server mode + if (!$Server::Dedicated) + { + //postFX stuffs + exec("./scripts/gui/postFxManager.gui"); + + //init the postFX + %pattern = "./scripts/client/*.cs"; + %file = findFirstFile( %pattern ); + if ( %file $= "" ) + { + // Try for DSOs next. + %pattern = "./scripts/client/*.cs.dso"; + %file = findFirstFile( %pattern ); + } + + while( %file !$= "" ) + { + exec( %file ); + %file = findNextFile( %pattern ); + } + } +} + +function PostFX::destroy( %this ) +{ +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/postFX/postFX.module b/Templates/BaseGame/game/data/postFX/postFX.module new file mode 100644 index 000000000..e5970b9a9 --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/postFX.module @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/GammaPostFX.cs b/Templates/BaseGame/game/data/postFX/scripts/client/GammaPostFX.cs new file mode 100644 index 000000000..0b7d98403 --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/GammaPostFX.cs @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton ShaderData( GammaShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/gammaP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/gl/gammaP.glsl"; + + samplerNames[0] = "$backBuffer"; + samplerNames[1] = "$colorCorrectionTex"; + + pixVersion = 2.0; +}; + +singleton GFXStateBlockData( GammaStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampLinear; +}; + +singleton PostEffect( GammaPostFX ) +{ + isEnabled = true; + allowReflectPass = true; + + renderTime = "PFXBeforeBin"; + renderBin = "EditorBin"; + renderPriority = 9999; + + shader = GammaShader; + stateBlock = GammaStateBlock; + + texture[0] = "$backBuffer"; + texture[1] = $HDRPostFX::colorCorrectionRamp; + + targetFormat = getBestHDRFormat(); +}; + +function GammaPostFX::preProcess( %this ) +{ + if ( %this.texture[1] !$= $HDRPostFX::colorCorrectionRamp ) + %this.setTexture( 1, $HDRPostFX::colorCorrectionRamp ); +} + +function GammaPostFX::setShaderConsts( %this ) +{ + %clampedGamma = mClamp( $pref::Video::Gamma, 2.0, 2.5); + %this.setShaderConst( "$OneOverGamma", 1 / %clampedGamma ); + %this.setShaderConst( "$Brightness", $pref::Video::Brightness ); + %this.setShaderConst( "$Contrast", $pref::Video::Contrast ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/MLAA.cs b/Templates/BaseGame/game/data/postFX/scripts/client/MLAA.cs new file mode 100644 index 000000000..db5fa8f8a --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/MLAA.cs @@ -0,0 +1,186 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + +// NOTE: This is currently disabled in favor of FXAA. See +// core\scripts\client\canvas.cs if you want to re-enable it. + +singleton GFXStateBlockData( MLAA_EdgeDetectStateBlock : PFX_DefaultStateBlock ) +{ + // Mark the edge pixels in stencil. + stencilDefined = true; + stencilEnable = true; + stencilPassOp = GFXStencilOpReplace; + stencilFunc = GFXCmpAlways; + stencilRef = 1; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; +}; + +singleton ShaderData( MLAA_EdgeDetectionShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/mlaa/offsetV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/mlaa/edgeDetectionP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/mlaa/gl/offsetV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/mlaa/gl/edgeDetectionP.glsl"; + + samplerNames[0] = "$colorMapG"; + samplerNames[1] = "$prepassMap"; + + pixVersion = 3.0; +}; + +singleton GFXStateBlockData( MLAA_BlendWeightCalculationStateBlock : PFX_DefaultStateBlock ) +{ + // Here we want to process only marked pixels. + stencilDefined = true; + stencilEnable = true; + stencilPassOp = GFXStencilOpKeep; + stencilFunc = GFXCmpEqual; + stencilRef = 1; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + samplerStates[1] = SamplerClampLinear; + samplerStates[2] = SamplerClampPoint; +}; + +singleton ShaderData( MLAA_BlendWeightCalculationShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/mlaa/passthruV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/mlaa/blendWeightCalculationP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/mlaa/gl/passthruV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/mlaa/gl/blendWeightCalculationP.glsl"; + + samplerNames[0] = "$edgesMap"; + samplerNames[1] = "$edgesMapL"; + samplerNames[2] = "$areaMap"; + + pixVersion = 3.0; +}; + +singleton GFXStateBlockData( MLAA_NeighborhoodBlendingStateBlock : PFX_DefaultStateBlock ) +{ + // Here we want to process only marked pixels too. + stencilDefined = true; + stencilEnable = true; + stencilPassOp = GFXStencilOpKeep; + stencilFunc = GFXCmpEqual; + stencilRef = 1; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + samplerStates[1] = SamplerClampLinear; + samplerStates[2] = SamplerClampPoint; +}; + +singleton ShaderData( MLAA_NeighborhoodBlendingShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFx/mlaa/offsetV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/postFx/mlaa/neighborhoodBlendingP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFx/mlaa/gl/offsetV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/postFx/mlaa/gl/neighborhoodBlendingP.glsl"; + + samplerNames[0] = "$blendMap"; + samplerNames[1] = "$colorMapL"; + samplerNames[2] = "$colorMap"; + + pixVersion = 3.0; +}; + + +singleton PostEffect( MLAAFx ) +{ + isEnabled = false; + + allowReflectPass = false; + renderTime = "PFXAfterDiffuse"; + + texture[0] = "$backBuffer"; //colorMapG + texture[1] = "#prepass"; // Used for depth detection + + target = "$outTex"; + targetClear = PFXTargetClear_OnDraw; + targetClearColor = "0 0 0 0"; + + stateBlock = MLAA_EdgeDetectStateBlock; + shader = MLAA_EdgeDetectionShader; + + // The luma calculation weights which can be user adjustable + // per-scene if nessasary. The default value of... + // + // 0.2126 0.7152 0.0722 + // + // ... is the HDTV ITU-R Recommendation BT. 709. + lumaCoefficients = "0.2126 0.7152 0.0722"; + + // The tweakable color threshold used to select + // the range of edge pixels to blend. + threshold = 0.1; + + // The depth delta threshold used to select + // the range of edge pixels to blend. + depthThreshold = 0.01; + + new PostEffect() + { + internalName = "blendingWeightsCalculation"; + + target = "$outTex"; + targetClear = PFXTargetClear_OnDraw; + + shader = MLAA_BlendWeightCalculationShader; + stateBlock = MLAA_BlendWeightCalculationStateBlock; + + texture[0] = "$inTex"; // Edges mask + texture[1] = "$inTex"; // Edges mask + texture[2] = "data/postFX/art/AreaMap33.dds"; + }; + + new PostEffect() + { + internalName = "neighborhoodBlending"; + + shader = MLAA_NeighborhoodBlendingShader; + stateBlock = MLAA_NeighborhoodBlendingStateBlock; + + texture[0] = "$inTex"; // Blend weights + texture[1] = "$backBuffer"; + texture[2] = "$backBuffer"; + }; +}; + +function MLAAFx::setShaderConsts(%this) +{ + %this.setShaderConst("$lumaCoefficients", %this.lumaCoefficients); + %this.setShaderConst("$threshold", %this.threshold); + %this.setShaderConst("$depthThreshold", %this.depthThreshold); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/MotionBlurFx.cs b/Templates/BaseGame/game/data/postFX/scripts/client/MotionBlurFx.cs new file mode 100644 index 000000000..d6d86f63a --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/MotionBlurFx.cs @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton ShaderData( PFX_MotionBlurShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; //we use the bare-bones postFxV.hlsl + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/motionBlurP.hlsl"; //new pixel shader + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/gl/motionBlurP.glsl"; + + samplerNames[0] = "$backBuffer"; + samplerNames[1] = "$prepassTex"; + + pixVersion = 3.0; +}; + +singleton PostEffect(MotionBlurFX) +{ + isEnabled = false; + + renderTime = "PFXAfterDiffuse"; + + shader = PFX_MotionBlurShader; + stateBlock = PFX_DefaultStateBlock; + texture[0] = "$backbuffer"; + texture[1] = "#prepass"; + target = "$backBuffer"; +}; + +function MotionBlurFX::setShaderConsts(%this) +{ + %this.setShaderConst( "$velocityMultiplier", 3000 ); +} diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/caustics.cs b/Templates/BaseGame/game/data/postFX/scripts/client/caustics.cs new file mode 100644 index 000000000..85267be78 --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/caustics.cs @@ -0,0 +1,64 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton GFXStateBlockData( PFX_CausticsStateBlock : PFX_DefaultStateBlock ) +{ + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendOne; + blendDest = GFXBlendOne; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerWrapLinear; + samplerStates[2] = SamplerWrapLinear; +}; + +singleton ShaderData( PFX_CausticsShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/caustics/causticsP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/caustics/gl/causticsP.glsl"; + + samplerNames[0] = "$prepassTex"; + samplerNames[1] = "$causticsTex0"; + samplerNames[2] = "$causticsTex1"; + + pixVersion = 3.0; +}; + +singleton PostEffect( CausticsPFX ) +{ + isEnabled = false; + renderTime = "PFXAfterDiffuse"; + renderBin = "ObjTranslucentBin"; + //renderPriority = 0.1; + + shader = PFX_CausticsShader; + stateBlock = PFX_CausticsStateBlock; + texture[0] = "#prepass"; + texture[1] = "data/postFX/art/caustics_1"; + texture[2] = "data/postFX/art/caustics_2"; + target = "$backBuffer"; +}; diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/chromaticLens.cs b/Templates/BaseGame/game/data/postFX/scripts/client/chromaticLens.cs new file mode 100644 index 000000000..fbf52d915 --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/chromaticLens.cs @@ -0,0 +1,77 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +/// +$CAPostFx::enabled = false; + +/// The lens distortion coefficient. +$CAPostFx::distCoeffecient = -0.05; + +/// The cubic distortion value. +$CAPostFx::cubeDistortionFactor = -0.1; + +/// The amount and direction of the maxium shift for +/// the red, green, and blue channels. +$CAPostFx::colorDistortionFactor = "0.005 -0.005 0.01"; + + +singleton GFXStateBlockData( PFX_DefaultChromaticLensStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; +}; + +singleton ShaderData( PFX_ChromaticLensShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/chromaticLens.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/gl/chromaticLens.glsl"; + + samplerNames[0] = "$backBuffer"; + + pixVersion = 3.0; +}; + +singleton PostEffect( ChromaticLensPostFX ) +{ + renderTime = "PFXAfterDiffuse"; + renderPriority = 0.2; + isEnabled = false; + allowReflectPass = false; + + shader = PFX_ChromaticLensShader; + stateBlock = PFX_DefaultChromaticLensStateBlock; + texture[0] = "$backBuffer"; + target = "$backBuffer"; +}; + +function ChromaticLensPostFX::setShaderConsts( %this ) +{ + %this.setShaderConst( "$distCoeff", $CAPostFx::distCoeffecient ); + %this.setShaderConst( "$cubeDistort", $CAPostFx::cubeDistortionFactor ); + %this.setShaderConst( "$colorDistort", $CAPostFx::colorDistortionFactor ); +} diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/default.postfxpreset.cs b/Templates/BaseGame/game/data/postFX/scripts/client/default.postfxpreset.cs new file mode 100644 index 000000000..10f986516 --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/default.postfxpreset.cs @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +$PostFXManager::Settings::EnableVignette = "1"; +$PostFXManager::Settings::EnableDOF = "1"; +$PostFXManager::Settings::EnabledSSAO = "1"; +$PostFXManager::Settings::EnableHDR = "1"; +$PostFXManager::Settings::EnableLightRays = "1"; +$PostFXManager::Settings::EnablePostFX = "1"; +$PostFXManager::Settings::Vignette::VMax = "0.6"; +$PostFXManager::Settings::DOF::BlurCurveFar = ""; +$PostFXManager::Settings::DOF::BlurCurveNear = ""; +$PostFXManager::Settings::DOF::BlurMax = ""; +$PostFXManager::Settings::DOF::BlurMin = ""; +$PostFXManager::Settings::DOF::EnableAutoFocus = ""; +$PostFXManager::Settings::DOF::EnableDOF = ""; +$PostFXManager::Settings::DOF::FocusRangeMax = ""; +$PostFXManager::Settings::DOF::FocusRangeMin = ""; +$PostFXManager::Settings::HDR::adaptRate = "2"; +$PostFXManager::Settings::HDR::blueShiftColor = "1.05 0.97 1.27"; +$PostFXManager::Settings::HDR::brightPassThreshold = "1"; +$PostFXManager::Settings::HDR::enableBloom = "1"; +$PostFXManager::Settings::HDR::enableBlueShift = "0"; +$PostFXManager::Settings::HDR::enableToneMapping = "0.5"; +$PostFXManager::Settings::HDR::gaussMean = "0"; +$PostFXManager::Settings::HDR::gaussMultiplier = "0.3"; +$PostFXManager::Settings::HDR::gaussStdDev = "0.8"; +$PostFXManager::Settings::HDR::keyValue = "0.18"; +$PostFXManager::Settings::HDR::minLuminace = "0.001"; +$PostFXManager::Settings::HDR::whiteCutoff = "1"; +$PostFXManager::Settings::LightRays::brightScalar = "0.75"; +$PostFXManager::Settings::LightRays::decay = "1.0"; +$PostFXManager::Settings::LightRays::density = "0.94"; +$PostFXManager::Settings::LightRays::numSamples = "40"; +$PostFXManager::Settings::LightRays::weight = "5.65"; +$PostFXManager::Settings::SSAO::blurDepthTol = "0.001"; +$PostFXManager::Settings::SSAO::blurNormalTol = "0.95"; +$PostFXManager::Settings::SSAO::lDepthMax = "2"; +$PostFXManager::Settings::SSAO::lDepthMin = "0.2"; +$PostFXManager::Settings::SSAO::lDepthPow = "0.2"; +$PostFXManager::Settings::SSAO::lNormalPow = "2"; +$PostFXManager::Settings::SSAO::lNormalTol = "-0.5"; +$PostFXManager::Settings::SSAO::lRadius = "1"; +$PostFXManager::Settings::SSAO::lStrength = "10"; +$PostFXManager::Settings::SSAO::overallStrength = "2"; +$PostFXManager::Settings::SSAO::quality = "0"; +$PostFXManager::Settings::SSAO::sDepthMax = "1"; +$PostFXManager::Settings::SSAO::sDepthMin = "0.1"; +$PostFXManager::Settings::SSAO::sDepthPow = "1"; +$PostFXManager::Settings::SSAO::sNormalPow = "1"; +$PostFXManager::Settings::SSAO::sNormalTol = "0"; +$PostFXManager::Settings::SSAO::sRadius = "0.1"; +$PostFXManager::Settings::SSAO::sStrength = "6"; +$PostFXManager::Settings::ColorCorrectionRamp = "data/postFX/art/null_color_ramp.png"; diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/dof.cs b/Templates/BaseGame/game/data/postFX/scripts/client/dof.cs new file mode 100644 index 000000000..fd47c4ae2 --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/dof.cs @@ -0,0 +1,599 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +/* + +================================================================================ + The DOFPostEffect API +================================================================================ + +DOFPostEffect::setFocalDist( %dist ) + +@summary +This method is for manually controlling the focus distance. It will have no +effect if auto focus is currently enabled. Makes use of the parameters set by +setFocusParams. + +@param dist +float distance in meters + +-------------------------------------------------------------------------------- + +DOFPostEffect::setAutoFocus( %enabled ) + +@summary +This method sets auto focus enabled or disabled. Makes use of the parameters set +by setFocusParams. When auto focus is enabled it determines the focal depth +by performing a raycast at the screen-center. + +@param enabled +bool + +-------------------------------------------------------------------------------- + +DOFPostEffect::setFocusParams( %nearBlurMax, %farBlurMax, %minRange, %maxRange, %nearSlope, %farSlope ) + +Set the parameters that control how the near and far equations are calculated +from the focal distance. If you are not using auto focus you will need to call +setFocusParams PRIOR to calling setFocalDist. + +@param nearBlurMax +float between 0.0 and 1.0 +The max allowed value of near blur. + +@param farBlurMax +float between 0.0 and 1.0 +The max allowed value of far blur. + +@param minRange/maxRange +float in meters +The distance range around the focal distance that remains in focus is a lerp +between the min/maxRange using the normalized focal distance as the parameter. +The point is to allow the focal range to expand as you focus farther away since this is +visually appealing. + +Note: since min/maxRange are lerped by the "normalized" focal distance it is +dependant on the visible distance set in your level. + +@param nearSlope +float less than zero +The slope of the near equation. A small number causes bluriness to increase gradually +at distances closer than the focal distance. A large number causes bluriness to +increase quickly. + +@param farSlope +float greater than zero +The slope of the far equation. A small number causes bluriness to increase gradually +at distances farther than the focal distance. A large number causes bluriness to +increase quickly. + +Note: To rephrase, the min/maxRange parameters control how much area around the +focal distance is completely in focus where the near/farSlope parameters control +how quickly or slowly bluriness increases at distances outside of that range. + +================================================================================ + Examples +================================================================================ + +Example1: Turn on DOF while zoomed in with a weapon. + +NOTE: These are not real callbacks! Hook these up to your code where appropriate! + +function onSniperZoom() +{ + // Parameterize how you want DOF to look. + DOFPostEffect.setFocusParams( 0.3, 0.3, 50, 500, -5, 5 ); + + // Turn on auto focus + DOFPostEffect.setAutoFocus( true ); + + // Turn on the PostEffect + DOFPostEffect.enable(); +} + +function onSniperUnzoom() +{ + // Turn off the PostEffect + DOFPostEffect.disable(); +} + +Example2: Manually control DOF with the mouse wheel. + +// Somewhere on startup... + +// Parameterize how you want DOF to look. +DOFPostEffect.setFocusParams( 0.3, 0.3, 50, 500, -5, 5 ); + +// Turn off auto focus +DOFPostEffect.setAutoFocus( false ); + +// Turn on the PostEffect +DOFPostEffect.enable(); + + +NOTE: These are not real callbacks! Hook these up to your code where appropriate! + +function onMouseWheelUp() +{ + // Since setFocalDist is really just a wrapper to assign to the focalDist + // dynamic field we can shortcut and increment it directly. + DOFPostEffect.focalDist += 8; +} + +function onMouseWheelDown() +{ + DOFPostEffect.focalDist -= 8; +} +*/ + +/// This method is for manually controlling the focal distance. It will have no +/// effect if auto focus is currently enabled. Makes use of the parameters set by +/// setFocusParams. +function DOFPostEffect::setFocalDist( %this, %dist ) +{ + %this.focalDist = %dist; +} + +/// This method sets auto focus enabled or disabled. Makes use of the parameters set +/// by setFocusParams. When auto focus is enabled it determine the focal depth +/// by performing a raycast at the screen-center. +function DOFPostEffect::setAutoFocus( %this, %enabled ) +{ + %this.autoFocusEnabled = %enabled; +} + +/// Set the parameters that control how the near and far equations are calculated +/// from the focal distance. If you are not using auto focus you will need to call +/// setFocusParams PRIOR to calling setFocalDist. +function DOFPostEffect::setFocusParams( %this, %nearBlurMax, %farBlurMax, %minRange, %maxRange, %nearSlope, %farSlope ) +{ + %this.nearBlurMax = %nearBlurMax; + %this.farBlurMax = %farBlurMax; + %this.minRange = %minRange; + %this.maxRange = %maxRange; + %this.nearSlope = %nearSlope; + %this.farSlope = %farSlope; +} + +/* + +More information... + +This DOF technique is based on this paper: +http://http.developer.nvidia.com/GPUGems3/gpugems3_ch28.html + +================================================================================ +1. Overview of how we represent "Depth of Field" +================================================================================ + +DOF is expressed as an amount of bluriness per pixel according to its depth. +We represented this by a piecewise linear curve depicted below. + +Note: we also refer to "bluriness" as CoC ( circle of confusion ) which is the term +used in the basis paper and in photography. + + +X-axis (depth) +x = 0.0----------------------------------------------x = 1.0 + +Y-axis (bluriness) +y = 1.0 + | + | ____(x1,y1) (x4,y4)____ + | (ns,nb)\ <--Line1 line2---> /(fe,fb) + | \ / + | \(x2,y2) (x3,y3)/ + | (ne,0)------(fs,0) +y = 0.0 + + +I have labeled the "corners" of this graph with (Xn,Yn) to illustrate that +this is in fact a collection of line segments where the x/y of each point +corresponds to the key below. + +key: +ns - (n)ear blur (s)tart distance +nb - (n)ear (b)lur amount (max value) +ne - (n)ear blur (e)nd distance +fs - (f)ar blur (s)tart distance +fe - (f)ar blur (e)nd distance +fb - (f)ar (b)lur amount (max value) + +Of greatest importance in this graph is Line1 and Line2. Where... +L1 { (x1,y1), (x2,y2) } +L2 { (x3,y3), (x4,y4) } + +Line one represents the amount of "near" blur given a pixels depth and line two +represents the amount of "far" blur at that depth. + +Both these equations are evaluated for each pixel and then the larger of the two +is kept. Also the output blur (for each equation) is clamped between 0 and its +maximum allowable value. + +Therefore, to specify a DOF "qualify" you need to specify the near-blur-line, +far-blur-line, and maximum near and far blur value. + +================================================================================ +2. Abstracting a "focal depth" +================================================================================ + +Although the shader(s) work in terms of a near and far equation it is more +useful to express DOF as an adjustable focal depth and derive the other parameters +"under the hood". + +Given a maximum near/far blur amount and a near/far slope we can calculate the +near/far equations for any focal depth. We extend this to also support a range +of depth around the focal depth that is also in focus and for that range to +shrink or grow as the focal depth moves closer or farther. + +Keep in mind this is only one implementation and depending on the effect you +desire you may which to express the relationship between focal depth and +the shader paramaters different. + +*/ + +//----------------------------------------------------------------------------- +// GFXStateBlockData / ShaderData +//----------------------------------------------------------------------------- + +singleton GFXStateBlockData( PFX_DefaultDOFStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + samplerStates[1] = SamplerClampPoint; +}; + +singleton GFXStateBlockData( PFX_DOFCalcCoCStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampLinear; +}; + +singleton GFXStateBlockData( PFX_DOFDownSampleStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampPoint; +}; + +singleton GFXStateBlockData( PFX_DOFBlurStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; +}; + +singleton GFXStateBlockData( PFX_DOFFinalStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampLinear; + samplerStates[2] = SamplerClampLinear; + samplerStates[3] = SamplerClampPoint; + + blendDefined = true; + blendEnable = true; + blendDest = GFXBlendInvSrcAlpha; + blendSrc = GFXBlendOne; +}; + +singleton ShaderData( PFX_DOFDownSampleShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/dof/DOF_DownSample_V.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/dof/DOF_DownSample_P.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/dof/gl/DOF_DownSample_V.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/dof/gl/DOF_DownSample_P.glsl"; + + samplerNames[0] = "$colorSampler"; + samplerNames[1] = "$depthSampler"; + + pixVersion = 3.0; +}; + +singleton ShaderData( PFX_DOFBlurYShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/dof/DOF_Gausian_V.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/dof/DOF_Gausian_P.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/dof/gl/DOF_Gausian_V.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/dof/gl/DOF_Gausian_P.glsl"; + + samplerNames[0] = "$diffuseMap"; + + pixVersion = 2.0; + defines = "BLUR_DIR=float2(0.0,1.0)"; +}; + +singleton ShaderData( PFX_DOFBlurXShader : PFX_DOFBlurYShader ) +{ + defines = "BLUR_DIR=float2(1.0,0.0)"; +}; + +singleton ShaderData( PFX_DOFCalcCoCShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/dof/DOF_CalcCoC_V.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/dof/DOF_CalcCoC_P.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/dof/gl/DOF_CalcCoC_V.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/dof/gl/DOF_CalcCoC_P.glsl"; + + samplerNames[0] = "$shrunkSampler"; + samplerNames[1] = "$blurredSampler"; + + pixVersion = 3.0; +}; + +singleton ShaderData( PFX_DOFSmallBlurShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/dof/DOF_SmallBlur_V.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/dof/DOF_SmallBlur_P.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/dof/gl/DOF_SmallBlur_V.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/dof/gl/DOF_SmallBlur_P.glsl"; + + samplerNames[0] = "$colorSampler"; + + pixVersion = 3.0; +}; + +singleton ShaderData( PFX_DOFFinalShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/dof/DOF_Final_V.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/dof/DOF_Final_P.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/dof/gl/DOF_Final_V.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/dof/gl/DOF_Final_P.glsl"; + + samplerNames[0] = "$colorSampler"; + samplerNames[1] = "$smallBlurSampler"; + samplerNames[2] = "$largeBlurSampler"; + samplerNames[3] = "$depthSampler"; + + pixVersion = 3.0; +}; + +//----------------------------------------------------------------------------- +// PostEffects +//----------------------------------------------------------------------------- + +function DOFPostEffect::onAdd( %this ) +{ + // The weighted distribution of CoC value to the three blur textures + // in the order small, medium, large. Most likely you will not need to + // change this value. + %this.setLerpDist( 0.2, 0.3, 0.5 ); + + // Fill out some default values but DOF really should not be turned on + // without actually specifying your own parameters! + %this.autoFocusEnabled = false; + %this.focalDist = 0.0; + %this.nearBlurMax = 0.5; + %this.farBlurMax = 0.5; + %this.minRange = 50; + %this.maxRange = 500; + %this.nearSlope = -5.0; + %this.farSlope = 5.0; +} + +function DOFPostEffect::setLerpDist( %this, %d0, %d1, %d2 ) +{ + %this.lerpScale = -1.0 / %d0 SPC -1.0 / %d1 SPC -1.0 / %d2 SPC 1.0 / %d2; + %this.lerpBias = 1.0 SPC ( 1.0 - %d2 ) / %d1 SPC 1.0 / %d2 SPC ( %d2 - 1.0 ) / %d2; +} + +singleton PostEffect( DOFPostEffect ) +{ + renderTime = "PFXAfterBin"; + renderBin = "GlowBin"; + renderPriority = 0.1; + + shader = PFX_DOFDownSampleShader; + stateBlock = PFX_DOFDownSampleStateBlock; + texture[0] = "$backBuffer"; + texture[1] = "#prepass"; + target = "#shrunk"; + targetScale = "0.25 0.25"; + + isEnabled = false; +}; + +singleton PostEffect( DOFBlurY ) +{ + shader = PFX_DOFBlurYShader; + stateBlock = PFX_DOFBlurStateBlock; + texture[0] = "#shrunk"; + target = "$outTex"; +}; + +DOFPostEffect.add( DOFBlurY ); + +singleton PostEffect( DOFBlurX ) +{ + shader = PFX_DOFBlurXShader; + stateBlock = PFX_DOFBlurStateBlock; + texture[0] = "$inTex"; + target = "#largeBlur"; +}; + +DOFPostEffect.add( DOFBlurX ); + +singleton PostEffect( DOFCalcCoC ) +{ + shader = PFX_DOFCalcCoCShader; + stateBlock = PFX_DOFCalcCoCStateBlock; + texture[0] = "#shrunk"; + texture[1] = "#largeBlur"; + target = "$outTex"; +}; + +DOFPostEffect.add( DOFCalcCoc ); + +singleton PostEffect( DOFSmallBlur ) +{ + shader = PFX_DOFSmallBlurShader; + stateBlock = PFX_DefaultDOFStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; +}; + +DOFPostEffect.add( DOFSmallBlur ); + +singleton PostEffect( DOFFinalPFX ) +{ + shader = PFX_DOFFinalShader; + stateBlock = PFX_DOFFinalStateBlock; + texture[0] = "$backBuffer"; + texture[1] = "$inTex"; + texture[2] = "#largeBlur"; + texture[3] = "#prepass"; + target = "$backBuffer"; +}; + +DOFPostEffect.add( DOFFinalPFX ); + + +//----------------------------------------------------------------------------- +// Scripts +//----------------------------------------------------------------------------- + +function DOFPostEffect::setShaderConsts( %this ) +{ + if ( %this.autoFocusEnabled ) + %this.autoFocus(); + + %fd = %this.focalDist / $Param::FarDist; + + %range = mLerp( %this.minRange, %this.maxRange, %fd ) / $Param::FarDist * 0.5; + + // We work in "depth" space rather than real-world units for the + // rest of this method... + + // Given the focal distance and the range around it we want in focus + // we can determine the near-end-distance and far-start-distance + + %ned = getMax( %fd - %range, 0.0 ); + %fsd = getMin( %fd + %range, 1.0 ); + + // near slope + %nsl = %this.nearSlope; + + // Given slope of near blur equation and the near end dist and amount (x2,y2) + // solve for the y-intercept + // y = mx + b + // so... + // y - mx = b + + %b = 0.0 - %nsl * %ned; + + %eqNear = %nsl SPC %b SPC 0.0; + + // Do the same for the far blur equation... + + %fsl = %this.farSlope; + + %b = 0.0 - %fsl * %fsd; + + %eqFar = %fsl SPC %b SPC 1.0; + + %this.setShaderConst( "$dofEqWorld", %eqNear ); + DOFFinalPFX.setShaderConst( "$dofEqFar", %eqFar ); + + %this.setShaderConst( "$maxWorldCoC", %this.nearBlurMax ); + DOFFinalPFX.setShaderConst( "$maxFarCoC", %this.farBlurMax ); + + DOFFinalPFX.setShaderConst( "$dofLerpScale", %this.lerpScale ); + DOFFinalPFX.setShaderConst( "$dofLerpBias", %this.lerpBias ); +} + +function DOFPostEffect::autoFocus( %this ) +{ + if ( !isObject( ServerConnection ) || + !isObject( ServerConnection.getCameraObject() ) ) + { + return; + } + + %mask = $TypeMasks::StaticObjectType | $TypeMasks::TerrainObjectType; + %control = ServerConnection.getCameraObject(); + + %fvec = %control.getEyeVector(); + %start = %control.getEyePoint(); + + %end = VectorAdd( %start, VectorScale( %fvec, $Param::FarDist ) ); + + // Use the client container for this ray cast. + %result = containerRayCast( %start, %end, %mask, %control, true ); + + %hitPos = getWords( %result, 1, 3 ); + + if ( %hitPos $= "" ) + %focDist = $Param::FarDist; + else + %focDist = VectorDist( %hitPos, %start ); + + // For debuging + //$DOF::debug_dist = %focDist; + //$DOF::debug_depth = %focDist / $Param::FarDist; + //echo( "F: " @ %focDist SPC "D: " @ %delta ); + + %this.focalDist = %focDist; +} + + +// For debugging +/* +function reloadDOF() +{ + exec( "./dof.cs" ); + DOFPostEffect.reload(); + DOFPostEffect.disable(); + DOFPostEffect.enable(); +} + +function dofMetricsCallback() +{ + return " | DOF |" @ + " Dist: " @ $DOF::debug_dist @ + " Depth: " @ $DOF::debug_depth; +} +*/ \ No newline at end of file diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/edgeAA.cs b/Templates/BaseGame/game/data/postFX/scripts/client/edgeAA.cs new file mode 100644 index 000000000..4a5014c62 --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/edgeAA.cs @@ -0,0 +1,113 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +singleton GFXStateBlockData( PFX_DefaultEdgeAAStateBlock ) +{ + zDefined = true; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + //samplerStates[1] = SamplerWrapPoint; +}; + +singleton ShaderData( PFX_EdgeAADetectShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/edgeaa/edgeDetectP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/edgeaa/gl/edgeDetectP.glsl"; + + samplerNames[0] = "$prepassBuffer"; + + pixVersion = 3.0; +}; + +singleton ShaderData( PFX_EdgeAAShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/edgeaa/edgeAAV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/edgeaa/edgeAAP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/edgeaa/gl/edgeAAV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/edgeaa/gl/edgeAAP.glsl"; + + samplerNames[0] = "$edgeBuffer"; + samplerNames[1] = "$backBuffer"; + + pixVersion = 3.0; +}; + +singleton ShaderData( PFX_EdgeAADebugShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/edgeaa/dbgEdgeDisplayP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/edgeaa/gl/dbgEdgeDisplayP.glsl"; + + samplerNames[0] = "$edgeBuffer"; + + pixVersion = 3.0; +}; + +singleton PostEffect( EdgeDetectPostEffect ) +{ + renderTime = "PFXBeforeBin"; + renderBin = "ObjTranslucentBin"; + //renderPriority = 0.1; + targetScale = "0.5 0.5"; + + shader = PFX_EdgeAADetectShader; + stateBlock = PFX_DefaultEdgeAAStateBlock; + texture[0] = "#prepass"; + target = "#edge"; + + isEnabled = true; +}; + +singleton PostEffect( EdgeAAPostEffect ) +{ + renderTime = "PFXAfterDiffuse"; + //renderBin = "ObjTranslucentBin"; + //renderPriority = 0.1; + + shader = PFX_EdgeAAShader; + stateBlock = PFX_DefaultEdgeAAStateBlock; + texture[0] = "#edge"; + texture[1] = "$backBuffer"; + target = "$backBuffer"; +}; + +singleton PostEffect( Debug_EdgeAAPostEffect ) +{ + renderTime = "PFXAfterDiffuse"; + //renderBin = "ObjTranslucentBin"; + //renderPriority = 0.1; + + shader = PFX_EdgeAADebugShader; + stateBlock = PFX_DefaultEdgeAAStateBlock; + texture[0] = "#edge"; + target = "$backBuffer"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/flash.cs b/Templates/BaseGame/game/data/postFX/scripts/client/flash.cs new file mode 100644 index 000000000..ff82c37ee --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/flash.cs @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton ShaderData( PFX_FlashShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/flashP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/gl/flashP.glsl"; + + samplerNames[0] = "$backBuffer"; + + defines = "WHITE_COLOR=float4(1.0,1.0,1.0,0.0);MUL_COLOR=float4(1.0,0.25,0.25,0.0)"; + + pixVersion = 2.0; +}; + +singleton PostEffect( FlashFx ) +{ + isEnabled = false; + allowReflectPass = false; + + renderTime = "PFXAfterDiffuse"; + + shader = PFX_FlashShader; + texture[0] = "$backBuffer"; + renderPriority = 10; + stateBlock = PFX_DefaultStateBlock; +}; + +function FlashFx::setShaderConsts( %this ) +{ + if ( isObject( ServerConnection ) ) + { + %this.setShaderConst( "$damageFlash", ServerConnection.getDamageFlash() ); + %this.setShaderConst( "$whiteOut", ServerConnection.getWhiteOut() ); + } + else + { + %this.setShaderConst( "$damageFlash", 0 ); + %this.setShaderConst( "$whiteOut", 0 ); + } +} diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/fog.cs b/Templates/BaseGame/game/data/postFX/scripts/client/fog.cs new file mode 100644 index 000000000..ea1bd805d --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/fog.cs @@ -0,0 +1,135 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Fog +//------------------------------------------------------------------------------ + +singleton ShaderData( FogPassShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/fogP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/gl/fogP.glsl"; + + samplerNames[0] = "$prepassTex"; + + pixVersion = 2.0; +}; + + +singleton GFXStateBlockData( FogPassStateBlock : PFX_DefaultStateBlock ) +{ + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendSrcAlpha; + blendDest = GFXBlendInvSrcAlpha; +}; + + +singleton PostEffect( FogPostFx ) +{ + // We forward render the reflection pass + // so it does its own fogging. + allowReflectPass = false; + + renderTime = "PFXBeforeBin"; + renderBin = "ObjTranslucentBin"; + + shader = FogPassShader; + stateBlock = FogPassStateBlock; + texture[0] = "#prepass"; + + renderPriority = 5; + + targetFormat = getBestHDRFormat(); + isEnabled = true; +}; + + +//------------------------------------------------------------------------------ +// UnderwaterFog +//------------------------------------------------------------------------------ + +singleton ShaderData( UnderwaterFogPassShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/underwaterFogP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/gl/underwaterFogP.glsl"; + + samplerNames[0] = "$prepassTex"; + samplerNames[1] = "$backbuffer"; + samplerNames[2] = "$waterDepthGradMap"; + + pixVersion = 2.0; +}; + + +singleton GFXStateBlockData( UnderwaterFogPassStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + samplerStates[1] = SamplerClampPoint; + samplerStates[2] = SamplerClampLinear; +}; + + +singleton PostEffect( UnderwaterFogPostFx ) +{ + oneFrameOnly = true; + onThisFrame = false; + + // Let the fog effect render during the + // reflection pass. + allowReflectPass = true; + + renderTime = "PFXBeforeBin"; + renderBin = "ObjTranslucentBin"; + + shader = UnderwaterFogPassShader; + stateBlock = UnderwaterFogPassStateBlock; + texture[0] = "#prepass"; + texture[1] = "$backBuffer"; + texture[2] = "#waterDepthGradMap"; + + // Needs to happen after the FogPostFx + renderPriority = 4; + + isEnabled = true; +}; + +function UnderwaterFogPostFx::onEnabled( %this ) +{ + TurbulenceFx.enable(); + CausticsPFX.enable(); + return true; +} + +function UnderwaterFogPostFx::onDisabled( %this ) +{ + TurbulenceFx.disable(); + CausticsPFX.disable(); + return false; +} diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/fxaa.cs b/Templates/BaseGame/game/data/postFX/scripts/client/fxaa.cs new file mode 100644 index 000000000..3f741a072 --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/fxaa.cs @@ -0,0 +1,64 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// An implementation of "NVIDIA FXAA 3.11" by TIMOTHY LOTTES +// +// http://timothylottes.blogspot.com/ +// +// The shader is tuned for the defaul quality and good performance. +// See shaders\common\postFx\fxaa\fxaaP.hlsl to tweak the internal +// quality and performance settings. + +singleton GFXStateBlockData( FXAA_StateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; +}; + +singleton ShaderData( FXAA_ShaderData ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/fxaa/fxaaV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/fxaa/fxaaP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/fxaa/gl/fxaaV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/fxaa/gl/fxaaP.glsl"; + + samplerNames[0] = "$colorTex"; + + pixVersion = 3.0; +}; + +singleton PostEffect( FXAA_PostEffect ) +{ + isEnabled = false; + + allowReflectPass = false; + renderTime = "PFXAfterDiffuse"; + + texture[0] = "$backBuffer"; + + target = "$backBuffer"; + + stateBlock = FXAA_StateBlock; + shader = FXAA_ShaderData; +}; + diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/glow.cs b/Templates/BaseGame/game/data/postFX/scripts/client/glow.cs new file mode 100644 index 000000000..3314aa97a --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/glow.cs @@ -0,0 +1,184 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +singleton ShaderData( PFX_GlowBlurVertShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/glowBlurV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/glowBlurP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/gl/glowBlurV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/gl/glowBlurP.glsl"; + + defines = "BLUR_DIR=float2(0.0,1.0)"; + + samplerNames[0] = "$diffuseMap"; + + pixVersion = 2.0; +}; + + +singleton ShaderData( PFX_GlowBlurHorzShader : PFX_GlowBlurVertShader ) +{ + defines = "BLUR_DIR=float2(1.0,0.0)"; +}; + + +singleton GFXStateBlockData( PFX_GlowCombineStateBlock : PFX_DefaultStateBlock ) +{ + // Use alpha test to save some fillrate + // on the non-glowing areas of the scene. + alphaDefined = true; + alphaTestEnable = true; + alphaTestRef = 1; + alphaTestFunc = GFXCmpGreaterEqual; + + // Do a one to one blend. + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendOne; + blendDest = GFXBlendOne; +}; + + +singleton PostEffect( GlowPostFx ) +{ + // Do not allow the glow effect to work in reflection + // passes by default so we don't do the extra drawing. + allowReflectPass = false; + + renderTime = "PFXAfterBin"; + renderBin = "GlowBin"; + renderPriority = 1; + + // First we down sample the glow buffer. + shader = PFX_PassthruShader; + stateBlock = PFX_DefaultStateBlock; + texture[0] = "#glowbuffer"; + target = "$outTex"; + targetScale = "0.5 0.5"; + + isEnabled = true; + + // Blur vertically + new PostEffect() + { + shader = PFX_GlowBlurVertShader; + stateBlock = PFX_DefaultStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + }; + + // Blur horizontally + new PostEffect() + { + shader = PFX_GlowBlurHorzShader; + stateBlock = PFX_DefaultStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + }; + + // Upsample and combine with the back buffer. + new PostEffect() + { + shader = PFX_PassthruShader; + stateBlock = PFX_GlowCombineStateBlock; + texture[0] = "$inTex"; + target = "$backBuffer"; + }; +}; + +singleton ShaderData( PFX_VolFogGlowBlurVertShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/glowBlurV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/VolFogGlowP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/gl/glowBlurV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/gl/VolFogGlowP.glsl"; + + defines = "BLUR_DIR=float2(0.0,1.0)"; + samplerNames[0] = "$diffuseMap"; + pixVersion = 2.0; +}; +singleton ShaderData( PFX_VolFogGlowBlurHorzShader : PFX_VolFogGlowBlurVertShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/glowBlurV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/VolFogGlowP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/gl/glowBlurV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/gl/VolFogGlowP.glsl"; + + defines = "BLUR_DIR=float2(1.0,0.0)"; +}; + +$VolFogGlowPostFx::glowStrength = 0.3; + +singleton PostEffect( VolFogGlowPostFx ) +{ + // Do not allow the glow effect to work in reflection + // passes by default so we don't do the extra drawing. + allowReflectPass = false; + renderTime = "PFXAfterBin"; + renderBin = "FogBin"; + renderPriority = 1; + // First we down sample the glow buffer. + shader = PFX_PassthruShader; + stateBlock = PFX_DefaultStateBlock; + texture[0] = "$backbuffer"; + target = "$outTex"; + targetScale = "0.5 0.5"; + isEnabled = true; + // Blur vertically + new PostEffect() + { + shader = PFX_VolFogGlowBlurVertShader; + stateBlock = PFX_DefaultStateBlock; + internalName = "vert"; + texture[0] = "$inTex"; + target = "$outTex"; + }; + // Blur horizontally + new PostEffect() + { + shader = PFX_VolFogGlowBlurHorzShader; + stateBlock = PFX_DefaultStateBlock; + internalName = "hor"; + texture[0] = "$inTex"; + target = "$outTex"; + }; + // Upsample and combine with the back buffer. + new PostEffect() + { + shader = PFX_PassthruShader; + stateBlock = PFX_GlowCombineStateBlock; + texture[0] = "$inTex"; + target = "$backBuffer"; + }; +}; + +function VolFogGlowPostFx::setShaderConsts( %this ) +{ + %vp=%this-->vert; + %vp.setShaderConst( "$strength", $VolFogGlowPostFx::glowStrength ); + %vp=%this-->hor; + %vp.setShaderConst( "$strength", $VolFogGlowPostFx::glowStrength ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/hdr.cs b/Templates/BaseGame/game/data/postFX/scripts/client/hdr.cs new file mode 100644 index 000000000..1ccf07145 --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/hdr.cs @@ -0,0 +1,533 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +/// Blends between the scene and the tone mapped scene. +$HDRPostFX::enableToneMapping = 0.5; + +/// The tone mapping middle grey or exposure value used +/// to adjust the overall "balance" of the image. +/// +/// 0.18 is fairly common value. +/// +$HDRPostFX::keyValue = 0.18; + +/// The minimum luninace value to allow when tone mapping +/// the scene. Is particularly useful if your scene very +/// dark or has a black ambient color in places. +$HDRPostFX::minLuminace = 0.001; + +/// The lowest luminance value which is mapped to white. This +/// is usually set to the highest visible luminance in your +/// scene. By setting this to smaller values you get a contrast +/// enhancement. +$HDRPostFX::whiteCutoff = 1.0; + +/// The rate of adaptation from the previous and new +/// average scene luminance. +$HDRPostFX::adaptRate = 2.0; + +/// Blends between the scene and the blue shifted version +/// of the scene for a cinematic desaturated night effect. +$HDRPostFX::enableBlueShift = 0.0; + +/// The blue shift color value. +$HDRPostFX::blueShiftColor = "1.05 0.97 1.27"; + + +/// Blends between the scene and the bloomed scene. +$HDRPostFX::enableBloom = 1.0; + +/// The threshold luminace value for pixels which are +/// considered "bright" and need to be bloomed. +$HDRPostFX::brightPassThreshold = 1.0; + +/// These are used in the gaussian blur of the +/// bright pass for the bloom effect. +$HDRPostFX::gaussMultiplier = 0.3; +$HDRPostFX::gaussMean = 0.0; +$HDRPostFX::gaussStdDev = 0.8; + +/// The 1x255 color correction ramp texture used +/// by both the HDR shader and the GammaPostFx shader +/// for doing full screen color correction. +$HDRPostFX::colorCorrectionRamp = "data/postFX/art/null_color_ramp.png"; + + +singleton ShaderData( HDR_BrightPassShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/brightPassFilterP.hlsl"; + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/gl/brightPassFilterP.glsl"; + + samplerNames[0] = "$inputTex"; + samplerNames[1] = "$luminanceTex"; + + pixVersion = 3.0; +}; + +singleton ShaderData( HDR_DownScale4x4Shader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/downScale4x4V.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/downScale4x4P.hlsl"; + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/gl/downScale4x4V.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/gl/downScale4x4P.glsl"; + + samplerNames[0] = "$inputTex"; + + pixVersion = 2.0; +}; + +singleton ShaderData( HDR_BloomGaussBlurHShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/bloomGaussBlurHP.hlsl"; + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/gl/bloomGaussBlurHP.glsl"; + + samplerNames[0] = "$inputTex"; + + pixVersion = 3.0; +}; + +singleton ShaderData( HDR_BloomGaussBlurVShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/bloomGaussBlurVP.hlsl"; + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/gl/bloomGaussBlurVP.glsl"; + + samplerNames[0] = "$inputTex"; + + pixVersion = 3.0; +}; + +singleton ShaderData( HDR_SampleLumShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/sampleLumInitialP.hlsl"; + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/gl/sampleLumInitialP.glsl"; + + samplerNames[0] = "$inputTex"; + + pixVersion = 3.0; +}; + +singleton ShaderData( HDR_DownSampleLumShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/sampleLumIterativeP.hlsl"; + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/gl/sampleLumIterativeP.glsl"; + + samplerNames[0] = "$inputTex"; + + pixVersion = 3.0; +}; + +singleton ShaderData( HDR_CalcAdaptedLumShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/calculateAdaptedLumP.hlsl"; + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/gl/calculateAdaptedLumP.glsl"; + + samplerNames[0] = "$currLum"; + samplerNames[1] = "$lastAdaptedLum"; + + pixVersion = 3.0; +}; + +singleton ShaderData( HDR_CombineShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/finalPassCombineP.hlsl"; + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/gl/finalPassCombineP.glsl"; + + samplerNames[0] = "$sceneTex"; + samplerNames[1] = "$luminanceTex"; + samplerNames[2] = "$bloomTex"; + samplerNames[3] = "$colorCorrectionTex"; + samplerNames[4] = "prepassTex"; + + pixVersion = 3.0; +}; + + +singleton GFXStateBlockData( HDR_SampleStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + samplerStates[1] = SamplerClampPoint; +}; + +singleton GFXStateBlockData( HDR_DownSampleStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampLinear; +}; + +singleton GFXStateBlockData( HDR_CombineStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + samplerStates[1] = SamplerClampLinear; + samplerStates[2] = SamplerClampLinear; + samplerStates[3] = SamplerClampLinear; +}; + +singleton GFXStateBlockData( HDRStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampLinear; + samplerStates[2] = SamplerClampLinear; + samplerStates[3] = SamplerClampLinear; + + blendDefined = true; + blendDest = GFXBlendOne; + blendSrc = GFXBlendZero; + + zDefined = true; + zEnable = false; + zWriteEnable = false; + + cullDefined = true; + cullMode = GFXCullNone; +}; + + +function HDRPostFX::setShaderConsts( %this ) +{ + %this.setShaderConst( "$brightPassThreshold", $HDRPostFX::brightPassThreshold ); + %this.setShaderConst( "$g_fMiddleGray", $HDRPostFX::keyValue ); + + %bloomH = %this-->bloomH; + %bloomH.setShaderConst( "$gaussMultiplier", $HDRPostFX::gaussMultiplier ); + %bloomH.setShaderConst( "$gaussMean", $HDRPostFX::gaussMean ); + %bloomH.setShaderConst( "$gaussStdDev", $HDRPostFX::gaussStdDev ); + + %bloomV = %this-->bloomV; + %bloomV.setShaderConst( "$gaussMultiplier", $HDRPostFX::gaussMultiplier ); + %bloomV.setShaderConst( "$gaussMean", $HDRPostFX::gaussMean ); + %bloomV.setShaderConst( "$gaussStdDev", $HDRPostFX::gaussStdDev ); + + %minLuminace = $HDRPostFX::minLuminace; + if ( %minLuminace <= 0.0 ) + { + // The min should never be pure zero else the + // log() in the shader will generate INFs. + %minLuminace = 0.00001; + } + %this-->adaptLum.setShaderConst( "$g_fMinLuminace", %minLuminace ); + + %this-->finalLum.setShaderConst( "$adaptRate", $HDRPostFX::adaptRate ); + + %combinePass = %this-->combinePass; + %combinePass.setShaderConst( "$g_fEnableToneMapping", $HDRPostFX::enableToneMapping ); + %combinePass.setShaderConst( "$g_fMiddleGray", $HDRPostFX::keyValue ); + %combinePass.setShaderConst( "$g_fBloomScale", $HDRPostFX::enableBloom ); + %combinePass.setShaderConst( "$g_fEnableBlueShift", $HDRPostFX::enableBlueShift ); + %combinePass.setShaderConst( "$g_fBlueShiftColor", $HDRPostFX::blueShiftColor ); + + %clampedGamma = mClamp( $pref::Video::Gamma, 2.0, 2.5); + %combinePass.setShaderConst( "$g_fOneOverGamma", 1 / %clampedGamma ); + %combinePass.setShaderConst( "$Brightness", $pref::Video::Brightness ); + %combinePass.setShaderConst( "$Contrast", $pref::Video::Contrast ); + + %whiteCutoff = ( $HDRPostFX::whiteCutoff * $HDRPostFX::whiteCutoff ) * + ( $HDRPostFX::whiteCutoff * $HDRPostFX::whiteCutoff ); + %combinePass.setShaderConst( "$g_fWhiteCutoff", %whiteCutoff ); +} + +function HDRPostFX::preProcess( %this ) +{ + %combinePass = %this-->combinePass; + + if ( %combinePass.texture[3] !$= $HDRPostFX::colorCorrectionRamp ) + %combinePass.setTexture( 3, $HDRPostFX::colorCorrectionRamp ); +} + +function HDRPostFX::onEnabled( %this ) +{ + // We don't allow hdr on OSX yet. + if ( $platform $= "macos" ) + return false; + + // See what HDR format would be best. + %format = getBestHDRFormat(); + if ( %format $= "" || %format $= "GFXFormatR8G8B8A8" ) + { + // We didn't get a valid HDR format... so fail. + return false; + } + + // HDR does it's own gamma calculation so + // disable this postFx. + GammaPostFX.disable(); + + // Set the right global shader define for HDR. + if ( %format $= "GFXFormatR10G10B10A2" ) + addGlobalShaderMacro( "TORQUE_HDR_RGB10" ); + else if ( %format $= "GFXFormatR16G16B16A16" ) + addGlobalShaderMacro( "TORQUE_HDR_RGB16" ); + + echo( "HDR FORMAT: " @ %format ); + + // Change the format of the offscreen surface + // to an HDR compatible format. + AL_FormatToken.format = %format; + setReflectFormat( %format ); + + // Reset the light manager which will ensure the new + // hdr encoding takes effect in all the shaders and + // that the offscreen surface is enabled. + resetLightManager(); + + return true; +} + +function HDRPostFX::onDisabled( %this ) +{ + // Enable a special GammaCorrection PostFX when this is disabled. + GammaPostFX.enable(); + + // Restore the non-HDR offscreen surface format. + %format = getBestHDRFormat(); + AL_FormatToken.format = %format; + setReflectFormat( %format ); + + removeGlobalShaderMacro( "TORQUE_HDR_RGB10" ); + removeGlobalShaderMacro( "TORQUE_HDR_RGB16" ); + + // Reset the light manager which will ensure the new + // hdr encoding takes effect in all the shaders. + resetLightManager(); +} + +singleton PostEffect( HDRPostFX ) +{ + isEnabled = false; + allowReflectPass = false; + + // Resolve the HDR before we render any editor stuff + // and before we resolve the scene to the backbuffer. + renderTime = "PFXBeforeBin"; + renderBin = "EditorBin"; + renderPriority = 9999; + + // The bright pass generates a bloomed version of + // the scene for pixels which are brighter than a + // fixed threshold value. + // + // This is then used in the final HDR combine pass + // at the end of this post effect chain. + // + + shader = HDR_BrightPassShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$backBuffer"; + texture[1] = "#adaptedLum"; + target = "$outTex"; + targetFormat = "GFXFormatR16G16B16A16F"; + targetScale = "0.5 0.5"; + + new PostEffect() + { + allowReflectPass = false; + shader = HDR_DownScale4x4Shader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + targetFormat = "GFXFormatR16G16B16A16F"; + targetScale = "0.25 0.25"; + }; + + new PostEffect() + { + allowReflectPass = false; + internalName = "bloomH"; + + shader = HDR_BloomGaussBlurHShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + targetFormat = "GFXFormatR16G16B16A16F"; + }; + + new PostEffect() + { + allowReflectPass = false; + internalName = "bloomV"; + + shader = HDR_BloomGaussBlurVShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$inTex"; + target = "#bloomFinal"; + targetFormat = "GFXFormatR16G16B16A16F"; + }; + + // BrightPass End + + // Now calculate the adapted luminance. + new PostEffect() + { + allowReflectPass = false; + internalName = "adaptLum"; + + shader = HDR_SampleLumShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$backBuffer"; + target = "$outTex"; + targetScale = "0.0625 0.0625"; // 1/16th + targetFormat = "GFXFormatR16F"; + + new PostEffect() + { + allowReflectPass = false; + shader = HDR_DownSampleLumShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + targetScale = "0.25 0.25"; // 1/4 + targetFormat = "GFXFormatR16F"; + }; + + new PostEffect() + { + allowReflectPass = false; + shader = HDR_DownSampleLumShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + targetScale = "0.25 0.25"; // 1/4 + targetFormat = "GFXFormatR16F"; + }; + + new PostEffect() + { + allowReflectPass = false; + shader = HDR_DownSampleLumShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$inTex"; + target = "$outTex"; + targetScale = "0.25 0.25"; // At this point the target should be 1x1. + targetFormat = "GFXFormatR16F"; + }; + + // Note that we're reading the adapted luminance + // from the previous frame when generating this new + // one... PostEffect takes care to manage that. + new PostEffect() + { + allowReflectPass = false; + internalName = "finalLum"; + shader = HDR_CalcAdaptedLumShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "$inTex"; + texture[1] = "#adaptedLum"; + target = "#adaptedLum"; + targetFormat = "GFXFormatR16F"; + targetClear = "PFXTargetClear_OnCreate"; + targetClearColor = "1 1 1 1"; + }; + }; + + // Output the combined bloom and toned mapped + // version of the scene. + new PostEffect() + { + allowReflectPass = false; + internalName = "combinePass"; + + shader = HDR_CombineShader; + stateBlock = HDR_CombineStateBlock; + texture[0] = "$backBuffer"; + texture[1] = "#adaptedLum"; + texture[2] = "#bloomFinal"; + texture[3] = $HDRPostFX::colorCorrectionRamp; + target = "$backBuffer"; + }; +}; + +singleton ShaderData( LuminanceVisShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/luminanceVisP.hlsl"; + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/hdr/gl/luminanceVisP.glsl"; + + samplerNames[0] = "$inputTex"; + + pixVersion = 3.0; +}; + +singleton GFXStateBlockData( LuminanceVisStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; +}; + +function LuminanceVisPostFX::setShaderConsts( %this ) +{ + %this.setShaderConst( "$brightPassThreshold", $HDRPostFX::brightPassThreshold ); +} + +singleton PostEffect( LuminanceVisPostFX ) +{ + isEnabled = false; + allowReflectPass = false; + + // Render before we do any editor rendering. + renderTime = "PFXBeforeBin"; + renderBin = "EditorBin"; + renderPriority = 9999; + + shader = LuminanceVisShader; + stateBlock = LuminanceVisStateBlock; + texture[0] = "$backBuffer"; + target = "$backBuffer"; + //targetScale = "0.0625 0.0625"; // 1/16th + //targetFormat = "GFXFormatR16F"; +}; + +function LuminanceVisPostFX::onEnabled( %this ) +{ + if ( !HDRPostFX.isEnabled() ) + { + HDRPostFX.enable(); + } + + HDRPostFX.skip = true; + + return true; +} + +function LuminanceVisPostFX::onDisabled( %this ) +{ + HDRPostFX.skip = false; +} + diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/lightRay.cs b/Templates/BaseGame/game/data/postFX/scripts/client/lightRay.cs new file mode 100644 index 000000000..14c17885c --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/lightRay.cs @@ -0,0 +1,110 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +$LightRayPostFX::brightScalar = 0.75; +$LightRayPostFX::numSamples = 40; +$LightRayPostFX::density = 0.94; +$LightRayPostFX::weight = 5.65; +$LightRayPostFX::decay = 1.0; +$LightRayPostFX::exposure = 0.0005; +$LightRayPostFX::resolutionScale = 1.0; + + +singleton ShaderData( LightRayOccludeShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/lightRay/lightRayOccludeP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/lightRay/gl/lightRayOccludeP.glsl"; + + samplerNames[0] = "$backBuffer"; + samplerNames[1] = "$prepassTex"; + + pixVersion = 3.0; +}; + +singleton ShaderData( LightRayShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/lightRay/lightRayP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/lightRay/gl/lightRayP.glsl"; + + samplerNames[0] = "$frameSampler"; + samplerNames[1] = "$backBuffer"; + + pixVersion = 3.0; +}; + +singleton GFXStateBlockData( LightRayStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampLinear; +}; + +singleton PostEffect( LightRayPostFX ) +{ + isEnabled = false; + allowReflectPass = false; + + renderTime = "PFXBeforeBin"; + renderBin = "EditorBin"; + renderPriority = 10; + + shader = LightRayOccludeShader; + stateBlock = LightRayStateBlock; + texture[0] = "$backBuffer"; + texture[1] = "#prepass"; + target = "$outTex"; + targetFormat = "GFXFormatR16G16B16A16F"; + + new PostEffect() + { + shader = LightRayShader; + stateBlock = LightRayStateBlock; + internalName = "final"; + texture[0] = "$inTex"; + texture[1] = "$backBuffer"; + target = "$backBuffer"; + }; +}; + +function LightRayPostFX::preProcess( %this ) +{ + %this.targetScale = $LightRayPostFX::resolutionScale SPC $LightRayPostFX::resolutionScale; +} + +function LightRayPostFX::setShaderConsts( %this ) +{ + %this.setShaderConst( "$brightScalar", $LightRayPostFX::brightScalar ); + + %pfx = %this-->final; + %pfx.setShaderConst( "$numSamples", $LightRayPostFX::numSamples ); + %pfx.setShaderConst( "$density", $LightRayPostFX::density ); + %pfx.setShaderConst( "$weight", $LightRayPostFX::weight ); + %pfx.setShaderConst( "$decay", $LightRayPostFX::decay ); + %pfx.setShaderConst( "$exposure", $LightRayPostFX::exposure ); +} diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/ovrBarrelDistortion.cs b/Templates/BaseGame/game/data/postFX/scripts/client/ovrBarrelDistortion.cs new file mode 100644 index 000000000..bffde5fce --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/ovrBarrelDistortion.cs @@ -0,0 +1,167 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Only load these shaders if an Oculus VR device is present +if(!isFunction(isOculusVRDeviceActive)) + return; + +//----------------------------------------------------------------------------- +// Shader data +//----------------------------------------------------------------------------- + +singleton ShaderData( OVRMonoToStereoShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/oculusvr/monoToStereoP.hlsl"; + + //OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/gl/postFxV.hlsl"; + //OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/oculusvr/gl/monoToStereoP.glsl"; + + samplerNames[0] = "$backBuffer"; + + pixVersion = 2.0; +}; + +singleton ShaderData( OVRBarrelDistortionShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/oculusvr/barrelDistortionP.hlsl"; + + //OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/gl/postFxV.glsl"; + //OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/oculusvr/gl/barrelDistortionP.glsl"; + + samplerNames[0] = "$backBuffer"; + + pixVersion = 2.0; +}; + +singleton ShaderData( OVRBarrelDistortionChromaShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/oculusvr/barrelDistortionChromaP.hlsl"; + + pixVersion = 2.0; +}; + +//----------------------------------------------------------------------------- +// GFX state blocks +//----------------------------------------------------------------------------- + +singleton GFXStateBlockData( OVRBarrelDistortionStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; +}; + +//----------------------------------------------------------------------------- +// Barrel Distortion PostFx +// +// To be used with the Oculus Rift. +// Expects a stereo pair to exist on the back buffer and then applies the +// appropriate barrel distortion. +//----------------------------------------------------------------------------- +singleton BarrelDistortionPostEffect( OVRBarrelDistortionPostFX ) +{ + isEnabled = false; + allowReflectPass = false; + + renderTime = "PFXAfterDiffuse"; + renderPriority = 100; + + // The barrel distortion + shader = OVRBarrelDistortionShader; + stateBlock = OVRBarrelDistortionStateBlock; + + texture[0] = "$backBuffer"; + + scaleOutput = 1.25; +}; + +//----------------------------------------------------------------------------- +// Barrel Distortion with Chromatic Aberration Correction PostFx +// +// To be used with the Oculus Rift. +// Expects a stereo pair to exist on the back buffer and then applies the +// appropriate barrel distortion. +// This version applies a chromatic aberration correction during the +// barrel distortion. +//----------------------------------------------------------------------------- +singleton BarrelDistortionPostEffect( OVRBarrelDistortionChromaPostFX ) +{ + isEnabled = false; + allowReflectPass = false; + + renderTime = "PFXAfterDiffuse"; + renderPriority = 100; + + // The barrel distortion + shader = OVRBarrelDistortionChromaShader; + stateBlock = OVRBarrelDistortionStateBlock; + + texture[0] = "$backBuffer"; + + scaleOutput = 1.25; +}; + +//----------------------------------------------------------------------------- +// Barrel Distortion Mono PostFx +// +// To be used with the Oculus Rift. +// Takes a non-stereo image and turns it into a stereo pair with barrel +// distortion applied. Only a vertical slice around the center of the back +// buffer is used to generate the pseudo stereo pair. +//----------------------------------------------------------------------------- +singleton PostEffect( OVRBarrelDistortionMonoPostFX ) +{ + isEnabled = false; + allowReflectPass = false; + + renderTime = "PFXAfterDiffuse"; + renderPriority = 100; + + // Converts the mono display to a stereo one + shader = OVRMonoToStereoShader; + stateBlock = OVRBarrelDistortionStateBlock; + + texture[0] = "$backBuffer"; + target = "$outTex"; + + // The actual barrel distortion + new BarrelDistortionPostEffect(OVRBarrelDistortionMonoStage2PostFX) + { + shader = OVRBarrelDistortionShader; + stateBlock = OVRBarrelDistortionStateBlock; + texture[0] = "$inTex"; + target = "$backBuffer"; + + scaleOutput = 1.25; + }; + +}; + +function OVRBarrelDistortionMonoPostFX::setShaderConsts( %this ) +{ + %HMDIndex = 0; + + %xOffsets = getOVRHMDEyeXOffsets(%HMDIndex); + %this.setShaderConst( "$LensXOffsets", %xOffsets ); +} diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/postFxManager.gui.cs b/Templates/BaseGame/game/data/postFX/scripts/client/postFxManager.gui.cs new file mode 100644 index 000000000..8c1c8e8c7 --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/postFxManager.gui.cs @@ -0,0 +1,446 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +$PostFXManager::vebose = true; +function postVerbose(%string) +{ + if($PostFXManager::vebose == true) + { + echo(%string); + } +} + +function PostFXManager::onDialogPush( %this ) +{ + //Apply the settings to the controls + postVerbose("% - PostFX Manager - Loading GUI."); + + %this.settingsRefreshAll(); +} + +// :: Controls for the overall postFX manager dialog +function ppOptionsEnable::onAction(%this) +{ + //Disable / Enable all PostFX + + if(ppOptionsEnable.getValue()) + { + %toEnable = true; + } + else + { + %toEnable = false; + } + + PostFXManager.settingsSetEnabled(%toEnable); + +} + +function PostFXManager::getEnableResultFromControl(%this, %control) +{ + %toEnable = -1; + %bTest = %control.getValue(); + if(%bTest == 1) + { + %toEnable = true; + } + else + { + %toEnable = false; + } + + return %toEnable; +} + +function ppOptionsEnableSSAO::onAction(%this) +{ + %toEnable = PostFXManager.getEnableResultFromControl(%this); + PostFXManager.settingsEffectSetEnabled("SSAO", %toEnable); +} + +function ppOptionsEnableHDR::onAction(%this) +{ + %toEnable = PostFXManager.getEnableResultFromControl(%this); + PostFXManager.settingsEffectSetEnabled("HDR", %toEnable); +} + +function ppOptionsEnableLightRays::onAction(%this) +{ + %toEnable = PostFXManager.getEnableResultFromControl(%this); + PostFXManager.settingsEffectSetEnabled("LightRays", %toEnable); +} + +function ppOptionsEnableDOF::onAction(%this) +{ + %toEnable = PostFXManager.getEnableResultFromControl(%this); + PostFXManager.settingsEffectSetEnabled("DOF", %toEnable); +} + +function ppOptionsEnableVignette::onAction(%this) +{ + %toEnable = PostFXManager.getEnableResultFromControl(%this); + PostFXManager.settingsEffectSetEnabled("Vignette", %toEnable); +} + +function ppOptionsSavePreset::onClick(%this) +{ + //Stores the current settings into a preset file for loading and use later on +} + +function ppOptionsLoadPreset::onClick(%this) +{ + //Loads and applies the settings from a postfxpreset file +} + + +//Other controls, Quality dropdown +function ppOptionsSSAOQuality::onSelect( %this, %id, %text ) +{ + if(%id > -1 && %id < 3) + { + $SSAOPostFx::quality = %id; + } +} + +//SSAO Slider controls +//General Tab +function ppOptionsSSAOOverallStrength::onMouseDragged(%this) +{ + $SSAOPostFx::overallStrength = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsSSAOBlurDepth::onMouseDragged(%this) +{ + $SSAOPostFx::blurDepthTol = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsSSAOBlurNormal::onMouseDragged(%this) +{ + $SSAOPostFx::blurNormalTol = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +//Near Tab +function ppOptionsSSAONearRadius::onMouseDragged(%this) +{ + $SSAOPostFx::sRadius = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsSSAONearStrength::onMouseDragged(%this) +{ + $SSAOPostFx::sStrength = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsSSAONearDepthMin::onMouseDragged(%this) +{ + $SSAOPostFx::sDepthMin = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsSSAONearDepthMax::onMouseDragged(%this) +{ + $SSAOPostFx::sDepthMax = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsSSAONearToleranceNormal::onMouseDragged(%this) +{ + $SSAOPostFx::sNormalTol = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsSSAONearTolerancePower::onMouseDragged(%this) +{ + $SSAOPostFx::sNormalPow = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +//Far Tab +function ppOptionsSSAOFarRadius::onMouseDragged(%this) +{ + $SSAOPostFx::lRadius = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} +function ppOptionsSSAOFarStrength::onMouseDragged(%this) +{ + $SSAOPostFx::lStrength = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} +function ppOptionsSSAOFarDepthMin::onMouseDragged(%this) +{ + $SSAOPostFx::lDepthMin = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} +function ppOptionsSSAOFarDepthMax::onMouseDragged(%this) +{ + $SSAOPostFx::lDepthMax = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} +function ppOptionsSSAOFarToleranceNormal::onMouseDragged(%this) +{ + $SSAOPostFx::lNormalTol = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} +function ppOptionsSSAOFarTolerancePower::onMouseDragged(%this) +{ + $SSAOPostFx::lNormalPow = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +//HDR Slider Controls +//Brighness tab + +function ppOptionsHDRToneMappingAmount::onMouseDragged(%this) +{ + + $HDRPostFX::enableToneMapping = %this.value; + %this.ToolTip = "value : " @ %this.value; +} + +function ppOptionsHDRKeyValue::onMouseDragged(%this) +{ + $HDRPostFX::keyValue = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsHDRMinLuminance::onMouseDragged(%this) +{ + $HDRPostFX::minLuminace = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsHDRWhiteCutoff::onMouseDragged(%this) +{ + $HDRPostFX::whiteCutoff = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsHDRBrightnessAdaptRate::onMouseDragged(%this) +{ + $HDRPostFX::adaptRate = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +//Blur tab +function ppOptionsHDRBloomBlurBrightPassThreshold::onMouseDragged(%this) +{ + $HDRPostFX::brightPassThreshold = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsHDRBloomBlurMultiplier::onMouseDragged(%this) +{ + $HDRPostFX::gaussMultiplier = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsHDRBloomBlurMean::onMouseDragged(%this) +{ + $HDRPostFX::gaussMean = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsHDRBloomBlurStdDev::onMouseDragged(%this) +{ + $HDRPostFX::gaussStdDev = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + +function ppOptionsHDRBloom::onAction(%this) +{ + $HDRPostFX::enableBloom = %this.getValue(); +} + +function ppOptionsHDRToneMapping::onAction(%this) +{ + //$HDRPostFX::enableToneMapping = %this.getValue(); +} + +function ppOptionsHDREffectsBlueShift::onAction(%this) +{ + $HDRPostFX::enableBlueShift = %this.getValue(); +} + + +//Controls for color range in blue Shift dialog + +function ppOptionsHDREffectsBlueShiftColorBlend::onAction(%this) +{ + $HDRPostFX::blueShiftColor = %this.PickColor; + %this.ToolTip = "Color Values : " @ %this.PickColor; +} + +function ppOptionsHDREffectsBlueShiftColorBaseColor::onAction(%this) +{ + //This one feeds the one above + ppOptionsHDREffectsBlueShiftColorBlend.baseColor = %this.PickColor; + %this.ToolTip = "Color Values : " @ %this.PickColor; +} + + +//Light rays Brightness Slider Controls +function ppOptionsLightRaysBrightScalar::onMouseDragged(%this) +{ + $LightRayPostFX::brightScalar = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} +//Light rays Number of Samples Slider Control +function ppOptionsLightRaysSampleScalar::onMouseDragged(%this) +{ + $LightRayPostFX::numSamples = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} +//Light rays Density Slider Control +function ppOptionsLightRaysDensityScalar::onMouseDragged(%this) +{ + $LightRayPostFX::density = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} +//Light rays Weight Slider Control +function ppOptionsLightRaysWeightScalar::onMouseDragged(%this) +{ + $LightRayPostFX::weight = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} +//Light rays Decay Slider Control +function ppOptionsLightRaysDecayScalar::onMouseDragged(%this) +{ + $LightRayPostFX::decay = %this.value; + %this.ToolTip = "Value : " @ %this.value; +} + + +function ppOptionsUpdateDOFSettings() +{ + DOFPostEffect.setFocusParams( $DOFPostFx::BlurMin, $DOFPostFx::BlurMax, $DOFPostFx::FocusRangeMin, $DOFPostFx::FocusRangeMax, -($DOFPostFx::BlurCurveNear), $DOFPostFx::BlurCurveFar ); + + DOFPostEffect.setAutoFocus( $DOFPostFx::EnableAutoFocus ); + DOFPostEffect.setFocalDist(0); + + if($PostFXManager::PostFX::EnableDOF) + { + DOFPostEffect.enable(); + } + else + { + DOFPostEffect.disable(); + } +} + +//DOF General Tab +//DOF Toggles +function ppOptionsDOFEnableDOF::onAction(%this) +{ + $PostFXManager::PostFX::EnableDOF = %this.getValue(); + ppOptionsUpdateDOFSettings(); +} + + +function ppOptionsDOFEnableAutoFocus::onAction(%this) +{ + $DOFPostFx::EnableAutoFocus = %this.getValue(); + DOFPostEffect.setAutoFocus( %this.getValue() ); +} + +//DOF AutoFocus Slider controls +function ppOptionsDOFFarBlurMinSlider::onMouseDragged(%this) +{ + $DOFPostFx::BlurMin = %this.value; + ppOptionsUpdateDOFSettings(); +} + +function ppOptionsDOFFarBlurMaxSlider::onMouseDragged(%this) +{ + $DOFPostFx::BlurMax = %this.value; + ppOptionsUpdateDOFSettings(); +} + +function ppOptionsDOFFocusRangeMinSlider::onMouseDragged(%this) +{ + $DOFPostFx::FocusRangeMin = %this.value; + ppOptionsUpdateDOFSettings(); +} + +function ppOptionsDOFFocusRangeMaxSlider::onMouseDragged(%this) +{ + $DOFPostFx::FocusRangeMax = %this.value; + ppOptionsUpdateDOFSettings(); +} + +function ppOptionsDOFBlurCurveNearSlider::onMouseDragged(%this) +{ + $DOFPostFx::BlurCurveNear = %this.value; + ppOptionsUpdateDOFSettings(); +} + +function ppOptionsDOFBlurCurveFarSlider::onMouseDragged(%this) +{ + $DOFPostFx::BlurCurveFar = %this.value; + ppOptionsUpdateDOFSettings(); +} + +function ppOptionsEnableHDRDebug::onAction(%this) +{ + if ( %this.getValue() ) + LuminanceVisPostFX.enable(); + else + LuminanceVisPostFX.disable(); +} + +function ppOptionsUpdateVignetteSettings() +{ + if($PostFXManager::PostFX::EnableVignette) + { + VignettePostEffect.enable(); + } + else + { + VignettePostEffect.disable(); + } +} + +function ppOptionsVignetteEnableVignette::onAction(%this) +{ + $PostFXManager::PostFX::EnableVignette = %this.getValue(); + ppOptionsUpdateVignetteSettings(); +} + +function ppColorCorrection_selectFile() +{ + %filter = "Image Files (*.png, *.jpg, *.dds, *.bmp, *.gif, *.jng. *.tga)|*.png;*.jpg;*.dds;*.bmp;*.gif;*.jng;*.tga|All Files (*.*)|*.*|"; + getLoadFilename( %filter, "ppColorCorrection_selectFileHandler"); +} + +function ppColorCorrection_selectFileHandler( %filename ) +{ + if ( %filename $= "" || !isFile( %filename ) ) + %filename = "data/postFX/art/null_color_ramp.png"; + else + %filename = makeRelativePath( %filename, getMainDotCsDir() ); + + $HDRPostFX::colorCorrectionRamp = %filename; + PostFXManager-->ColorCorrectionFileName.Text = %filename; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/postFxManager.gui.settings.cs b/Templates/BaseGame/game/data/postFX/scripts/client/postFxManager.gui.settings.cs new file mode 100644 index 000000000..bc28edc70 --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/postFxManager.gui.settings.cs @@ -0,0 +1,439 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +$PostFXManager::defaultPreset = "data/postFX/scripts/client/default.postfxpreset.cs"; + +function PostFXManager::settingsSetEnabled(%this, %bEnablePostFX) +{ + $PostFXManager::PostFX::Enabled = %bEnablePostFX; + + //if to enable the postFX, apply the ones that are enabled + if ( %bEnablePostFX ) + { + //SSAO, HDR, LightRays, DOF + + if ( $PostFXManager::PostFX::EnableSSAO ) + SSAOPostFx.enable(); + else + SSAOPostFx.disable(); + + if ( $PostFXManager::PostFX::EnableHDR ) + HDRPostFX.enable(); + else + HDRPostFX.disable(); + + if ( $PostFXManager::PostFX::EnableLightRays ) + LightRayPostFX.enable(); + else + LightRayPostFX.disable(); + + if ( $PostFXManager::PostFX::EnableDOF ) + DOFPostEffect.enable(); + else + DOFPostEffect.disable(); + + if ( $PostFXManager::PostFX::EnableVignette ) + VignettePostEffect.enable(); + else + VignettePostEffect.disable(); + + postVerbose("% - PostFX Manager - PostFX enabled"); + } + else + { + //Disable all postFX + + SSAOPostFx.disable(); + HDRPostFX.disable(); + LightRayPostFX.disable(); + DOFPostEffect.disable(); + VignettePostEffect.disable(); + + postVerbose("% - PostFX Manager - PostFX disabled"); + } + + VolFogGlowPostFx.disable(); +} + +function PostFXManager::settingsEffectSetEnabled(%this, %sName, %bEnable) +{ + %postEffect = 0; + + //Determine the postFX to enable, and apply the boolean + if(%sName $= "SSAO") + { + %postEffect = SSAOPostFx; + $PostFXManager::PostFX::EnableSSAO = %bEnable; + //$pref::PostFX::SSAO::Enabled = %bEnable; + } + else if(%sName $= "HDR") + { + %postEffect = HDRPostFX; + $PostFXManager::PostFX::EnableHDR = %bEnable; + //$pref::PostFX::HDR::Enabled = %bEnable; + } + else if(%sName $= "LightRays") + { + %postEffect = LightRayPostFX; + $PostFXManager::PostFX::EnableLightRays = %bEnable; + //$pref::PostFX::LightRays::Enabled = %bEnable; + } + else if(%sName $= "DOF") + { + %postEffect = DOFPostEffect; + $PostFXManager::PostFX::EnableDOF = %bEnable; + //$pref::PostFX::DOF::Enabled = %bEnable; + } + else if(%sName $= "Vignette") + { + %postEffect = VignettePostEffect; + $PostFXManager::PostFX::EnableVignette = %bEnable; + //$pref::PostFX::Vignette::Enabled = %bEnable; + } + + // Apply the change + if ( %bEnable == true ) + { + %postEffect.enable(); + postVerbose("% - PostFX Manager - " @ %sName @ " enabled"); + } + else + { + %postEffect.disable(); + postVerbose("% - PostFX Manager - " @ %sName @ " disabled"); + } +} + +function PostFXManager::settingsRefreshSSAO(%this) +{ + //Apply the enabled flag + ppOptionsEnableSSAO.setValue($PostFXManager::PostFX::EnableSSAO); + + //Add the items we need to display + ppOptionsSSAOQuality.clear(); + ppOptionsSSAOQuality.add("Low", 0); + ppOptionsSSAOQuality.add("Medium", 1); + ppOptionsSSAOQuality.add("High", 2); + + //Set the selected, after adding the items! + ppOptionsSSAOQuality.setSelected($SSAOPostFx::quality); + + //SSAO - Set the values of the sliders, General Tab + ppOptionsSSAOOverallStrength.setValue($SSAOPostFx::overallStrength); + ppOptionsSSAOBlurDepth.setValue($SSAOPostFx::blurDepthTol); + ppOptionsSSAOBlurNormal.setValue($SSAOPostFx::blurNormalTol); + + //SSAO - Set the values for the near tab + ppOptionsSSAONearDepthMax.setValue($SSAOPostFx::sDepthMax); + ppOptionsSSAONearDepthMin.setValue($SSAOPostFx::sDepthMin); + ppOptionsSSAONearRadius.setValue($SSAOPostFx::sRadius); + ppOptionsSSAONearStrength.setValue($SSAOPostFx::sStrength); + ppOptionsSSAONearToleranceNormal.setValue($SSAOPostFx::sNormalTol); + ppOptionsSSAONearTolerancePower.setValue($SSAOPostFx::sNormalPow); + + //SSAO - Set the values for the far tab + ppOptionsSSAOFarDepthMax.setValue($SSAOPostFx::lDepthMax); + ppOptionsSSAOFarDepthMin.setValue($SSAOPostFx::lDepthMin); + ppOptionsSSAOFarRadius.setValue($SSAOPostFx::lRadius); + ppOptionsSSAOFarStrength.setValue($SSAOPostFx::lStrength); + ppOptionsSSAOFarToleranceNormal.setValue($SSAOPostFx::lNormalTol); + ppOptionsSSAOFarTolerancePower.setValue($SSAOPostFx::lNormalPow); +} + +function PostFXManager::settingsRefreshHDR(%this) +{ + //Apply the enabled flag + ppOptionsEnableHDR.setValue($PostFXManager::PostFX::EnableHDR); + + ppOptionsHDRBloom.setValue($HDRPostFX::enableBloom); + ppOptionsHDRBloomBlurBrightPassThreshold.setValue($HDRPostFX::brightPassThreshold); + ppOptionsHDRBloomBlurMean.setValue($HDRPostFX::gaussMean); + ppOptionsHDRBloomBlurMultiplier.setValue($HDRPostFX::gaussMultiplier); + ppOptionsHDRBloomBlurStdDev.setValue($HDRPostFX::gaussStdDev); + ppOptionsHDRBrightnessAdaptRate.setValue($HDRPostFX::adaptRate); + ppOptionsHDREffectsBlueShift.setValue($HDRPostFX::enableBlueShift); + ppOptionsHDREffectsBlueShiftColor.BaseColor = $HDRPostFX::blueShiftColor; + ppOptionsHDREffectsBlueShiftColor.PickColor = $HDRPostFX::blueShiftColor; + ppOptionsHDRKeyValue.setValue($HDRPostFX::keyValue); + ppOptionsHDRMinLuminance.setValue($HDRPostFX::minLuminace); + ppOptionsHDRToneMapping.setValue($HDRPostFX::enableToneMapping); + ppOptionsHDRToneMappingAmount.setValue($HDRPostFX::enableToneMapping); + ppOptionsHDRWhiteCutoff.setValue($HDRPostFX::whiteCutoff); + + %this-->ColorCorrectionFileName.Text = $HDRPostFX::colorCorrectionRamp; +} + +function PostFXManager::settingsRefreshLightrays(%this) +{ + //Apply the enabled flag + ppOptionsEnableLightRays.setValue($PostFXManager::PostFX::EnableLightRays); + + ppOptionsLightRaysBrightScalar.setValue($LightRayPostFX::brightScalar); + + ppOptionsLightRaysSampleScalar.setValue($LightRayPostFX::numSamples); + ppOptionsLightRaysDensityScalar.setValue($LightRayPostFX::density); + ppOptionsLightRaysWeightScalar.setValue($LightRayPostFX::weight); + ppOptionsLightRaysDecayScalar.setValue($LightRayPostFX::decay); +} + +function PostFXManager::settingsRefreshDOF(%this) +{ + //Apply the enabled flag + ppOptionsEnableDOF.setValue($PostFXManager::PostFX::EnableDOF); + + + //ppOptionsDOFEnableDOF.setValue($PostFXManager::PostFX::EnableDOF); + ppOptionsDOFEnableAutoFocus.setValue($DOFPostFx::EnableAutoFocus); + + ppOptionsDOFFarBlurMinSlider.setValue($DOFPostFx::BlurMin); + ppOptionsDOFFarBlurMaxSlider.setValue($DOFPostFx::BlurMax); + + ppOptionsDOFFocusRangeMinSlider.setValue($DOFPostFx::FocusRangeMin); + ppOptionsDOFFocusRangeMaxSlider.setValue($DOFPostFx::FocusRangeMax); + + ppOptionsDOFBlurCurveNearSlider.setValue($DOFPostFx::BlurCurveNear); + ppOptionsDOFBlurCurveFarSlider.setValue($DOFPostFx::BlurCurveFar); + +} + +function PostFXManager::settingsRefreshVignette(%this) +{ + //Apply the enabled flag + ppOptionsEnableVignette.setValue($PostFXManager::PostFX::EnableVignette); + +} + +function PostFXManager::settingsRefreshAll(%this) +{ + $PostFXManager::PostFX::Enabled = $pref::enablePostEffects; + $PostFXManager::PostFX::EnableSSAO = SSAOPostFx.isEnabled(); + $PostFXManager::PostFX::EnableHDR = HDRPostFX.isEnabled(); + $PostFXManager::PostFX::EnableLightRays = LightRayPostFX.isEnabled(); + $PostFXManager::PostFX::EnableDOF = DOFPostEffect.isEnabled(); + $PostFXManager::PostFX::EnableVignette = VignettePostEffect.isEnabled(); + + //For all the postFX here, apply the active settings in the system + //to the gui controls. + + %this.settingsRefreshSSAO(); + %this.settingsRefreshHDR(); + %this.settingsRefreshLightrays(); + %this.settingsRefreshDOF(); + %this.settingsRefreshVignette(); + + ppOptionsEnable.setValue($PostFXManager::PostFX::Enabled); + + postVerbose("% - PostFX Manager - GUI values updated."); +} + +function PostFXManager::settingsApplyFromPreset(%this) +{ + postVerbose("% - PostFX Manager - Applying from preset"); + + //SSAO Settings + $SSAOPostFx::blurDepthTol = $PostFXManager::Settings::SSAO::blurDepthTol; + $SSAOPostFx::blurNormalTol = $PostFXManager::Settings::SSAO::blurNormalTol; + $SSAOPostFx::lDepthMax = $PostFXManager::Settings::SSAO::lDepthMax; + $SSAOPostFx::lDepthMin = $PostFXManager::Settings::SSAO::lDepthMin; + $SSAOPostFx::lDepthPow = $PostFXManager::Settings::SSAO::lDepthPow; + $SSAOPostFx::lNormalPow = $PostFXManager::Settings::SSAO::lNormalPow; + $SSAOPostFx::lNormalTol = $PostFXManager::Settings::SSAO::lNormalTol; + $SSAOPostFx::lRadius = $PostFXManager::Settings::SSAO::lRadius; + $SSAOPostFx::lStrength = $PostFXManager::Settings::SSAO::lStrength; + $SSAOPostFx::overallStrength = $PostFXManager::Settings::SSAO::overallStrength; + $SSAOPostFx::quality = $PostFXManager::Settings::SSAO::quality; + $SSAOPostFx::sDepthMax = $PostFXManager::Settings::SSAO::sDepthMax; + $SSAOPostFx::sDepthMin = $PostFXManager::Settings::SSAO::sDepthMin; + $SSAOPostFx::sDepthPow = $PostFXManager::Settings::SSAO::sDepthPow; + $SSAOPostFx::sNormalPow = $PostFXManager::Settings::SSAO::sNormalPow; + $SSAOPostFx::sNormalTol = $PostFXManager::Settings::SSAO::sNormalTol; + $SSAOPostFx::sRadius = $PostFXManager::Settings::SSAO::sRadius; + $SSAOPostFx::sStrength = $PostFXManager::Settings::SSAO::sStrength; + + //HDR settings + $HDRPostFX::adaptRate = $PostFXManager::Settings::HDR::adaptRate; + $HDRPostFX::blueShiftColor = $PostFXManager::Settings::HDR::blueShiftColor; + $HDRPostFX::brightPassThreshold = $PostFXManager::Settings::HDR::brightPassThreshold; + $HDRPostFX::enableBloom = $PostFXManager::Settings::HDR::enableBloom; + $HDRPostFX::enableBlueShift = $PostFXManager::Settings::HDR::enableBlueShift; + $HDRPostFX::enableToneMapping = $PostFXManager::Settings::HDR::enableToneMapping; + $HDRPostFX::gaussMean = $PostFXManager::Settings::HDR::gaussMean; + $HDRPostFX::gaussMultiplier = $PostFXManager::Settings::HDR::gaussMultiplier; + $HDRPostFX::gaussStdDev = $PostFXManager::Settings::HDR::gaussStdDev; + $HDRPostFX::keyValue = $PostFXManager::Settings::HDR::keyValue; + $HDRPostFX::minLuminace = $PostFXManager::Settings::HDR::minLuminace; + $HDRPostFX::whiteCutoff = $PostFXManager::Settings::HDR::whiteCutoff; + $HDRPostFX::colorCorrectionRamp = $PostFXManager::Settings::ColorCorrectionRamp; + + //Light rays settings + $LightRayPostFX::brightScalar = $PostFXManager::Settings::LightRays::brightScalar; + + $LightRayPostFX::numSamples = $PostFXManager::Settings::LightRays::numSamples; + $LightRayPostFX::density = $PostFXManager::Settings::LightRays::density; + $LightRayPostFX::weight = $PostFXManager::Settings::LightRays::weight; + $LightRayPostFX::decay = $PostFXManager::Settings::LightRays::decay; + + //DOF settings + $DOFPostFx::EnableAutoFocus = $PostFXManager::Settings::DOF::EnableAutoFocus; + $DOFPostFx::BlurMin = $PostFXManager::Settings::DOF::BlurMin; + $DOFPostFx::BlurMax = $PostFXManager::Settings::DOF::BlurMax; + $DOFPostFx::FocusRangeMin = $PostFXManager::Settings::DOF::FocusRangeMin; + $DOFPostFx::FocusRangeMax = $PostFXManager::Settings::DOF::FocusRangeMax; + $DOFPostFx::BlurCurveNear = $PostFXManager::Settings::DOF::BlurCurveNear; + $DOFPostFx::BlurCurveFar = $PostFXManager::Settings::DOF::BlurCurveFar; + + //Vignette settings + $VignettePostEffect::VMax = $PostFXManager::Settings::Vignette::VMax; + $VignettePostEffect::VMin = $PostFXManager::Settings::Vignette::VMin; + + if ( $PostFXManager::forceEnableFromPresets ) + { + $PostFXManager::PostFX::Enabled = $PostFXManager::Settings::EnablePostFX; + $PostFXManager::PostFX::EnableDOF = $pref::PostFX::EnableDOF ? $PostFXManager::Settings::EnableDOF : false; + $PostFXManager::PostFX::EnableVignette = $pref::PostFX::EnableVignette ? $PostFXManager::Settings::EnableVignette : false; + $PostFXManager::PostFX::EnableLightRays = $pref::PostFX::EnableLightRays ? $PostFXManager::Settings::EnableLightRays : false; + $PostFXManager::PostFX::EnableHDR = $pref::PostFX::EnableHDR ? $PostFXManager::Settings::EnableHDR : false; + $PostFXManager::PostFX::EnableSSAO = $pref::PostFX::EnabledSSAO ? $PostFXManager::Settings::EnableSSAO : false; + + %this.settingsSetEnabled( true ); + } + + //make sure we apply the correct settings to the DOF + ppOptionsUpdateDOFSettings(); + + // Update the actual GUI controls if its awake ( otherwise it will when opened ). + if ( PostFXManager.isAwake() ) + %this.settingsRefreshAll(); +} + +function PostFXManager::settingsApplySSAO(%this) +{ + $PostFXManager::Settings::SSAO::blurDepthTol = $SSAOPostFx::blurDepthTol; + $PostFXManager::Settings::SSAO::blurNormalTol = $SSAOPostFx::blurNormalTol; + $PostFXManager::Settings::SSAO::lDepthMax = $SSAOPostFx::lDepthMax; + $PostFXManager::Settings::SSAO::lDepthMin = $SSAOPostFx::lDepthMin; + $PostFXManager::Settings::SSAO::lDepthPow = $SSAOPostFx::lDepthPow; + $PostFXManager::Settings::SSAO::lNormalPow = $SSAOPostFx::lNormalPow; + $PostFXManager::Settings::SSAO::lNormalTol = $SSAOPostFx::lNormalTol; + $PostFXManager::Settings::SSAO::lRadius = $SSAOPostFx::lRadius; + $PostFXManager::Settings::SSAO::lStrength = $SSAOPostFx::lStrength; + $PostFXManager::Settings::SSAO::overallStrength = $SSAOPostFx::overallStrength; + $PostFXManager::Settings::SSAO::quality = $SSAOPostFx::quality; + $PostFXManager::Settings::SSAO::sDepthMax = $SSAOPostFx::sDepthMax; + $PostFXManager::Settings::SSAO::sDepthMin = $SSAOPostFx::sDepthMin; + $PostFXManager::Settings::SSAO::sDepthPow = $SSAOPostFx::sDepthPow; + $PostFXManager::Settings::SSAO::sNormalPow = $SSAOPostFx::sNormalPow; + $PostFXManager::Settings::SSAO::sNormalTol = $SSAOPostFx::sNormalTol; + $PostFXManager::Settings::SSAO::sRadius = $SSAOPostFx::sRadius; + $PostFXManager::Settings::SSAO::sStrength = $SSAOPostFx::sStrength; + + postVerbose("% - PostFX Manager - Settings Saved - SSAO"); + +} + +function PostFXManager::settingsApplyHDR(%this) +{ + $PostFXManager::Settings::HDR::adaptRate = $HDRPostFX::adaptRate; + $PostFXManager::Settings::HDR::blueShiftColor = $HDRPostFX::blueShiftColor; + $PostFXManager::Settings::HDR::brightPassThreshold = $HDRPostFX::brightPassThreshold; + $PostFXManager::Settings::HDR::enableBloom = $HDRPostFX::enableBloom; + $PostFXManager::Settings::HDR::enableBlueShift = $HDRPostFX::enableBlueShift; + $PostFXManager::Settings::HDR::enableToneMapping = $HDRPostFX::enableToneMapping; + $PostFXManager::Settings::HDR::gaussMean = $HDRPostFX::gaussMean; + $PostFXManager::Settings::HDR::gaussMultiplier = $HDRPostFX::gaussMultiplier; + $PostFXManager::Settings::HDR::gaussStdDev = $HDRPostFX::gaussStdDev; + $PostFXManager::Settings::HDR::keyValue = $HDRPostFX::keyValue; + $PostFXManager::Settings::HDR::minLuminace = $HDRPostFX::minLuminace; + $PostFXManager::Settings::HDR::whiteCutoff = $HDRPostFX::whiteCutoff; + $PostFXManager::Settings::ColorCorrectionRamp = $HDRPostFX::colorCorrectionRamp; + + postVerbose("% - PostFX Manager - Settings Saved - HDR"); +} + +function PostFXManager::settingsApplyLightRays(%this) +{ + $PostFXManager::Settings::LightRays::brightScalar = $LightRayPostFX::brightScalar; + + $PostFXManager::Settings::LightRays::numSamples = $LightRayPostFX::numSamples; + $PostFXManager::Settings::LightRays::density = $LightRayPostFX::density; + $PostFXManager::Settings::LightRays::weight = $LightRayPostFX::weight; + $PostFXManager::Settings::LightRays::decay = $LightRayPostFX::decay; + + postVerbose("% - PostFX Manager - Settings Saved - Light Rays"); + +} + +function PostFXManager::settingsApplyDOF(%this) +{ + $PostFXManager::Settings::DOF::EnableAutoFocus = $DOFPostFx::EnableAutoFocus; + $PostFXManager::Settings::DOF::BlurMin = $DOFPostFx::BlurMin; + $PostFXManager::Settings::DOF::BlurMax = $DOFPostFx::BlurMax; + $PostFXManager::Settings::DOF::FocusRangeMin = $DOFPostFx::FocusRangeMin; + $PostFXManager::Settings::DOF::FocusRangeMax = $DOFPostFx::FocusRangeMax; + $PostFXManager::Settings::DOF::BlurCurveNear = $DOFPostFx::BlurCurveNear; + $PostFXManager::Settings::DOF::BlurCurveFar = $DOFPostFx::BlurCurveFar; + + postVerbose("% - PostFX Manager - Settings Saved - DOF"); + +} + +function PostFXManager::settingsApplyVignette(%this) +{ + $PostFXManager::Settings::Vignette::VMax = $VignettePostEffect::VMax; + $PostFXManager::Settings::Vignette::VMin = $VignettePostEffect::VMin; + + postVerbose("% - PostFX Manager - Settings Saved - Vignette"); + +} + +function PostFXManager::settingsApplyAll(%this, %sFrom) +{ + // Apply settings which control if effects are on/off altogether. + $PostFXManager::Settings::EnablePostFX = $PostFXManager::PostFX::Enabled; + $PostFXManager::Settings::EnableDOF = $PostFXManager::PostFX::EnableDOF; + $PostFXManager::Settings::EnableVignette = $PostFXManager::PostFX::EnableVignette; + $PostFXManager::Settings::EnableLightRays = $PostFXManager::PostFX::EnableLightRays; + $PostFXManager::Settings::EnableHDR = $PostFXManager::PostFX::EnableHDR; + $PostFXManager::Settings::EnableSSAO = $PostFXManager::PostFX::EnableSSAO; + + // Apply settings should save the values in the system to the + // the preset structure ($PostFXManager::Settings::*) + + // SSAO Settings + %this.settingsApplySSAO(); + // HDR settings + %this.settingsApplyHDR(); + // Light rays settings + %this.settingsApplyLightRays(); + // DOF + %this.settingsApplyDOF(); + // Vignette + %this.settingsApplyVignette(); + + postVerbose("% - PostFX Manager - All Settings applied to $PostFXManager::Settings"); +} + +function PostFXManager::settingsApplyDefaultPreset(%this) +{ + PostFXManager::loadPresetHandler($PostFXManager::defaultPreset); +} + diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/postFxManager.persistance.cs b/Templates/BaseGame/game/data/postFX/scripts/client/postFxManager.persistance.cs new file mode 100644 index 000000000..31fec95f1 --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/postFxManager.persistance.cs @@ -0,0 +1,79 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +// Used to name the saved files. +$PostFXManager::fileExtension = ".postfxpreset.cs"; + +// The filter string for file open/save dialogs. +$PostFXManager::fileFilter = "Post Effect Presets|*.postfxpreset.cs"; + +// Enable / disable PostFX when loading presets or just apply the settings? +$PostFXManager::forceEnableFromPresets = true; + +//Load a preset file from the disk, and apply the settings to the +//controls. If bApplySettings is true - the actual values in the engine +//will be changed to reflect the settings from the file. +function PostFXManager::loadPresetFile() +{ + //Show the dialog and set the flag + getLoadFilename($PostFXManager::fileFilter, "PostFXManager::loadPresetHandler"); +} + +function PostFXManager::loadPresetHandler( %filename ) +{ + //Check the validity of the file + if ( isScriptFile( %filename ) ) + { + %filename = expandFilename(%filename); + postVerbose("% - PostFX Manager - Executing " @ %filename); + exec(%filename); + + PostFXManager.settingsApplyFromPreset(); + } +} + +//Save a preset file to the specified file. The extension used +//is specified by $PostFXManager::fileExtension for on the fly +//name changes to the extension used. + +function PostFXManager::savePresetFile(%this) +{ + %defaultFile = filePath($Client::MissionFile) @ "/" @ fileBase($Client::MissionFile); + getSaveFilename($PostFXManager::fileFilter, "PostFXManager::savePresetHandler", %defaultFile); +} + +//Called from the PostFXManager::savePresetFile() function +function PostFXManager::savePresetHandler( %filename ) +{ + %filename = makeRelativePath( %filename, getMainDotCsDir() ); + if(strStr(%filename, ".") == -1) + %filename = %filename @ $PostFXManager::fileExtension; + + //Apply the current settings to the preset + PostFXManager.settingsApplyAll(); + + export("$PostFXManager::Settings::*", %filename, false); + + postVerbose("% - PostFX Manager - Save complete. Preset saved at : " @ %filename); +} + diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/ssao.cs b/Templates/BaseGame/game/data/postFX/scripts/client/ssao.cs new file mode 100644 index 000000000..729e0beea --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/ssao.cs @@ -0,0 +1,302 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +/// +$SSAOPostFx::overallStrength = 2.0; + +// TODO: Add small/large param docs. + +// The small radius SSAO settings. +$SSAOPostFx::sRadius = 0.1; +$SSAOPostFx::sStrength = 6.0; +$SSAOPostFx::sDepthMin = 0.1; +$SSAOPostFx::sDepthMax = 1.0; +$SSAOPostFx::sDepthPow = 1.0; +$SSAOPostFx::sNormalTol = 0.0; +$SSAOPostFx::sNormalPow = 1.0; + +// The large radius SSAO settings. +$SSAOPostFx::lRadius = 1.0; +$SSAOPostFx::lStrength = 10.0; +$SSAOPostFx::lDepthMin = 0.2; +$SSAOPostFx::lDepthMax = 2.0; +$SSAOPostFx::lDepthPow = 0.2; +$SSAOPostFx::lNormalTol = -0.5; +$SSAOPostFx::lNormalPow = 2.0; + +/// Valid values: 0, 1, 2 +$SSAOPostFx::quality = 0; + +/// +$SSAOPostFx::blurDepthTol = 0.001; + +/// +$SSAOPostFx::blurNormalTol = 0.95; + +/// +$SSAOPostFx::targetScale = "0.5 0.5"; + + +function SSAOPostFx::onAdd( %this ) +{ + %this.wasVis = "Uninitialized"; + %this.quality = "Uninitialized"; +} + +function SSAOPostFx::preProcess( %this ) +{ + if ( $SSAOPostFx::quality !$= %this.quality ) + { + %this.quality = mClamp( mRound( $SSAOPostFx::quality ), 0, 2 ); + + %this.setShaderMacro( "QUALITY", %this.quality ); + } + + %this.targetScale = $SSAOPostFx::targetScale; +} + +function SSAOPostFx::setShaderConsts( %this ) +{ + %this.setShaderConst( "$overallStrength", $SSAOPostFx::overallStrength ); + + // Abbreviate is s-small l-large. + + %this.setShaderConst( "$sRadius", $SSAOPostFx::sRadius ); + %this.setShaderConst( "$sStrength", $SSAOPostFx::sStrength ); + %this.setShaderConst( "$sDepthMin", $SSAOPostFx::sDepthMin ); + %this.setShaderConst( "$sDepthMax", $SSAOPostFx::sDepthMax ); + %this.setShaderConst( "$sDepthPow", $SSAOPostFx::sDepthPow ); + %this.setShaderConst( "$sNormalTol", $SSAOPostFx::sNormalTol ); + %this.setShaderConst( "$sNormalPow", $SSAOPostFx::sNormalPow ); + + %this.setShaderConst( "$lRadius", $SSAOPostFx::lRadius ); + %this.setShaderConst( "$lStrength", $SSAOPostFx::lStrength ); + %this.setShaderConst( "$lDepthMin", $SSAOPostFx::lDepthMin ); + %this.setShaderConst( "$lDepthMax", $SSAOPostFx::lDepthMax ); + %this.setShaderConst( "$lDepthPow", $SSAOPostFx::lDepthPow ); + %this.setShaderConst( "$lNormalTol", $SSAOPostFx::lNormalTol ); + %this.setShaderConst( "$lNormalPow", $SSAOPostFx::lNormalPow ); + + %blur = %this->blurY; + %blur.setShaderConst( "$blurDepthTol", $SSAOPostFx::blurDepthTol ); + %blur.setShaderConst( "$blurNormalTol", $SSAOPostFx::blurNormalTol ); + + %blur = %this->blurX; + %blur.setShaderConst( "$blurDepthTol", $SSAOPostFx::blurDepthTol ); + %blur.setShaderConst( "$blurNormalTol", $SSAOPostFx::blurNormalTol ); + + %blur = %this->blurY2; + %blur.setShaderConst( "$blurDepthTol", $SSAOPostFx::blurDepthTol ); + %blur.setShaderConst( "$blurNormalTol", $SSAOPostFx::blurNormalTol ); + + %blur = %this->blurX2; + %blur.setShaderConst( "$blurDepthTol", $SSAOPostFx::blurDepthTol ); + %blur.setShaderConst( "$blurNormalTol", $SSAOPostFx::blurNormalTol ); +} + +function SSAOPostFx::onEnabled( %this ) +{ + // This tells the AL shaders to reload and sample + // from our #ssaoMask texture target. + $AL::UseSSAOMask = true; + + return true; +} + +function SSAOPostFx::onDisabled( %this ) +{ + $AL::UseSSAOMask = false; +} + + +//----------------------------------------------------------------------------- +// GFXStateBlockData / ShaderData +//----------------------------------------------------------------------------- + +singleton GFXStateBlockData( SSAOStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + samplerStates[1] = SamplerWrapLinear; + samplerStates[2] = SamplerClampPoint; +}; + +singleton GFXStateBlockData( SSAOBlurStateBlock : PFX_DefaultStateBlock ) +{ + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; + samplerStates[1] = SamplerClampPoint; +}; + +singleton ShaderData( SSAOShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/ssao/SSAO_P.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/ssao/gl/SSAO_P.glsl"; + + samplerNames[0] = "$prepassMap"; + samplerNames[1] = "$randNormalTex"; + samplerNames[2] = "$powTable"; + + pixVersion = 3.0; +}; + +singleton ShaderData( SSAOBlurYShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/ssao/SSAO_Blur_V.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/ssao/SSAO_Blur_P.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/ssao/gl/SSAO_Blur_V.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/ssao/gl/SSAO_Blur_P.glsl"; + + samplerNames[0] = "$occludeMap"; + samplerNames[1] = "$prepassMap"; + + pixVersion = 3.0; + + defines = "BLUR_DIR=float2(0.0,1.0)"; +}; + +singleton ShaderData( SSAOBlurXShader : SSAOBlurYShader ) +{ + defines = "BLUR_DIR=float2(1.0,0.0)"; +}; + +//----------------------------------------------------------------------------- +// PostEffects +//----------------------------------------------------------------------------- + +singleton PostEffect( SSAOPostFx ) +{ + allowReflectPass = false; + + renderTime = "PFXBeforeBin"; + renderBin = "AL_LightBinMgr"; + renderPriority = 10; + + shader = SSAOShader; + stateBlock = SSAOStateBlock; + + texture[0] = "#prepass"; + texture[1] = "data/postFX/art/noise.png"; + texture[2] = "#ssao_pow_table"; + + target = "$outTex"; + targetScale = "0.5 0.5"; + targetViewport = "PFXTargetViewport_NamedInTexture0"; + + singleton PostEffect() + { + internalName = "blurY"; + + shader = SSAOBlurYShader; + stateBlock = SSAOBlurStateBlock; + + texture[0] = "$inTex"; + texture[1] = "#prepass"; + + target = "$outTex"; + }; + + singleton PostEffect() + { + internalName = "blurX"; + + shader = SSAOBlurXShader; + stateBlock = SSAOBlurStateBlock; + + texture[0] = "$inTex"; + texture[1] = "#prepass"; + + target = "$outTex"; + }; + + singleton PostEffect() + { + internalName = "blurY2"; + + shader = SSAOBlurYShader; + stateBlock = SSAOBlurStateBlock; + + texture[0] = "$inTex"; + texture[1] = "#prepass"; + + target = "$outTex"; + }; + + singleton PostEffect() + { + internalName = "blurX2"; + + shader = SSAOBlurXShader; + stateBlock = SSAOBlurStateBlock; + + texture[0] = "$inTex"; + texture[1] = "#prepass"; + + // We write to a mask texture which is then + // read by the lighting shaders to mask ambient. + target = "#ssaoMask"; + }; +}; + + +/// Just here for debug visualization of the +/// SSAO mask texture used during lighting. +singleton PostEffect( SSAOVizPostFx ) +{ + allowReflectPass = false; + + shader = PFX_PassthruShader; + stateBlock = PFX_DefaultStateBlock; + + texture[0] = "#ssaoMask"; + + target = "$backbuffer"; +}; + +singleton ShaderData( SSAOPowTableShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/ssao/SSAO_PowerTable_V.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/ssao/SSAO_PowerTable_P.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/ssao/gl/SSAO_PowerTable_V.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/ssao/gl/SSAO_PowerTable_P.glsl"; + + pixVersion = 2.0; +}; + +singleton PostEffect( SSAOPowTablePostFx ) +{ + shader = SSAOPowTableShader; + stateBlock = PFX_DefaultStateBlock; + + renderTime = "PFXTexGenOnDemand"; + + target = "#ssao_pow_table"; + + targetFormat = "GFXFormatR16F"; + targetSize = "256 1"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/turbulence.cs b/Templates/BaseGame/game/data/postFX/scripts/client/turbulence.cs new file mode 100644 index 000000000..7842a6429 --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/turbulence.cs @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton GFXStateBlockData( PFX_TurbulenceStateBlock : PFX_DefaultStateBlock) +{ + zDefined = false; + zEnable = false; + zWriteEnable = false; + + samplersDefined = true; + samplerStates[0] = SamplerClampLinear; +}; + +singleton ShaderData( PFX_TurbulenceShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/turbulenceP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/gl/turbulenceP.glsl"; + + samplerNames[0] = "$inputTex"; + pixVersion = 3.0; +}; + +singleton PostEffect( TurbulenceFx ) +{ + isEnabled = false; + allowReflectPass = true; + + renderTime = "PFXAfterDiffuse"; + renderBin = "GlowBin"; + renderPriority = 0.5; // Render after the glows themselves + + shader = PFX_TurbulenceShader; + stateBlock=PFX_TurbulenceStateBlock; + texture[0] = "$backBuffer"; + }; diff --git a/Templates/BaseGame/game/data/postFX/scripts/client/vignette.cs b/Templates/BaseGame/game/data/postFX/scripts/client/vignette.cs new file mode 100644 index 000000000..c824f5240 --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/client/vignette.cs @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +$VignettePostEffect::VMax = 0.6; +$VignettePostEffect::VMin = 0.2; + +singleton ShaderData( VignetteShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/postFx/vignette/VignetteP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFx/vignette/gl/VignetteP.glsl"; + + samplerNames[0] = "$backBuffer"; + + pixVersion = 2.0; +}; + +singleton PostEffect( VignettePostEffect ) +{ + isEnabled = false; + allowReflectPass = false; + renderTime = "PFXAfterBin"; + renderBin = "GlowBin"; + shader = VignetteShader; + stateBlock = PFX_DefaultStateBlock; + texture[0] = "$backBuffer"; + renderPriority = 10; +}; + +function VignettePostEffect::setShaderConsts(%this) +{ + %this.setShaderConst("$Vmax", $VignettePostEffect::VMax); + %this.setShaderConst("$Vmin", $VignettePostEffect::VMin); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/postFX/scripts/gui/postFxManager.gui b/Templates/BaseGame/game/data/postFX/scripts/gui/postFxManager.gui new file mode 100644 index 000000000..78248e2ae --- /dev/null +++ b/Templates/BaseGame/game/data/postFX/scripts/gui/postFxManager.gui @@ -0,0 +1,2755 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(PostFXManager) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiModelessDialogProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new DbgFileView() { + position = "0 0"; + extent = "8 2"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiWindowCtrl(ppOptionsWindow) { + text = "PostFX Manager"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(PostFXManager);"; + edgeSnap = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "306 216"; + extent = "411 336"; + minExtent = "8 8"; + horizSizing = "center"; + vertSizing = "center"; + profile = "GuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapBorderCtrl() { + position = "11 77"; + extent = "390 216"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTabBookCtrl(ppOptionsTabBook) { + tabPosition = "Top"; + tabMargin = "7"; + minTabWidth = "32"; + tabHeight = "20"; + allowReorder = "0"; + defaultPage = "-1"; + selectedPage = "1"; + frontTabPadding = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 58"; + extent = "394 233"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBookProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl(ppOptionsSSAOTab) { + fitBook = "0"; + text = "SSAO"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "394 213"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Options for the Screen Space Ambient Occlusion postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapBorderCtrl() { + position = "12 30"; + extent = "365 170"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTabBookCtrl(ppOptionsSSAOOptions) { + tabPosition = "Top"; + tabMargin = "7"; + minTabWidth = "64"; + tabHeight = "20"; + allowReorder = "0"; + defaultPage = "-1"; + selectedPage = "2"; + frontTabPadding = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 11"; + extent = "362 185"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBookProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl(ppOptionsSSAOGeneralTab) { + fitBook = "0"; + text = "General"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "362 165"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains general overall settings for the SSAO postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl(ppOptionsSSAOOverallStrengthLabel) { + text = "Overall Strength"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "31 57"; + extent = "77 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the overall strength of the Ambient Occlusion effect."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAOBlurDepthLabel) { + text = "Blur (Softness)"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "38 85"; + extent = "73 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the amount of softness in the SSAO, overall."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAOBlurNormalLabel) { + text = "Blur (Normal Maps)"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "19 112"; + extent = "92 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the amount of softness in the SSAO, in the normal maps."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(ppOptionsSSAOQuality) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Low"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "120 28"; + extent = "211 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAOQualityLabel) { + text = "Quality"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "76 29"; + extent = "32 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOOverallStrength) { + range = "0 50"; + ticks = "1000"; + snap = "0"; + value = "2"; + position = "120 56"; + extent = "211 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOBlurDepth) { + range = "0 0.3"; + ticks = "1000"; + snap = "0"; + value = "0.001"; + position = "120 86"; + extent = "211 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOBlurNormal) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0.95"; + position = "119 113"; + extent = "212 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsSSAONearTab) { + fitBook = "0"; + text = "Near"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "362 165"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains settings for the near range ambient occlusion aspect of the SSAO postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSliderCtrl(ppOptionsSSAONearRadius) { + range = "0.001 5"; + ticks = "1000"; + snap = "0"; + value = "0.1"; + position = "122 17"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAONearDepthMin) { + range = "0 5"; + ticks = "1000"; + snap = "0"; + value = "0.1"; + position = "122 62"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAONearStrength) { + range = "0 20"; + ticks = "1000"; + snap = "0"; + value = "6"; + position = "122 39"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAONearRadiusLabel) { + text = "Radius"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "80 16"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the near/small radius SSAO reach."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAONearStrengthLabel) { + text = "Strength"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "73 38"; + extent = "41 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the near/small radius SSAO strength."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAONearDepthMinLabel) { + text = "Depth Min"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "66 61"; + extent = "48 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the near/small radius SSAO minimum depth value."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAONearDepthMaxLabel) { + text = "Depth Max"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "62 85"; + extent = "52 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the near/small radius SSAO maximum depth value."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAONearDepthMax) { + range = "0 50"; + ticks = "1000"; + snap = "0"; + value = "1"; + position = "122 86"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAONearToleranceNormal) { + range = "0 2"; + ticks = "1000"; + snap = "0"; + value = "0"; + position = "122 133"; + extent = "103 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAONearTolerancePower) { + range = "0 2"; + ticks = "1000"; + snap = "0"; + value = "1"; + position = "246 133"; + extent = "97 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAONearToleranceLabel2) { + text = "Tolerance / Power"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "24 132"; + extent = "92 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAONearToleranceLabel1) { + text = "Normal Maps : "; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "19 113"; + extent = "71 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsSSAOFarTab) { + fitBook = "0"; + text = "Far"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "362 165"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains settings for the far range ambient occlusion aspect of the SSAO postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl(ppOptionsSSAOFarRadiusLabel) { + text = "Radius"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "80 16"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the far/large radius SSAO reach."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOFarRadius) { + range = "0.001 5"; + ticks = "1000"; + snap = "0"; + value = "1"; + position = "122 17"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAOFarStrengthLabel) { + text = "Strength"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "73 38"; + extent = "41 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the far/large radius SSAO strength."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOFarStrength) { + range = "0 20"; + ticks = "1000"; + snap = "0"; + value = "10"; + position = "122 39"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAOFarDepthMinLabel) { + text = "Depth Min"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "66 61"; + extent = "48 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the far/large radius SSAO minimum depth."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOFarDepthMin) { + range = "0 5"; + ticks = "1000"; + snap = "0"; + value = "0.2"; + position = "122 62"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAOFarDepthMaxLabel) { + text = "Depth Max"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "62 85"; + extent = "52 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the far/large radius SSAO maximum."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOFarDepthMax) { + range = "0 5"; + ticks = "1000"; + snap = "0"; + value = "2"; + position = "122 86"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsSSAOFarToleranceLabel1) { + text = "Normal Maps :"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 113"; + extent = "72 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Tolerance / Power"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "24 132"; + extent = "90 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOFarToleranceNormal) { + range = "0 2"; + ticks = "1000"; + snap = "0"; + value = "0"; + position = "122 133"; + extent = "100 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsSSAOFarTolerancePower) { + range = "0 2"; + ticks = "1000"; + snap = "0"; + value = "2"; + position = "239 133"; + extent = "104 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiCheckBoxCtrl(ppOptionsEnableSSAO) { + useInactiveState = "0"; + text = "Enable"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "329 7"; + extent = "53 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable/Disable the SSAO postFX"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsHDRTab) { + fitBook = "0"; + text = "HDR"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "394 213"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Options for the High Definition Range Lighting postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapBorderCtrl() { + position = "12 30"; + extent = "363 172"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTabBookCtrl(ppOptionsHDROptions) { + tabPosition = "Top"; + tabMargin = "7"; + minTabWidth = "64"; + tabHeight = "20"; + allowReorder = "0"; + defaultPage = "-1"; + selectedPage = "0"; + frontTabPadding = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 11"; + extent = "365 195"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBookProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl(ppOptionsHDRBrightnessTab) { + fitBook = "0"; + text = "Brightness"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "365 175"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains settings related to the brightness of the HDR postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSliderCtrl(ppOptionsHDRMinLuminance) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0"; + position = "132 77"; + extent = "206 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Value : 0"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsHDRKeyValue) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0.0459184"; + position = "132 50"; + extent = "206 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Value : 0.0459184"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRKeyValueLabel) { + text = "Key Value"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "69 50"; + extent = "52 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The tone mapping middle grey or exposure value used to adjust the overall \"balance\" of the image."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRMinLuminanceLabel) { + text = "Minimum Luminance"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "25 77"; + extent = "96 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The minimum luminance value to allow when tone mapping the scene. This is particularly useful if your scene is very dark or has a black ambient color in places."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRWhiteCutoffLabel) { + text = "White Cutoff"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 104"; + extent = "65 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The cutoff level for the white levels in the brightness."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsHDRWhiteCutoff) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0.52551"; + position = "132 104"; + extent = "206 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Value : 0.52551"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsHDRBrightnessAdaptRate) { + range = "0.1 10"; + ticks = "1000"; + snap = "0"; + value = "2"; + position = "132 132"; + extent = "205 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRBrightnessAdaptRateLabel) { + text = "Brightness Adapt Rate"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 132"; + extent = "109 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The speed at which the view adjusts to the new lighting in the environment."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRKeyValueLabel1) { + text = "Tone Mapping Contrast"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "10 24"; + extent = "111 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Tone mapping contrast is the amount of scene to blend, with the tone mapped HDR scene. Lower values are recommended but higher values give a strong contrasted darker shadowed look."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsHDRToneMappingAmount) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0.265306"; + position = "132 24"; + extent = "206 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "value : 0.265306"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsHDRBloomTab) { + fitBook = "0"; + text = "Bloom"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "365 175"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains settings related to the blooming aspect of the HDR postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSliderCtrl(ppOptionsHDRBloomBlurMultiplier) { + range = "0 5"; + ticks = "1000"; + snap = "0"; + value = "0.502645"; + position = "132 70"; + extent = "199 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Value : 0.502645"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsHDRBloomBlurMean) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0.510526"; + position = "132 97"; + extent = "200 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Value : 0.510526"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsHDRBloomBlurStdDev) { + range = "0 3"; + ticks = "1000"; + snap = "0"; + value = "1.4127"; + position = "132 123"; + extent = "199 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Value : 1.4127"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRBlurMultiplierLabel) { + text = "Blur Multiplier"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "59 70"; + extent = "63 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The amount of blur to apply to the bloomed areas in the HDR."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRBlurMeanLabel) { + text = "Blur \"mean\" value"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "38 97"; + extent = "84 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRBlurStandardDevianceLabel) { + text = "Blur \"Std Dev\" value"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "23 123"; + extent = "99 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsHDRBloomBrightPassThresholdLabel) { + text = "Bright pass threshold"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "19 43"; + extent = "103 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The bright pass threshold controls how bright the brightest areas of the scene are in the HDR."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsHDRBloomBlurBrightPassThreshold) { + range = "0 5"; + ticks = "1000"; + snap = "0"; + value = "1.60526"; + position = "132 43"; + extent = "200 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Value : 1.60526"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppOptionsHDRBloom) { + useInactiveState = "0"; + text = " Enable Bloom"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "250 9"; + extent = "85 24"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enables or disables the bloom (glowing effect) of the HDR PostFX."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsHDRBloomEffectsTab) { + fitBook = "0"; + text = "Effects"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "365 175"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains settings related to the effects the HDR postFX can offer"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiCheckBoxCtrl(ppOptionsHDREffectsBlueShift) { + useInactiveState = "0"; + text = " Enable Color Shift"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "11 4"; + extent = "117 24"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enables a scene tinting/Blue shift based on the color selected below."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiColorPickerCtrl(ppOptionsHDREffectsBlueShiftColorBlend) { + baseColor = "1 0 0.0235294 1"; + pickColor = "0 0 0 1"; + selectorGap = "1"; + displayMode = "BlendColor"; + actionOnMove = "1"; + showReticle = "1"; + position = "10 29"; + extent = "344 110"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Select a color"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiColorPickerCtrl(ppOptionsHDREffectsBlueShiftColorBaseColor) { + baseColor = "1 0 0.0235294 1"; + pickColor = "0 0 0 1"; + selectorGap = "1"; + displayMode = "HorizColor"; + actionOnMove = "1"; + showReticle = "1"; + position = "10 142"; + extent = "343 21"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Select a color"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiCheckBoxCtrl(ppOptionsHDRToneMapping) { + useInactiveState = "0"; + text = " Enable Tone Mapping"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "18 8"; + extent = "120 24"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enables or disabled tone mapping on the HDR. The tone mapping balanced the brightness levels during the HDR process. Recommended"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppOptionsEnableHDR) { + useInactiveState = "0"; + text = "Enable"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "329 7"; + extent = "53 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable/Disable the HDR postFX (takes some time to initialise, be patient)"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppOptionsEnableHDRDebug) { + useInactiveState = "0"; + text = "Debug"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "262 7"; + extent = "53 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsLightRaysTab) { + fitBook = "0"; + text = "Light Rays"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "394 213"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Options for the Light Rays postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSliderCtrl(ppOptionsLightRaysBrightScalar) { + range = "0 5"; + ticks = "1000"; + snap = "0"; + value = "0.75"; + position = "96 46"; + extent = "264 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsLightRaysBrightnessScalarLabel) { + text = "Brightness"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "26 48"; + extent = "87 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls how bright the rays and the object casting them are in the scene."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + new GuiSliderCtrl(ppOptionsLightRaysSampleScalar) { + range = "20 512"; + ticks = "512"; + snap = "0"; + value = "40"; + position = "96 75"; + extent = "264 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + new GuiTextCtrl(ppOptionsLightRaysSampleScalarLabel) { + text = "Samples"; + maxLength = "512"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "26 76"; + extent = "87 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the number of samples for the shader."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + new GuiSliderCtrl(ppOptionsLightRaysDensityScalar) { + range = "0.01 1"; + ticks = "1000"; + snap = "0"; + value = "0.94"; + position = "96 105"; + extent = "264 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + new GuiTextCtrl(ppOptionsLightRaysDensityScalarLabel) { + text = "Density"; + maxLength = "1000"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "26 106"; + extent = "87 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the density of the rays."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + new GuiSliderCtrl(ppOptionsLightRaysWeightScalar) { + range = "0.1 10"; + ticks = "1000"; + snap = "0"; + value = "5.65"; + position = "96 135"; + extent = "264 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + new GuiTextCtrl(ppOptionsLightRaysWeightScalarLabel) { + text = "Weight"; + maxLength = "1000"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "26 136"; + extent = "87 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the weight of the rays."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + + new GuiSliderCtrl(ppOptionsLightRaysDecayScalar) { + range = "0.01 1"; + ticks = "1000"; + snap = "0"; + value = "1.0"; + position = "96 165"; + extent = "264 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + new GuiTextCtrl(ppOptionsLightRaysDecayScalarLabel) { + text = "Decay"; + maxLength = "1000"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "26 166"; + extent = "87 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the decay of the rays."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppOptionsEnableLightRays) { + useInactiveState = "0"; + text = "Enable"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "329 7"; + extent = "53 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable/Disable the light rays postFX"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsDOFTab) { + fitBook = "0"; + text = "DOF"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "394 213"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Options for the Depth Of Field postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapBorderCtrl() { + position = "14 28"; + extent = "362 170"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTabBookCtrl() { + tabPosition = "Top"; + tabMargin = "7"; + minTabWidth = "64"; + tabHeight = "20"; + allowReorder = "0"; + defaultPage = "-1"; + selectedPage = "1"; + frontTabPadding = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "14 9"; + extent = "360 189"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBookProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl(ppOptionsDOFGeneralTab) { + fitBook = "0"; + text = "General"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "360 169"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains general settings related to the DOF system"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + //new GuiCheckBoxCtrl(ppOptionsDOFEnableDOF) { + //useInactiveState = "0"; + //text = "Enable DOF"; + //groupNum = "-1"; + //buttonType = "ToggleButton"; + //useMouseEvents = "0"; + //position = "31 43"; + //extent = "140 30"; + //minExtent = "8 2"; + //horizSizing = "right"; + //vertSizing = "bottom"; + //profile = "GuiCheckBoxProfile"; + //visible = "1"; + //active = "1"; + //tooltipProfile = "GuiToolTipProfile"; + //hovertime = "1000"; + //isContainer = "0"; + //canSave = "1"; + //canSaveDynamicFields = "0"; + //}; + new GuiCheckBoxCtrl(ppOptionsDOFEnableAutoFocus) { + useInactiveState = "0"; + text = "Enable Auto Focus"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "31 8"; + extent = "140 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsDOFAutoFocusTab) { + fitBook = "0"; + text = "Auto Focus"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 20"; + extent = "360 169"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Contains settings related to the fine control of the auto focus system"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl(ppOptionsDOFNearBlurMaxLabel) { + text = "Near Blur Max"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "36 8"; + extent = "67 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The max allowed value of near blur"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsDOFFarBlurMinSlider) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0"; + position = "120 8"; + extent = "224 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsDOFFarBlurMaxLabel) { + text = "Far Blur Max"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "43 34"; + extent = "60 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The max allowed value of far blur"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsDOFFarBlurMaxSlider) { + range = "0 1"; + ticks = "1000"; + snap = "0"; + value = "0"; + position = "120 34"; + extent = "224 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsDOFFocusRangeMinLabel) { + text = "Focus Range (Min)"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "13 61"; + extent = "90 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The distance range around the focal distance that remains in focus (in meters, minimum distance in focus) focal distance it is\r\ndependant on the visible distance set in your level"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsDOFFocusRangeMinSlider) { + range = "0.01 1e+003"; + ticks = "1000"; + snap = "0"; + value = "0.01"; + position = "120 61"; + extent = "224 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsDOFFocusRangeMaxLabel) { + text = "Focus Range (Max)"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "9 88"; + extent = "95 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "The distance range around the focal distance that remains in focus (in meters, maximum distance in focus) focal distance it is\r\ndependant on the visible distance set in your level"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsDOFFocusRangeMaxSlider) { + range = "0.01 1e+003"; + ticks = "1000"; + snap = "0"; + value = "0.01"; + position = "119 87"; + extent = "224 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsDOFBurCurveNearLabel) { + text = "Blur Curve Near"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "27 114"; + extent = "77 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "A small number causes bluriness to increase gradually\r\nat distances closer than the focal distance. A large number causes bluriness to \r\nincrease quickly"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsDOFBlurCurveNearSlider) { + range = "0 50"; + ticks = "1000"; + snap = "0"; + value = "0"; + position = "119 114"; + extent = "225 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsDOFBlurCurveFarLabel) { + text = "Blur Curve Far"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "33 139"; + extent = "70 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "A small number causes bluriness to increase gradually\r\nat distances closer than the focal distance. A large number causes bluriness to \r\nincrease quickly"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsDOFBlurCurveFarSlider) { + range = "0 50"; + ticks = "1000"; + snap = "0"; + value = "0"; + position = "119 141"; + extent = "224 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiCheckBoxCtrl(ppOptionsEnableDOF) { + useInactiveState = "0"; + text = "Enable"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "329 7"; + extent = "53 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable/Disable the Depth of field postFX"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl(ppOptionsVignetteTab) { + fitBook = "0"; + text = "Vignette"; + maxLength = "1024"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "1"; + anchorLeft = "1"; + anchorRight = "1"; + position = "0 40"; + extent = "394 193"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Options for the Vignette postFX"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + Enabled = "1"; + + new GuiCheckBoxCtrl(ppOptionsEnableVignette) { + text = "Enable"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "329 7"; + extent = "53 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable/Disable the vignette postFX"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(ppOptionsVignetteVMax) { + range = "0.001 5"; + ticks = "1000"; + snap = "0"; + value = "0.6"; + position = "96 46"; + extent = "221 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderBoxProfile"; + visible = "1"; + active = "1"; + variable = "$VignettePostEffect::VMax"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsVignetteVMaxLabel) { + text = "Radius"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "26 48"; + extent = "41 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Controls the maximum exposure of vignetting."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTabPageCtrl() { + fitBook = "0"; + text = "Color Correction"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "8 27"; + extent = "376 200"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "ColorCorrectionTab"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Color Correction Ramp"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 7"; + extent = "118 13"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "data/postFX/art/null_color_ramp.png"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 29"; + extent = "365 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + altCommand = "ppColorCorrection_selectFileHandler( $thisControl.getText() );"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "ColorCorrectionFileName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Select..."; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "252 54"; + extent = "56 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ppColorCorrection_selectFile();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "ColorCorrectionButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Reset"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "315 54"; + extent = "56 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ppColorCorrection_selectFileHandler( \"\" );"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "ColorCorrectionReset"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiButtonCtrl(ppOptionsApply) { + text = "Apply"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "309 302"; + extent = "93 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "PostFXManager.settingsApplyAll(); Canvas.popDialog(PostFXManager);"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Apply the settings and close this dialog"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(ppOptionsSavePreset) { + text = "Save Preset..."; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "111 302"; + extent = "93 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "PostFXManager.savePresetFile();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Save the preset to a file to disk for later use (use postfx::applyPreset)"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(ppOptionsLoadPreset) { + text = "Load Preset..."; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "12 302"; + extent = "93 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "PostFXManager.loadPresetFile();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Load a post FX preset file from disk"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppOptionsEnable) { + useInactiveState = "0"; + text = "Enable PostFX System"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "13 24"; + extent = "127 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable or Disable the postFX system"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(ppOptionsQuality) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "278 30"; + extent = "122 21"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Used to adjust the quality/performance settings of the PostFX system. Some PostFX may not adhere to the settings in this dialog."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(ppOptionsQualityLabel) { + text = "Quality"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "238 32"; + extent = "39 12"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Used to adjust the quality/performance settings of the PostFX system. Some PostFX may not adhere to the settings in this dialog."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(ppOptionsOk1) { + text = "Revert"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "210 302"; + extent = "93 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "postProcessOptionsDlg.applySettings(); Canvas.popDialog(postProcessOptionsDlg);"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Revert any changes made since opening the dialog"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/shaders/common/VolumetricFog/VFogP.hlsl b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/VFogP.hlsl new file mode 100644 index 000000000..e900f7548 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/VFogP.hlsl @@ -0,0 +1,87 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Volumetric Fog final pixel shader V2.00 +#include "../shaderModel.hlsl" +#include "../shaderModelAutoGen.hlsl" +#include "../torque.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(prepassTex, 0); +TORQUE_UNIFORM_SAMPLER2D(depthBuffer, 1); +TORQUE_UNIFORM_SAMPLER2D(frontBuffer, 2); +TORQUE_UNIFORM_SAMPLER2D(density, 3); + +uniform float3 ambientColor; +uniform float accumTime; +uniform float4 fogColor; +uniform float4 modspeed;//xy speed layer 1, zw speed layer 2 +uniform float2 viewpoint; +uniform float2 texscale; +uniform float fogDensity; +uniform float preBias; +uniform float textured; +uniform float modstrength; +uniform float numtiles; +uniform float fadesize; +uniform float2 PixelSize; + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float4 htpos : TEXCOORD0; + float2 uv0 : TEXCOORD1; +}; + +float4 main( ConnectData IN ) : TORQUE_TARGET0 +{ + float2 uvscreen=((IN.htpos.xy/IN.htpos.w) + 1.0 ) / 2.0; + uvscreen.y = 1.0 - uvscreen.y; + + float obj_test = TORQUE_PREPASS_UNCONDITION(prepassTex, uvscreen).w * preBias; + float depth = TORQUE_TEX2D(depthBuffer, uvscreen).r; + float front = TORQUE_TEX2D(frontBuffer, uvscreen).r; + + if (depth <= front) + return float4(0,0,0,0); + else if ( obj_test < depth ) + depth = obj_test; + if ( front >= 0.0) + depth -= front; + + float diff = 1.0; + float3 col = fogColor.rgb; + if (textured != 0.0) + { + float2 offset = viewpoint + ((-0.5 + (texscale * uvscreen)) * numtiles); + + float2 mod1 = TORQUE_TEX2D(density, (offset + (modspeed.xy*accumTime))).rg; + float2 mod2 = TORQUE_TEX2D(density, (offset + (modspeed.zw*accumTime))).rg; + diff = (mod2.r + mod1.r) * modstrength; + col *= (2.0 - ((mod1.g + mod2.g) * fadesize))/2.0; + } + + col *= ambientColor; + + float4 resultColor = float4(col, 1.0 - saturate(exp(-fogDensity * depth * diff * fadesize))); + + return hdrEncode(resultColor); +} diff --git a/Templates/BaseGame/game/data/shaders/common/VolumetricFog/VFogPreP.hlsl b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/VFogPreP.hlsl new file mode 100644 index 000000000..fdc839507 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/VFogPreP.hlsl @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Volumetric Fog prepass pixel shader V1.00 +#include "../shaderModel.hlsl" + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float4 pos : TEXCOORD0; +}; + +float4 main( ConnectData IN ) : TORQUE_TARGET0 +{ + float OUT; + + clip( IN.pos.w ); + OUT = IN.pos.w; + + return float4(OUT,0,0,1); +} diff --git a/Templates/BaseGame/game/data/shaders/common/VolumetricFog/VFogPreV.hlsl b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/VFogPreV.hlsl new file mode 100644 index 000000000..aba7a745d --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/VFogPreV.hlsl @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Volumetric Fog prepass vertex shader V1.00 + +#include "../shaderModel.hlsl" +#include "../hlslStructs.hlsl" + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float4 pos : TEXCOORD0; +}; + +uniform float4x4 modelView; + +ConnectData main( VertexIn_P IN) +{ + ConnectData OUT; + + OUT.hpos = mul(modelView, float4(IN.pos, 1.0)); + OUT.pos = OUT.hpos; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/VolumetricFog/VFogRefl.hlsl b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/VFogRefl.hlsl new file mode 100644 index 000000000..380233b5f --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/VFogRefl.hlsl @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Volumetric Fog Reflection pixel shader V1.00 +#include "../shaderModel.hlsl" +uniform float4 fogColor; +uniform float fogDensity; +uniform float reflStrength; + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float4 pos : TEXCOORD0; +}; + +float4 main( ConnectData IN ) : TORQUE_TARGET0 +{ + return float4(fogColor.rgb,saturate(fogDensity*reflStrength)); +} diff --git a/Templates/BaseGame/game/data/shaders/common/VolumetricFog/VFogV.hlsl b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/VFogV.hlsl new file mode 100644 index 000000000..167f83946 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/VFogV.hlsl @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Volumetric Fog final vertex shader V1.00 + +#include "../shaderModel.hlsl" +#include "../hlslStructs.hlsl" + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float4 htpos : TEXCOORD0; + float2 uv0 : TEXCOORD1; +}; + +uniform float4x4 modelView; + +ConnectData main( VertexIn_PNTT IN) +{ + ConnectData OUT; + + OUT.hpos = mul(modelView, float4(IN.pos,1.0)); + OUT.htpos = OUT.hpos; + OUT.uv0 = IN.uv0; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/VolumetricFog/gl/VFogP.glsl b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/gl/VFogP.glsl new file mode 100644 index 000000000..7895d9e2d --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/gl/VFogP.glsl @@ -0,0 +1,87 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../gl/torque.glsl" + +uniform sampler2D prepassTex; +uniform sampler2D depthBuffer; +uniform sampler2D frontBuffer; +uniform sampler2D density; + +uniform float accumTime; +uniform vec4 fogColor; +uniform float fogDensity; +uniform float preBias; +uniform float textured; +uniform float modstrength; +uniform vec4 modspeed;//xy speed layer 1, zw speed layer 2 +uniform vec2 viewpoint; +uniform vec2 texscale; +uniform vec3 ambientColor; +uniform float numtiles; +uniform float fadesize; +uniform vec2 PixelSize; + +in vec4 _hpos; +#define IN_hpos _hpos +out vec4 OUT_col; + +void main() +{ + vec2 uvscreen=((IN_hpos.xy/IN_hpos.w) + 1.0 ) / 2.0; + uvscreen.y = 1.0 - uvscreen.y; + + float obj_test = prepassUncondition( prepassTex, uvscreen).w * preBias; + float depth = tex2D(depthBuffer,uvscreen).r; + float front = tex2D(frontBuffer,uvscreen).r; + + if (depth <= front) + { + OUT_col = vec4(0,0,0,0); + return; + } + + else if ( obj_test < depth ) + depth = obj_test; + if ( front >= 0.0) + depth -= front; + + float diff = 1.0; + vec3 col = fogColor.rgb; + if (textured != 0.0) + { + vec2 offset = viewpoint + ((-0.5 + (texscale * uvscreen)) * numtiles); + + vec2 mod1 = tex2D(density,(offset + (modspeed.xy*accumTime))).rg; + vec2 mod2= tex2D(density,(offset + (modspeed.zw*accumTime))).rg; + diff = (mod2.r + mod1.r) * modstrength; + col *= (2.0 - ((mod1.g + mod2.g) * fadesize))/2.0; + } + + col *= ambientColor; + + vec4 returnColor = vec4(col, 1.0 - saturate(exp(-fogDensity * depth * diff * fadesize))); + + OUT_col = hdrEncode(returnColor); +} diff --git a/Templates/BaseGame/game/data/shaders/common/VolumetricFog/gl/VFogPreP.glsl b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/gl/VFogPreP.glsl new file mode 100644 index 000000000..017ea6ef8 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/gl/VFogPreP.glsl @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../gl/hlslCompat.glsl" + +in vec4 _hpos; +#define IN_hpos _hpos + +out vec4 OUT_col; + +void main() +{ + float OUT; + clip( IN_hpos.w ); + OUT = IN_hpos.w; + + OUT_col = vec4(OUT,0,0,1); +} diff --git a/Templates/BaseGame/game/data/shaders/common/VolumetricFog/gl/VFogPreV.glsl b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/gl/VFogPreV.glsl new file mode 100644 index 000000000..2f2a1318a --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/gl/VFogPreV.glsl @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../gl/hlslCompat.glsl" + +in vec4 vPosition; +#define IN_position vPosition + +out vec4 _hpos; +#define OUT_hpos _hpos + +uniform mat4 modelView; + +void main() +{ + vec4 inPos = IN_position; + inPos.w = 1.0; + + OUT_hpos = tMul( modelView, inPos ); + + gl_Position = OUT_hpos; + correctSSP(gl_Position); +} diff --git a/Templates/BaseGame/game/data/shaders/common/VolumetricFog/gl/VFogRefl.glsl b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/gl/VFogRefl.glsl new file mode 100644 index 000000000..78e149fbf --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/gl/VFogRefl.glsl @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../gl/hlslCompat.glsl" + +uniform vec4 fogColor; +uniform float fogDensity; +uniform float reflStrength; +out vec4 OUT_col; + +void main() +{ + OUT_col = vec4(fogColor.rgb,saturate(fogDensity*reflStrength)); +} diff --git a/Templates/BaseGame/game/data/shaders/common/VolumetricFog/gl/VFogV.glsl b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/gl/VFogV.glsl new file mode 100644 index 000000000..57b3ba87e --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/VolumetricFog/gl/VFogV.glsl @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../gl/hlslCompat.glsl" + +in vec4 vPosition; +#define IN_position vPosition + +out vec4 _hpos; +#define OUT_hpos _hpos + +uniform mat4 modelView; + +void main() +{ + OUT_hpos = tMul(modelView, IN_position); + gl_Position = OUT_hpos; + correctSSP(gl_Position); +} diff --git a/Templates/BaseGame/game/data/shaders/common/basicCloudsP.hlsl b/Templates/BaseGame/game/data/shaders/common/basicCloudsP.hlsl new file mode 100644 index 000000000..4b40e5e8c --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/basicCloudsP.hlsl @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "torque.hlsl" + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float2 texCoord : TEXCOORD0; +}; + +TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0); + +float4 main( ConnectData IN ) : TORQUE_TARGET0 +{ + float4 col = TORQUE_TEX2D(diffuseMap, IN.texCoord); + return hdrEncode( col ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/basicCloudsV.hlsl b/Templates/BaseGame/game/data/shaders/common/basicCloudsV.hlsl new file mode 100644 index 000000000..a176fdbcd --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/basicCloudsV.hlsl @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "shaderModel.hlsl" + +struct CloudVert +{ + float3 pos : POSITION; + float2 uv0 : TEXCOORD0; +}; + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float2 texCoord : TEXCOORD0; +}; + +uniform float4x4 modelview; +uniform float2 texDirection; +uniform float2 texOffset; +uniform float accumTime; +uniform float texScale; + + +ConnectData main( CloudVert IN ) +{ + ConnectData OUT; + + OUT.hpos = mul(modelview, float4(IN.pos,1.0)); + + float2 uv = IN.uv0; + uv += texOffset; + uv *= texScale; + uv += accumTime * texDirection; + + OUT.texCoord = uv; + + return OUT; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/cloudLayerP.hlsl b/Templates/BaseGame/game/data/shaders/common/cloudLayerP.hlsl new file mode 100644 index 000000000..efa8fe0b4 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/cloudLayerP.hlsl @@ -0,0 +1,146 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "shaderModel.hlsl" +#include "torque.hlsl" + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float4 texCoord12 : TEXCOORD0; + float4 texCoord34 : TEXCOORD1; + float3 vLightTS : TEXCOORD2; // light vector in tangent space, denormalized + float3 vViewTS : TEXCOORD3; // view vector in tangent space, denormalized + float worldDist : TEXCOORD4; +}; + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +TORQUE_UNIFORM_SAMPLER2D(normalHeightMap, 0); +uniform float3 ambientColor; +uniform float3 sunColor; +uniform float cloudCoverage; +uniform float3 cloudBaseColor; +uniform float cloudExposure; + +//----------------------------------------------------------------------------- +// Globals +//----------------------------------------------------------------------------- +// The per-color weighting to be used for luminance calculations in RGB order. +static const float3 LUMINANCE_VECTOR = float3(0.2125f, 0.7154f, 0.0721f); + + +//----------------------------------------------------------------------------- +// Functions +//----------------------------------------------------------------------------- + +// Calculates the Rayleigh phase function +float getRayleighPhase( float angle ) +{ + return 0.75 * ( 1.0 + pow( angle, 2 ) ); +} + +// Returns the output rgb color given a texCoord and parameters it uses +// for lighting calculation. +float3 ComputeIllumination( float2 texCoord, + float3 vLightTS, + float3 vViewTS, + float3 vNormalTS ) +{ + //return noiseNormal; + //return vNormalTS; + + float3 vLightTSAdj = float3( -vLightTS.x, -vLightTS.y, vLightTS.z ); + + float dp = dot( vNormalTS, vLightTSAdj ); + + // Calculate the amount of illumination (lightTerm)... + + // We do both a rim lighting effect and a halfLambertian lighting effect + // and combine the result. + float halfLambertTerm = saturate( pow( dp * 0.5 + 0.5, 1 ) ); + float rimLightTerm = pow( ( 1.0 - dp ), 1.0 ); + float lightTerm = saturate( halfLambertTerm * 1.0 + rimLightTerm * dp ); + lightTerm *= 0.5; + + // Use a simple RayleighPhase function to simulate single scattering towards + // the camera. + float angle = dot( vLightTS, vViewTS ); + lightTerm *= getRayleighPhase( angle ); + + // Combine terms and colors into the output color. + //float3 lightColor = ( lightTerm * sunColor * fOcclusionShadow ) + ambientColor; + float3 lightColor = lerp( ambientColor, sunColor, lightTerm ); + //lightColor = lerp( lightColor, ambientColor, cloudCoverage ); + float3 finalColor = cloudBaseColor * lightColor; + + return finalColor; +} + +float4 main( ConnectData IN ) : TORQUE_TARGET0 +{ + // Normalize the interpolated vectors: + float3 vViewTS = normalize( IN.vViewTS ); + float3 vLightTS = normalize( IN.vLightTS ); + + float4 cResultColor = float4( 0, 0, 0, 1 ); + + float2 texSample = IN.texCoord12.xy; + + float4 noise1 = TORQUE_TEX2D( normalHeightMap, IN.texCoord12.zw ); + noise1 = normalize( ( noise1 - 0.5 ) * 2.0 ); + //return noise1; + + float4 noise2 = TORQUE_TEX2D(normalHeightMap, IN.texCoord34.xy); + noise2 = normalize( ( noise2 - 0.5 ) * 2.0 ); + //return noise2; + + float3 noiseNormal = normalize( noise1 + noise2 ).xyz; + //return float4( noiseNormal, 1.0 ); + + float noiseHeight = noise1.a * noise2.a * ( cloudCoverage / 2.0 + 0.5 ); + + float3 vNormalTS = normalize( TORQUE_TEX2D(normalHeightMap, texSample).xyz * 2.0 - 1.0); + vNormalTS += noiseNormal; + vNormalTS = normalize( vNormalTS ); + + // Compute resulting color for the pixel: + cResultColor.rgb = ComputeIllumination( texSample, vLightTS, vViewTS, vNormalTS ); + + float coverage = ( cloudCoverage - 0.5 ) * 2.0; + cResultColor.a = TORQUE_TEX2D(normalHeightMap, texSample).a + coverage + noiseHeight; + + if ( cloudCoverage > -1.0 ) + cResultColor.a /= 1.0 + coverage; + + cResultColor.a = saturate( cResultColor.a * pow( saturate(cloudCoverage), 0.25 ) ); + + cResultColor.a = lerp( cResultColor.a, 0.0, 1.0 - pow(IN.worldDist,2.0) ); + + cResultColor.rgb *= cloudExposure; + + return hdrEncode( cResultColor ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/cloudLayerV.hlsl b/Templates/BaseGame/game/data/shaders/common/cloudLayerV.hlsl new file mode 100644 index 000000000..d60dd251d --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/cloudLayerV.hlsl @@ -0,0 +1,106 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +#include "shaderModel.hlsl" + +struct CloudVert +{ + float3 pos : POSITION; + float3 normal : NORMAL; + float3 binormal : BINORMAL; + float3 tangent : TANGENT; + float2 uv0 : TEXCOORD0; +}; + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float4 texCoord12 : TEXCOORD0; + float4 texCoord34 : TEXCOORD1; + float3 vLightTS : TEXCOORD2; // light vector in tangent space, denormalized + float3 vViewTS : TEXCOORD3; // view vector in tangent space, denormalized + float worldDist : TEXCOORD4; +}; + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform float4x4 modelview; +uniform float3 eyePosWorld; +uniform float3 sunVec; +uniform float2 texOffset0; +uniform float2 texOffset1; +uniform float2 texOffset2; +uniform float3 texScale; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( CloudVert IN ) +{ + ConnectData OUT; + + OUT.hpos = mul(modelview, float4(IN.pos,1.0)); + // Offset the uv so we don't have a seam directly over our head. + float2 uv = IN.uv0 + float2( 0.5, 0.5 ); + + OUT.texCoord12.xy = uv * texScale.x; + OUT.texCoord12.xy += texOffset0; + + OUT.texCoord12.zw = uv * texScale.y; + OUT.texCoord12.zw += texOffset1; + + OUT.texCoord34.xy = uv * texScale.z; + OUT.texCoord34.xy += texOffset2; + + OUT.texCoord34.z = IN.pos.z; + OUT.texCoord34.w = 0.0; + + // Transform the normal, tangent and binormal vectors from object space to + // homogeneous projection space: + float3 vNormalWS = -IN.normal; + float3 vTangentWS = -IN.tangent; + float3 vBinormalWS = -IN.binormal; + + // Compute position in world space: + float4 vPositionWS = float4(IN.pos, 1.0) + float4(eyePosWorld, 1); //mul( IN.pos, objTrans ); + + // Compute and output the world view vector (unnormalized): + float3 vViewWS = eyePosWorld - vPositionWS.xyz; + + // Compute denormalized light vector in world space: + float3 vLightWS = -sunVec; + + // Normalize the light and view vectors and transform it to the tangent space: + float3x3 mWorldToTangent = float3x3( vTangentWS, vBinormalWS, vNormalWS ); + + // Propagate the view and the light vectors (in tangent space): + OUT.vLightTS = mul( vLightWS, mWorldToTangent ); + OUT.vViewTS = mul( mWorldToTangent, vViewWS ); + + OUT.worldDist = saturate( pow( max( IN.pos.z, 0 ), 2 ) ); + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/addColorTextureP.hlsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/addColorTextureP.hlsl new file mode 100644 index 000000000..d0577428f --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/addColorTextureP.hlsl @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../shaderModel.hlsl" + +struct Conn +{ + float4 HPOS : TORQUE_POSITION; + float4 color : COLOR; + float2 texCoord : TEXCOORD0; +}; + +TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0); + +float4 main( Conn IN ) : TORQUE_TARGET0 +{ + return float4(IN.color.rgb, IN.color.a * TORQUE_TEX2D(diffuseMap, IN.texCoord).a); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/addColorTextureV.hlsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/addColorTextureV.hlsl new file mode 100644 index 000000000..8bf4e88d8 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/addColorTextureV.hlsl @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../shaderModel.hlsl" + +struct Appdata +{ + float3 position : POSITION; + float4 color : COLOR; + float2 texCoord : TEXCOORD0; +}; + +struct Conn +{ + float4 HPOS : TORQUE_POSITION; + float4 color : COLOR; + float2 texCoord : TEXCOORD0; +}; + +uniform float4x4 modelview; + +Conn main( Appdata In ) +{ + Conn Out; + Out.HPOS = mul(modelview, float4(In.position,1.0)); + Out.color = In.color; + Out.texCoord = In.texCoord; + return Out; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/colorP.hlsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/colorP.hlsl new file mode 100644 index 000000000..dd9990e07 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/colorP.hlsl @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../shaderModel.hlsl" + +struct Conn +{ + float4 HPOS : TORQUE_POSITION; + float4 color : COLOR; +}; + +float4 main(Conn IN) : TORQUE_TARGET0 +{ + return IN.color; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/colorV.hlsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/colorV.hlsl new file mode 100644 index 000000000..d16dfb863 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/colorV.hlsl @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../shaderModel.hlsl" + +struct Appdata +{ + float3 position : POSITION; + float4 color : COLOR; +}; + +struct Conn +{ + float4 HPOS : TORQUE_POSITION; + float4 color : COLOR; +}; + +uniform float4x4 modelview; + +Conn main( Appdata In ) +{ + Conn Out; + Out.HPOS = mul(modelview, float4(In.position,1.0)); + Out.color = In.color; + return Out; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/addColorTextureP.glsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/addColorTextureP.glsl new file mode 100644 index 000000000..b9a10adf3 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/addColorTextureP.glsl @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +uniform sampler2D diffuseMap; +in vec4 color; +in vec2 texCoord; + +out vec4 OUT_col; + +void main() +{ + OUT_col = vec4(color.rgb, color.a * texture(diffuseMap, texCoord).a); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/addColorTextureV.glsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/addColorTextureV.glsl new file mode 100644 index 000000000..5d7f10168 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/addColorTextureV.glsl @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "../../gl/hlslCompat.glsl" + +in vec4 vPosition; +in vec4 vColor; +in vec2 vTexCoord0; + +uniform mat4 modelview; +out vec4 color; +out vec2 texCoord; + +void main() +{ + gl_Position = tMul(modelview, vPosition); + correctSSP(gl_Position); + color = vColor; + texCoord = vTexCoord0.st; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/colorP.glsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/colorP.glsl new file mode 100644 index 000000000..f9dfc3d4f --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/colorP.glsl @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +in vec4 color; + +out vec4 OUT_col; + +void main() +{ + OUT_col = color; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/colorV.glsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/colorV.glsl new file mode 100644 index 000000000..895917b55 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/colorV.glsl @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "../../gl/hlslCompat.glsl" + +in vec4 vPosition; +in vec4 vColor; + +uniform mat4 modelview; +out vec4 color; + +void main() +{ + gl_Position = tMul(modelview, vPosition); + correctSSP(gl_Position); + color = vColor; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/modColorTextureP.glsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/modColorTextureP.glsl new file mode 100644 index 000000000..c24b9db12 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/modColorTextureP.glsl @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +uniform sampler2D diffuseMap; +in vec4 color; +in vec2 texCoord; + +out vec4 OUT_col; + +void main() +{ + OUT_col = texture(diffuseMap, texCoord) * color; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/modColorTextureV.glsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/modColorTextureV.glsl new file mode 100644 index 000000000..5d7f10168 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/modColorTextureV.glsl @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "../../gl/hlslCompat.glsl" + +in vec4 vPosition; +in vec4 vColor; +in vec2 vTexCoord0; + +uniform mat4 modelview; +out vec4 color; +out vec2 texCoord; + +void main() +{ + gl_Position = tMul(modelview, vPosition); + correctSSP(gl_Position); + color = vColor; + texCoord = vTexCoord0.st; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/targetRestoreP.glsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/targetRestoreP.glsl new file mode 100644 index 000000000..770f8904d --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/targetRestoreP.glsl @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +uniform sampler2D colorTarget0Texture ; + +vec4 main( vec2 ScreenPos : VPOS ) : COLOR0 +{ + vec2 TexCoord = ScreenPos; + vec4 diffuse; + asm { tfetch2D diffuse, TexCoord, colorTarget0Texture, UnnormalizedTextureCoords = true }; + return diffuse; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/targetRestoreV.glsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/targetRestoreV.glsl new file mode 100644 index 000000000..e99d2e537 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/targetRestoreV.glsl @@ -0,0 +1,22 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/textureP.glsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/textureP.glsl new file mode 100644 index 000000000..50cef4bda --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/textureP.glsl @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +uniform sampler2D diffuseMap; +in vec2 texCoord; + +out vec4 OUT_col; + +void main() +{ + OUT_col = texture(diffuseMap, texCoord); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/textureV.glsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/textureV.glsl new file mode 100644 index 000000000..20dbb6f10 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/gl/textureV.glsl @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "../../gl/hlslCompat.glsl" + +in vec4 vPosition; +in vec2 vTexCoord0; + +uniform mat4 modelview; +out vec2 texCoord; + +void main() +{ + gl_Position = tMul(modelview, vPosition); + correctSSP(gl_Position); + texCoord = vTexCoord0.st; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/modColorTextureP.hlsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/modColorTextureP.hlsl new file mode 100644 index 000000000..63afec2a4 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/modColorTextureP.hlsl @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../shaderModel.hlsl" + +struct Conn +{ + float4 HPOS : TORQUE_POSITION; + float4 color : COLOR; + float2 texCoord : TEXCOORD0; +}; + +TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0); + +float4 main( Conn IN ) : TORQUE_TARGET0 +{ + return TORQUE_TEX2D(diffuseMap, IN.texCoord) * IN.color; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/modColorTextureV.hlsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/modColorTextureV.hlsl new file mode 100644 index 000000000..8bf4e88d8 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/modColorTextureV.hlsl @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../shaderModel.hlsl" + +struct Appdata +{ + float3 position : POSITION; + float4 color : COLOR; + float2 texCoord : TEXCOORD0; +}; + +struct Conn +{ + float4 HPOS : TORQUE_POSITION; + float4 color : COLOR; + float2 texCoord : TEXCOORD0; +}; + +uniform float4x4 modelview; + +Conn main( Appdata In ) +{ + Conn Out; + Out.HPOS = mul(modelview, float4(In.position,1.0)); + Out.color = In.color; + Out.texCoord = In.texCoord; + return Out; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/targetRestoreP.hlsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/targetRestoreP.hlsl new file mode 100644 index 000000000..9ef44f426 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/targetRestoreP.hlsl @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +uniform sampler2D colorTarget0Texture : register(s0); + +float4 main( float2 ScreenPos : VPOS ) : COLOR0 +{ + float2 TexCoord = ScreenPos; + float4 diffuse; + asm { tfetch2D diffuse, TexCoord, colorTarget0Texture, UnnormalizedTextureCoords = true }; + return diffuse; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/targetRestoreV.hlsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/targetRestoreV.hlsl new file mode 100644 index 000000000..3c4aefaec --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/targetRestoreV.hlsl @@ -0,0 +1,26 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +float4 main( const float2 inPosition : POSITION ) : POSITION +{ + return float4( inPosition, 0, 1 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/textureP.hlsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/textureP.hlsl new file mode 100644 index 000000000..82dbd4ce9 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/textureP.hlsl @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../shaderModel.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0); + +struct Conn +{ + float4 hpos : TORQUE_POSITION; + float2 texCoord : TEXCOORD0; +}; + +float4 main(Conn IN) : TORQUE_TARGET0 +{ + return TORQUE_TEX2D(diffuseMap, IN.texCoord); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fixedFunction/textureV.hlsl b/Templates/BaseGame/game/data/shaders/common/fixedFunction/textureV.hlsl new file mode 100644 index 000000000..204cf9514 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fixedFunction/textureV.hlsl @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../shaderModel.hlsl" + +struct Appdata +{ + float3 position : POSITION; + float4 color : COLOR; + float2 texCoord : TEXCOORD0; +}; + +struct Conn +{ + float4 hpos : TORQUE_POSITION; + float2 texCoord : TEXCOORD0; +}; + +uniform float4x4 modelview; + +Conn main( Appdata In ) +{ + Conn Out; + Out.hpos = mul(modelview, float4(In.position, 1.0)); + Out.texCoord = In.texCoord; + return Out; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/foliage.hlsl b/Templates/BaseGame/game/data/shaders/common/foliage.hlsl new file mode 100644 index 000000000..9952c29d6 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/foliage.hlsl @@ -0,0 +1,186 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// CornerId corresponds to this arrangement +// from the perspective of the camera. +// +// 3 ---- 2 +// | | +// 0 ---- 1 +// + +#define MAX_COVERTYPES 8 + +uniform float2 gc_fadeParams; +uniform float2 gc_windDir; +uniform float3 gc_camRight; +uniform float3 gc_camUp; +uniform float4 gc_typeRects[MAX_COVERTYPES]; + +// .x = gust length +// .y = premultiplied simulation time and gust frequency +// .z = gust strength +uniform float3 gc_gustInfo; + +// .x = premultiplied simulation time and turbulance frequency +// .y = turbulance strength +uniform float2 gc_turbInfo; + + +static float sCornerRight[4] = { -0.5, 0.5, 0.5, -0.5 }; + +static float sCornerUp[4] = { 0, 0, 1, 1 }; + +static float sMovableCorner[4] = { 0, 0, 1, 1 }; + +static float2 sUVCornerExtent[4] = +{ + float2( 0, 1 ), + float2( 1, 1 ), + float2( 1, 0 ), + float2( 0, 0 ) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// The following wind effect was derived from the GPU Gems 3 chapter... +// +// "Vegetation Procedural Animation and Shading in Crysis" +// by Tiago Sousa, Crytek +// + +float2 smoothCurve( float2 x ) +{ + return x * x * ( 3.0 - 2.0 * x ); +} + +float2 triangleWave( float2 x ) +{ + return abs( frac( x + 0.5 ) * 2.0 - 1.0 ); +} + +float2 smoothTriangleWave( float2 x ) +{ + return smoothCurve( triangleWave( x ) ); +} + +float windTurbulence( float bbPhase, float frequency, float strength ) +{ + // We create the input value for wave generation from the frequency and phase. + float2 waveIn = bbPhase.xx + frequency.xx; + + // We use two square waves to generate the effect which + // is then scaled by the overall strength. + float2 waves = ( frac( waveIn.xy * float2( 1.975, 0.793 ) ) * 2.0 - 1.0 ); + waves = smoothTriangleWave( waves ); + + // Sum up the two waves into a single wave. + return ( waves.x + waves.y ) * strength; +} + +float2 windEffect( float bbPhase, + float2 windDirection, + float gustLength, + float gustFrequency, + float gustStrength, + float turbFrequency, + float turbStrength ) +{ + // Calculate the ambient wind turbulence. + float turbulence = windTurbulence( bbPhase, turbFrequency, turbStrength ); + + // We simulate the overall gust via a sine wave. + float gustPhase = clamp( sin( ( bbPhase - gustFrequency ) / gustLength ) , 0, 1 ); + float gustOffset = ( gustPhase * gustStrength ) + ( ( 0.2 + gustPhase ) * turbulence ); + + // Return the final directional wind effect. + return gustOffset.xx * windDirection.xy; +} + +void foliageProcessVert( inout float3 position, + inout float4 diffuse, + inout float4 texCoord, + inout float3 normal, + inout float3 T, + in float3 eyePos ) +{ + // Assign the normal and tagent values. + //normal = float3( 0, 0, 1 );//cross( gc_camUp, gc_camRight ); + T = gc_camRight; + + // Pull out local vars we need for work. + int corner = ( diffuse.a * 255.0f ) + 0.5f; + float2 size = texCoord.xy; + int type = texCoord.z; + + // The billboarding is based on the camera direction. + float3 rightVec = gc_camRight * sCornerRight[corner]; + float3 upVec = gc_camUp * sCornerUp[corner]; + + // Figure out the corner position. + float3 outPos = ( upVec * size.y ) + ( rightVec * size.x ); + float len = length( outPos.xyz ); + + // We derive the billboard phase used for wind calculations from its position. + float bbPhase = dot( position.xyz, 1 ); + + // Get the overall wind gust and turbulence effects. + float3 wind; + wind.xy = windEffect( bbPhase, + gc_windDir, + gc_gustInfo.x, gc_gustInfo.y, gc_gustInfo.z, + gc_turbInfo.x, gc_turbInfo.y ); + wind.z = 0; + + // Add the summed wind effect into the point. + outPos.xyz += wind.xyz * texCoord.w; + + // Do a simple spherical clamp to keep the foliage + // from stretching too much by wind effect. + outPos.xyz = normalize( outPos.xyz ) * len; + + // Move the point into world space. + position += outPos; + + // Grab the uv set and setup the texture coord. + float4 uvSet = gc_typeRects[type]; + texCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x ); + texCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y ); + + // Animate the normal to get lighting changes + // across the the wind swept foliage. + // + // TODO: Expose the 10x as a factor to control + // how much the wind effects the lighting on the grass. + // + normal.xy += wind.xy * ( 10.0 * texCoord.w ); + normal = normalize( normal ); + + // Get the alpha fade value. + + float fadeStart = gc_fadeParams.x; + float fadeEnd = gc_fadeParams.y; + const float fadeRange = fadeEnd - fadeStart; + + float dist = distance( eyePos, position.xyz ) - fadeStart; + diffuse.a = 1 - clamp( dist / fadeRange, 0, 1 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/fxFoliageReplicatorP.hlsl b/Templates/BaseGame/game/data/shaders/common/fxFoliageReplicatorP.hlsl new file mode 100644 index 000000000..a8bb68e28 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fxFoliageReplicatorP.hlsl @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "shdrConsts.h" +#include "shaderModel.hlsl" +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float2 outTexCoord : TEXCOORD0; + float4 color : COLOR0; + float4 groundAlphaCoeff : COLOR1; + float2 alphaLookup : TEXCOORD1; +}; + +struct Fragout +{ + float4 col : TORQUE_TARGET0; +}; + +TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0); +TORQUE_UNIFORM_SAMPLER2D(alphaMap, 1); + +uniform float4 groundAlpha; +uniform float4 ambient; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN ) +{ + Fragout OUT; + + float4 alpha = TORQUE_TEX2D(alphaMap, IN.alphaLookup); + OUT.col = float4( ambient.rgb * IN.lum.rgb, 1.0 ) * TORQUE_TEX2D(diffuseMap, IN.texCoord); + OUT.col.a = OUT.col.a * min(alpha, groundAlpha + IN.groundAlphaCoeff.x).x; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/fxFoliageReplicatorV.hlsl b/Templates/BaseGame/game/data/shaders/common/fxFoliageReplicatorV.hlsl new file mode 100644 index 000000000..70ec9ff4c --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/fxFoliageReplicatorV.hlsl @@ -0,0 +1,129 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- + +#include "shaderModel.hlsl" + +struct VertData +{ + float3 position : POSITION; + float3 normal : NORMAL; + float2 texCoord : TEXCOORD0; + float2 waveScale : TEXCOORD1; +}; + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float2 outTexCoord : TEXCOORD0; + float4 color : COLOR0; + float4 groundAlphaCoeff : COLOR1; + float2 alphaLookup : TEXCOORD1; +}; + +uniform float4x4 projection : register(C0); +uniform float4x4 world : register(C4); +uniform float GlobalSwayPhase : register(C8); +uniform float SwayMagnitudeSide : register(C9); +uniform float SwayMagnitudeFront : register(C10); +uniform float GlobalLightPhase : register(C11); +uniform float LuminanceMagnitude : register(C12); +uniform float LuminanceMidpoint : register(C13); +uniform float DistanceRange : register(C14); +uniform float3 CameraPos : register(C15); +uniform float TrueBillboard : register(C16); + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN ) +{ + ConnectData OUT; + + // Init a transform matrix to be used in the following steps + float4x4 trans = 0; + trans[0][0] = 1; + trans[1][1] = 1; + trans[2][2] = 1; + trans[3][3] = 1; + trans[0][3] = IN.position.x; + trans[1][3] = IN.position.y; + trans[2][3] = IN.position.z; + + // Billboard transform * world matrix + float4x4 o = world; + o = mul(o, trans); + + // Keep only the up axis result and position transform. + // This gives us "cheating" cylindrical billboarding. + o[0][0] = 1; + o[1][0] = 0; + o[2][0] = 0; + o[3][0] = 0; + o[0][1] = 0; + o[1][1] = 1; + o[2][1] = 0; + o[3][1] = 0; + + // Unless the user specified TrueBillboard, + // in which case we want the z axis to also be camera facing. + +#ifdef TRUE_BILLBOARD + + o[0][2] = 0; + o[1][2] = 0; + o[2][2] = 1; + o[3][2] = 0; + +#endif + + // Handle sway. Sway is stored in a texture coord. The x coordinate is the sway phase multiplier, + // the y coordinate determines if this vertex actually sways or not. + float xSway, ySway; + float wavePhase = GlobalSwayPhase * IN.waveScale.x; + sincos(wavePhase, ySway, xSway); + xSway = xSway * IN.waveScale.y * SwayMagnitudeSide; + ySway = ySway * IN.waveScale.y * SwayMagnitudeFront; + float4 p; + p = mul(o, float4(IN.normal.x + xSway, ySway, IN.normal.z, 1)); + + // Project the point + OUT.hpos = mul(projection, p); + + // Lighting + float Luminance = LuminanceMidpoint + LuminanceMagnitude * cos(GlobalLightPhase + IN.normal.y); + + // Alpha + float3 worldPos = IN.position; + float alpha = abs(distance(worldPos, CameraPos)) / DistanceRange; + alpha = clamp(alpha, 0.0f, 1.0f); //pass it through + + OUT.alphaLookup = float2(alpha, 0.0f); + OUT.groundAlphaCoeff = all(IN.normal.z); + OUT.outTexCoord = IN.texCoord; + OUT.color = float4(Luminance, Luminance, Luminance, 1.0f); + + return OUT; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/gl/basicCloudsP.glsl b/Templates/BaseGame/game/data/shaders/common/gl/basicCloudsP.glsl new file mode 100644 index 000000000..5b3f50519 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/basicCloudsP.glsl @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "torque.glsl" +#include "hlslCompat.glsl" + +//ConnectData +in vec2 texCoord; +#define IN_texCoord texCoord + + +uniform sampler2D diffuseMap ; + +out vec4 OUT_col; + +void main() +{ + vec4 col = texture( diffuseMap, IN_texCoord ); + OUT_col = hdrEncode( col ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/gl/basicCloudsV.glsl b/Templates/BaseGame/game/data/shaders/common/gl/basicCloudsV.glsl new file mode 100644 index 000000000..cccbafa8c --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/basicCloudsV.glsl @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "hlslCompat.glsl" + +//CloudVert +in vec4 vPosition; +in vec2 vTexCoord0; + +#define IN_pos vPosition +#define IN_uv0 vTexCoord0 + +uniform mat4 modelview; +uniform float accumTime; +uniform float texScale; +uniform vec2 texDirection; +uniform vec2 texOffset; + +out vec2 texCoord; +#define OUT_texCoord texCoord + +void main() +{ + gl_Position = tMul(modelview, IN_pos); + + vec2 uv = IN_uv0; + uv += texOffset; + uv *= texScale; + uv += accumTime * texDirection; + + OUT_texCoord = uv; + + correctSSP(gl_Position); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/gl/blurP.glsl b/Templates/BaseGame/game/data/shaders/common/gl/blurP.glsl new file mode 100644 index 000000000..a27538762 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/blurP.glsl @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//***************************************************************************** +// Glow Shader +//***************************************************************************** +uniform vec4 kernel; +uniform sampler2D diffuseMap; + +in vec2 texc0, texc1, texc2, texc3; + +out vec4 OUT_col; + +void main() +{ + OUT_col = texture(diffuseMap, texc0) * kernel.x; + OUT_col += texture(diffuseMap, texc1) * kernel.y; + OUT_col += texture(diffuseMap, texc2) * kernel.z; + OUT_col += texture(diffuseMap, texc3) * kernel.w; +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/blurV.glsl b/Templates/BaseGame/game/data/shaders/common/gl/blurV.glsl new file mode 100644 index 000000000..1bfb0cd1b --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/blurV.glsl @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//***************************************************************************** +// Glow shader +//***************************************************************************** + +in vec4 vPosition; +in vec4 vColor; +in vec2 vTexCoord0; + +uniform mat4 modelview; +uniform vec2 offset0, offset1, offset2, offset3; + +out vec2 texc0, texc1, texc2, texc3; + +void main() +{ + gl_Position = modelview * vPosition; + + vec2 tc = vTexCoord0.st; + tc.y = 1.0 - tc.y; + + texc0 = tc + offset0; + texc1 = tc + offset1; + texc2 = tc + offset2; + texc3 = tc + offset3; + gl_Position.y *= -1; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/gl/cloudLayerP.glsl b/Templates/BaseGame/game/data/shaders/common/gl/cloudLayerP.glsl new file mode 100644 index 000000000..877a132da --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/cloudLayerP.glsl @@ -0,0 +1,147 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "hlslCompat.glsl" +#include "torque.glsl" +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +//ConnectData +in vec4 texCoord12; +#define IN_texCoord12 texCoord12 +in vec4 texCoord34; +#define IN_texCoord34 texCoord34 +in vec3 vLightTS; // light vector in tangent space, denormalized +#define IN_vLightTS vLightTS +in vec3 vViewTS; // view vector in tangent space, denormalized +#define IN_vViewTS vViewTS +in float worldDist; +#define IN_worldDist worldDist + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform sampler2D normalHeightMap; +uniform vec3 ambientColor; +uniform vec3 sunColor; +uniform float cloudCoverage; +uniform vec3 cloudBaseColor; +uniform float cloudExposure; + +out vec4 OUT_col; + +//----------------------------------------------------------------------------- +// Globals +//----------------------------------------------------------------------------- +// The per-color weighting to be used for luminance calculations in RGB order. +const vec3 LUMINANCE_VECTOR = vec3(0.2125f, 0.7154f, 0.0721f); + + +//----------------------------------------------------------------------------- +// Functions +//----------------------------------------------------------------------------- + +// Calculates the Rayleigh phase function +float getRayleighPhase( float angle ) +{ + return 0.75 * ( 1.0 + pow( angle, 2.0 ) ); +} + +// Returns the output rgb color given a texCoord and parameters it uses +// for lighting calculation. +vec3 ComputeIllumination( vec2 texCoord, + vec3 vLightTS, + vec3 vViewTS, + vec3 vNormalTS ) +{ + //return noiseNormal; + //return vNormalTS; + + vec3 vLightTSAdj = vec3( -vLightTS.x, -vLightTS.y, vLightTS.z ); + + float dp = dot( vNormalTS, vLightTSAdj ); + + // Calculate the amount of illumination (lightTerm)... + + // We do both a rim lighting effect and a halfLambertian lighting effect + // and combine the result. + float halfLambertTerm = clamp( pow( dp * 0.5 + 0.5, 1.0 ), 0.0, 1.0 ); + float rimLightTerm = pow( ( 1.0 - dp ), 1.0 ); + float lightTerm = clamp( halfLambertTerm * 1.0 + rimLightTerm * dp, 0.0, 1.0 ); + lightTerm *= 0.5; + + // Use a simple RayleighPhase function to simulate single scattering towards + // the camera. + float angle = dot( vLightTS, vViewTS ); + lightTerm *= getRayleighPhase( angle ); + + // Combine terms and colors into the output color. + //vec3 lightColor = ( lightTerm * sunColor * fOcclusionShadow ) + ambientColor; + vec3 lightColor = mix( ambientColor, sunColor, lightTerm ); + //lightColor = mix( lightColor, ambientColor, cloudCoverage ); + vec3 finalColor = cloudBaseColor * lightColor; + + return finalColor; +} + +void main() +{ + // Normalize the interpolated vectors: + vec3 vViewTS = normalize( vViewTS ); + vec3 vLightTS = normalize( vLightTS ); + + vec4 cResultColor = vec4( 0, 0, 0, 1 ); + + vec2 texSample = IN_texCoord12.xy; + + vec4 noise1 = texture( normalHeightMap, IN_texCoord12.zw ); + noise1 = normalize( ( noise1 - 0.5 ) * 2.0 ); + //return noise1; + + vec4 noise2 = texture( normalHeightMap, IN_texCoord34.xy ); + noise2 = normalize( ( noise2 - 0.5 ) * 2.0 ); + //return noise2; + + vec3 noiseNormal = normalize( noise1 + noise2 ).xyz; + //return vec4( noiseNormal, 1.0 ); + + float noiseHeight = noise1.a * noise2.a * ( cloudCoverage / 2.0 + 0.5 ); + + vec3 vNormalTS = normalize( texture( normalHeightMap, texSample ).xyz * 2.0 - 1.0 ); + vNormalTS += noiseNormal; + vNormalTS = normalize( vNormalTS ); + + // Compute resulting color for the pixel: + cResultColor.rgb = ComputeIllumination( texSample, vLightTS, vViewTS, vNormalTS ); + + float coverage = ( cloudCoverage - 0.5 ) * 2.0; + cResultColor.a = texture( normalHeightMap, texSample ).a + coverage + noiseHeight; + + if ( cloudCoverage > -1.0 ) + cResultColor.a /= 1.0 + coverage; + + cResultColor.a = clamp( cResultColor.a * pow( saturate(cloudCoverage), 0.25 ), 0.0, 1.0 ); + + cResultColor.a = mix( cResultColor.a, 0.0, 1.0 - pow(IN_worldDist,2.0) ); + + OUT_col = hdrEncode(cResultColor); +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/cloudLayerV.glsl b/Templates/BaseGame/game/data/shaders/common/gl/cloudLayerV.glsl new file mode 100644 index 000000000..395c6f286 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/cloudLayerV.glsl @@ -0,0 +1,106 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "hlslCompat.glsl" + +in vec4 vPosition; +in vec3 vNormal; +in vec3 vBinormal; +in vec3 vTangent; +in vec2 vTexCoord0; + +out vec4 texCoord12; +#define OUT_texCoord12 texCoord12 +out vec4 texCoord34; +#define OUT_texCoord34 texCoord34 +out vec3 vLightTS; // light vector in tangent space, denormalized +#define OUT_vLightTS vLightTS +out vec3 vViewTS; // view vector in tangent space, denormalized +#define OUT_vViewTS vViewTS +out float worldDist; +#define OUT_worldDist worldDist + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform mat4 modelview; +uniform vec3 eyePosWorld; +uniform vec3 sunVec; +uniform vec2 texOffset0; +uniform vec2 texOffset1; +uniform vec2 texOffset2; +uniform vec3 texScale; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + vec4 IN_pos = vPosition; + vec3 IN_normal = vNormal; + vec3 IN_binormal = vBinormal; + vec3 IN_tangent = vTangent; + vec2 IN_uv0 = vTexCoord0.st; + + gl_Position = modelview * IN_pos; + + // Offset the uv so we don't have a seam directly over our head. + vec2 uv = IN_uv0 + vec2( 0.5, 0.5 ); + + OUT_texCoord12.xy = uv * texScale.x; + OUT_texCoord12.xy += texOffset0; + + OUT_texCoord12.zw = uv * texScale.y; + OUT_texCoord12.zw += texOffset1; + + OUT_texCoord34.xy = uv * texScale.z; + OUT_texCoord34.xy += texOffset2; + + OUT_texCoord34.z = IN_pos.z; + OUT_texCoord34.w = 0.0; + + // Transform the normal, tangent and binormal vectors from object space to + // homogeneous projection space: + vec3 vNormalWS = -IN_normal; + vec3 vTangentWS = -IN_tangent; + vec3 vBinormalWS = -IN_binormal; + + // Compute position in world space: + vec4 vPositionWS = IN_pos + vec4( eyePosWorld, 1 ); //tMul( IN_pos, objTrans ); + + // Compute and output the world view vector (unnormalized): + vec3 vViewWS = eyePosWorld - vPositionWS.xyz; + + // Compute denormalized light vector in world space: + vec3 vLightWS = -sunVec; + + // Normalize the light and view vectors and transform it to the IN_tangent space: + mat3 mWorldToTangent = mat3( vTangentWS, vBinormalWS, vNormalWS ); + + // Propagate the view and the light vectors (in tangent space): + OUT_vLightTS = vLightWS * mWorldToTangent; + OUT_vViewTS = mWorldToTangent * vViewWS; + + OUT_worldDist = clamp( pow( max( IN_pos.z, 0 ), 2 ), 0.0, 1.0 ); + + correctSSP(gl_Position); +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/foliage.glsl b/Templates/BaseGame/game/data/shaders/common/gl/foliage.glsl new file mode 100644 index 000000000..38b66e767 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/foliage.glsl @@ -0,0 +1,186 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// CornerId corresponds to this arrangement +// from the perspective of the camera. +// +// 3 ---- 2 +// | | +// 0 ---- 1 +// + +#define MAX_COVERTYPES 8 + +uniform vec3 gc_camRight; +uniform vec3 gc_camUp; +uniform vec4 gc_typeRects[MAX_COVERTYPES]; +uniform vec2 gc_fadeParams; +uniform vec2 gc_windDir; + +// .x = gust length +// .y = premultiplied simulation time and gust frequency +// .z = gust strength +uniform vec3 gc_gustInfo; + +// .x = premultiplied simulation time and turbulance frequency +// .y = turbulance strength +uniform vec2 gc_turbInfo; + + +const float sCornerRight[4] = float[]( -0.5, 0.5, 0.5, -0.5 ); + +const float sCornerUp[4] = float[]( 0, 0, 1, 1 ); + +const float sMovableCorner[4] = float[]( 0, 0, 1, 1 ); + +const vec2 sUVCornerExtent[4] = vec2[] +( + vec2( 0, 1 ), + vec2( 1, 1 ), + vec2( 1, 0 ), + vec2( 0, 0 ) +); + + +/////////////////////////////////////////////////////////////////////////////// +// The following wind effect was derived from the GPU Gems 3 chapter... +// +// "Vegetation Procedural Animation and Shading in Crysis" +// by Tiago Sousa, Crytek +// + +vec2 smoothCurve( vec2 x ) +{ + return x * x * ( 3.0 - 2.0 * x ); +} + +vec2 triangleWave( vec2 x ) +{ + return abs( fract( x + 0.5 ) * 2.0 - 1.0 ); +} + +vec2 smoothTriangleWave( vec2 x ) +{ + return smoothCurve( triangleWave( x ) ); +} + +float windTurbulence( float bbPhase, float frequency, float strength ) +{ + // We create the input value for wave generation from the frequency and phase. + vec2 waveIn = vec2( bbPhase + frequency ); + + // We use two square waves to generate the effect which + // is then scaled by the overall strength. + vec2 waves = ( fract( waveIn.xy * vec2( 1.975, 0.793 ) ) * 2.0 - 1.0 ); + waves = smoothTriangleWave( waves ); + + // Sum up the two waves into a single wave. + return ( waves.x + waves.y ) * strength; +} + +vec2 windEffect( float bbPhase, + vec2 windDirection, + float gustLength, + float gustFrequency, + float gustStrength, + float turbFrequency, + float turbStrength ) +{ + // Calculate the ambient wind turbulence. + float turbulence = windTurbulence( bbPhase, turbFrequency, turbStrength ); + + // We simulate the overall gust via a sine wave. + float gustPhase = clamp( sin( ( bbPhase - gustFrequency ) / gustLength ) , 0.0, 1.0 ); + float gustOffset = ( gustPhase * gustStrength ) + ( ( 0.2 + gustPhase ) * turbulence ); + + // Return the final directional wind effect. + return vec2(gustOffset) * windDirection.xy; +} + +void foliageProcessVert( inout vec3 position, + inout vec4 diffuse, + inout vec4 texCoord, + inout vec3 normal, + inout vec3 T, + in vec3 eyePos ) +{ + // Assign the normal and tagent values. + //normal = vec3( 0, 0, 1 );//cross( gc_camUp, gc_camRight ); + T = gc_camRight; + + // Pull out local vars we need for work. + int corner = int( ( diffuse.a * 255.0 ) + 0.5 ); + vec2 size = texCoord.xy; + int type = int( texCoord.z ); + + // The billboarding is based on the camera direction. + vec3 rightVec = gc_camRight * sCornerRight[corner]; + vec3 upVec = gc_camUp * sCornerUp[corner]; + + // Figure out the corner position. + vec3 outPos = ( upVec * size.y ) + ( rightVec * size.x ); + float len = length( outPos.xyz ); + + // We derive the billboard phase used for wind calculations from its position. + float bbPhase = dot( position.xyz, vec3( 1.0 ) ); + + // Get the overall wind gust and turbulence effects. + vec3 wind; + wind.xy = windEffect( bbPhase, + gc_windDir, + gc_gustInfo.x, gc_gustInfo.y, gc_gustInfo.z, + gc_turbInfo.x, gc_turbInfo.y ); + wind.z = 0.0; + + // Add the summed wind effect into the point. + outPos.xyz += wind.xyz * texCoord.w; + + // Do a simple spherical clamp to keep the foliage + // from stretching too much by wind effect. + outPos.xyz = normalize( outPos.xyz ) * len; + + // Move the point into world space. + position += outPos; + + // Grab the uv set and setup the texture coord. + vec4 uvSet = gc_typeRects[type]; + texCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x ); + texCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y ); + + // Animate the normal to get lighting changes + // across the the wind swept foliage. + // + // TODO: Expose the 10x as a factor to control + // how much the wind effects the lighting on the grass. + // + normal.xy += wind.xy * ( 10.0 * texCoord.w ); + normal = normalize( normal ); + + // Get the alpha fade value. + + float fadeStart = gc_fadeParams.x; + float fadeEnd = gc_fadeParams.y; + float fadeRange = fadeEnd - fadeStart; + + float dist = distance( eyePos, position.xyz ) - fadeStart; + diffuse.a = 1.0 - clamp( dist / fadeRange, 0.0, 1.0 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/fxFoliageReplicatorP.glsl b/Templates/BaseGame/game/data/shaders/common/gl/fxFoliageReplicatorP.glsl new file mode 100644 index 000000000..b4d591486 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/fxFoliageReplicatorP.glsl @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +uniform sampler2D diffuseMap, alphaMap; +uniform vec4 groundAlpha; + +in vec4 color, groundAlphaCoeff; +in vec2 outTexCoord, alphaLookup; + +out vec4 OUT_col; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + vec4 alpha = texture(alphaMap, alphaLookup); + OUT_col = color * texture(diffuseMap, outTexCoord); + OUT_col.a = OUT_col.a * min(alpha, groundAlpha + groundAlphaCoeff.x).x; +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/fxFoliageReplicatorV.glsl b/Templates/BaseGame/game/data/shaders/common/gl/fxFoliageReplicatorV.glsl new file mode 100644 index 000000000..c8dcf1ddb --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/fxFoliageReplicatorV.glsl @@ -0,0 +1,99 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +in vec4 vPosition; +in vec3 vNormal; +in vec4 vColor; +in vec2 vTexCoord0; +in vec2 vTexCoord1; +in vec2 vTexCoord2; + +uniform mat4 projection, world; +uniform vec3 CameraPos; +uniform float GlobalSwayPhase, SwayMagnitudeSide, SwayMagnitudeFront, + GlobalLightPhase, LuminanceMagnitude, LuminanceMidpoint, DistanceRange; + +out vec4 color, groundAlphaCoeff; +out vec2 outTexCoord, alphaLookup; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + // Init a transform matrix to be used in the following steps + mat4 trans = mat4(0.0); + trans[0][0] = 1.0; + trans[1][1] = 1.0; + trans[2][2] = 1.0; + trans[3][3] = 1.0; + trans[3][0] = vPosition.x; + trans[3][1] = vPosition.y; + trans[3][2] = vPosition.z; + + // Billboard transform * world matrix + mat4 o = world; + o = o * trans; + + // Keep only the up axis result and position transform. + // This gives us "cheating" cylindrical billboarding. + o[0][0] = 1.0; + o[0][1] = 0.0; + o[0][2] = 0.0; + o[0][3] = 0.0; + o[1][0] = 0.0; + o[1][1] = 1.0; + o[1][2] = 0.0; + o[1][3] = 0.0; + + // Handle sway. Sway is stored in a texture coord. The x coordinate is the sway phase multiplier, + // the y coordinate determines if this vertex actually sways or not. + float xSway, ySway; + float wavePhase = GlobalSwayPhase * vTexCoord1.x; + ySway = sin(wavePhase); + xSway = cos(wavePhase); + xSway = xSway * vTexCoord1.y * SwayMagnitudeSide; + ySway = ySway * vTexCoord1.y * SwayMagnitudeFront; + vec4 p; + p = o * vec4(vNormal.x + xSway, ySway, vNormal.z, 1.0); + + // Project the point + gl_Position = projection * p; + + // Lighting + float Luminance = LuminanceMidpoint + LuminanceMagnitude * cos(GlobalLightPhase + vNormal.y); + + // Alpha + vec3 worldPos = vec3(vPosition.x, vPosition.y, vPosition.z); + float alpha = abs(distance(worldPos, CameraPos)) / DistanceRange; + alpha = clamp(alpha, 0.0, 1.0); //pass it through + + alphaLookup = vec2(alpha, 0.0); + bool alphaCoeff = bool(vNormal.z); + groundAlphaCoeff = vec4(float(alphaCoeff)); + outTexCoord = vTexCoord0.st; + color = vec4(Luminance, Luminance, Luminance, 1.0); + gl_Position.y *= -1; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/gl/guiMaterialV.glsl b/Templates/BaseGame/game/data/shaders/common/gl/guiMaterialV.glsl new file mode 100644 index 000000000..de3845ee7 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/guiMaterialV.glsl @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +in vec4 vPosition; +in vec2 vTexCoord0; + +uniform mat4x4 modelview; + +out vec4 hpos; +out vec2 uv0; + + +void main() +{ + hpos = vec4( modelview * vPosition ); + gl_Position = hpos; + + uv0 = vTexCoord0.st; + gl_Position.y *= -1; +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/hlslCompat.glsl b/Templates/BaseGame/game/data/shaders/common/gl/hlslCompat.glsl new file mode 100644 index 000000000..c8fe73620 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/hlslCompat.glsl @@ -0,0 +1,103 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// These are some simple wrappers for simple +// HLSL compatibility. + +#define float4 vec4 +#define float3 vec3 +#define float2 vec2 + +#define half float +#define half2 vec2 +#define half3 vec3 +#define half4 vec4 + +#define float4x4 mat4 +#define float3x3 mat3 +#define float2x2 mat2 + +#define texCUBE texture +#define tex2D texture +#define tex1D texture +#define tex2Dproj textureProj +#define tex2Dlod( sampler, texCoord ) textureLod(sampler, texCoord.xy, texCoord.w) + +#define samplerCUBE samplerCube + +#define frac fract + +#define lerp mix + +void tSetMatrixRow(inout float3x3 m, int row, float3 value) +{ + m[0][row] = value.x; + m[1][row] = value.y; + m[2][row] = value.z; +} + +void tSetMatrixRow(inout float4x4 m, int row, float4 value) +{ + m[0][row] = value.x; + m[1][row] = value.y; + m[2][row] = value.z; + m[3][row] = value.w; +} + +#define tGetMatrix3Row(matrix, row) float3(matrix[0][row], matrix[1][row], matrix[2][row]) +#define tGetMatrix4Row(matrix, row) float4(matrix[0][row], matrix[1][row], matrix[2][row], matrix[3][row]) + +float3x3 float4x4to3x3(float4x4 m) +{ + return float3x3( vec3(m[0]).xyz, m[1].xyz, m[2].xyz); +} + +float3x3 float4x4to3x3_(float4x4 m) +{ + return float3x3( vec3(m[0]), m[1].xyz, m[2].xyz); +} + +mat4 mat4FromRow( float r0c0, float r0c1, float r0c2, float r0c3, + float r1c0, float r1c1, float r1c2, float r1c3, + float r2c0, float r2c1, float r2c2, float r2c3, + float r3c0, float r3c1, float r3c2, float r3c3 ) +{ + return mat4( r0c0, r1c0, r2c0, r3c0, + r0c1, r1c1, r2c1, r3c1, + r0c2, r1c2, r2c2, r3c2, + r0c3, r1c3, r2c3, r3c3 ); +} + + +#define saturate( val ) clamp( val, 0.0, 1.0 ) + +#define round( n ) (sign( n ) * floor( abs( n ) + 0.5 )) + +#define tMul(a, b) (a*b) + +#define inversesqrt( n ) inversesqrt( n ) + +#define correctSSP(vec) vec.y *= -1 + +#ifdef TORQUE_PIXEL_SHADER + void clip(float a) { if(a < 0) discard;} +#endif diff --git a/Templates/BaseGame/game/data/shaders/common/gl/imposter.glsl b/Templates/BaseGame/game/data/shaders/common/gl/imposter.glsl new file mode 100644 index 000000000..20bc62688 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/imposter.glsl @@ -0,0 +1,161 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "torque.glsl" + + +#define IMPOSTER_MAX_UVS 64 + + +void imposter_v( + // These parameters usually come from the vertex. + vec3 center, + int corner, + float halfSize, + vec3 imposterUp, + vec3 imposterRight, + + // These are from the imposter shader constant. + int numEquatorSteps, + int numPolarSteps, + float polarAngle, + bool includePoles, + + // Other shader constants. + vec3 camPos, + vec4 uvs[IMPOSTER_MAX_UVS], + + // The outputs of this function. + out vec3 outWsPosition, + out vec2 outTexCoord, + out mat3 outWorldToTangent + ) +{ + + float M_HALFPI_F = 1.57079632679489661923; + float M_PI_F = 3.14159265358979323846; + float M_2PI_F = 6.28318530717958647692; + + + float sCornerRight[4];// = float[]( -1.0, 1.0, 1.0, -1.0 ); + sCornerRight[0] = -1.0; + sCornerRight[1] = 1.0; + sCornerRight[2] = 1.0; + sCornerRight[3] = -1.0; + float sCornerUp[4];// = float[]( -1.0, -1.0, 1.0, 1.0 ); + sCornerUp[0] = -1.0; + sCornerUp[1] = -1.0; + sCornerUp[2] = 1.0; + sCornerUp[3] = 1.0; + vec2 sUVCornerExtent[4];// = vec2[](vec2( 0.0, 1.0 ), vec2( 1.0, 1.0 ), vec2( 1.0, 0.0 ), vec2( 0.0, 0.0 )); + sUVCornerExtent[0] = vec2( 0.0, 1.0 ); + sUVCornerExtent[1] = vec2( 1.0, 1.0 ); + sUVCornerExtent[2] = vec2( 1.0, 0.0 ); + sUVCornerExtent[3] = vec2( 0.0, 0.0 ); + + // TODO: This could all be calculated on the CPU. + float equatorStepSize = M_2PI_F / float( numEquatorSteps ); + float equatorHalfStep = ( equatorStepSize / 2.0 ) - 0.0001; + float polarStepSize = M_PI_F / float( numPolarSteps ); + float polarHalfStep = ( polarStepSize / 2.0 ) - 0.0001; + + // The vector between the camera and the billboard. + vec3 lookVec = normalize( camPos - center ); + + // Generate the camera up and right vectors from + // the object transform and camera forward. + vec3 camUp = imposterUp; + vec3 camRight = cross( -lookVec, camUp ); + + // The billboarding is based on the camera directions. + vec3 rightVec = camRight * sCornerRight[corner]; + vec3 upVec = camUp * sCornerUp[corner]; + + float lookPitch = acos( dot( imposterUp, lookVec ) ); + + // First check to see if we need to render the top billboard. + int index; + /* + if ( includePoles && ( lookPitch < polarAngle || lookPitch > sPi - polarAngle ) ) + { + index = numEquatorSteps * 3; + + // When we render the top/bottom billboard we always use + // a fixed vector that matches the rotation of the object. + rightVec = vec3( 1, 0, 0 ) * sCornerRight[corner]; + upVec = vec3( 0, 1, 0 ) * sCornerUp[corner]; + + if ( lookPitch > sPi - polarAngle ) + { + upVec = -upVec; + index++; + } + } + else + */ + { + // Calculate the rotation around the z axis then add the + // equator half step. This gets the images to switch a + // half step before the captured angle is met. + float lookAzimuth = atan( lookVec.y, lookVec.x ); + float azimuth = atan( imposterRight.y, imposterRight.x ); + float rotZ = ( lookAzimuth - azimuth ) + equatorHalfStep; + + // The y rotation is calculated from the look vector and + // the object up vector. + float rotY = lookPitch - polarHalfStep; + + // TODO: How can we do this without conditionals? + // Normalize the result to 0 to 2PI. + if ( rotZ < 0.0 ) + rotZ += M_2PI_F; + if ( rotZ > M_2PI_F ) + rotZ -= M_2PI_F; + if ( rotY < 0.0 ) + rotY += M_2PI_F; + if ( rotY > M_PI_F ) // Not M_2PI_F? + rotY -= M_2PI_F; + + float polarIdx = round( abs( rotY ) / polarStepSize ); + + // Get the index to the start of the right polar + // images for this viewing angle. + int numPolarOffset = int( float( numEquatorSteps ) * polarIdx ); + + // Calculate the final image index for lookup + // of the texture coords. + index = int( rotZ / equatorStepSize ) + numPolarOffset; + } + + // Generate the final world space position. + outWsPosition = center + ( upVec * halfSize ) + ( rightVec * halfSize ); + + // Grab the uv set and setup the texture coord. + vec4 uvSet = uvs[index]; + outTexCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x ); + outTexCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y ); + + // Needed for normal mapping and lighting. + outWorldToTangent[0] = vec3( 1, 0, 0 ); + outWorldToTangent[1] = vec3( 0, 1, 0 ); + outWorldToTangent[2] = vec3( 0, 0, -1 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/lighting.glsl b/Templates/BaseGame/game/data/shaders/common/gl/lighting.glsl new file mode 100644 index 000000000..804ab1e3b --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/lighting.glsl @@ -0,0 +1,249 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./torque.glsl" + +#ifndef TORQUE_SHADERGEN + +// These are the uniforms used by most lighting shaders. + +uniform vec4 inLightPos[3]; +uniform vec4 inLightInvRadiusSq; +uniform vec4 inLightColor[4]; + +#ifndef TORQUE_BL_NOSPOTLIGHT + uniform vec4 inLightSpotDir[3]; + uniform vec4 inLightSpotAngle; + uniform vec4 inLightSpotFalloff; +#endif + +uniform vec4 ambient; +#define ambientCameraFactor 0.3 +uniform float specularPower; +uniform vec4 specularColor; + +#endif // !TORQUE_SHADERGEN + + +void compute4Lights( vec3 wsView, + vec3 wsPosition, + vec3 wsNormal, + vec4 shadowMask, + + #ifdef TORQUE_SHADERGEN + + vec4 inLightPos[3], + vec4 inLightInvRadiusSq, + vec4 inLightColor[4], + vec4 inLightSpotDir[3], + vec4 inLightSpotAngle, + vec4 inLightSpotFalloff, + float specularPower, + vec4 specularColor, + + #endif // TORQUE_SHADERGEN + + out vec4 outDiffuse, + out vec4 outSpecular ) +{ + // NOTE: The light positions and spotlight directions + // are stored in SoA order, so inLightPos[0] is the + // x coord for all 4 lights... inLightPos[1] is y... etc. + // + // This is the key to fully utilizing the vector units and + // saving a huge amount of instructions. + // + // For example this change saved more than 10 instructions + // over a simple for loop for each light. + + int i; + + vec4 lightVectors[3]; + for ( i = 0; i < 3; i++ ) + lightVectors[i] = wsPosition[i] - inLightPos[i]; + + vec4 squareDists = vec4(0); + for ( i = 0; i < 3; i++ ) + squareDists += lightVectors[i] * lightVectors[i]; + + // Accumulate the dot product between the light + // vector and the normal. + // + // The normal is negated because it faces away from + // the surface and the light faces towards the + // surface... this keeps us from needing to flip + // the light vector direction which complicates + // the spot light calculations. + // + // We normalize the result a little later. + // + vec4 nDotL = vec4(0); + for ( i = 0; i < 3; i++ ) + nDotL += lightVectors[i] * -wsNormal[i]; + + vec4 rDotL = vec4(0); + #ifndef TORQUE_BL_NOSPECULAR + + // We're using the Phong specular reflection model + // here where traditionally Torque has used Blinn-Phong + // which has proven to be more accurate to real materials. + // + // We do so because its cheaper as do not need to + // calculate the half angle for all 4 lights. + // + // Advanced Lighting still uses Blinn-Phong, but the + // specular reconstruction it does looks fairly similar + // to this. + // + vec3 R = reflect( wsView, -wsNormal ); + + for ( i = 0; i < 3; i++ ) + rDotL += lightVectors[i] * R[i]; + + #endif + + // Normalize the dots. + // + // Notice we're using the half type here to get a + // much faster sqrt via the rsq_pp instruction at + // the loss of some precision. + // + // Unless we have some extremely large point lights + // i don't believe the precision loss will matter. + // + half4 correction = half4(inversesqrt( squareDists )); + nDotL = saturate( nDotL * correction ); + rDotL = clamp( rDotL * correction, 0.00001, 1.0 ); + + // First calculate a simple point light linear + // attenuation factor. + // + // If this is a directional light the inverse + // radius should be greater than the distance + // causing the attenuation to have no affect. + // + vec4 atten = saturate( 1.0 - ( squareDists * inLightInvRadiusSq ) ); + + #ifndef TORQUE_BL_NOSPOTLIGHT + + // The spotlight attenuation factor. This is really + // fast for what it does... 6 instructions for 4 spots. + + vec4 spotAtten = vec4(0); + for ( i = 0; i < 3; i++ ) + spotAtten += lightVectors[i] * inLightSpotDir[i]; + + vec4 cosAngle = ( spotAtten * correction ) - inLightSpotAngle; + atten *= saturate( cosAngle * inLightSpotFalloff ); + + #endif + + // Finally apply the shadow masking on the attenuation. + atten *= shadowMask; + + // Get the final light intensity. + vec4 intensity = nDotL * atten; + + // Combine the light colors for output. + outDiffuse = vec4(0); + for ( i = 0; i < 4; i++ ) + outDiffuse += intensity[i] * inLightColor[i]; + + // Output the specular power. + vec4 specularIntensity = pow( rDotL, vec4(specularPower) ) * atten; + + // Apply the per-light specular attenuation. + vec4 specular = vec4(0,0,0,1); + for ( i = 0; i < 4; i++ ) + specular += vec4( inLightColor[i].rgb * inLightColor[i].a * specularIntensity[i], 1 ); + + // Add the final specular intensity values together + // using a single dot product operation then get the + // final specular lighting color. + outSpecular = specularColor * specular; +} + + +// This value is used in AL as a constant power to raise specular values +// to, before storing them into the light info buffer. The per-material +// specular value is then computer by using the integer identity of +// exponentiation: +// +// (a^m)^n = a^(m*n) +// +// or +// +// (specular^constSpecular)^(matSpecular/constSpecular) = specular^(matSpecular*constSpecular) +// +#define AL_ConstantSpecularPower 12.0f + +/// The specular calculation used in Advanced Lighting. +/// +/// @param toLight Normalized vector representing direction from the pixel +/// being lit, to the light source, in world space. +/// +/// @param normal Normalized surface normal. +/// +/// @param toEye The normalized vector representing direction from the pixel +/// being lit to the camera. +/// +float AL_CalcSpecular( vec3 toLight, vec3 normal, vec3 toEye ) +{ + // (R.V)^c + float specVal = dot( normalize( -reflect( toLight, normal ) ), toEye ); + + // Return the specular factor. + return pow( max( specVal, 0.00001f ), AL_ConstantSpecularPower ); +} + +/// The output for Deferred Lighting +/// +/// @param toLight Normalized vector representing direction from the pixel +/// being lit, to the light source, in world space. +/// +/// @param normal Normalized surface normal. +/// +/// @param toEye The normalized vector representing direction from the pixel +/// being lit to the camera. +/// +vec4 AL_DeferredOutput( + vec3 lightColor, + vec3 diffuseColor, + vec4 matInfo, + vec4 ambient, + float specular, + float shadowAttenuation) +{ + vec3 specularColor = vec3(specular); + bool metalness = getFlag(matInfo.r, 3); + if ( metalness ) + { + specularColor = 0.04 * (1 - specular) + diffuseColor * specular; + } + + //specular = color * map * spec^gloss + float specularOut = (specularColor * matInfo.b * min(pow(max(specular,1.0f), max((matInfo.a / AL_ConstantSpecularPower),1.0f)),matInfo.a)).r; + + lightColor *= vec3(shadowAttenuation); + lightColor += ambient.rgb; + return vec4(lightColor.rgb, specularOut); +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/particleCompositeP.glsl b/Templates/BaseGame/game/data/shaders/common/gl/particleCompositeP.glsl new file mode 100644 index 000000000..e33c9bd97 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/particleCompositeP.glsl @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "torque.glsl" +#include "hlslCompat.glsl" + +in vec4 offscreenPos; +in vec4 backbufferPos; + +#define IN_offscreenPos offscreenPos +#define IN_backbufferPos backbufferPos + +uniform sampler2D colorSource; +uniform vec4 offscreenTargetParams; + +#ifdef TORQUE_LINEAR_DEPTH +#define REJECT_EDGES +uniform sampler2D edgeSource; +uniform vec4 edgeTargetParams; +#endif + +out vec4 OUT_col; + +void main() +{ + // Off-screen particle source screenspace position in XY + // Back-buffer screenspace position in ZW + vec4 ssPos = vec4(offscreenPos.xy / offscreenPos.w, backbufferPos.xy / backbufferPos.w); + + vec4 uvScene = ( ssPos + 1.0 ) / 2.0; + uvScene.yw = 1.0 - uvScene.yw; + uvScene.xy = viewportCoordToRenderTarget(uvScene.xy, offscreenTargetParams); + +#ifdef REJECT_EDGES + // Cut out particles along the edges, this will create the stencil mask + uvScene.zw = viewportCoordToRenderTarget(uvScene.zw, edgeTargetParams); + float edge = texture( edgeSource, uvScene.zw ).r; + clip( -edge ); +#endif + + // Sample offscreen target and return + OUT_col = texture( colorSource, uvScene.xy ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/gl/particleCompositeV.glsl b/Templates/BaseGame/game/data/shaders/common/gl/particleCompositeV.glsl new file mode 100644 index 000000000..8c8f840d1 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/particleCompositeV.glsl @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "hlslCompat.glsl" + +in vec2 vTexCoord0; +#define uvCoord vTexCoord0 + +out vec4 offscreenPos; +out vec4 backbufferPos; + +#define OUT_hpos gl_Position +#define OUT_offscreenPos offscreenPos +#define OUT_backbufferPos backbufferPos + +uniform vec4 screenRect; // point, extent + +void main() +{ + OUT_hpos = vec4(uvCoord.xy, 1.0, 1.0); + OUT_hpos.xy *= screenRect.zw; + OUT_hpos.xy += screenRect.xy; + + OUT_backbufferPos = OUT_hpos; + OUT_offscreenPos = OUT_hpos; + + correctSSP(gl_Position); +} + diff --git a/Templates/BaseGame/game/data/shaders/common/gl/particlesP.glsl b/Templates/BaseGame/game/data/shaders/common/gl/particlesP.glsl new file mode 100644 index 000000000..813e31a1d --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/particlesP.glsl @@ -0,0 +1,113 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "torque.glsl" +#include "hlslCompat.glsl" + +// With advanced lighting we get soft particles. +#ifdef TORQUE_LINEAR_DEPTH + #define SOFTPARTICLES +#endif + +#ifdef SOFTPARTICLES + + #include "shadergen:/autogenConditioners.h" + + uniform float oneOverSoftness; + uniform float oneOverFar; + uniform sampler2D prepassTex; + //uniform vec3 vEye; + uniform vec4 prePassTargetParams; +#endif + +#define CLIP_Z // TODO: Make this a proper macro + +in vec4 color; +in vec2 uv0; +in vec4 pos; + +#define IN_color color +#define IN_uv0 uv0 +#define IN_pos pos + +uniform sampler2D diffuseMap; + +uniform sampler2D paraboloidLightMap; + +vec4 lmSample( vec3 nrm ) +{ + bool calcBack = (nrm.z < 0.0); + if ( calcBack ) + nrm.z = nrm.z * -1.0; + + vec2 lmCoord; + lmCoord.x = (nrm.x / (2*(1 + nrm.z))) + 0.5; + lmCoord.y = 1-((nrm.y / (2*(1 + nrm.z))) + 0.5); + + + // If this is the back, offset in the atlas + if ( calcBack ) + lmCoord.x += 1.0; + + // Atlasing front and back maps, so scale + lmCoord.x *= 0.5; + + return texture(paraboloidLightMap, lmCoord); +} + + +uniform float alphaFactor; +uniform float alphaScale; + +out vec4 OUT_col; + +void main() +{ + float softBlend = 1; + + #ifdef SOFTPARTICLES + vec2 tc = IN_pos.xy * vec2(1.0, -1.0) / IN_pos.w; + tc = viewportCoordToRenderTarget(saturate( ( tc + 1.0 ) * 0.5 ), prePassTargetParams); + + float sceneDepth = prepassUncondition( prepassTex, tc ).w; + float depth = IN_pos.w * oneOverFar; + float diff = sceneDepth - depth; + #ifdef CLIP_Z + // If drawing offscreen, this acts as the depth test, since we don't line up with the z-buffer + // When drawing high-res, though, we want to be able to take advantage of hi-z + // so this is #ifdef'd out + //clip(diff); + #endif + softBlend = saturate( diff * oneOverSoftness ); + #endif + + vec4 diffuse = texture( diffuseMap, IN_uv0 ); + + //OUT_col = vec4( lmSample(vec3(0, 0, -1)).rgb, IN_color.a * diffuse.a * softBlend * alphaScale); + + // Scale output color by the alpha factor (turn LerpAlpha into pre-multiplied alpha) + vec3 colorScale = ( alphaFactor < 0.0 ? IN_color.rgb * diffuse.rgb : vec3( alphaFactor > 0.0 ? IN_color.a * diffuse.a * alphaFactor * softBlend : softBlend ) ); + + OUT_col = hdrEncode( vec4( IN_color.rgb * diffuse.rgb * colorScale, + IN_color.a * diffuse.a * softBlend * alphaScale ) ); +} + diff --git a/Templates/BaseGame/game/data/shaders/common/gl/particlesV.glsl b/Templates/BaseGame/game/data/shaders/common/gl/particlesV.glsl new file mode 100644 index 000000000..3d75a6fb6 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/particlesV.glsl @@ -0,0 +1,54 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "hlslCompat.glsl" + +in vec4 vPosition; +in vec4 vColor; +in vec2 vTexCoord0; + +#define In_pos vPosition +#define In_color vColor +#define In_uv0 vTexCoord0 + +out vec4 color; +out vec2 uv0; +out vec4 pos; + +#define OUT_hpos gl_Position +#define OUT_color color +#define OUT_uv0 uv0 +#define OUT_pos pos + +uniform mat4 modelViewProj; +uniform mat4 fsModelViewProj; + +void main() +{ + OUT_hpos = tMul( modelViewProj, In_pos ); + OUT_pos = tMul( fsModelViewProj, In_pos ); + OUT_color = In_color; + OUT_uv0 = In_uv0; + + correctSSP(gl_Position); +} + diff --git a/Templates/BaseGame/game/data/shaders/common/gl/planarReflectBumpP.glsl b/Templates/BaseGame/game/data/shaders/common/gl/planarReflectBumpP.glsl new file mode 100644 index 000000000..db4250487 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/planarReflectBumpP.glsl @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +uniform sampler2D diffuseMap, refractMap, bumpMap; +uniform vec4 shadeColor; + +in vec2 TEX0; +in vec4 TEX1; + +out vec4 OUT_col; + +//----------------------------------------------------------------------------- +// Fade edges of axis for texcoord passed in +//----------------------------------------------------------------------------- +float fadeAxis( float val ) +{ + // Fades from 1.0 to 0.0 when less than 0.1 + float fadeLow = clamp( val * 10.0, 0.0, 1.0 ); + + // Fades from 1.0 to 0.0 when greater than 0.9 + float fadeHigh = 1.0 - clamp( (val - 0.9) * 10.0, 0.0, 1.0 ); + + return fadeLow * fadeHigh; +} + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + vec3 bumpNorm = texture( bumpMap, TEX0 ).rgb * 2.0 - 1.0; + vec2 offset = vec2( bumpNorm.x, bumpNorm.y ); + vec4 texIndex = TEX1; + + // The fadeVal is used to "fade" the distortion at the edges of the screen. + // This is done so it won't sample the reflection texture out-of-bounds and create artifacts + // Note - this can be done more efficiently with a texture lookup + float fadeVal = fadeAxis( texIndex.x / texIndex.w ) * fadeAxis( texIndex.y / texIndex.w ); + + const float distortion = 0.2; + texIndex.xy += offset * distortion * fadeVal; + + vec4 diffuseColor = texture( diffuseMap, TEX0 ); + vec4 reflectColor = textureProj( refractMap, texIndex ); + + OUT_col = diffuseColor + reflectColor * diffuseColor.a; +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/planarReflectBumpV.glsl b/Templates/BaseGame/game/data/shaders/common/gl/planarReflectBumpV.glsl new file mode 100644 index 000000000..90bcd27d8 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/planarReflectBumpV.glsl @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +in vec4 vPosition; +in vec2 vTexCoord0; + +uniform mat4 modelview; + +out vec2 TEX0; +out vec4 TEX1; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + mat4 texGenTest = mat4(0.5, 0.0, 0.0, 0.0, + 0.0, -0.5, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.5, 0.5, 0.0, 1.0); + + gl_Position = modelview * vPosition; + + TEX0 = vTexCoord0.st; + + TEX1 = texGenTest * gl_Position; + TEX1.y = -TEX1.y; + gl_Position.y *= -1; +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/planarReflectP.glsl b/Templates/BaseGame/game/data/shaders/common/gl/planarReflectP.glsl new file mode 100644 index 000000000..384c16188 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/planarReflectP.glsl @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +uniform sampler2D diffuseMap, refractMap; +uniform vec4 shadeColor; + +in vec2 TEX0; +in vec4 TEX1; + +out vec4 OUT_col; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + vec4 diffuseColor = texture( diffuseMap, TEX0 ); + vec4 reflectColor = textureProj( refractMap, TEX1 ); + + OUT_col = diffuseColor + reflectColor * diffuseColor.a; +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/planarReflectV.glsl b/Templates/BaseGame/game/data/shaders/common/gl/planarReflectV.glsl new file mode 100644 index 000000000..ba2484f66 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/planarReflectV.glsl @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +in vec4 vPosition; +in vec2 vTexCoord0; + +uniform mat4 modelview; + +out vec2 TEX0; +out vec4 TEX1; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + mat4 texGenTest = mat4(0.5, 0.0, 0.0, 0.0, + 0.0, -0.5, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.5, 0.5, 0.0, 1.0); + + gl_Position = modelview * vPosition; + + TEX0 = vTexCoord0; + + TEX1 = texGenTest * gl_Position; + TEX1.y = -TEX1.y; + +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/precipP.glsl b/Templates/BaseGame/game/data/shaders/common/gl/precipP.glsl new file mode 100644 index 000000000..102d0b0aa --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/precipP.glsl @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +uniform sampler2D diffuseMap; + +in vec4 color; +in vec2 texCoord; + +out vec4 OUT_col; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + OUT_col = texture(diffuseMap, texCoord) * color; +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/precipV.glsl b/Templates/BaseGame/game/data/shaders/common/gl/precipV.glsl new file mode 100644 index 000000000..29f921630 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/precipV.glsl @@ -0,0 +1,54 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +in vec4 vPosition; +in vec2 vTexCoord0; + +uniform mat4 modelview; +uniform vec3 cameraPos, ambient; +uniform vec2 fadeStartEnd; + +out vec4 color; +out vec2 texCoord; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + gl_Position = modelview * vPosition; + texCoord = vTexCoord0.st; + color = vec4( ambient.r, ambient.g, ambient.b, 1.0 ); + + // Do we need to do a distance fade? + if ( fadeStartEnd.x < fadeStartEnd.y ) + { + + float distance = length( cameraPos - vPosition.xyz ); + color.a = abs( clamp( ( distance - fadeStartEnd.x ) / ( fadeStartEnd.y - fadeStartEnd.x ), 0.0, 1.0 ) - 1.0 ); + } + gl_Position.y *= -1; +} + diff --git a/Templates/BaseGame/game/data/shaders/common/gl/projectedShadowP.glsl b/Templates/BaseGame/game/data/shaders/common/gl/projectedShadowP.glsl new file mode 100644 index 000000000..9b0ff0d0b --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/projectedShadowP.glsl @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +in vec2 texCoord; +in vec4 color; +in float fade; + +out vec4 OUT_col; + +uniform sampler2D inputTex; +uniform vec4 ambient; + + +void main() +{ + float shadow = texture( inputTex, texCoord ).a * color.a; + OUT_col = ( ambient * shadow ) + ( 1 - shadow ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/projectedShadowV.glsl b/Templates/BaseGame/game/data/shaders/common/gl/projectedShadowV.glsl new file mode 100644 index 000000000..c8b6d2a92 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/projectedShadowV.glsl @@ -0,0 +1,49 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "hlslCompat.glsl" + +in vec4 vPosition; +in vec4 vColor; +in vec2 vTexCoord0; +in vec2 vTexCoord1; + +out vec2 texCoord; +out vec4 color; +out float fade; + +uniform mat4 modelview; +uniform float shadowLength; +uniform vec3 shadowCasterPosition; + +void main() +{ + gl_Position = modelview * vec4(vPosition.xyz, 1.0); + + color = vColor; + texCoord = vTexCoord0.st; + + float fromCasterDist = length(vPosition.xyz - shadowCasterPosition) - shadowLength; + fade = 1.0 - clamp( fromCasterDist / shadowLength , 0.0, 1.0 ); + + correctSSP(gl_Position); +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/scatterSkyP.glsl b/Templates/BaseGame/game/data/shaders/common/gl/scatterSkyP.glsl new file mode 100644 index 000000000..6d4e3ea75 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/scatterSkyP.glsl @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "torque.glsl" +#include "hlslCompat.glsl" + + +// Conn +in vec4 rayleighColor; +#define IN_rayleighColor rayleighColor +in vec4 mieColor; +#define IN_mieColor mieColor +in vec3 v3Direction; +#define IN_v3Direction v3Direction +in vec3 pos; +#define IN_pos pos + +uniform samplerCube nightSky ; +uniform vec4 nightColor; +uniform vec2 nightInterpAndExposure; +uniform float useCubemap; +uniform vec3 lightDir; +uniform vec3 sunDir; + +out vec4 OUT_col; + +void main() +{ + + float fCos = dot( lightDir, IN_v3Direction ) / length(IN_v3Direction); + float fCos2 = fCos*fCos; + + float g = -0.991; + float g2 = -0.991 * -0.991; + + float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(abs(1.0 + g2 - 2.0*g*fCos), 1.5); + + vec4 color = IN_rayleighColor + fMiePhase * IN_mieColor; + color.a = color.b; + + vec4 nightSkyColor = texture(nightSky, -v3Direction); + nightSkyColor = mix(nightColor, nightSkyColor, useCubemap); + + float fac = dot( normalize( pos ), sunDir ); + fac = max( nightInterpAndExposure.y, pow( clamp( fac, 0.0, 1.0 ), 2 ) ); + OUT_col = mix( color, nightSkyColor, nightInterpAndExposure.y ); + + OUT_col.a = 1; + + OUT_col = clamp(OUT_col, 0.0, 1.0); + + OUT_col = hdrEncode( OUT_col ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/scatterSkyV.glsl b/Templates/BaseGame/game/data/shaders/common/gl/scatterSkyV.glsl new file mode 100644 index 000000000..5780d2df9 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/scatterSkyV.glsl @@ -0,0 +1,154 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "hlslCompat.glsl" + +// The scale equation calculated by Vernier's Graphical Analysis +float vernierScale(float fCos) +{ + float x = 1.0 - fCos; + float x5 = x * 5.25; + float x5p6 = (-6.80 + x5); + float xnew = (3.83 + x * x5p6); + float xfinal = (0.459 + x * xnew); + float xfinal2 = -0.00287 + x * xfinal; + float outx = exp( xfinal2 ); + return 0.25 * outx; +} + +in vec4 vPosition; + +// This is the shader input vertex structure. +#define IN_position vPosition + +// This is the shader output data. +out vec4 rayleighColor; +#define OUT_rayleighColor rayleighColor +out vec4 mieColor; +#define OUT_mieColor mieColor +out vec3 v3Direction; +#define OUT_v3Direction v3Direction +out vec3 pos; +#define OUT_pos pos + +uniform mat4 modelView; +uniform vec4 misc; +uniform vec4 sphereRadii; +uniform vec4 scatteringCoeffs; +uniform vec3 camPos; +uniform vec3 lightDir; +uniform vec4 invWaveLength; +uniform vec4 colorize; + +vec3 desaturate(const vec3 color, const float desaturation) +{ + const vec3 gray_conv = vec3 (0.30, 0.59, 0.11); + return mix(color, vec3(dot(gray_conv , color)), desaturation); +} + +void main() +{ + // Pull some variables out: + float camHeight = misc.x; + float camHeightSqr = misc.y; + + float scale = misc.z; + float scaleOverScaleDepth = misc.w; + + float outerRadius = sphereRadii.x; + float outerRadiusSqr = sphereRadii.y; + + float innerRadius = sphereRadii.z; + float innerRadiusSqr = sphereRadii.w; + + float rayleighBrightness = scatteringCoeffs.x; // Kr * ESun + float rayleigh4PI = scatteringCoeffs.y; // Kr * 4 * PI + + float mieBrightness = scatteringCoeffs.z; // Km * ESun + float mie4PI = scatteringCoeffs.w; // Km * 4 * PI + + // Get the ray from the camera to the vertex, + // and its length (which is the far point of the ray + // passing through the atmosphere). + vec3 v3Pos = vec3(IN_position / 6378000.0);// / outerRadius; + vec3 newCamPos = vec3( 0, 0, camHeight ); + v3Pos.z += innerRadius; + vec3 v3Ray = v3Pos.xyz - newCamPos; + float fFar = length(v3Ray); + v3Ray /= fFar; + + // Calculate the ray's starting position, + // then calculate its scattering offset. + vec3 v3Start = newCamPos; + float fHeight = length(v3Start); + float fDepth = exp(scaleOverScaleDepth * (innerRadius - camHeight)); + float fStartAngle = dot(v3Ray, v3Start) / fHeight; + + float fStartOffset = fDepth * vernierScale( fStartAngle ); + + // Initialize the scattering loop variables. + float fSampleLength = fFar / 2.0; + float fScaledLength = fSampleLength * scale; + vec3 v3SampleRay = v3Ray * fSampleLength; + vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5; + + // Now loop through the sample rays + vec3 v3FrontColor = vec3(0.0, 0.0, 0.0); + for(int i=0; i<2; i++) + { + float fHeight = length(v3SamplePoint); + float fDepth = exp(scaleOverScaleDepth * (innerRadius - fHeight)); + float fLightAngle = dot(lightDir, v3SamplePoint) / fHeight; + float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight; + + float vscale3 = vernierScale( fCameraAngle ); + float vscale2 = vernierScale( fLightAngle ); + + float fScatter = (fStartOffset + fDepth*(vscale2 - vscale3)); + vec3 v3Attenuate = exp(-fScatter * (invWaveLength.xyz * rayleigh4PI + mie4PI)); + v3FrontColor += v3Attenuate * (fDepth * fScaledLength); + v3SamplePoint += v3SampleRay; + } + + // Finally, scale the Mie and Rayleigh colors + // and set up the varying variables for the pixel shader. + gl_Position = modelView * IN_position; + OUT_mieColor.rgb = v3FrontColor * mieBrightness; + OUT_mieColor.a = 1.0; + OUT_rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness); + OUT_rayleighColor.a = 1.0; + OUT_v3Direction = newCamPos - v3Pos.xyz; + OUT_pos = IN_position.xyz; + +#ifdef USE_COLORIZE + + OUT_rayleighColor.rgb = desaturate(OUT_rayleighColor.rgb, 1) * colorize.a; + + OUT_rayleighColor.r *= colorize.r; + OUT_rayleighColor.g *= colorize.g; + OUT_rayleighColor.b *= colorize.b; + +#endif + + correctSSP(gl_Position); +} + diff --git a/Templates/BaseGame/game/data/shaders/common/gl/torque.glsl b/Templates/BaseGame/game/data/shaders/common/gl/torque.glsl new file mode 100644 index 000000000..6e369bd5e --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/torque.glsl @@ -0,0 +1,339 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef _TORQUE_GLSL_ +#define _TORQUE_GLSL_ + + +float M_HALFPI_F = 1.57079632679489661923; +float M_PI_F = 3.14159265358979323846; +float M_2PI_F = 6.28318530717958647692; + +/// Calculate fog based on a start and end positions in worldSpace. +float computeSceneFog( vec3 startPos, + vec3 endPos, + float fogDensity, + float fogDensityOffset, + float fogHeightFalloff ) +{ + float f = length( startPos - endPos ) - fogDensityOffset; + float h = 1.0 - ( endPos.z * fogHeightFalloff ); + return exp( -fogDensity * f * h ); +} + + +/// Calculate fog based on a start and end position and a height. +/// Positions do not need to be in worldSpace but height does. +float computeSceneFog( vec3 startPos, + vec3 endPos, + float height, + float fogDensity, + float fogDensityOffset, + float fogHeightFalloff ) +{ + float f = length( startPos - endPos ) - fogDensityOffset; + float h = 1.0 - ( height * fogHeightFalloff ); + return exp( -fogDensity * f * h ); +} + + +/// Calculate fog based on a distance, height is not used. +float computeSceneFog( float dist, float fogDensity, float fogDensityOffset ) +{ + float f = dist - fogDensityOffset; + return exp( -fogDensity * f ); +} + + +/// Convert a vec4 uv in viewport space to render target space. +vec2 viewportCoordToRenderTarget( vec4 inCoord, vec4 rtParams ) +{ + vec2 outCoord = inCoord.xy / inCoord.w; + outCoord = ( outCoord * rtParams.zw ) + rtParams.xy; + return outCoord; +} + + +/// Convert a vec2 uv in viewport space to render target space. +vec2 viewportCoordToRenderTarget( vec2 inCoord, vec4 rtParams ) +{ + vec2 outCoord = ( inCoord * rtParams.zw ) + rtParams.xy; + return outCoord; +} + + +/// Convert a vec4 quaternion into a 3x3 matrix. +mat3x3 quatToMat( vec4 quat ) +{ + float xs = quat.x * 2.0; + float ys = quat.y * 2.0; + float zs = quat.z * 2.0; + + float wx = quat.w * xs; + float wy = quat.w * ys; + float wz = quat.w * zs; + + float xx = quat.x * xs; + float xy = quat.x * ys; + float xz = quat.x * zs; + + float yy = quat.y * ys; + float yz = quat.y * zs; + float zz = quat.z * zs; + + mat3x3 mat; + + mat[0][0] = 1.0 - (yy + zz); + mat[1][0] = xy - wz; + mat[2][0] = xz + wy; + + mat[0][1] = xy + wz; + mat[1][1] = 1.0 - (xx + zz); + mat[2][1] = yz - wx; + + mat[0][2] = xz - wy; + mat[1][2] = yz + wx; + mat[2][2] = 1.0 - (xx + yy); + + return mat; +} + + +/// The number of additional substeps we take when refining +/// the results of the offset parallax mapping function below. +/// +/// You should turn down the number of steps if your needing +/// more performance out of your parallax surfaces. Increasing +/// the number doesn't yeild much better results and is rarely +/// worth the additional cost. +/// +#define PARALLAX_REFINE_STEPS 3 + +/// Performs fast parallax offset mapping using +/// multiple refinement steps. +/// +/// @param texMap The texture map whos alpha channel we sample the parallax depth. +/// @param texCoord The incoming texture coordinate for sampling the parallax depth. +/// @param negViewTS The negative view vector in tangent space. +/// @param depthScale The parallax factor used to scale the depth result. +/// +vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale ) +{ + float depth = texture( texMap, texCoord ).a/(PARALLAX_REFINE_STEPS*2); + vec2 offset = negViewTS.xy * vec2( depth * depthScale )/vec2(PARALLAX_REFINE_STEPS*2); + + for ( int i=0; i < PARALLAX_REFINE_STEPS; i++ ) + { + depth = ( depth + texture( texMap, texCoord + offset ).a )/(PARALLAX_REFINE_STEPS*2); + offset = negViewTS.xy * vec2( depth * depthScale )/vec2(PARALLAX_REFINE_STEPS*2); + } + + return offset; +} + +/// Same as parallaxOffset but for dxtnm where depth is stored in the red channel instead of the alpha +vec2 parallaxOffsetDxtnm(sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale) +{ + float depth = texture(texMap, texCoord).r/(PARALLAX_REFINE_STEPS*2); + vec2 offset = negViewTS.xy * vec2(depth * depthScale)/vec2(PARALLAX_REFINE_STEPS*2); + + for (int i = 0; i < PARALLAX_REFINE_STEPS; i++) + { + depth = (depth + texture(texMap, texCoord + offset).r)/(PARALLAX_REFINE_STEPS*2); + offset = negViewTS.xy * vec2(depth * depthScale)/vec2(PARALLAX_REFINE_STEPS*2); + } + + return offset; +} + + +/// The maximum value for 16bit per component integer HDR encoding. +const float HDR_RGB16_MAX = 100.0; +/// The maximum value for 10bit per component integer HDR encoding. +const float HDR_RGB10_MAX = 4.0; + +/// Encodes an HDR color for storage into a target. +vec3 hdrEncode( vec3 _sample ) +{ + #if defined( TORQUE_HDR_RGB16 ) + + return _sample / HDR_RGB16_MAX; + + #elif defined( TORQUE_HDR_RGB10 ) + + return _sample / HDR_RGB10_MAX; + + #else + + // No encoding. + return _sample; + + #endif +} + +/// Encodes an HDR color for storage into a target. +vec4 hdrEncode( vec4 _sample ) +{ + return vec4( hdrEncode( _sample.rgb ), _sample.a ); +} + +/// Decodes an HDR color from a target. +vec3 hdrDecode( vec3 _sample ) +{ + #if defined( TORQUE_HDR_RGB16 ) + + return _sample * HDR_RGB16_MAX; + + #elif defined( TORQUE_HDR_RGB10 ) + + return _sample * HDR_RGB10_MAX; + + #else + + // No encoding. + return _sample; + + #endif +} + +/// Decodes an HDR color from a target. +vec4 hdrDecode( vec4 _sample ) +{ + return vec4( hdrDecode( _sample.rgb ), _sample.a ); +} + +/// Returns the luminance for an HDR pixel. +float hdrLuminance( vec3 _sample ) +{ + // There are quite a few different ways to + // calculate luminance from an rgb value. + // + // If you want to use a different technique + // then plug it in here. + // + + //////////////////////////////////////////////////////////////////////////// + // + // Max component luminance. + // + //float lum = max( _sample.r, max( _sample.g, _sample.b ) ); + + //////////////////////////////////////////////////////////////////////////// + // The perceptual relative luminance. + // + // See http://en.wikipedia.org/wiki/Luminance_(relative) + // + const vec3 RELATIVE_LUMINANCE = vec3( 0.2126, 0.7152, 0.0722 ); + float lum = dot( _sample, RELATIVE_LUMINANCE ); + + //////////////////////////////////////////////////////////////////////////// + // + // The average component luminance. + // + //const vec3 AVERAGE_LUMINANCE = vec3( 0.3333, 0.3333, 0.3333 ); + //float lum = dot( _sample, AVERAGE_LUMINANCE ); + + return lum; +} + +#ifdef TORQUE_PIXEL_SHADER +/// Called from the visibility feature to do screen +/// door transparency for fading of objects. +void fizzle(vec2 vpos, float visibility) +{ + // NOTE: The magic values below are what give us + // the nice even pattern during the fizzle. + // + // These values can be changed to get different + // patterns... some better than others. + // + // Horizontal Blinds - { vpos.x, 0.916, vpos.y, 0 } + // Vertical Lines - { vpos.x, 12.9898, vpos.y, 78.233 } + // + // I'm sure there are many more patterns here to + // discover for different effects. + + mat2x2 m = mat2x2( vpos.x, vpos.y, 0.916, 0.350 ); + if( (visibility - fract( determinant( m ) )) < 0 ) //if(a < 0) discard; + discard; +} +#endif //TORQUE_PIXEL_SHADER + +/// Basic assert macro. If the condition fails, then the shader will output color. +/// @param condition This should be a bvec[2-4]. If any items is false, condition is considered to fail. +/// @param color The color that should be outputted if the condition fails. +/// @note This macro will only work in the void main() method of a pixel shader. +#define assert(condition, color) { if(!any(condition)) { OUT_col = color; return; } } + +// Deferred Shading: Material Info Flag Check +bool getFlag(float flags, float num) +{ + float process = round(flags * 255); + float squareNum = pow(2.0, num); + return (mod(process, pow(2.0, squareNum)) >= squareNum); +} + +// #define TORQUE_STOCK_GAMMA +#ifdef TORQUE_STOCK_GAMMA +// Sample in linear space. Decodes gamma. +vec4 toLinear(vec4 tex) +{ + return tex; +} +// Encodes gamma. +vec4 toGamma(vec4 tex) +{ + return tex; +} +vec3 toLinear(vec3 tex) +{ + return tex; +} +// Encodes gamma. +vec3 toGamma(vec3 tex) +{ + return tex; +} +#else +// Sample in linear space. Decodes gamma. +vec4 toLinear(vec4 tex) +{ + return vec4(pow(abs(tex.rgb), vec3(2.2)), tex.a); +} +// Encodes gamma. +vec4 toGamma(vec4 tex) +{ + return vec4(pow(abs(tex.rgb), vec3(1.0/2.2)), tex.a); +} +// Sample in linear space. Decodes gamma. +vec3 toLinear(vec3 tex) +{ + return pow(abs(tex), vec3(2.2)); +} +// Encodes gamma. +vec3 toGamma(vec3 tex) +{ + return pow(abs(tex), vec3(1.0/2.2)); +} +#endif // + +#endif // _TORQUE_GLSL_ diff --git a/Templates/BaseGame/game/data/shaders/common/gl/wavesP.glsl b/Templates/BaseGame/game/data/shaders/common/gl/wavesP.glsl new file mode 100644 index 000000000..06c8a1a28 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/wavesP.glsl @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +uniform sampler2D diffMap; +uniform sampler2D bumpMap; +uniform samplerCube cubeMap; +uniform vec4 specularColor; +uniform float specularPower; +uniform vec4 ambient; +uniform float accumTime; + +in vec2 TEX0; +in vec4 outLightVec; +in vec3 outPos; +in vec3 outEyePos; + +out vec4 OUT_col; + +void main() +{ + vec2 texOffset; + float sinOffset1 = sin( accumTime * 1.5 + TEX0.y * 6.28319 * 3.0 ) * 0.03; + float sinOffset2 = sin( accumTime * 3.0 + TEX0.y * 6.28319 ) * 0.04; + + texOffset.x = TEX0.x + sinOffset1 + sinOffset2; + texOffset.y = TEX0.y + cos( accumTime * 3.0 + TEX0.x * 6.28319 * 2.0 ) * 0.05; + + vec4 bumpNorm = texture(bumpMap, texOffset) * 2.0 - 1.0; + vec4 diffuse = texture(diffMap, texOffset); + + OUT_col = diffuse * (clamp(dot(outLightVec.xyz, bumpNorm.xyz), 0.0, 1.0) + ambient); + + vec3 eyeVec = normalize(outEyePos - outPos); + vec3 halfAng = normalize(eyeVec + outLightVec.xyz); + float specular = clamp(dot(bumpNorm.xyz, halfAng), 0.0, 1.0) * outLightVec.w; + specular = pow(specular, specularPower); + OUT_col += specularColor * specular; +} diff --git a/Templates/BaseGame/game/data/shaders/common/gl/wind.glsl b/Templates/BaseGame/game/data/shaders/common/gl/wind.glsl new file mode 100644 index 000000000..0ddb492b9 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/gl/wind.glsl @@ -0,0 +1,101 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// +// A tip of the hat.... +// +// The following wind effects were derived from the GPU Gems +// 3 chapter "Vegetation Procedural Animation and Shading in Crysis" +// by Tiago Sousa of Crytek. +// + +vec4 smoothCurve( vec4 x ) +{ + return x * x * ( 3.0 - 2.0 * x ); +} + +vec4 triangleWave( vec4 x ) +{ + return abs( fract( x + 0.5 ) * 2.0 - 1.0 ); +} + +vec4 smoothTriangleWave( vec4 x ) +{ + return smoothCurve( triangleWave( x ) ); +} + +vec3 windTrunkBending( vec3 vPos, vec2 vWind, float fBendFactor ) +{ + // Smooth the bending factor and increase + // the near by height limit. + fBendFactor += 1.0; + fBendFactor *= fBendFactor; + fBendFactor = fBendFactor * fBendFactor - fBendFactor; + + // Displace the vert. + vec3 vNewPos = vPos; + vNewPos.xy += vWind * fBendFactor; + + // Limit the length which makes the bend more + // spherical and prevents stretching. + float fLength = length( vPos ); + vPos = normalize( vNewPos ) * fLength; + + return vPos; +} + +vec3 windBranchBending( vec3 vPos, + vec3 vNormal, + + float fTime, + float fWindSpeed, + + float fBranchPhase, + float fBranchAmp, + float fBranchAtten, + + float fDetailPhase, + float fDetailAmp, + float fDetailFreq, + + float fEdgeAtten ) +{ + float fVertPhase = dot( vPos, vec3( fDetailPhase + fBranchPhase ) ); + + vec2 vWavesIn = fTime + vec2( fVertPhase, fBranchPhase ); + + vec4 vWaves = ( fract( vWavesIn.xxyy * + vec4( 1.975, 0.793, 0.375, 0.193 ) ) * + 2.0 - 1.0 ) * fWindSpeed * fDetailFreq; + + vWaves = smoothTriangleWave( vWaves ); + + vec2 vWavesSum = vWaves.xz + vWaves.yw; + + // We want the branches to bend both up and down. + vWavesSum.y = 1.0 - ( vWavesSum.y * 2.0 ); + + vPos += vWavesSum.xxy * vec3( fEdgeAtten * fDetailAmp * vNormal.xy, + fBranchAtten * fBranchAmp ); + + return vPos; +} diff --git a/Templates/BaseGame/game/data/shaders/common/guiMaterialV.hlsl b/Templates/BaseGame/game/data/shaders/common/guiMaterialV.hlsl new file mode 100644 index 000000000..5d725338f --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/guiMaterialV.hlsl @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "hlslStructs.hlsl" +#include "shaderModel.hlsl" + +struct MaterialDecoratorConnectV +{ + float4 hpos : TORQUE_POSITION; + float2 uv0 : TEXCOORD0; +}; + +uniform float4x4 modelview : register(C0); + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +MaterialDecoratorConnectV main( VertexIn_PCT IN ) +{ + MaterialDecoratorConnectV OUT; + + OUT.hpos = mul(modelview, float4(IN.pos,1.0)); + OUT.uv0 = IN.uv0; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/hlslStructs.h b/Templates/BaseGame/game/data/shaders/common/hlslStructs.h new file mode 100644 index 000000000..6a57e4db7 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/hlslStructs.h @@ -0,0 +1,116 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// The purpose of this file is to get all of our HLSL structures into one place. +// Please use the structures here instead of redefining input and output structures +// in each shader file. If structures are added, please adhere to the naming convention. + +//------------------------------------------------------------------------------ +// Vertex Input Structures +// +// These structures map to FVFs/Vertex Declarations in Torque. See gfxStructs.h +//------------------------------------------------------------------------------ + +// Notes +// +// Position should be specified as a float4. Right now our vertex structures in +// the engine output float3s for position. This does NOT mean that the POSITION +// binding should be float3, because it will assign 0 to the w coordinate, which +// results in the vertex not getting translated when it is transformed. + +struct VertexIn_P +{ + float4 pos : POSITION; +}; + +struct VertexIn_PT +{ + float4 pos : POSITION; + float2 uv0 : TEXCOORD0; +}; + +struct VertexIn_PTTT +{ + float4 pos : POSITION; + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; +}; + +struct VertexIn_PC +{ + float4 pos : POSITION; + float4 color : DIFFUSE; +}; + +struct VertexIn_PNC +{ + float4 pos : POSITION; + float3 normal : NORMAL; + float4 color : DIFFUSE; +}; + +struct VertexIn_PCT +{ + float4 pos : POSITION; + float4 color : DIFFUSE; + float2 uv0 : TEXCOORD0; +}; + +struct VertexIn_PN +{ + float4 pos : POSITION; + float3 normal : NORMAL; +}; + +struct VertexIn_PNT +{ + float4 pos : POSITION; + float3 normal : NORMAL; + float2 uv0 : TEXCOORD0; +}; + +struct VertexIn_PNTT +{ + float4 pos : POSITION; + float3 normal : NORMAL; + float3 tangent : TANGENT; + float2 uv0 : TEXCOORD0; +}; + +struct VertexIn_PNCT +{ + float4 pos : POSITION; + float3 normal : NORMAL; + float4 color : DIFFUSE; + float2 uv0 : TEXCOORD0; +}; + +struct VertexIn_PNTTTB +{ + float4 pos : POSITION; + float3 normal : NORMAL; + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float3 T : TEXCOORD2; + float3 B : TEXCOORD3; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/hlslStructs.hlsl b/Templates/BaseGame/game/data/shaders/common/hlslStructs.hlsl new file mode 100644 index 000000000..ce0ca305c --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/hlslStructs.hlsl @@ -0,0 +1,114 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// The purpose of this file is to get all of our HLSL structures into one place. +// Please use the structures here instead of redefining input and output structures +// in each shader file. If structures are added, please adhere to the naming convention. + +//------------------------------------------------------------------------------ +// Vertex Input Structures +// +// These structures map to FVFs/Vertex Declarations in Torque. See gfxStructs.h +//------------------------------------------------------------------------------ + +// Notes +// +// Position should be specified as a float3 as our vertex structures in +// the engine output float3s for position. + +struct VertexIn_P +{ + float3 pos : POSITION; +}; + +struct VertexIn_PT +{ + float3 pos : POSITION; + float2 uv0 : TEXCOORD0; +}; + +struct VertexIn_PTTT +{ + float3 pos : POSITION; + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; +}; + +struct VertexIn_PC +{ + float3 pos : POSITION; + float4 color : DIFFUSE; +}; + +struct VertexIn_PNC +{ + float3 pos : POSITION; + float3 normal : NORMAL; + float4 color : DIFFUSE; +}; + +struct VertexIn_PCT +{ + float3 pos : POSITION; + float4 color : DIFFUSE; + float2 uv0 : TEXCOORD0; +}; + +struct VertexIn_PN +{ + float3 pos : POSITION; + float3 normal : NORMAL; +}; + +struct VertexIn_PNT +{ + float3 pos : POSITION; + float3 normal : NORMAL; + float2 uv0 : TEXCOORD0; +}; + +struct VertexIn_PNTT +{ + float3 pos : POSITION; + float3 normal : NORMAL; + float3 tangent : TANGENT; + float2 uv0 : TEXCOORD0; +}; + +struct VertexIn_PNCT +{ + float3 pos : POSITION; + float3 normal : NORMAL; + float4 color : DIFFUSE; + float2 uv0 : TEXCOORD0; +}; + +struct VertexIn_PNTTTB +{ + float3 pos : POSITION; + float3 normal : NORMAL; + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float3 T : TEXCOORD2; + float3 B : TEXCOORD3; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/imposter.hlsl b/Templates/BaseGame/game/data/shaders/common/imposter.hlsl new file mode 100644 index 000000000..bc700ba03 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/imposter.hlsl @@ -0,0 +1,149 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "torque.hlsl" + + +static float sCornerRight[4] = { -1, 1, 1, -1 }; +static float sCornerUp[4] = { -1, -1, 1, 1 }; +static float2 sUVCornerExtent[4] = +{ + float2( 0, 1 ), + float2( 1, 1 ), + float2( 1, 0 ), + float2( 0, 0 ) +}; + +#define IMPOSTER_MAX_UVS 64 + + +void imposter_v( + // These parameters usually come from the vertex. + float3 center, + int corner, + float halfSize, + float3 imposterUp, + float3 imposterRight, + + // These are from the imposter shader constant. + int numEquatorSteps, + int numPolarSteps, + float polarAngle, + bool includePoles, + + // Other shader constants. + float3 camPos, + float4 uvs[IMPOSTER_MAX_UVS], + + // The outputs of this function. + out float3 outWsPosition, + out float2 outTexCoord, + out float3x3 outWorldToTangent + ) +{ + // TODO: This could all be calculated on the CPU. + float equatorStepSize = M_2PI_F / numEquatorSteps; + float equatorHalfStep = ( equatorStepSize / 2.0 ) - 0.0001; + float polarStepSize = M_PI_F / numPolarSteps; + float polarHalfStep = ( polarStepSize / 2.0 ) - 0.0001; + + // The vector between the camera and the billboard. + float3 lookVec = normalize( camPos - center ); + + // Generate the camera up and right vectors from + // the object transform and camera forward. + float3 camUp = imposterUp; + float3 camRight = normalize( cross( -lookVec, camUp ) ); + + // The billboarding is based on the camera directions. + float3 rightVec = camRight * sCornerRight[corner]; + float3 upVec = camUp * sCornerUp[corner]; + + float lookPitch = acos( dot( imposterUp, lookVec ) ); + + // First check to see if we need to render the top billboard. + int index; + /* + if ( includePoles && ( lookPitch < polarAngle || lookPitch > sPi - polarAngle ) ) + { + index = numEquatorSteps * 3; + + // When we render the top/bottom billboard we always use + // a fixed vector that matches the rotation of the object. + rightVec = float3( 1, 0, 0 ) * sCornerRight[corner]; + upVec = float3( 0, 1, 0 ) * sCornerUp[corner]; + + if ( lookPitch > sPi - polarAngle ) + { + upVec = -upVec; + index++; + } + } + else + */ + { + // Calculate the rotation around the z axis then add the + // equator half step. This gets the images to switch a + // half step before the captured angle is met. + float lookAzimuth = atan2( lookVec.y, lookVec.x ); + float azimuth = atan2( imposterRight.y, imposterRight.x ); + float rotZ = ( lookAzimuth - azimuth ) + equatorHalfStep; + + // The y rotation is calculated from the look vector and + // the object up vector. + float rotY = lookPitch - polarHalfStep; + + // TODO: How can we do this without conditionals? + // Normalize the result to 0 to 2PI. + if ( rotZ < 0 ) + rotZ += M_2PI_F; + if ( rotZ > M_2PI_F ) + rotZ -= M_2PI_F; + if ( rotY < 0 ) + rotY += M_2PI_F; + if ( rotY > M_PI_F ) // Not M_2PI_F? + rotY -= M_2PI_F; + + float polarIdx = round( abs( rotY ) / polarStepSize ); + + // Get the index to the start of the right polar + // images for this viewing angle. + int numPolarOffset = numEquatorSteps * polarIdx; + + // Calculate the final image index for lookup + // of the texture coords. + index = ( rotZ / equatorStepSize ) + numPolarOffset; + } + + // Generate the final world space position. + outWsPosition = center + ( upVec * halfSize ) + ( rightVec * halfSize ); + + // Grab the uv set and setup the texture coord. + float4 uvSet = uvs[index]; + outTexCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x ); + outTexCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y ); + + // Needed for normal mapping and lighting. + outWorldToTangent[0] = float3( 1, 0, 0 ); + outWorldToTangent[1] = float3( 0, 1, 0 ); + outWorldToTangent[2] = float3( 0, 0, -1 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting.hlsl new file mode 100644 index 000000000..a41b8a873 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting.hlsl @@ -0,0 +1,249 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./torque.hlsl" + +#ifndef TORQUE_SHADERGEN + +// These are the uniforms used by most lighting shaders. + +uniform float4 inLightPos[3]; +uniform float4 inLightInvRadiusSq; +uniform float4 inLightColor[4]; + +#ifndef TORQUE_BL_NOSPOTLIGHT + uniform float4 inLightSpotDir[3]; + uniform float4 inLightSpotAngle; + uniform float4 inLightSpotFalloff; +#endif + +uniform float4 ambient; +#define ambientCameraFactor 0.3 +uniform float specularPower; +uniform float4 specularColor; + +#endif // !TORQUE_SHADERGEN + + +void compute4Lights( float3 wsView, + float3 wsPosition, + float3 wsNormal, + float4 shadowMask, + + #ifdef TORQUE_SHADERGEN + + float4 inLightPos[3], + float4 inLightInvRadiusSq, + float4 inLightColor[4], + float4 inLightSpotDir[3], + float4 inLightSpotAngle, + float4 inLightSpotFalloff, + float specularPower, + float4 specularColor, + + #endif // TORQUE_SHADERGEN + + out float4 outDiffuse, + out float4 outSpecular ) +{ + // NOTE: The light positions and spotlight directions + // are stored in SoA order, so inLightPos[0] is the + // x coord for all 4 lights... inLightPos[1] is y... etc. + // + // This is the key to fully utilizing the vector units and + // saving a huge amount of instructions. + // + // For example this change saved more than 10 instructions + // over a simple for loop for each light. + + int i; + + float4 lightVectors[3]; + for ( i = 0; i < 3; i++ ) + lightVectors[i] = wsPosition[i] - inLightPos[i]; + + float4 squareDists = 0; + for ( i = 0; i < 3; i++ ) + squareDists += lightVectors[i] * lightVectors[i]; + + // Accumulate the dot product between the light + // vector and the normal. + // + // The normal is negated because it faces away from + // the surface and the light faces towards the + // surface... this keeps us from needing to flip + // the light vector direction which complicates + // the spot light calculations. + // + // We normalize the result a little later. + // + float4 nDotL = 0; + for ( i = 0; i < 3; i++ ) + nDotL += lightVectors[i] * -wsNormal[i]; + + float4 rDotL = 0; + #ifndef TORQUE_BL_NOSPECULAR + + // We're using the Phong specular reflection model + // here where traditionally Torque has used Blinn-Phong + // which has proven to be more accurate to real materials. + // + // We do so because its cheaper as do not need to + // calculate the half angle for all 4 lights. + // + // Advanced Lighting still uses Blinn-Phong, but the + // specular reconstruction it does looks fairly similar + // to this. + // + float3 R = reflect( wsView, -wsNormal ); + + for ( i = 0; i < 3; i++ ) + rDotL += lightVectors[i] * R[i]; + + #endif + + // Normalize the dots. + // + // Notice we're using the half type here to get a + // much faster sqrt via the rsq_pp instruction at + // the loss of some precision. + // + // Unless we have some extremely large point lights + // i don't believe the precision loss will matter. + // + half4 correction = (half4)rsqrt( squareDists ); + nDotL = saturate( nDotL * correction ); + rDotL = clamp( rDotL * correction, 0.00001, 1.0 ); + + // First calculate a simple point light linear + // attenuation factor. + // + // If this is a directional light the inverse + // radius should be greater than the distance + // causing the attenuation to have no affect. + // + float4 atten = saturate( 1.0 - ( squareDists * inLightInvRadiusSq ) ); + + #ifndef TORQUE_BL_NOSPOTLIGHT + + // The spotlight attenuation factor. This is really + // fast for what it does... 6 instructions for 4 spots. + + float4 spotAtten = 0; + for ( i = 0; i < 3; i++ ) + spotAtten += lightVectors[i] * inLightSpotDir[i]; + + float4 cosAngle = ( spotAtten * correction ) - inLightSpotAngle; + atten *= saturate( cosAngle * inLightSpotFalloff ); + + #endif + + // Finally apply the shadow masking on the attenuation. + atten *= shadowMask; + + // Get the final light intensity. + float4 intensity = nDotL * atten; + + // Combine the light colors for output. + outDiffuse = 0; + for ( i = 0; i < 4; i++ ) + outDiffuse += intensity[i] * inLightColor[i]; + + // Output the specular power. + float4 specularIntensity = pow( rDotL, specularPower.xxxx ) * atten; + + // Apply the per-light specular attenuation. + float4 specular = float4(0,0,0,1); + for ( i = 0; i < 4; i++ ) + specular += float4( inLightColor[i].rgb * inLightColor[i].a * specularIntensity[i], 1 ); + + // Add the final specular intensity values together + // using a single dot product operation then get the + // final specular lighting color. + outSpecular = specularColor * specular; +} + + +// This value is used in AL as a constant power to raise specular values +// to, before storing them into the light info buffer. The per-material +// specular value is then computer by using the integer identity of +// exponentiation: +// +// (a^m)^n = a^(m*n) +// +// or +// +// (specular^constSpecular)^(matSpecular/constSpecular) = specular^(matSpecular*constSpecular) +// +#define AL_ConstantSpecularPower 12.0f + +/// The specular calculation used in Advanced Lighting. +/// +/// @param toLight Normalized vector representing direction from the pixel +/// being lit, to the light source, in world space. +/// +/// @param normal Normalized surface normal. +/// +/// @param toEye The normalized vector representing direction from the pixel +/// being lit to the camera. +/// +float AL_CalcSpecular( float3 toLight, float3 normal, float3 toEye ) +{ + // (R.V)^c + float specVal = dot( normalize( -reflect( toLight, normal ) ), toEye ); + + // Return the specular factor. + return pow( max( specVal, 0.00001f ), AL_ConstantSpecularPower ); +} + +/// The output for Deferred Lighting +/// +/// @param toLight Normalized vector representing direction from the pixel +/// being lit, to the light source, in world space. +/// +/// @param normal Normalized surface normal. +/// +/// @param toEye The normalized vector representing direction from the pixel +/// being lit to the camera. +/// +float4 AL_DeferredOutput( + float3 lightColor, + float3 diffuseColor, + float4 matInfo, + float4 ambient, + float specular, + float shadowAttenuation) +{ + float3 specularColor = float3(specular, specular, specular); + bool metalness = getFlag(matInfo.r, 3); + if ( metalness ) + { + specularColor = 0.04 * (1 - specular) + diffuseColor * specular; + } + + //specular = color * map * spec^gloss + float specularOut = (specularColor * matInfo.b * min(pow(abs(specular), max(( matInfo.a/ AL_ConstantSpecularPower),1.0f)),matInfo.a)).r; + + lightColor *= shadowAttenuation; + lightColor += ambient.rgb; + return float4(lightColor.rgb, specularOut); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/convexGeometryV.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/convexGeometryV.hlsl new file mode 100644 index 000000000..064fcffa6 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/convexGeometryV.hlsl @@ -0,0 +1,54 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../hlslStructs.hlsl" +#include "../../shaderModel.hlsl" + +struct VertData +{ + float3 pos : POSITION; + float4 color : COLOR; +}; + +struct ConvexConnectV +{ + float4 hpos : TORQUE_POSITION; + float4 wsEyeDir : TEXCOORD0; + float4 ssPos : TEXCOORD1; + float4 vsEyeDir : TEXCOORD2; +}; + +ConvexConnectV main( VertData IN, + uniform float4x4 modelview, + uniform float4x4 objTrans, + uniform float4x4 worldViewOnly, + uniform float3 eyePosWorld ) +{ + ConvexConnectV OUT; + + OUT.hpos = mul( modelview, float4(IN.pos,1.0) ); + OUT.wsEyeDir = mul(objTrans, float4(IN.pos, 1.0)) - float4(eyePosWorld, 0.0); + OUT.vsEyeDir = mul(worldViewOnly, float4(IN.pos, 1.0)); + OUT.ssPos = OUT.hpos; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgColorBufferP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgColorBufferP.hlsl new file mode 100644 index 000000000..ad3debbaf --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgColorBufferP.hlsl @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../postfx/postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(colorBufferTex,0); + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + return float4(TORQUE_TEX2D( colorBufferTex, IN.uv0 ).rgb, 1.0); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgDepthVisualizeP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgDepthVisualizeP.hlsl new file mode 100644 index 000000000..68df09a78 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgDepthVisualizeP.hlsl @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../postfx/postFx.hlsl" +#include "../../shaderModelAutoGen.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(prepassTex, 0); +TORQUE_UNIFORM_SAMPLER1D(depthViz, 1); + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float depth = TORQUE_PREPASS_UNCONDITION( prepassTex, IN.uv0 ).w; + return float4( TORQUE_TEX1D( depthViz, depth ).rgb, 1.0 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgGlowVisualizeP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgGlowVisualizeP.hlsl new file mode 100644 index 000000000..257383659 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgGlowVisualizeP.hlsl @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../postfx/postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(glowBuffer, 0); + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + return TORQUE_TEX2D(glowBuffer, IN.uv0); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgLightColorVisualizeP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgLightColorVisualizeP.hlsl new file mode 100644 index 000000000..ca6d8d677 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgLightColorVisualizeP.hlsl @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../shaderModelAutoGen.hlsl" +#include "../../postfx/postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(lightPrePassTex,0); + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float4 lightColor = TORQUE_TEX2D( lightPrePassTex, IN.uv0 ); + return float4( lightColor.rgb, 1.0 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgLightSpecularVisualizeP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgLightSpecularVisualizeP.hlsl new file mode 100644 index 000000000..072f07e00 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgLightSpecularVisualizeP.hlsl @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../postfx/postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(lightPrePassTex,0); + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float specular = TORQUE_TEX2D( lightPrePassTex, IN.uv0 ).a; + return float4( specular, specular, specular, 1.0 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgNormalVisualizeP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgNormalVisualizeP.hlsl new file mode 100644 index 000000000..4f31d2c53 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgNormalVisualizeP.hlsl @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../postfx/postFx.hlsl" +#include "../../shaderModelAutoGen.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(prepassTex, 0); + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float3 normal = TORQUE_PREPASS_UNCONDITION( prepassTex, IN.uv0 ).xyz; + return float4( ( normal + 1.0 ) * 0.5, 1.0 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgShadowVisualizeP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgShadowVisualizeP.hlsl new file mode 100644 index 000000000..b54833499 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgShadowVisualizeP.hlsl @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../shaderModel.hlsl" + +struct MaterialDecoratorConnectV +{ + float4 hpos : TORQUE_POSITION; + float2 uv0 : TEXCOORD0; +}; + +TORQUE_UNIFORM_SAMPLER2D(shadowMap, 0); +TORQUE_UNIFORM_SAMPLER1D(depthViz, 1); + +float4 main( MaterialDecoratorConnectV IN ) : TORQUE_TARGET0 +{ + float depth = saturate( TORQUE_TEX2D( shadowMap, IN.uv0 ).r ); + return float4( TORQUE_TEX1D( depthViz, depth ).rgb, 1 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgSpecMapVisualizeP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgSpecMapVisualizeP.hlsl new file mode 100644 index 000000000..eba38a879 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/dbgSpecMapVisualizeP.hlsl @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../postfx/postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(matinfoTex,0); + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float specular = TORQUE_TEX2D( matinfoTex, IN.uv0 ).b; + return float4( specular, specular, specular, 1.0 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/deferredClearGBufferP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/deferredClearGBufferP.hlsl new file mode 100644 index 000000000..cefebe8c7 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/deferredClearGBufferP.hlsl @@ -0,0 +1,54 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../shaderModel.hlsl" + +struct Conn +{ + float4 hpos : TORQUE_POSITION; +}; + +struct Fragout +{ + float4 col : TORQUE_TARGET0; + float4 col1 : TORQUE_TARGET1; + float4 col2 : TORQUE_TARGET2; +}; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( Conn IN ) +{ + Fragout OUT; + + // Clear Prepass Buffer ( Normals/Depth ); + OUT.col = float4(1.0, 1.0, 1.0, 1.0); + + // Clear Color Buffer. + OUT.col1 = float4(0.0, 0.0, 0.0, 1.0); + + // Clear Material Info Buffer. + OUT.col2 = float4(0.0, 0.0, 0.0, 1.0); + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/deferredClearGBufferV.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/deferredClearGBufferV.hlsl new file mode 100644 index 000000000..20ba4d509 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/deferredClearGBufferV.hlsl @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../shaderModel.hlsl" + +struct Appdata +{ + float3 pos : POSITION; + float4 color : COLOR; +}; + +struct Conn +{ + float4 hpos : TORQUE_POSITION; +}; + +uniform float4x4 modelview; + +Conn main( Appdata In ) +{ + Conn Out; + Out.hpos = float4(In.pos,1.0); + return Out; +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/deferredColorShaderP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/deferredColorShaderP.hlsl new file mode 100644 index 000000000..d91d2eb38 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/deferredColorShaderP.hlsl @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../shaderModel.hlsl" + +struct Fragout +{ + float4 col : TORQUE_TARGET0; + float4 col1 : TORQUE_TARGET1; + float4 col2 : TORQUE_TARGET2; +}; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ) +{ + Fragout OUT; + + OUT.col = float4(0.0, 0.0, 0.0, 0.0); + OUT.col1 = float4(1.0, 1.0, 1.0, 1.0); + + // Draw on color buffer. + OUT.col2 = float4(1.0, 0.0, 0.0, 1.0); + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/deferredShadingP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/deferredShadingP.hlsl new file mode 100644 index 000000000..338ebd8da --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/deferredShadingP.hlsl @@ -0,0 +1,54 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../shaderModelAutoGen.hlsl" +#include "../../postfx/postFx.hlsl" +#include "../../torque.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(colorBufferTex,0); +TORQUE_UNIFORM_SAMPLER2D(lightPrePassTex,1); +TORQUE_UNIFORM_SAMPLER2D(matInfoTex,2); +TORQUE_UNIFORM_SAMPLER2D(prepassTex,3); + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float4 lightBuffer = TORQUE_TEX2D( lightPrePassTex, IN.uv0 ); + float4 colorBuffer = TORQUE_TEX2D( colorBufferTex, IN.uv0 ); + float4 matInfo = TORQUE_TEX2D( matInfoTex, IN.uv0 ); + float specular = saturate(lightBuffer.a); + float depth = TORQUE_PREPASS_UNCONDITION( prepassTex, IN.uv0 ).w; + + if (depth>0.9999) + return float4(0,0,0,0); + + // Diffuse Color Altered by Metalness + bool metalness = getFlag(matInfo.r, 3); + if ( metalness ) + { + colorBuffer *= (1.0 - colorBuffer.a); + } + + colorBuffer += float4(specular, specular, specular, 1.0); + colorBuffer *= float4(lightBuffer.rgb, 1.0); + + return hdrEncode( float4(colorBuffer.rgb, 1.0) ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/farFrustumQuad.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/farFrustumQuad.hlsl new file mode 100644 index 000000000..543e21677 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/farFrustumQuad.hlsl @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "../../shaderModel.hlsl" + +struct FarFrustumQuadConnectV +{ + float4 hpos : TORQUE_POSITION; + float2 uv0 : TEXCOORD0; + float3 wsEyeRay : TEXCOORD1; + float3 vsEyeRay : TEXCOORD2; +}; + +struct FarFrustumQuadConnectP +{ + float4 hpos : TORQUE_POSITION; + float2 uv0 : TEXCOORD0; + float3 wsEyeRay : TEXCOORD1; + float3 vsEyeRay : TEXCOORD2; +}; + + +float2 getUVFromSSPos( float3 ssPos, float4 rtParams ) +{ + float2 outPos = ( ssPos.xy + 1.0 ) / 2.0; + outPos.y = 1.0 - outPos.y; + outPos = ( outPos * rtParams.zw ) + rtParams.xy; + return outPos; +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/farFrustumQuadV.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/farFrustumQuadV.hlsl new file mode 100644 index 000000000..0167d901a --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/farFrustumQuadV.hlsl @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../hlslStructs.hlsl" +#include "farFrustumQuad.hlsl" + + +FarFrustumQuadConnectV main( VertexIn_PNTT IN, + uniform float4 rtParams0 ) +{ + FarFrustumQuadConnectV OUT; + + OUT.hpos = float4( IN.uv0, 0, 1 ); + + // Get a RT-corrected UV from the SS coord + OUT.uv0 = getUVFromSSPos( OUT.hpos.xyz, rtParams0 ); + + // Interpolators will generate eye rays the + // from far-frustum corners. + OUT.wsEyeRay = IN.tangent; + OUT.vsEyeRay = IN.normal; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/convexGeometryV.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/convexGeometryV.glsl new file mode 100644 index 000000000..1807ac43f --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/convexGeometryV.glsl @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" + +in vec4 vPosition; + +#define IN_pos vPosition + +out vec4 wsEyeDir; +out vec4 ssPos; +out vec4 vsEyeDir; + +#define OUT_hpos gl_Position +#define OUT_wsEyeDir wsEyeDir +#define OUT_ssPos ssPos +#define OUT_vsEyeDir vsEyeDir + +uniform mat4 modelview; +uniform mat4 objTrans; +uniform mat4 worldViewOnly; +uniform vec3 eyePosWorld; + +void main() +{ + OUT_hpos = tMul( modelview, IN_pos ); + OUT_wsEyeDir = tMul( objTrans, IN_pos ) - vec4( eyePosWorld, 0.0 ); + OUT_vsEyeDir = tMul( worldViewOnly, IN_pos ); + OUT_ssPos = OUT_hpos; + + correctSSP(gl_Position); +} + diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgColorBufferP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgColorBufferP.glsl new file mode 100644 index 000000000..12962e798 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgColorBufferP.glsl @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" + +in vec2 uv0; +uniform sampler2D colorBufferTex; + +out vec4 OUT_FragColor0; + +void main() +{ + OUT_FragColor0 = vec4(texture( colorBufferTex, uv0 ).rgb, 1.0); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl new file mode 100644 index 000000000..6b9dd72ad --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" + +in vec2 uv0; +uniform sampler2D prepassTex; +uniform sampler1D depthViz; + +out vec4 OUT_col; + +void main() +{ + float depth = prepassUncondition( prepassTex, uv0 ).w; + OUT_col = vec4( texture( depthViz, depth ).rgb, 1.0 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgGlowVisualizeP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgGlowVisualizeP.glsl new file mode 100644 index 000000000..355e6ef53 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgGlowVisualizeP.glsl @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" + +in vec2 uv0; +uniform sampler2D glowBuffer; + +out vec4 OUT_FragColor0; + +void main() +{ + OUT_FragColor0 = texture(glowBuffer, uv0); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl new file mode 100644 index 000000000..3e7de5a66 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" + +in vec2 uv0; +uniform sampler2D lightPrePassTex; + +out vec4 OUT_col; + +void main() +{ + vec4 lightColor = texture( lightPrePassTex, uv0 ); + OUT_col = vec4( lightColor.rgb, 1.0 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl new file mode 100644 index 000000000..7b654c936 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" + +in vec2 uv0; +uniform sampler2D lightPrePassTex; + +out vec4 OUT_col; + +void main() +{ + float specular = texture( lightPrePassTex, uv0 ).a; + OUT_col = vec4( specular, specular, specular, 1.0 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl new file mode 100644 index 000000000..84ea4d3fb --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" + +in vec2 uv0; +uniform sampler2D prepassTex; + +out vec4 OUT_col; + +void main() +{ + vec3 normal = prepassUncondition( prepassTex, uv0 ).xyz; + OUT_col = vec4( ( normal + 1.0 ) * 0.5, 1.0 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl new file mode 100644 index 000000000..b51e7310a --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" + +in vec2 uv0; +uniform sampler2D shadowMap; +uniform sampler1D depthViz; + +out vec4 OUT_col; + +void main() +{ + float depth = saturate( texture( shadowMap, uv0 ).r ); + OUT_col = vec4( texture( depthViz, depth ).rgb, 1 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgSpecMapVisualizeP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgSpecMapVisualizeP.glsl new file mode 100644 index 000000000..3e5efd675 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/dbgSpecMapVisualizeP.glsl @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" + +in vec2 uv0; +uniform sampler2D matinfoTex; + +out vec4 OUT_FragColor0; + +void main() +{ + float specular = texture( matinfoTex, uv0 ).a; + OUT_FragColor0 = vec4( specular, specular, specular, 1.0 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/deferredClearGBufferP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/deferredClearGBufferP.glsl new file mode 100644 index 000000000..39dc0dc9f --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/deferredClearGBufferP.glsl @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +out vec4 OUT_col; +out vec4 OUT_col1; +out vec4 OUT_col2; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + // Clear Prepass Buffer ( Normals/Depth ); + OUT_col = vec4(1.0, 1.0, 1.0, 1.0); + + // Clear Color Buffer. + OUT_col1 = vec4(0.0, 0.0, 0.0, 1.0); + + // Clear Material Info Buffer. + OUT_col2 = vec4(0.0, 0.0, 0.0, 1.0); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/deferredColorShaderP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/deferredColorShaderP.glsl new file mode 100644 index 000000000..85c553089 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/deferredColorShaderP.glsl @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +layout (location = 0) out vec4 col; +layout (location = 1) out vec4 col1; +layout (location = 2) out vec4 col2; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + col = vec4(0.0, 0.0, 0.0, 0.0); + col1 = vec4(1.0, 1.0, 1.0, 1.0); + + // Draw on color buffer. + col2 = vec4(1.0, 0.0, 0.0, 1.0); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/deferredShadingP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/deferredShadingP.glsl new file mode 100644 index 000000000..ae01125af --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/deferredShadingP.glsl @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../../postFx/gl/postFX.glsl" +#include "../../../gl/torque.glsl" + +uniform sampler2D colorBufferTex; +uniform sampler2D lightPrePassTex; +uniform sampler2D matInfoTex; +uniform sampler2D prepassTex; + +out vec4 OUT_col; + +void main() +{ + float depth = prepassUncondition( prepassTex, uv0 ).w; + if (depth>0.9999) + { + OUT_col = vec4(0.0); + return; + } + vec4 lightBuffer = texture( lightPrePassTex, uv0 ); + vec4 colorBuffer = texture( colorBufferTex, uv0 ); + vec4 matInfo = texture( matInfoTex, uv0 ); + float specular = clamp(lightBuffer.a,0.0,1.0); + + // Diffuse Color Altered by Metalness + bool metalness = getFlag(matInfo.r, 3); + if ( metalness ) + { + colorBuffer *= (1.0 - colorBuffer.a); + } + + colorBuffer += vec4(specular, specular, specular, 1.0); + colorBuffer *= vec4(lightBuffer.rgb, 1.0); + + OUT_col = hdrEncode( vec4(colorBuffer.rgb, 1.0) ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/farFrustumQuad.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/farFrustumQuad.glsl new file mode 100644 index 000000000..76054eb09 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/farFrustumQuad.glsl @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +vec2 getUVFromSSPos( vec3 ssPos, vec4 rtParams ) +{ + vec2 outPos = ( ssPos.xy + 1.0 ) / 2.0; + outPos.y = 1.0 - outPos.y; + outPos = ( outPos * rtParams.zw ) + rtParams.xy; + return outPos; +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl new file mode 100644 index 000000000..a80e856ed --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "farFrustumQuad.glsl" + +in vec4 vPosition; +in vec3 vNormal; +in vec3 vTangent; +in vec2 vTexCoord0; + +uniform vec4 rtParams0; +out vec4 hpos; +out vec2 uv0; +out vec3 wsEyeRay; +out vec3 vsEyeRay; + +void main() +{ + hpos = vec4( vTexCoord0, 0, 1 ); + + // Get a RT-corrected UV from the SS coord + uv0 = getUVFromSSPos( hpos.xyz, rtParams0 ); + gl_Position = hpos; + + // Interpolators will generate eye rays the + // from far-frustum corners. + wsEyeRay = vTangent; + vsEyeRay = vNormal; + + correctSSP(gl_Position); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/lightingUtils.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/lightingUtils.glsl new file mode 100644 index 000000000..08af9231b --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/lightingUtils.glsl @@ -0,0 +1,79 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +float attenuate( vec4 lightColor, vec2 attParams, float dist ) +{ + // We're summing the results of a scaled constant, + // linear, and quadratic attenuation. + + #ifdef ACCUMULATE_LUV + return lightColor.w * ( 1.0 - dot( attParams, vec2( dist, dist * dist ) ) ); + #else + return 1.0 - dot( attParams, vec2( dist, dist * dist ) ); + #endif +} + +// Calculate the specular coefficent +// +// pxlToLight - Normalized vector representing direction from the pixel being lit, to the light source, in world space +// normal - Normalized surface normal +// pxlToEye - Normalized vector representing direction from pixel being lit, to the camera, in world space +// specPwr - Specular exponent +// specularScale - A scalar on the specular output used in RGB accumulation. +// +float calcSpecular( vec3 pxlToLight, vec3 normal, vec3 pxlToEye, float specPwr, float specularScale ) +{ +#ifdef PHONG_SPECULAR + // (R.V)^c + float specVal = dot( normalize( -reflect( pxlToLight, normal ) ), pxlToEye ); +#else + // (N.H)^c [Blinn-Phong, TGEA style, default] + float specVal = dot( normal, normalize( pxlToLight + pxlToEye ) ); +#endif + +#ifdef ACCUMULATE_LUV + return pow( max( specVal, 0.00001f ), specPwr ); +#else + // If this is RGB accumulation, than there is no facility for the luminance + // of the light to play in to the specular intensity. In LUV, the luminance + // of the light color gets rolled into N.L * Attenuation + return specularScale * pow( max( specVal, 0.00001f ), specPwr ); +#endif +} + +vec3 getDistanceVectorToPlane( vec3 origin, vec3 direction, vec4 plane ) +{ + float denum = dot( plane.xyz, direction.xyz ); + float num = dot( plane, vec4( origin, 1.0 ) ); + float t = -num / denum; + + return direction.xyz * t; +} + +vec3 getDistanceVectorToPlane( float negFarPlaneDotEye, vec3 direction, vec4 plane ) +{ + float denum = dot( plane.xyz, direction.xyz ); + float t = negFarPlaneDotEye / denum; + + return direction.xyz * t; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/pointLightP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/pointLightP.glsl new file mode 100644 index 000000000..8fe127e04 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/pointLightP.glsl @@ -0,0 +1,273 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" + +#include "farFrustumQuad.glsl" +#include "lightingUtils.glsl" +#include "../../../gl/lighting.glsl" +#include "../../shadowMap/shadowMapIO_GLSL.h" +#include "softShadow.glsl" +#include "../../../gl/torque.glsl" + +in vec4 wsEyeDir; +in vec4 ssPos; +in vec4 vsEyeDir; +in vec4 color; + +#ifdef USE_COOKIE_TEX + +/// The texture for cookie rendering. +uniform samplerCube cookieMap ; + +#endif + + +#ifdef SHADOW_CUBE + + vec3 decodeShadowCoord( vec3 shadowCoord ) + { + return shadowCoord; + } + + vec4 shadowSample( samplerCube shadowMap, vec3 shadowCoord ) + { + return texture( shadowMap, shadowCoord ); + } + +#else + + vec3 decodeShadowCoord( vec3 paraVec ) + { + // Flip y and z + paraVec = paraVec.xzy; + + #ifndef SHADOW_PARABOLOID + + bool calcBack = (paraVec.z < 0.0); + if ( calcBack ) + { + paraVec.z = paraVec.z * -1.0; + + #ifdef SHADOW_DUALPARABOLOID + paraVec.x = -paraVec.x; + #endif + } + + #endif + + vec3 shadowCoord; + shadowCoord.x = (paraVec.x / (2*(1 + paraVec.z))) + 0.5; + shadowCoord.y = 1-((paraVec.y / (2*(1 + paraVec.z))) + 0.5); + shadowCoord.z = 0; + + // adjust the co-ordinate slightly if it is near the extent of the paraboloid + // this value was found via experementation + // NOTE: this is wrong, it only biases in one direction, not towards the uv + // center ( 0.5 0.5 ). + //shadowCoord.xy *= 0.997; + + #ifndef SHADOW_PARABOLOID + + // If this is the back, offset in the atlas + if ( calcBack ) + shadowCoord.x += 1.0; + + // Atlasing front and back maps, so scale + shadowCoord.x *= 0.5; + + #endif + + return shadowCoord; + } + +#endif + +uniform sampler2D prePassBuffer; + +#ifdef SHADOW_CUBE + uniform samplerCube shadowMap; +#else + uniform sampler2D shadowMap; + uniform sampler2D dynamicShadowMap; +#endif + +uniform sampler2D lightBuffer; +uniform sampler2D colorBuffer; +uniform sampler2D matInfoBuffer; + +uniform vec4 rtParams0; + +uniform vec3 lightPosition; +uniform vec4 lightColor; +uniform float lightBrightness; +uniform float lightRange; +uniform vec2 lightAttenuation; +uniform vec4 lightMapParams; +uniform vec4 vsFarPlane; +uniform mat3 viewToLightProj; +uniform mat3 dynamicViewToLightProj; +uniform vec4 lightParams; +uniform float shadowSoftness; + +out vec4 OUT_col; + +void main() +{ + // Compute scene UV + vec3 ssPos = ssPos.xyz / ssPos.w; + vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); + + // Emissive. + vec4 matInfo = texture( matInfoBuffer, uvScene ); + bool emissive = getFlag( matInfo.r, 0 ); + if ( emissive ) + { + OUT_col = vec4(0.0, 0.0, 0.0, 0.0); + return; + } + + vec4 colorSample = texture( colorBuffer, uvScene ); + vec3 subsurface = vec3(0.0,0.0,0.0); + if (getFlag( matInfo.r, 1 )) + { + subsurface = colorSample.rgb; + if (colorSample.r>colorSample.g) + subsurface = vec3(0.772549, 0.337255, 0.262745); + else + subsurface = vec3(0.337255, 0.772549, 0.262745); + } + + // Sample/unpack the normal/z data + vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene ); + vec3 normal = prepassSample.rgb; + float depth = prepassSample.a; + + // Eye ray - Eye -> Pixel + vec3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, vsEyeDir.xyz, vsFarPlane ); + vec3 viewSpacePos = eyeRay * depth; + + // Build light vec, get length, clip pixel if needed + vec3 lightVec = lightPosition - viewSpacePos; + float lenLightV = length( lightVec ); + clip( lightRange - lenLightV ); + + // Get the attenuated falloff. + float atten = attenuate( lightColor, lightAttenuation, lenLightV ); + clip( atten - 1e-6 ); + + // Normalize lightVec + lightVec /= lenLightV; + + // If we can do dynamic branching then avoid wasting + // fillrate on pixels that are backfacing to the light. + float nDotL = dot( lightVec, normal ); + //DB_CLIP( nDotL < 0 ); + + #ifdef NO_SHADOW + + float shadowed = 1.0; + + #else + + // Get a linear depth from the light source. + float distToLight = lenLightV / lightRange; + + #ifdef SHADOW_CUBE + + // TODO: We need to fix shadow cube to handle soft shadows! + float occ = texture( shadowMap, tMul( viewToLightProj, -lightVec ) ).r; + float shadowed = saturate( exp( lightParams.y * ( occ - distToLight ) ) ); + + #else + + vec2 shadowCoord = decodeShadowCoord( tMul( viewToLightProj, -lightVec ) ).xy; + + float static_shadowed = softShadow_filter( shadowMap, + ssPos.xy, + shadowCoord, + shadowSoftness, + distToLight, + nDotL, + lightParams.y ); + + vec2 dynamicShadowCoord = decodeShadowCoord( tMul( dynamicViewToLightProj, -lightVec ) ).xy; + float dynamic_shadowed = softShadow_filter( dynamicShadowMap, + ssPos.xy, + dynamicShadowCoord, + shadowSoftness, + distToLight, + nDotL, + lightParams.y ); + + float shadowed = min(static_shadowed, dynamic_shadowed); + #endif + + #endif // !NO_SHADOW + + vec3 lightcol = lightColor.rgb; + #ifdef USE_COOKIE_TEX + + // Lookup the cookie sample. + vec4 cookie = texture( cookieMap, tMul( viewToLightProj, -lightVec ) ); + + // Multiply the light with the cookie tex. + lightcol *= cookie.rgb; + + // Use a maximum channel luminance to attenuate + // the lighting else we get specular in the dark + // regions of the cookie texture. + atten *= max( cookie.r, max( cookie.g, cookie.b ) ); + + #endif + + // NOTE: Do not clip on fully shadowed pixels as it would + // cause the hardware occlusion query to disable the shadow. + + // Specular term + float specular = AL_CalcSpecular( lightVec, + normal, + normalize( -eyeRay ) ) * lightBrightness * atten * shadowed; + + float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness; + vec3 lightColorOut = lightMapParams.rgb * lightcol; + vec4 addToResult = vec4(0.0); + + // TODO: This needs to be removed when lightmapping is disabled + // as its extra work per-pixel on dynamic lit scenes. + // + // Special lightmapping pass. + if ( lightMapParams.a < 0.0 ) + { + // This disables shadows on the backsides of objects. + shadowed = nDotL < 0.0f ? 1.0f : shadowed; + + Sat_NL_Att = 1.0f; + shadowed = mix( 1.0f, shadowed, atten ); + lightColorOut = vec3(shadowed); + specular *= lightBrightness; + addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + } + + OUT_col = AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/softShadow.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/softShadow.glsl new file mode 100644 index 000000000..a14213946 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/softShadow.glsl @@ -0,0 +1,159 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +#if defined( SOFTSHADOW ) && defined( SOFTSHADOW_HIGH_QUALITY ) + +#define NUM_PRE_TAPS 4 +#define NUM_TAPS 12 + +/// The non-uniform poisson disk used in the +/// high quality shadow filtering. +vec2 sNonUniformTaps[NUM_TAPS] = vec2[] +( + // These first 4 taps are located around the edges + // of the disk and are used to predict fully shadowed + // or unshadowed areas. + vec2( 0.992833, 0.979309 ), + vec2( -0.998585, 0.985853 ), + vec2( 0.949299, -0.882562 ), + vec2( -0.941358, -0.893924 ), + + // The rest of the samples. + vec2( 0.545055, -0.589072 ), + vec2( 0.346526, 0.385821 ), + vec2( -0.260183, 0.334412 ), + vec2( 0.248676, -0.679605 ), + vec2( -0.569502, -0.390637 ), + vec2( -0.614096, 0.212577 ), + vec2( -0.259178, 0.876272 ), + vec2( 0.649526, 0.864333 ) +); + +#else + +#define NUM_PRE_TAPS 5 + +/// The non-uniform poisson disk used in the +/// high quality shadow filtering. +vec2 sNonUniformTaps[NUM_PRE_TAPS] = vec2[] +( + vec2( 0.892833, 0.959309 ), + vec2( -0.941358, -0.873924 ), + vec2( -0.260183, 0.334412 ), + vec2( 0.348676, -0.679605 ), + vec2( -0.569502, -0.390637 ) +); + +#endif + + +/// The texture used to do per-pixel pseudorandom +/// rotations of the filter taps. +uniform sampler2D gTapRotationTex ; + + +float softShadow_sampleTaps( sampler2D shadowMap, + vec2 sinCos, + vec2 shadowPos, + float filterRadius, + float distToLight, + float esmFactor, + int startTap, + int endTap ) +{ + float shadow = 0; + + vec2 tap = vec2(0); + for ( int t = startTap; t < endTap; t++ ) + { + tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius; + tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius; + float occluder = tex2Dlod( shadowMap, vec4( shadowPos + tap, 0, 0 ) ).r; + + float esm = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); + shadow += esm / float( endTap - startTap ); + } + + return shadow; +} + + +float softShadow_filter( sampler2D shadowMap, + vec2 vpos, + vec2 shadowPos, + float filterRadius, + float distToLight, + float dotNL, + float esmFactor ) +{ + #ifndef SOFTSHADOW + + // If softshadow is undefined then we skip any complex + // filtering... just do a single sample ESM. + + float occluder = tex2Dlod( shadowMap, vec4( shadowPos, 0, 0 ) ).r; + float shadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); + + #else + + // Lookup the random rotation for this screen pixel. + vec2 sinCos = ( tex2Dlod( gTapRotationTex, vec4( vpos * 16, 0, 0 ) ).rg - 0.5 ) * 2; + + // Do the prediction taps first. + float shadow = softShadow_sampleTaps( shadowMap, + sinCos, + shadowPos, + filterRadius, + distToLight, + esmFactor, + 0, + NUM_PRE_TAPS ); + + // We live with only the pretap results if we don't + // have high quality shadow filtering enabled. + #ifdef SOFTSHADOW_HIGH_QUALITY + + // Only do the expensive filtering if we're really + // in a partially shadowed area. + if ( shadow * ( 1.0 - shadow ) * max( dotNL, 0 ) > 0.06 ) + { + shadow += softShadow_sampleTaps( shadowMap, + sinCos, + shadowPos, + filterRadius, + distToLight, + esmFactor, + NUM_PRE_TAPS, + NUM_TAPS ); + + // This averages the taps above with the results + // of the prediction samples. + shadow *= 0.5; + } + + #endif // SOFTSHADOW_HIGH_QUALITY + + #endif // SOFTSHADOW + + return shadow; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/spotLightP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/spotLightP.glsl new file mode 100644 index 000000000..c6ffa02a0 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/spotLightP.glsl @@ -0,0 +1,210 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "farFrustumQuad.glsl" +#include "lightingUtils.glsl" +#include "../../shadowMap/shadowMapIO_GLSL.h" +#include "shadergen:/autogenConditioners.h" +#include "softShadow.glsl" +#include "../../../gl/lighting.glsl" +#include "../../../gl/torque.glsl" + +in vec4 wsEyeDir; +in vec4 ssPos; +in vec4 vsEyeDir; +in vec4 color; + +#define IN_wsEyeDir wsEyeDir +#define IN_ssPos ssPos +#define IN_vsEyeDir vsEyeDir +#define IN_color color + +#ifdef USE_COOKIE_TEX + +/// The texture for cookie rendering. +uniform sampler2D cookieMap; + +#endif + +uniform sampler2D prePassBuffer; +uniform sampler2D shadowMap; +uniform sampler2D dynamicShadowMap; + +uniform sampler2D lightBuffer; +uniform sampler2D colorBuffer; +uniform sampler2D matInfoBuffer; + +uniform vec4 rtParams0; + +uniform vec3 lightPosition; +uniform vec4 lightColor; +uniform float lightBrightness; +uniform float lightRange; +uniform vec2 lightAttenuation; +uniform vec3 lightDirection; +uniform vec4 lightSpotParams; +uniform vec4 lightMapParams; + +uniform vec4 vsFarPlane; +uniform mat4 viewToLightProj; +uniform mat4 dynamicViewToLightProj; + +uniform vec4 lightParams; +uniform float shadowSoftness; + +out vec4 OUT_col; + +void main() +{ + // Compute scene UV + vec3 ssPos = IN_ssPos.xyz / IN_ssPos.w; + vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); + + // Emissive. + vec4 matInfo = texture( matInfoBuffer, uvScene ); + bool emissive = getFlag( matInfo.r, 0 ); + if ( emissive ) + { + OUT_col = vec4(0.0, 0.0, 0.0, 0.0); + return; + } + + vec4 colorSample = texture( colorBuffer, uvScene ); + vec3 subsurface = vec3(0.0,0.0,0.0); + if (getFlag( matInfo.r, 1 )) + { + subsurface = colorSample.rgb; + if (colorSample.r>colorSample.g) + subsurface = vec3(0.772549, 0.337255, 0.262745); + else + subsurface = vec3(0.337255, 0.772549, 0.262745); + } + + // Sample/unpack the normal/z data + vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene ); + vec3 normal = prepassSample.rgb; + float depth = prepassSample.a; + + // Eye ray - Eye -> Pixel + vec3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN_vsEyeDir.xyz, vsFarPlane ); + vec3 viewSpacePos = eyeRay * depth; + + // Build light vec, get length, clip pixel if needed + vec3 lightToPxlVec = viewSpacePos - lightPosition; + float lenLightV = length( lightToPxlVec ); + lightToPxlVec /= lenLightV; + + //lightDirection = vec3( -lightDirection.xy, lightDirection.z ); //vec3( 0, 0, -1 ); + float cosAlpha = dot( lightDirection, lightToPxlVec ); + clip( cosAlpha - lightSpotParams.x ); + clip( lightRange - lenLightV ); + + float atten = attenuate( lightColor, lightAttenuation, lenLightV ); + atten *= ( cosAlpha - lightSpotParams.x ) / lightSpotParams.y; + clip( atten - 1e-6 ); + atten = saturate( atten ); + + float nDotL = dot( normal, -lightToPxlVec ); + + // Get the shadow texture coordinate + vec4 pxlPosLightProj = tMul( viewToLightProj, vec4( viewSpacePos, 1 ) ); + vec2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 ); + shadowCoord.y = 1.0f - shadowCoord.y; + + // Get the dynamic shadow texture coordinate + vec4 dynpxlPosLightProj = tMul( dynamicViewToLightProj, vec4( viewSpacePos, 1 ) ); + vec2 dynshadowCoord = ( ( dynpxlPosLightProj.xy / dynpxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 ); + dynshadowCoord.y = 1.0f - dynshadowCoord.y; + #ifdef NO_SHADOW + + float shadowed = 1.0; + + #else + + // Get a linear depth from the light source. + float distToLight = pxlPosLightProj.z / lightRange; + + float static_shadowed = softShadow_filter( shadowMap, + ssPos.xy, + shadowCoord, + shadowSoftness, + distToLight, + nDotL, + lightParams.y ); + + float dynamic_shadowed = softShadow_filter( dynamicShadowMap, + ssPos.xy, + dynshadowCoord, + shadowSoftness, + distToLight, + nDotL, + lightParams.y ); + float shadowed = min(static_shadowed, dynamic_shadowed); + #endif // !NO_SHADOW + + vec3 lightcol = lightColor.rgb; + #ifdef USE_COOKIE_TEX + + // Lookup the cookie sample. + vec4 cookie = texture( cookieMap, shadowCoord ); + + // Multiply the light with the cookie tex. + lightcol *= cookie.rgb; + + // Use a maximum channel luminance to attenuate + // the lighting else we get specular in the dark + // regions of the cookie texture. + atten *= max( cookie.r, max( cookie.g, cookie.b ) ); + + #endif + + // NOTE: Do not clip on fully shadowed pixels as it would + // cause the hardware occlusion query to disable the shadow. + + // Specular term + float specular = AL_CalcSpecular( -lightToPxlVec, + normal, + normalize( -eyeRay ) ) * lightBrightness * atten * shadowed; + + float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness; + vec3 lightColorOut = lightMapParams.rgb * lightcol; + vec4 addToResult = vec4(0.0); + + // TODO: This needs to be removed when lightmapping is disabled + // as its extra work per-pixel on dynamic lit scenes. + // + // Special lightmapping pass. + if ( lightMapParams.a < 0.0 ) + { + // This disables shadows on the backsides of objects. + shadowed = nDotL < 0.0f ? 1.0f : shadowed; + + Sat_NL_Att = 1.0f; + shadowed = mix( 1.0f, shadowed, atten ); + lightColorOut = vec3(shadowed); + specular *= lightBrightness; + addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + } + + OUT_col = AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/vectorLightP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/vectorLightP.glsl new file mode 100644 index 000000000..15e0bf477 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/gl/vectorLightP.glsl @@ -0,0 +1,327 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "farFrustumQuad.glsl" +#include "../../../gl/torque.glsl" +#include "../../../gl/lighting.glsl" +#include "lightingUtils.glsl" +#include "../../shadowMap/shadowMapIO_GLSL.h" +#include "softShadow.glsl" + +in vec4 hpos; +in vec2 uv0; +in vec3 wsEyeRay; +in vec3 vsEyeRay; + +uniform sampler2D shadowMap; +uniform sampler2D dynamicShadowMap; + +#ifdef USE_SSAO_MASK +uniform sampler2D ssaoMask ; +uniform vec4 rtParams3; +#endif + +uniform sampler2D prePassBuffer; +uniform sampler2D lightBuffer; +uniform sampler2D colorBuffer; +uniform sampler2D matInfoBuffer; +uniform vec3 lightDirection; +uniform vec4 lightColor; +uniform float lightBrightness; +uniform vec4 lightAmbient; +uniform vec3 eyePosWorld; +uniform mat4x4 eyeMat; +uniform vec4 atlasXOffset; +uniform vec4 atlasYOffset; +uniform vec2 atlasScale; +uniform vec4 zNearFarInvNearFar; +uniform vec4 lightMapParams; +uniform vec2 fadeStartLength; +uniform vec4 overDarkPSSM; +uniform float shadowSoftness; + +//static shadowMap +uniform mat4x4 worldToLightProj; +uniform vec4 scaleX; +uniform vec4 scaleY; +uniform vec4 offsetX; +uniform vec4 offsetY; +uniform vec4 farPlaneScalePSSM; + +//dynamic shadowMap +uniform mat4x4 dynamicWorldToLightProj; +uniform vec4 dynamicScaleX; +uniform vec4 dynamicScaleY; +uniform vec4 dynamicOffsetX; +uniform vec4 dynamicOffsetY; +uniform vec4 dynamicFarPlaneScalePSSM; + +vec4 AL_VectorLightShadowCast( sampler2D _sourceshadowMap, + vec2 _texCoord, + mat4 _worldToLightProj, + vec4 _worldPos, + vec4 _scaleX, vec4 _scaleY, + vec4 _offsetX, vec4 _offsetY, + vec4 _farPlaneScalePSSM, + vec4 _atlasXOffset, vec4 _atlasYOffset, + vec2 _atlasScale, + float _shadowSoftness, + float _dotNL , + vec4 _overDarkPSSM +) +{ + + // Compute shadow map coordinate + vec4 pxlPosLightProj = tMul(_worldToLightProj, _worldPos); + vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w; + + // Distance to light, in shadowMap space + float distToLight = pxlPosLightProj.z / pxlPosLightProj.w; + + // Figure out which split to sample from. Basically, we compute the shadowMap sample coord + // for all of the splits and then check if its valid. + vec4 shadowCoordX = vec4( baseShadowCoord.x ); + vec4 shadowCoordY = vec4( baseShadowCoord.y ); + vec4 farPlaneDists = vec4( distToLight ); + shadowCoordX *= _scaleX; + shadowCoordY *= _scaleY; + shadowCoordX += _offsetX; + shadowCoordY += _offsetY; + farPlaneDists *= _farPlaneScalePSSM; + + // If the shadow sample is within -1..1 and the distance + // to the light for this pixel is less than the far plane + // of the split, use it. + vec4 finalMask; + if ( shadowCoordX.x > -0.99 && shadowCoordX.x < 0.99 && + shadowCoordY.x > -0.99 && shadowCoordY.x < 0.99 && + farPlaneDists.x < 1.0 ) + finalMask = vec4(1, 0, 0, 0); + + else if ( shadowCoordX.y > -0.99 && shadowCoordX.y < 0.99 && + shadowCoordY.y > -0.99 && shadowCoordY.y < 0.99 && + farPlaneDists.y < 1.0 ) + finalMask = vec4(0, 1, 0, 0); + + else if ( shadowCoordX.z > -0.99 && shadowCoordX.z < 0.99 && + shadowCoordY.z > -0.99 && shadowCoordY.z < 0.99 && + farPlaneDists.z < 1.0 ) + finalMask = vec4(0, 0, 1, 0); + + else + finalMask = vec4(0, 0, 0, 1); + + vec3 debugColor = vec3(0); + + #ifdef NO_SHADOW + debugColor = vec3(1.0); + #endif + + #ifdef PSSM_DEBUG_RENDER + if ( finalMask.x > 0 ) + debugColor += vec3( 1, 0, 0 ); + else if ( finalMask.y > 0 ) + debugColor += vec3( 0, 1, 0 ); + else if ( finalMask.z > 0 ) + debugColor += vec3( 0, 0, 1 ); + else if ( finalMask.w > 0 ) + debugColor += vec3( 1, 1, 0 ); + #endif + + // Here we know what split we're sampling from, so recompute the _texCoord location + // Yes, we could just use the result from above, but doing it this way actually saves + // shader instructions. + vec2 finalScale; + finalScale.x = dot(finalMask, _scaleX); + finalScale.y = dot(finalMask, _scaleY); + + vec2 finalOffset; + finalOffset.x = dot(finalMask, _offsetX); + finalOffset.y = dot(finalMask, _offsetY); + + vec2 shadowCoord; + shadowCoord = baseShadowCoord * finalScale; + shadowCoord += finalOffset; + + // Convert to _texCoord space + shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5); + shadowCoord.y = 1.0f - shadowCoord.y; + + // Move around inside of atlas + vec2 aOffset; + aOffset.x = dot(finalMask, _atlasXOffset); + aOffset.y = dot(finalMask, _atlasYOffset); + + shadowCoord *= _atlasScale; + shadowCoord += aOffset; + + // Each split has a different far plane, take this into account. + float farPlaneScale = dot( _farPlaneScalePSSM, finalMask ); + distToLight *= farPlaneScale; + + return vec4(debugColor, + softShadow_filter( _sourceshadowMap, + _texCoord, + shadowCoord, + farPlaneScale * _shadowSoftness, + distToLight, + _dotNL, + dot( finalMask, _overDarkPSSM ) ) ); +} + +out vec4 OUT_col; +void main() +{ + // Emissive. + float4 matInfo = texture( matInfoBuffer, uv0 ); + bool emissive = getFlag( matInfo.r, 0 ); + if ( emissive ) + { + OUT_col = vec4(1.0, 1.0, 1.0, 0.0); + return; + } + + vec4 colorSample = texture( colorBuffer, uv0 ); + vec3 subsurface = vec3(0.0,0.0,0.0); + if (getFlag( matInfo.r, 1 )) + { + subsurface = colorSample.rgb; + if (colorSample.r>colorSample.g) + subsurface = vec3(0.772549, 0.337255, 0.262745); + else + subsurface = vec3(0.337255, 0.772549, 0.262745); + } + + // Sample/unpack the normal/z data + vec4 prepassSample = prepassUncondition( prePassBuffer, uv0 ); + vec3 normal = prepassSample.rgb; + float depth = prepassSample.a; + + // Use eye ray to get ws pos + vec4 worldPos = vec4(eyePosWorld + wsEyeRay * depth, 1.0f); + + // Get the light attenuation. + float dotNL = dot(-lightDirection, normal); + + #ifdef PSSM_DEBUG_RENDER + vec3 debugColor = vec3(0); + #endif + + #ifdef NO_SHADOW + + // Fully unshadowed. + float shadowed = 1.0; + + #ifdef PSSM_DEBUG_RENDER + debugColor = vec3(1.0); + #endif + + #else + + vec4 static_shadowed_colors = AL_VectorLightShadowCast( shadowMap, + uv0.xy, + worldToLightProj, + worldPos, + scaleX, scaleY, + offsetX, offsetY, + farPlaneScalePSSM, + atlasXOffset, atlasYOffset, + atlasScale, + shadowSoftness, + dotNL, + overDarkPSSM); + vec4 dynamic_shadowed_colors = AL_VectorLightShadowCast( dynamicShadowMap, + uv0.xy, + dynamicWorldToLightProj, + worldPos, + dynamicScaleX, dynamicScaleY, + dynamicOffsetX, dynamicOffsetY, + dynamicFarPlaneScalePSSM, + atlasXOffset, atlasYOffset, + atlasScale, + shadowSoftness, + dotNL, + overDarkPSSM); + float static_shadowed = static_shadowed_colors.a; + float dynamic_shadowed = dynamic_shadowed_colors.a; + + #ifdef PSSM_DEBUG_RENDER + debugColor = static_shadowed_colors.rgb*0.5+dynamic_shadowed_colors.rgb*0.5; + #endif + + // Fade out the shadow at the end of the range. + vec4 zDist = vec4(zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth); + float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y; + + static_shadowed = mix( static_shadowed, 1.0, saturate( fadeOutAmt ) ); + dynamic_shadowed = mix( dynamic_shadowed, 1.0, saturate( fadeOutAmt ) ); + + // temp for debugging. uncomment one or the other. + //float shadowed = static_shadowed; + //float shadowed = dynamic_shadowed; + float shadowed = min(static_shadowed, dynamic_shadowed); + + #ifdef PSSM_DEBUG_RENDER + if ( fadeOutAmt > 1.0 ) + debugColor = vec3(1.0); + #endif + + #endif // !NO_SHADOW + + // Specular term + float specular = AL_CalcSpecular( -lightDirection, + normal, + normalize(-vsEyeRay) ) * lightBrightness * shadowed; + + float Sat_NL_Att = saturate( dotNL * shadowed ) * lightBrightness; + vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb; + vec4 addToResult = (lightAmbient * (1 - ambientCameraFactor)) + ( lightAmbient * ambientCameraFactor * saturate(dot(normalize(-vsEyeRay), normal)) ); + + // TODO: This needs to be removed when lightmapping is disabled + // as its extra work per-pixel on dynamic lit scenes. + // + // Special lightmapping pass. + if ( lightMapParams.a < 0.0 ) + { + // This disables shadows on the backsides of objects. + shadowed = dotNL < 0.0f ? 1.0f : shadowed; + + Sat_NL_Att = 1.0f; + lightColorOut = vec3(shadowed); + specular *= lightBrightness; + addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + } + + // Sample the AO texture. + #ifdef USE_SSAO_MASK + float ao = 1.0 - texture( ssaoMask, viewportCoordToRenderTarget( uv0.xy, rtParams3 ) ).r; + addToResult *= ao; + #endif + + #ifdef PSSM_DEBUG_RENDER + lightColorOut = debugColor; + #endif + + OUT_col = AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/lightingUtils.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/lightingUtils.hlsl new file mode 100644 index 000000000..2bff18999 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/lightingUtils.hlsl @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +float attenuate( float4 lightColor, float2 attParams, float dist ) +{ + // We're summing the results of a scaled constant, + // linear, and quadratic attenuation. + + #ifdef ACCUMULATE_LUV + return lightColor.w * ( 1.0 - dot( attParams, float2( dist, dist * dist ) ) ); + #else + return 1.0 - dot( attParams, float2( dist, dist * dist ) ); + #endif +} + +float3 getDistanceVectorToPlane( float3 origin, float3 direction, float4 plane ) +{ + float denum = dot( plane.xyz, direction.xyz ); + float num = dot( plane, float4( origin, 1.0 ) ); + float t = -num / denum; + + return direction.xyz * t; +} + +float3 getDistanceVectorToPlane( float negFarPlaneDotEye, float3 direction, float4 plane ) +{ + float denum = dot( plane.xyz, direction.xyz ); + float t = negFarPlaneDotEye / denum; + + return direction.xyz * t; +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/particlePointLightP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/particlePointLightP.hlsl new file mode 100644 index 000000000..7ff5d50d2 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/particlePointLightP.hlsl @@ -0,0 +1,76 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "farFrustumQuad.hlsl" +#include "lightingUtils.hlsl" +#include "../../lighting.hlsl" +#include "../../shaderModel.hlsl" +#include "../../shaderModelAutoGen.hlsl" + + +struct ConvexConnectP +{ + float4 pos : TORQUE_POSITION; + float4 ssPos : TEXCOORD0; + float3 vsEyeDir : TEXCOORD1; +}; + +TORQUE_UNIFORM_SAMPLER2D(prePassBuffer, 0); + +uniform float4 lightPosition; +uniform float4 lightColor; +uniform float lightRange; +uniform float4 vsFarPlane; +uniform float4 rtParams0; + +float4 main( ConvexConnectP IN ) : TORQUE_TARGET0 +{ + // Compute scene UV + float3 ssPos = IN.ssPos.xyz / IN.ssPos.w; + float2 uvScene = getUVFromSSPos(ssPos, rtParams0); + + // Sample/unpack the normal/z data + float4 prepassSample = TORQUE_PREPASS_UNCONDITION(prePassBuffer, uvScene); + float3 normal = prepassSample.rgb; + float depth = prepassSample.a; + + // Eye ray - Eye -> Pixel + float3 eyeRay = getDistanceVectorToPlane(-vsFarPlane.w, IN.vsEyeDir, vsFarPlane); + float3 viewSpacePos = eyeRay * depth; + + // Build light vec, get length, clip pixel if needed + float3 lightVec = lightPosition.xyz - viewSpacePos; + float lenLightV = length(lightVec); + clip(lightRange - lenLightV); + + // Do a very simple falloff instead of real attenuation + float atten = 1.0 - saturate(lenLightV / lightRange); + + // Normalize lightVec + lightVec /= lenLightV; + + // N.L * Attenuation + float Sat_NL_Att = saturate(dot(lightVec, normal)) * atten; + + // Output, no specular + return lightinfoCondition(lightColor.rgb, Sat_NL_Att, 0.0, 0.0); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/particlePointLightV.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/particlePointLightV.hlsl new file mode 100644 index 000000000..faa2ec115 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/particlePointLightV.hlsl @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../hlslStructs.hlsl" +#include "../../shaderModel.hlsl" + +struct ConvexConnectV +{ + float4 hpos : TORQUE_POSITION; + float4 ssPos : TEXCOORD0; + float3 vsEyeDir : TEXCOORD1; +}; + +uniform float4x4 viewProj; +uniform float4x4 view; +uniform float3 particlePosWorld; +uniform float lightRange; + +ConvexConnectV main( VertexIn_P IN ) +{ + ConvexConnectV OUT; + float4 pos = float4(IN.pos, 0.0); + float4 vPosWorld = pos + float4(particlePosWorld, 0.0) + pos * lightRange; + OUT.hpos = mul(viewProj, vPosWorld); + OUT.vsEyeDir = mul(view, vPosWorld); + OUT.ssPos = OUT.hpos; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/pointLightP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/pointLightP.hlsl new file mode 100644 index 000000000..a8c0ea105 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/pointLightP.hlsl @@ -0,0 +1,277 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../shaderModelAutoGen.hlsl" + +#include "farFrustumQuad.hlsl" +#include "lightingUtils.hlsl" +#include "../../lighting.hlsl" +#include "../shadowMap/shadowMapIO_HLSL.h" +#include "softShadow.hlsl" +#include "../../torque.hlsl" + +struct ConvexConnectP +{ + float4 pos : TORQUE_POSITION; + float4 wsEyeDir : TEXCOORD0; + float4 ssPos : TEXCOORD1; + float4 vsEyeDir : TEXCOORD2; +}; + + +#ifdef USE_COOKIE_TEX + +/// The texture for cookie rendering. +TORQUE_UNIFORM_SAMPLERCUBE(cookieMap, 3); + +#endif + + +#ifdef SHADOW_CUBE + + float3 decodeShadowCoord( float3 shadowCoord ) + { + return shadowCoord; + } + + float4 shadowSample( TORQUE_SAMPLERCUBE(shadowMap), float3 shadowCoord ) + { + return TORQUE_TEXCUBE( shadowMap, shadowCoord ); + } + +#else + + float3 decodeShadowCoord( float3 paraVec ) + { + // Flip y and z + paraVec = paraVec.xzy; + + #ifndef SHADOW_PARABOLOID + + bool calcBack = (paraVec.z < 0.0); + if ( calcBack ) + { + paraVec.z = paraVec.z * -1.0; + + #ifdef SHADOW_DUALPARABOLOID + paraVec.x = -paraVec.x; + #endif + } + + #endif + + float3 shadowCoord; + shadowCoord.x = (paraVec.x / (2*(1 + paraVec.z))) + 0.5; + shadowCoord.y = 1-((paraVec.y / (2*(1 + paraVec.z))) + 0.5); + shadowCoord.z = 0; + + // adjust the co-ordinate slightly if it is near the extent of the paraboloid + // this value was found via experementation + // NOTE: this is wrong, it only biases in one direction, not towards the uv + // center ( 0.5 0.5 ). + //shadowCoord.xy *= 0.997; + + #ifndef SHADOW_PARABOLOID + + // If this is the back, offset in the atlas + if ( calcBack ) + shadowCoord.x += 1.0; + + // Atlasing front and back maps, so scale + shadowCoord.x *= 0.5; + + #endif + + return shadowCoord; + } + +#endif + +TORQUE_UNIFORM_SAMPLER2D(prePassBuffer, 0); + +#ifdef SHADOW_CUBE +TORQUE_UNIFORM_SAMPLERCUBE(shadowMap, 1); +#else +TORQUE_UNIFORM_SAMPLER2D(shadowMap, 1); +TORQUE_UNIFORM_SAMPLER2D(dynamicShadowMap, 2); +#endif + +TORQUE_UNIFORM_SAMPLER2D(lightBuffer, 5); +TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 6); +TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 7); + +uniform float4 rtParams0; +uniform float4 lightColor; + +uniform float lightBrightness; +uniform float3 lightPosition; + +uniform float4 lightMapParams; +uniform float4 vsFarPlane; +uniform float4 lightParams; + +uniform float lightRange; +uniform float shadowSoftness; +uniform float2 lightAttenuation; + +uniform float3x3 viewToLightProj; +uniform float3x3 dynamicViewToLightProj; + +float4 main( ConvexConnectP IN ) : TORQUE_TARGET0 +{ + // Compute scene UV + float3 ssPos = IN.ssPos.xyz / IN.ssPos.w; + float2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); + + // Emissive. + float4 matInfo = TORQUE_TEX2D( matInfoBuffer, uvScene ); + bool emissive = getFlag( matInfo.r, 0 ); + if ( emissive ) + { + return float4(0.0, 0.0, 0.0, 0.0); + } + float4 colorSample = TORQUE_TEX2D( colorBuffer, uvScene ); + float3 subsurface = float3(0.0,0.0,0.0); + if (getFlag( matInfo.r, 1 )) + { + subsurface = colorSample.rgb; + if (colorSample.r>colorSample.g) + subsurface = float3(0.772549, 0.337255, 0.262745); + else + subsurface = float3(0.337255, 0.772549, 0.262745); + } + + // Sample/unpack the normal/z data + float4 prepassSample = TORQUE_PREPASS_UNCONDITION( prePassBuffer, uvScene ); + float3 normal = prepassSample.rgb; + float depth = prepassSample.a; + + // Eye ray - Eye -> Pixel + float3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN.vsEyeDir.xyz, vsFarPlane ); + float3 viewSpacePos = eyeRay * depth; + + // Build light vec, get length, clip pixel if needed + float3 lightVec = lightPosition - viewSpacePos; + float lenLightV = length( lightVec ); + clip( lightRange - lenLightV ); + + // Get the attenuated falloff. + float atten = attenuate( lightColor, lightAttenuation, lenLightV ); + clip( atten - 1e-6 ); + + // Normalize lightVec + lightVec /= lenLightV; + + // If we can do dynamic branching then avoid wasting + // fillrate on pixels that are backfacing to the light. + float nDotL = dot( lightVec, normal ); + //DB_CLIP( nDotL < 0 ); + + #ifdef NO_SHADOW + + float shadowed = 1.0; + + #else + + // Get a linear depth from the light source. + float distToLight = lenLightV / lightRange; + + #ifdef SHADOW_CUBE + + // TODO: We need to fix shadow cube to handle soft shadows! + float occ = TORQUE_TEXCUBE( shadowMap, mul( viewToLightProj, -lightVec ) ).r; + float shadowed = saturate( exp( lightParams.y * ( occ - distToLight ) ) ); + + #else + + // Static + float2 shadowCoord = decodeShadowCoord( mul( viewToLightProj, -lightVec ) ).xy; + float static_shadowed = softShadow_filter( TORQUE_SAMPLER2D_MAKEARG(shadowMap), + ssPos.xy, + shadowCoord, + shadowSoftness, + distToLight, + nDotL, + lightParams.y ); + + // Dynamic + float2 dynamicShadowCoord = decodeShadowCoord( mul( dynamicViewToLightProj, -lightVec ) ).xy; + float dynamic_shadowed = softShadow_filter( TORQUE_SAMPLER2D_MAKEARG(dynamicShadowMap), + ssPos.xy, + dynamicShadowCoord, + shadowSoftness, + distToLight, + nDotL, + lightParams.y ); + + float shadowed = min(static_shadowed, dynamic_shadowed); + + #endif + + #endif // !NO_SHADOW + + float3 lightcol = lightColor.rgb; + #ifdef USE_COOKIE_TEX + + // Lookup the cookie sample. + float4 cookie = TORQUE_TEXCUBE( cookieMap, mul( viewToLightProj, -lightVec ) ); + + // Multiply the light with the cookie tex. + lightcol *= cookie.rgb; + + // Use a maximum channel luminance to attenuate + // the lighting else we get specular in the dark + // regions of the cookie texture. + atten *= max( cookie.r, max( cookie.g, cookie.b ) ); + + #endif + + // NOTE: Do not clip on fully shadowed pixels as it would + // cause the hardware occlusion query to disable the shadow. + + // Specular term + float specular = AL_CalcSpecular( lightVec, + normal, + normalize( -eyeRay ) ) * lightBrightness * atten * shadowed; + + float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness; + float3 lightColorOut = lightMapParams.rgb * lightcol; + float4 addToResult = 0.0; + + // TODO: This needs to be removed when lightmapping is disabled + // as its extra work per-pixel on dynamic lit scenes. + // + // Special lightmapping pass. + if ( lightMapParams.a < 0.0 ) + { + // This disables shadows on the backsides of objects. + shadowed = nDotL < 0.0f ? 1.0f : shadowed; + + Sat_NL_Att = 1.0f; + shadowed = lerp( 1.0f, shadowed, atten ); + lightColorOut = shadowed; + specular *= lightBrightness; + addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + } + + return AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/softShadow.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/softShadow.hlsl new file mode 100644 index 000000000..0faf3e1fb --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/softShadow.hlsl @@ -0,0 +1,158 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../shaderModel.hlsl" + +#if defined( SOFTSHADOW ) && defined( SOFTSHADOW_HIGH_QUALITY ) + +#define NUM_PRE_TAPS 4 +#define NUM_TAPS 12 + +/// The non-uniform poisson disk used in the +/// high quality shadow filtering. +static float2 sNonUniformTaps[NUM_TAPS] = +{ + // These first 4 taps are located around the edges + // of the disk and are used to predict fully shadowed + // or unshadowed areas. + { 0.992833, 0.979309 }, + { -0.998585, 0.985853 }, + { 0.949299, -0.882562 }, + { -0.941358, -0.893924 }, + + // The rest of the samples. + { 0.545055, -0.589072 }, + { 0.346526, 0.385821 }, + { -0.260183, 0.334412 }, + { 0.248676, -0.679605 }, + { -0.569502, -0.390637 }, + { -0.614096, 0.212577 }, + { -0.259178, 0.876272 }, + { 0.649526, 0.864333 }, +}; + +#else + +#define NUM_PRE_TAPS 5 + +/// The non-uniform poisson disk used in the +/// high quality shadow filtering. +static float2 sNonUniformTaps[NUM_PRE_TAPS] = +{ + { 0.892833, 0.959309 }, + { -0.941358, -0.873924 }, + { -0.260183, 0.334412 }, + { 0.348676, -0.679605 }, + { -0.569502, -0.390637 }, +}; + +#endif + + +/// The texture used to do per-pixel pseudorandom +/// rotations of the filter taps. +TORQUE_UNIFORM_SAMPLER2D(gTapRotationTex, 4); + +float softShadow_sampleTaps( TORQUE_SAMPLER2D(shadowMap1), + float2 sinCos, + float2 shadowPos, + float filterRadius, + float distToLight, + float esmFactor, + int startTap, + int endTap ) +{ + float shadow = 0; + + float2 tap = 0; + for ( int t = startTap; t < endTap; t++ ) + { + tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius; + tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius; + float occluder = TORQUE_TEX2DLOD( shadowMap1, float4( shadowPos + tap, 0, 0 ) ).r; + + float esm = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); + shadow += esm / float( endTap - startTap ); + } + + return shadow; +} + + +float softShadow_filter( TORQUE_SAMPLER2D(shadowMap), + float2 vpos, + float2 shadowPos, + float filterRadius, + float distToLight, + float dotNL, + float esmFactor ) +{ + #ifndef SOFTSHADOW + + // If softshadow is undefined then we skip any complex + // filtering... just do a single sample ESM. + + float occluder = TORQUE_TEX2DLOD(shadowMap, float4(shadowPos, 0, 0)).r; + float shadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); + + #else + // Lookup the random rotation for this screen pixel. + float2 sinCos = ( TORQUE_TEX2DLOD(gTapRotationTex, float4(vpos * 16, 0, 0)).rg - 0.5) * 2; + + // Do the prediction taps first. + float shadow = softShadow_sampleTaps( TORQUE_SAMPLER2D_MAKEARG(shadowMap), + sinCos, + shadowPos, + filterRadius, + distToLight, + esmFactor, + 0, + NUM_PRE_TAPS ); + + // We live with only the pretap results if we don't + // have high quality shadow filtering enabled. + #ifdef SOFTSHADOW_HIGH_QUALITY + + // Only do the expensive filtering if we're really + // in a partially shadowed area. + if ( shadow * ( 1.0 - shadow ) * max( dotNL, 0 ) > 0.06 ) + { + shadow += softShadow_sampleTaps( TORQUE_SAMPLER2D_MAKEARG(shadowMap), + sinCos, + shadowPos, + filterRadius, + distToLight, + esmFactor, + NUM_PRE_TAPS, + NUM_TAPS ); + + // This averages the taps above with the results + // of the prediction samples. + shadow *= 0.5; + } + + #endif // SOFTSHADOW_HIGH_QUALITY + + #endif // SOFTSHADOW + + return shadow; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/spotLightP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/spotLightP.hlsl new file mode 100644 index 000000000..5040b15e2 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/spotLightP.hlsl @@ -0,0 +1,209 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../shaderModel.hlsl" +#include "../../shaderModelAutoGen.hlsl" + +#include "farFrustumQuad.hlsl" +#include "lightingUtils.hlsl" +#include "../../lighting.hlsl" +#include "../shadowMap/shadowMapIO_HLSL.h" +#include "softShadow.hlsl" +#include "../../torque.hlsl" + +struct ConvexConnectP +{ + float4 pos : TORQUE_POSITION; + float4 wsEyeDir : TEXCOORD0; + float4 ssPos : TEXCOORD1; + float4 vsEyeDir : TEXCOORD2; +}; + +TORQUE_UNIFORM_SAMPLER2D(prePassBuffer, 0); +TORQUE_UNIFORM_SAMPLER2D(shadowMap, 1); +TORQUE_UNIFORM_SAMPLER2D(dynamicShadowMap,2); + +#ifdef USE_COOKIE_TEX + +/// The texture for cookie rendering. +TORQUE_UNIFORM_SAMPLER2D(cookieMap, 3); + +#endif + +TORQUE_UNIFORM_SAMPLER2D(lightBuffer, 5); +TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 6); +TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 7); + +uniform float4 rtParams0; + +uniform float lightBrightness; +uniform float3 lightPosition; + +uniform float4 lightColor; + +uniform float lightRange; +uniform float3 lightDirection; + +uniform float4 lightSpotParams; +uniform float4 lightMapParams; +uniform float4 vsFarPlane; +uniform float4x4 viewToLightProj; +uniform float4 lightParams; +uniform float4x4 dynamicViewToLightProj; + +uniform float2 lightAttenuation; +uniform float shadowSoftness; + +float4 main( ConvexConnectP IN ) : TORQUE_TARGET0 +{ + // Compute scene UV + float3 ssPos = IN.ssPos.xyz / IN.ssPos.w; + float2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); + + // Emissive. + float4 matInfo = TORQUE_TEX2D( matInfoBuffer, uvScene ); + bool emissive = getFlag( matInfo.r, 0 ); + if ( emissive ) + { + return float4(0.0, 0.0, 0.0, 0.0); + } + + float4 colorSample = TORQUE_TEX2D( colorBuffer, uvScene ); + float3 subsurface = float3(0.0,0.0,0.0); + if (getFlag( matInfo.r, 1 )) + { + subsurface = colorSample.rgb; + if (colorSample.r>colorSample.g) + subsurface = float3(0.772549, 0.337255, 0.262745); + else + subsurface = float3(0.337255, 0.772549, 0.262745); + } + + // Sample/unpack the normal/z data + float4 prepassSample = TORQUE_PREPASS_UNCONDITION( prePassBuffer, uvScene ); + float3 normal = prepassSample.rgb; + float depth = prepassSample.a; + + // Eye ray - Eye -> Pixel + float3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN.vsEyeDir.xyz, vsFarPlane ); + float3 viewSpacePos = eyeRay * depth; + + // Build light vec, get length, clip pixel if needed + float3 lightToPxlVec = viewSpacePos - lightPosition; + float lenLightV = length( lightToPxlVec ); + lightToPxlVec /= lenLightV; + + //lightDirection = float3( -lightDirection.xy, lightDirection.z ); //float3( 0, 0, -1 ); + float cosAlpha = dot( lightDirection, lightToPxlVec ); + clip( cosAlpha - lightSpotParams.x ); + clip( lightRange - lenLightV ); + + float atten = attenuate( lightColor, lightAttenuation, lenLightV ); + atten *= ( cosAlpha - lightSpotParams.x ) / lightSpotParams.y; + clip( atten - 1e-6 ); + atten = saturate( atten ); + + float nDotL = dot( normal, -lightToPxlVec ); + + // Get the shadow texture coordinate + float4 pxlPosLightProj = mul( viewToLightProj, float4( viewSpacePos, 1 ) ); + float2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 ); + shadowCoord.y = 1.0f - shadowCoord.y; + + // Get the dynamic shadow texture coordinate + float4 dynpxlPosLightProj = mul( dynamicViewToLightProj, float4( viewSpacePos, 1 ) ); + float2 dynshadowCoord = ( ( dynpxlPosLightProj.xy / dynpxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 ); + dynshadowCoord.y = 1.0f - dynshadowCoord.y; + + #ifdef NO_SHADOW + + float shadowed = 1.0; + + #else + + // Get a linear depth from the light source. + float distToLight = pxlPosLightProj.z / lightRange; + + float static_shadowed = softShadow_filter( TORQUE_SAMPLER2D_MAKEARG(shadowMap), + ssPos.xy, + shadowCoord, + shadowSoftness, + distToLight, + nDotL, + lightParams.y ); + + float dynamic_shadowed = softShadow_filter( TORQUE_SAMPLER2D_MAKEARG(dynamicShadowMap), + ssPos.xy, + dynshadowCoord, + shadowSoftness, + distToLight, + nDotL, + lightParams.y ); + float shadowed = min(static_shadowed, dynamic_shadowed); + #endif // !NO_SHADOW + + float3 lightcol = lightColor.rgb; + #ifdef USE_COOKIE_TEX + + // Lookup the cookie sample. + float4 cookie = TORQUE_TEX2D( cookieMap, shadowCoord ); + + // Multiply the light with the cookie tex. + lightcol *= cookie.rgb; + + // Use a maximum channel luminance to attenuate + // the lighting else we get specular in the dark + // regions of the cookie texture. + atten *= max( cookie.r, max( cookie.g, cookie.b ) ); + + #endif + + // NOTE: Do not clip on fully shadowed pixels as it would + // cause the hardware occlusion query to disable the shadow. + + // Specular term + float specular = AL_CalcSpecular( -lightToPxlVec, + normal, + normalize( -eyeRay ) ) * lightBrightness * atten * shadowed; + + float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness; + float3 lightColorOut = lightMapParams.rgb * lightcol; + float4 addToResult = 0.0; + + // TODO: This needs to be removed when lightmapping is disabled + // as its extra work per-pixel on dynamic lit scenes. + // + // Special lightmapping pass. + if ( lightMapParams.a < 0.0 ) + { + // This disables shadows on the backsides of objects. + shadowed = nDotL < 0.0f ? 1.0f : shadowed; + + Sat_NL_Att = 1.0f; + shadowed = lerp( 1.0f, shadowed, atten ); + lightColorOut = shadowed; + specular *= lightBrightness; + addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + } + + return AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/advanced/vectorLightP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/vectorLightP.hlsl new file mode 100644 index 000000000..956227909 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/advanced/vectorLightP.hlsl @@ -0,0 +1,328 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../shaderModel.hlsl" +#include "../../shaderModelAutoGen.hlsl" + +#include "farFrustumQuad.hlsl" +#include "../../torque.hlsl" +#include "../../lighting.hlsl" +#include "lightingUtils.hlsl" +#include "../shadowMap/shadowMapIO_HLSL.h" +#include "softShadow.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(prePassBuffer, 0); +TORQUE_UNIFORM_SAMPLER2D(shadowMap, 1); +TORQUE_UNIFORM_SAMPLER2D(dynamicShadowMap, 2); + +#ifdef USE_SSAO_MASK +TORQUE_UNIFORM_SAMPLER2D(ssaoMask, 3); +uniform float4 rtParams3; +#endif +//register 4? +TORQUE_UNIFORM_SAMPLER2D(lightBuffer, 5); +TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 6); +TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 7); + +uniform float lightBrightness; +uniform float3 lightDirection; + +uniform float4 lightColor; +uniform float4 lightAmbient; + +uniform float shadowSoftness; +uniform float3 eyePosWorld; + +uniform float4 atlasXOffset; +uniform float4 atlasYOffset; +uniform float4 zNearFarInvNearFar; +uniform float4 lightMapParams; +uniform float4 farPlaneScalePSSM; +uniform float4 overDarkPSSM; + +uniform float2 fadeStartLength; +uniform float2 atlasScale; + +uniform float4x4 eyeMat; + +// Static Shadows +uniform float4x4 worldToLightProj; +uniform float4 scaleX; +uniform float4 scaleY; +uniform float4 offsetX; +uniform float4 offsetY; +// Dynamic Shadows +uniform float4x4 dynamicWorldToLightProj; +uniform float4 dynamicScaleX; +uniform float4 dynamicScaleY; +uniform float4 dynamicOffsetX; +uniform float4 dynamicOffsetY; +uniform float4 dynamicFarPlaneScalePSSM; + +float4 AL_VectorLightShadowCast( TORQUE_SAMPLER2D(sourceShadowMap), + float2 texCoord, + float4x4 worldToLightProj, + float4 worldPos, + float4 scaleX, + float4 scaleY, + float4 offsetX, + float4 offsetY, + float4 farPlaneScalePSSM, + float4 atlasXOffset, + float4 atlasYOffset, + float2 atlasScale, + float shadowSoftness, + float dotNL , + float4 overDarkPSSM) +{ + // Compute shadow map coordinate + float4 pxlPosLightProj = mul(worldToLightProj, worldPos); + float2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w; + + // Distance to light, in shadowmap space + float distToLight = pxlPosLightProj.z / pxlPosLightProj.w; + + // Figure out which split to sample from. Basically, we compute the shadowmap sample coord + // for all of the splits and then check if its valid. + float4 shadowCoordX = baseShadowCoord.xxxx; + float4 shadowCoordY = baseShadowCoord.yyyy; + float4 farPlaneDists = distToLight.xxxx; + shadowCoordX *= scaleX; + shadowCoordY *= scaleY; + shadowCoordX += offsetX; + shadowCoordY += offsetY; + farPlaneDists *= farPlaneScalePSSM; + + // If the shadow sample is within -1..1 and the distance + // to the light for this pixel is less than the far plane + // of the split, use it. + float4 finalMask; + if ( shadowCoordX.x > -0.99 && shadowCoordX.x < 0.99 && + shadowCoordY.x > -0.99 && shadowCoordY.x < 0.99 && + farPlaneDists.x < 1.0 ) + finalMask = float4(1, 0, 0, 0); + + else if ( shadowCoordX.y > -0.99 && shadowCoordX.y < 0.99 && + shadowCoordY.y > -0.99 && shadowCoordY.y < 0.99 && + farPlaneDists.y < 1.0 ) + finalMask = float4(0, 1, 0, 0); + + else if ( shadowCoordX.z > -0.99 && shadowCoordX.z < 0.99 && + shadowCoordY.z > -0.99 && shadowCoordY.z < 0.99 && + farPlaneDists.z < 1.0 ) + finalMask = float4(0, 0, 1, 0); + + else + finalMask = float4(0, 0, 0, 1); + + float3 debugColor = float3(0,0,0); + + #ifdef NO_SHADOW + debugColor = float3(1.0,1.0,1.0); + #endif + + #ifdef PSSM_DEBUG_RENDER + if ( finalMask.x > 0 ) + debugColor += float3( 1, 0, 0 ); + else if ( finalMask.y > 0 ) + debugColor += float3( 0, 1, 0 ); + else if ( finalMask.z > 0 ) + debugColor += float3( 0, 0, 1 ); + else if ( finalMask.w > 0 ) + debugColor += float3( 1, 1, 0 ); + #endif + + // Here we know what split we're sampling from, so recompute the texcoord location + // Yes, we could just use the result from above, but doing it this way actually saves + // shader instructions. + float2 finalScale; + finalScale.x = dot(finalMask, scaleX); + finalScale.y = dot(finalMask, scaleY); + + float2 finalOffset; + finalOffset.x = dot(finalMask, offsetX); + finalOffset.y = dot(finalMask, offsetY); + + float2 shadowCoord; + shadowCoord = baseShadowCoord * finalScale; + shadowCoord += finalOffset; + + // Convert to texcoord space + shadowCoord = 0.5 * shadowCoord + float2(0.5, 0.5); + shadowCoord.y = 1.0f - shadowCoord.y; + + // Move around inside of atlas + float2 aOffset; + aOffset.x = dot(finalMask, atlasXOffset); + aOffset.y = dot(finalMask, atlasYOffset); + + shadowCoord *= atlasScale; + shadowCoord += aOffset; + + // Each split has a different far plane, take this into account. + float farPlaneScale = dot( farPlaneScalePSSM, finalMask ); + distToLight *= farPlaneScale; + + return float4(debugColor, + softShadow_filter( TORQUE_SAMPLER2D_MAKEARG(sourceShadowMap), + texCoord, + shadowCoord, + farPlaneScale * shadowSoftness, + distToLight, + dotNL, + dot( finalMask, overDarkPSSM ) ) ); +}; + +float4 main( FarFrustumQuadConnectP IN ) : TORQUE_TARGET0 +{ + // Emissive. + float4 matInfo = TORQUE_TEX2D( matInfoBuffer, IN.uv0 ); + bool emissive = getFlag( matInfo.r, 0 ); + if ( emissive ) + { + return float4(1.0, 1.0, 1.0, 0.0); + } + + float4 colorSample = TORQUE_TEX2D( colorBuffer, IN.uv0 ); + float3 subsurface = float3(0.0,0.0,0.0); + if (getFlag( matInfo.r, 1 )) + { + subsurface = colorSample.rgb; + if (colorSample.r>colorSample.g) + subsurface = float3(0.772549, 0.337255, 0.262745); + else + subsurface = float3(0.337255, 0.772549, 0.262745); + } + // Sample/unpack the normal/z data + float4 prepassSample = TORQUE_PREPASS_UNCONDITION( prePassBuffer, IN.uv0 ); + float3 normal = prepassSample.rgb; + float depth = prepassSample.a; + + // Use eye ray to get ws pos + float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f); + + // Get the light attenuation. + float dotNL = dot(-lightDirection, normal); + + #ifdef PSSM_DEBUG_RENDER + float3 debugColor = float3(0,0,0); + #endif + + #ifdef NO_SHADOW + + // Fully unshadowed. + float shadowed = 1.0; + + #ifdef PSSM_DEBUG_RENDER + debugColor = float3(1.0,1.0,1.0); + #endif + + #else + + float4 static_shadowed_colors = AL_VectorLightShadowCast( TORQUE_SAMPLER2D_MAKEARG(shadowMap), + IN.uv0.xy, + worldToLightProj, + worldPos, + scaleX, scaleY, + offsetX, offsetY, + farPlaneScalePSSM, + atlasXOffset, atlasYOffset, + atlasScale, + shadowSoftness, + dotNL, + overDarkPSSM); + float4 dynamic_shadowed_colors = AL_VectorLightShadowCast( TORQUE_SAMPLER2D_MAKEARG(dynamicShadowMap), + IN.uv0.xy, + dynamicWorldToLightProj, + worldPos, + dynamicScaleX, dynamicScaleY, + dynamicOffsetX, dynamicOffsetY, + dynamicFarPlaneScalePSSM, + atlasXOffset, atlasYOffset, + atlasScale, + shadowSoftness, + dotNL, + overDarkPSSM); + + float static_shadowed = static_shadowed_colors.a; + float dynamic_shadowed = dynamic_shadowed_colors.a; + + #ifdef PSSM_DEBUG_RENDER + debugColor = static_shadowed_colors.rgb*0.5+dynamic_shadowed_colors.rgb*0.5; + #endif + + // Fade out the shadow at the end of the range. + float4 zDist = (zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth); + float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y; + + static_shadowed = lerp( static_shadowed, 1.0, saturate( fadeOutAmt ) ); + dynamic_shadowed = lerp( dynamic_shadowed, 1.0, saturate( fadeOutAmt ) ); + + // temp for debugging. uncomment one or the other. + //float shadowed = static_shadowed; + //float shadowed = dynamic_shadowed; + float shadowed = min(static_shadowed, dynamic_shadowed); + + #ifdef PSSM_DEBUG_RENDER + if ( fadeOutAmt > 1.0 ) + debugColor = 1.0; + #endif + + #endif // !NO_SHADOW + + // Specular term + float specular = AL_CalcSpecular( -lightDirection, + normal, + normalize(-IN.vsEyeRay) ) * lightBrightness * shadowed; + + float Sat_NL_Att = saturate( dotNL * shadowed ) * lightBrightness; + float3 lightColorOut = lightMapParams.rgb * lightColor.rgb; + + float4 addToResult = (lightAmbient * (1 - ambientCameraFactor)) + ( lightAmbient * ambientCameraFactor * saturate(dot(normalize(-IN.vsEyeRay), normal)) ); + + // TODO: This needs to be removed when lightmapping is disabled + // as its extra work per-pixel on dynamic lit scenes. + // + // Special lightmapping pass. + if ( lightMapParams.a < 0.0 ) + { + // This disables shadows on the backsides of objects. + shadowed = dotNL < 0.0f ? 1.0f : shadowed; + + Sat_NL_Att = 1.0f; + lightColorOut = shadowed; + specular *= lightBrightness; + addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + } + + // Sample the AO texture. + #ifdef USE_SSAO_MASK + float ao = 1.0 - TORQUE_TEX2D( ssaoMask, viewportCoordToRenderTarget( IN.uv0.xy, rtParams3 ) ).r; + addToResult *= ao; + #endif + + #ifdef PSSM_DEBUG_RENDER + lightColorOut = debugColor; + #endif + + return AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att); +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/basic/gl/shadowFilterP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/basic/gl/shadowFilterP.glsl new file mode 100644 index 000000000..9b510e0cf --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/basic/gl/shadowFilterP.glsl @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" + +uniform sampler2D diffuseMap; + +in vec2 uv; + +uniform vec2 oneOverTargetSize; + +const float offset[3] = float[]( 0.0, 1.3846153846, 3.2307692308 ); +const float weight[3] = float[]( 0.2270270270, 0.3162162162, 0.0702702703 ); + +out vec4 OUT_col; + +void main() +{ + OUT_col = texture( diffuseMap, uv ) * weight[0]; + + for ( int i=1; i < 3; i++ ) + { + vec2 _sample = (BLUR_DIR * offset[i]) * oneOverTargetSize; + OUT_col += texture( diffuseMap, uv + _sample ) * weight[i]; + OUT_col += texture( diffuseMap, uv - _sample ) * weight[i]; + } +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/basic/gl/shadowFilterV.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/basic/gl/shadowFilterV.glsl new file mode 100644 index 000000000..0eeb2e0fd --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/basic/gl/shadowFilterV.glsl @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../../../../shaders/common/gl/torque.glsl" + +in vec4 vPosition; +in vec2 vTexCoord0; + +uniform vec4 rtParams0; + +out vec2 uv; + +void main() +{ + gl_Position = vPosition; + uv = viewportCoordToRenderTarget( vTexCoord0.st, rtParams0 ); + gl_Position.y *= -1; //correct ssp +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/basic/shadowFilterP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/basic/shadowFilterP.hlsl new file mode 100644 index 000000000..b56aade8d --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/basic/shadowFilterP.hlsl @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "shaders/common/postFx/postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0); + +struct VertToPix +{ + float4 hpos : TORQUE_POSITION; + float2 uv : TEXCOORD0; +}; + +static float offset[3] = { 0.0, 1.3846153846, 3.2307692308 }; +static float weight[3] = { 0.2270270270, 0.3162162162, 0.0702702703 }; + +uniform float2 oneOverTargetSize; + +float4 main( VertToPix IN ) : TORQUE_TARGET0 +{ + float4 OUT = TORQUE_TEX2D( diffuseMap, IN.uv ) * weight[0]; + + for ( int i=1; i < 3; i++ ) + { + float2 sample = (BLUR_DIR * offset[i]) * oneOverTargetSize; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv + sample ) * weight[i]; + OUT += TORQUE_TEX2D(diffuseMap, IN.uv - sample) * weight[i]; + } + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/basic/shadowFilterV.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/basic/shadowFilterV.hlsl new file mode 100644 index 000000000..c89af7357 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/basic/shadowFilterV.hlsl @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../../../../shaders/common/postFx/postFx.hlsl" +#include "../../../../../../shaders/common/torque.hlsl" + +float4 rtParams0; + +struct VertToPix +{ + float4 hpos : TORQUE_POSITION; + float2 uv : TEXCOORD0; +}; + +VertToPix main( PFXVert IN ) +{ + VertToPix OUT; + + OUT.hpos = float4(IN.pos,1.0); + OUT.uv = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/boxFilterP.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/boxFilterP.hlsl new file mode 100644 index 000000000..a187c3c63 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/boxFilterP.hlsl @@ -0,0 +1,82 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//***************************************************************************** +// Box Filter +//***************************************************************************** +#include "../ShaderModel.hlsl" + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float2 tex0 : TEXCOORD0; +}; + +// If not defined from ShaderData then define +// the default blur kernel size here. +//#ifndef blurSamples +// #define blurSamples 4 +//#endif + +float log_conv ( float x0, float X, float y0, float Y ) +{ + return (X + log(x0 + (y0 * exp(Y - X)))); +} + +TORQUE_UNIFORM_SAMPLER2D(diffuseMap0, 0); +uniform float texSize : register(C0); +uniform float2 blurDimension : register(C2); +uniform float2 blurBoundaries : register(C3); + +float4 main( ConnectData IN ) : TORQUE_TARGET0 +{ + // 5x5 + if (IN.tex0.x <= blurBoundaries.x) + { + float texelSize = 1.2f / texSize; + float2 sampleOffset = texelSize * blurDimension; + //float2 offset = 0.5 * float( blurSamples ) * sampleOffset; + + float2 texCoord = IN.tex0; + + float accum = log_conv(0.3125, TORQUE_TEX2D(diffuseMap0, texCoord - sampleOffset), 0.375, tex2D(diffuseMap0, texCoord)); + accum = log_conv(1, accum, 0.3125, TORQUE_TEX2D(diffuseMap0, texCoord + sampleOffset)); + + return accum; + } else { + // 3x3 + if (IN.tex0.x <= blurBoundaries.y) + { + float texelSize = 1.3f / texSize; + float2 sampleOffset = texelSize * blurDimension; + //float2 offset = 0.5 * float( blurSamples ) * sampleOffset; + + float2 texCoord = IN.tex0; + float accum = log_conv(0.5, tex2D(diffuseMap0, texCoord - sampleOffset), 0.5, tex2D(diffuseMap0, texCoord + sampleOffset)); + + return accum; + } else { + return TORQUE_TEX2D(diffuseMap0, IN.tex0); + } + } +} + diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/boxFilterV.hlsl b/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/boxFilterV.hlsl new file mode 100644 index 000000000..3679e41bb --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/boxFilterV.hlsl @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//***************************************************************************** +// Box Filter +//***************************************************************************** +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- + +#include "../ShaderModel.hlsl" + +struct VertData +{ + float3 position : POSITION; + float2 texCoord : TEXCOORD0; +}; + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float2 tex0 : TEXCOORD0; +}; + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN, + uniform float4x4 modelview : register(C0)) +{ + ConnectData OUT; + + OUT.hpos = mul(modelview, float4(IN.position,1.0)); + OUT.tex0 = IN.texCoord; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/gl/boxFilterP.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/gl/boxFilterP.glsl new file mode 100644 index 000000000..d4e05132b --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/gl/boxFilterP.glsl @@ -0,0 +1,49 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#define blurSamples 4.0 + +uniform sampler2D diffuseMap0; +uniform float texSize; +uniform vec2 blurDimension; + +in vec2 tex0; + +out vec4 OUT_col; + +void main() +{ + // Preshader + float TexelSize = 1.0 / texSize; + vec2 SampleOffset = TexelSize * blurDimension; + vec2 Offset = 0.5 * float(blurSamples - 1.0) * SampleOffset; + + vec2 BaseTexCoord = tex0 - Offset; + + vec4 accum = vec4(0.0, 0.0, 0.0, 0.0); + for(int i = 0; i < int(blurSamples); i++) + { + accum += texture(diffuseMap0, BaseTexCoord + float(i) * SampleOffset); + } + accum /= blurSamples; + OUT_col = accum; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/gl/boxFilterV.glsl b/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/gl/boxFilterV.glsl new file mode 100644 index 000000000..9fc436f6c --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/gl/boxFilterV.glsl @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +in vec4 vPosition; +in vec2 vTexCoord0; + +uniform mat4 modelview; + +out vec2 tex0; + +void main() +{ + gl_Position = modelview * vPosition; + tex0 = vTexCoord0.st; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/shadowMapIO.h b/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/shadowMapIO.h new file mode 100644 index 000000000..84ef6b6a8 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/shadowMapIO.h @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//#define SM_Fmt_R8G8B8A8 + +#define pkDepthBitShft 65536.0 +#define pkDepthChanMax 256.0 +#define bias -0.5/255.0 +#define coeff 0.9999991 +//#define coeff 1.0 + +float4 encodeShadowMap( float depth ) +{ +#if defined(SM_Fmt_R8G8B8A8) + return frac( float4(1.0, 255.0, 65025.0, 160581375.0) * depth ) + bias; + + //float4 packedValue = frac((depth / coeff) * float4(16777216.0, 65536.0, 256.0, 1.0)); + //return (packedValue - packedValue.xxyz * float4(0, 1.0 / 256, 1.0 / 256, 1.0 / 256)); +#else + return depth; +#endif +} + +float decodeShadowMap( float4 smSample ) +{ +#if defined(SM_Fmt_R8G8B8A8) + return dot( smSample, float4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) ); +#else + return smSample.x; +#endif +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/shadowMapIO_GLSL.h b/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/shadowMapIO_GLSL.h new file mode 100644 index 000000000..10d69b834 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/shadowMapIO_GLSL.h @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//#define SM_Fmt_R8G8B8A8 + +#define pkDepthBitShft 65536.0 +#define pkDepthChanMax 256.0 +#define bias -0.5/255.0 +#define coeff 0.9999991 +//#define coeff 1.0 + +vec4 encodeShadowMap( float depth ) +{ +#if defined(SM_Fmt_R8G8B8A8) + return frac( vec4(1.0, 255.0, 65025.0, 160581375.0) * depth ) + vec4(bias); + + //float4 packedValue = frac((depth / coeff) * float4(16777216.0, 65536.0, 256.0, 1.0)); + //return (packedValue - packedValue.xxyz * float4(0, 1.0 / 256, 1.0 / 256, 1.0 / 256)); +#else + return vec4(depth); +#endif +} + +float decodeShadowMap( vec4 smSample ) +{ +#if defined(SM_Fmt_R8G8B8A8) + return dot( smSample, vec4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) ); +#else + return smSample.x; +#endif +} diff --git a/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/shadowMapIO_HLSL.h b/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/shadowMapIO_HLSL.h new file mode 100644 index 000000000..84ef6b6a8 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/lighting/shadowMap/shadowMapIO_HLSL.h @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//#define SM_Fmt_R8G8B8A8 + +#define pkDepthBitShft 65536.0 +#define pkDepthChanMax 256.0 +#define bias -0.5/255.0 +#define coeff 0.9999991 +//#define coeff 1.0 + +float4 encodeShadowMap( float depth ) +{ +#if defined(SM_Fmt_R8G8B8A8) + return frac( float4(1.0, 255.0, 65025.0, 160581375.0) * depth ) + bias; + + //float4 packedValue = frac((depth / coeff) * float4(16777216.0, 65536.0, 256.0, 1.0)); + //return (packedValue - packedValue.xxyz * float4(0, 1.0 / 256, 1.0 / 256, 1.0 / 256)); +#else + return depth; +#endif +} + +float decodeShadowMap( float4 smSample ) +{ +#if defined(SM_Fmt_R8G8B8A8) + return dot( smSample, float4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) ); +#else + return smSample.x; +#endif +} diff --git a/Templates/BaseGame/game/data/shaders/common/particleCompositeP.hlsl b/Templates/BaseGame/game/data/shaders/common/particleCompositeP.hlsl new file mode 100644 index 000000000..6e26ddbdb --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/particleCompositeP.hlsl @@ -0,0 +1,61 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "torque.hlsl" +#include "shaderModel.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(colorSource, 0); +uniform float4 offscreenTargetParams; + +#ifdef TORQUE_LINEAR_DEPTH +#define REJECT_EDGES +TORQUE_UNIFORM_SAMPLER2D(edgeSource, 1); +uniform float4 edgeTargetParams; +#endif + +struct Conn +{ + float4 hpos : TORQUE_POSITION; + float4 offscreenPos : TEXCOORD0; + float4 backbufferPos : TEXCOORD1; +}; + + +float4 main(Conn IN) : TORQUE_TARGET0 +{ + // Off-screen particle source screenspace position in XY + // Back-buffer screenspace position in ZW + float4 ssPos = float4(IN.offscreenPos.xy / IN.offscreenPos.w, IN.backbufferPos.xy / IN.backbufferPos.w); + + float4 uvScene = ( ssPos + 1.0 ) / 2.0; + uvScene.yw = 1.0 - uvScene.yw; + uvScene.xy = viewportCoordToRenderTarget(uvScene.xy, offscreenTargetParams); + +#ifdef REJECT_EDGES + // Cut out particles along the edges, this will create the stencil mask + uvScene.zw = viewportCoordToRenderTarget(uvScene.zw, edgeTargetParams); + float edge = TORQUE_TEX2D( edgeSource, uvScene.zw ).r; + clip( -edge ); +#endif + + // Sample offscreen target and return + return TORQUE_TEX2D( colorSource, uvScene.xy ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/particleCompositeV.hlsl b/Templates/BaseGame/game/data/shaders/common/particleCompositeV.hlsl new file mode 100644 index 000000000..c4c51204a --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/particleCompositeV.hlsl @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "shaderModel.hlsl" + +struct Vertex +{ + float3 pos : POSITION; + float4 uvCoord : COLOR0; +}; + +struct Conn +{ + float4 hpos : TORQUE_POSITION; + float4 offscreenPos : TEXCOORD0; + float4 backbufferPos : TEXCOORD1; +}; + +uniform float4 screenRect; // point, extent + +Conn main(Vertex IN) +{ + Conn OUT; + + OUT.hpos = float4(IN.uvCoord.xy, 1.0, 1.0); + OUT.hpos.xy *= screenRect.zw; + OUT.hpos.xy += screenRect.xy; + + OUT.backbufferPos = OUT.hpos; + OUT.offscreenPos = OUT.hpos; + + return OUT; +} + diff --git a/Templates/BaseGame/game/data/shaders/common/particlesP.hlsl b/Templates/BaseGame/game/data/shaders/common/particlesP.hlsl new file mode 100644 index 000000000..37439c59a --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/particlesP.hlsl @@ -0,0 +1,109 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "torque.hlsl" +#include "shaderModel.hlsl" +// With advanced lighting we get soft particles. +#ifdef TORQUE_LINEAR_DEPTH + #define SOFTPARTICLES +#endif + +#ifdef SOFTPARTICLES + + #include "shaderModelAutoGen.hlsl" + + uniform float oneOverSoftness; + uniform float oneOverFar; + TORQUE_UNIFORM_SAMPLER2D(prepassTex, 1); + //uniform float3 vEye; + uniform float4 prePassTargetParams; +#endif + +#define CLIP_Z // TODO: Make this a proper macro + +struct Conn +{ + float4 hpos : TORQUE_POSITION; + float4 color : TEXCOORD0; + float2 uv0 : TEXCOORD1; + float4 pos : TEXCOORD2; +}; + +TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0); +TORQUE_UNIFORM_SAMPLER2D(paraboloidLightMap, 2); + +float4 lmSample( float3 nrm ) +{ + bool calcBack = (nrm.z < 0.0); + if ( calcBack ) + nrm.z = nrm.z * -1.0; + + float2 lmCoord; + lmCoord.x = (nrm.x / (2*(1 + nrm.z))) + 0.5; + lmCoord.y = 1-((nrm.y / (2*(1 + nrm.z))) + 0.5); + + + // If this is the back, offset in the atlas + if ( calcBack ) + lmCoord.x += 1.0; + + // Atlasing front and back maps, so scale + lmCoord.x *= 0.5; + + return TORQUE_TEX2D(paraboloidLightMap, lmCoord); +} + + +uniform float alphaFactor; +uniform float alphaScale; + +float4 main( Conn IN ) : TORQUE_TARGET0 +{ + float softBlend = 1; + + #ifdef SOFTPARTICLES + float2 tc = IN.pos.xy * float2(1.0, -1.0) / IN.pos.w; + tc = viewportCoordToRenderTarget(saturate( ( tc + 1.0 ) * 0.5 ), prePassTargetParams); + + float sceneDepth = TORQUE_PREPASS_UNCONDITION(prepassTex, tc).w; + float depth = IN.pos.w * oneOverFar; + float diff = sceneDepth - depth; + #ifdef CLIP_Z + // If drawing offscreen, this acts as the depth test, since we don't line up with the z-buffer + // When drawing high-res, though, we want to be able to take advantage of hi-z + // so this is #ifdef'd out + //clip(diff); + #endif + softBlend = saturate( diff * oneOverSoftness ); + #endif + + float4 diffuse = TORQUE_TEX2D( diffuseMap, IN.uv0 ); + + //return float4( lmSample(float3(0, 0, -1)).rgb, IN.color.a * diffuse.a * softBlend * alphaScale); + + // Scale output color by the alpha factor (turn LerpAlpha into pre-multiplied alpha) + float3 colorScale = ( alphaFactor < 0.0 ? IN.color.rgb * diffuse.rgb : ( alphaFactor > 0.0 ? IN.color.a * diffuse.a * alphaFactor * softBlend : softBlend ) ); + + return hdrEncode( float4( IN.color.rgb * diffuse.rgb * colorScale, + IN.color.a * diffuse.a * softBlend * alphaScale ) ); +} + diff --git a/Templates/BaseGame/game/data/shaders/common/particlesV.hlsl b/Templates/BaseGame/game/data/shaders/common/particlesV.hlsl new file mode 100644 index 000000000..dbeff0cc2 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/particlesV.hlsl @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "shaderModel.hlsl" + +struct Vertex +{ + float3 pos : POSITION; + float4 color : COLOR0; + float2 uv0 : TEXCOORD0; +}; + +struct Conn +{ + float4 hpos : TORQUE_POSITION; + float4 color : TEXCOORD0; + float2 uv0 : TEXCOORD1; + float4 pos : TEXCOORD2; +}; + + +uniform float4x4 modelViewProj; +uniform float4x4 fsModelViewProj; + +Conn main( Vertex In ) +{ + Conn Out; + + Out.hpos = mul( modelViewProj, float4(In.pos,1.0) ); + Out.pos = mul(fsModelViewProj, float4(In.pos, 1.0) ); + Out.color = In.color; + Out.uv0 = In.uv0; + + return Out; +} + diff --git a/Templates/BaseGame/game/data/shaders/common/planarReflectBumpP.hlsl b/Templates/BaseGame/game/data/shaders/common/planarReflectBumpP.hlsl new file mode 100644 index 000000000..d18331fb6 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/planarReflectBumpP.hlsl @@ -0,0 +1,87 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- + +#include "shaderModel.hlsl" + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float2 texCoord : TEXCOORD0; + float4 tex2 : TEXCOORD1; +}; + + +struct Fragout +{ + float4 col : TORQUE_TARGET0; +}; + +TORQUE_UNIFORM_SAMPLER2D(texMap, 0); +TORQUE_UNIFORM_SAMPLER2D(refractMap, 1); +TORQUE_UNIFORM_SAMPLER2D(bumpMap, 2); + + +//----------------------------------------------------------------------------- +// Fade edges of axis for texcoord passed in +//----------------------------------------------------------------------------- +float fadeAxis( float val ) +{ + // Fades from 1.0 to 0.0 when less than 0.1 + float fadeLow = saturate( val * 10.0 ); + + // Fades from 1.0 to 0.0 when greater than 0.9 + float fadeHigh = 1.0 - saturate( (val - 0.9) * 10.0 ); + + return fadeLow * fadeHigh; +} + + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN ) +{ + Fragout OUT; + + float3 bumpNorm = TORQUE_TEX2D( bumpMap, IN.tex2 ) * 2.0 - 1.0; + float2 offset = float2( bumpNorm.x, bumpNorm.y ); + float4 texIndex = IN.texCoord; + + // The fadeVal is used to "fade" the distortion at the edges of the screen. + // This is done so it won't sample the reflection texture out-of-bounds and create artifacts + // Note - this can be done more efficiently with a texture lookup + float fadeVal = fadeAxis( texIndex.x / texIndex.w ) * fadeAxis( texIndex.y / texIndex.w ); + + const float distortion = 0.2; + texIndex.xy += offset * distortion * fadeVal; + + float4 reflectColor = TORQUE_TEX2DPROJ( refractMap, texIndex ); + float4 diffuseColor = TORQUE_TEX2D( texMap, IN.tex2 ); + + OUT.col = diffuseColor + reflectColor * diffuseColor.a; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/planarReflectBumpV.hlsl b/Templates/BaseGame/game/data/shaders/common/planarReflectBumpV.hlsl new file mode 100644 index 000000000..d45adb574 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/planarReflectBumpV.hlsl @@ -0,0 +1,67 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#define IN_HLSL +#include "shdrConsts.h" +#include "shaderModel.hlsl" + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct VertData +{ + float3 position : POSITION; + float3 normal : NORMAL; + float2 texCoord : TEXCOORD0; + float2 lmCoord : TEXCOORD1; + float3 T : TEXCOORD2; + float3 B : TEXCOORD3; +}; + + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float4 texCoord : TEXCOORD0; + float2 tex2 : TEXCOORD1; +}; + +uniform float4x4 modelview; +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN ) +{ + ConnectData OUT; + OUT.hpos = mul(modelview, float4(IN.position,1.0)); + + float4x4 texGenTest = { 0.5, 0.0, 0.0, 0.5, + 0.0, -0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 }; + + OUT.texCoord = mul( texGenTest, OUT.hpos ); + + OUT.tex2 = IN.texCoord; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/planarReflectP.hlsl b/Templates/BaseGame/game/data/shaders/common/planarReflectP.hlsl new file mode 100644 index 000000000..43b420544 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/planarReflectP.hlsl @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- + +#include "shaderModel.hlsl" + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float2 texCoord : TEXCOORD0; + float4 tex2 : TEXCOORD1; +}; + + +struct Fragout +{ + float4 col : TORQUE_TARGET0; +}; + +TORQUE_UNIFORM_SAMPLER2D(texMap, 0); +TORQUE_UNIFORM_SAMPLER2D(refractMap, 1); + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main( ConnectData IN ) +{ + Fragout OUT; + + float4 diffuseColor = TORQUE_TEX2D( texMap, IN.texCoord ); + float4 reflectColor = TORQUE_TEX2DPROJ(refractMap, IN.tex2); + + OUT.col = diffuseColor + reflectColor * diffuseColor.a; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/planarReflectV.hlsl b/Templates/BaseGame/game/data/shaders/common/planarReflectV.hlsl new file mode 100644 index 000000000..1f2ca9d4f --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/planarReflectV.hlsl @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#define IN_HLSL +#include "hlslStructs.hlsl" +#include "shaderModel.hlsl" + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float2 texCoord : TEXCOORD0; + float4 tex2 : TEXCOORD1; +}; + +uniform float4x4 modelview; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertexIn_PNTTTB IN ) +{ + ConnectData OUT; + OUT.hpos = mul(modelview, float4(IN.pos,1.0)); + + float4x4 texGenTest = { 0.5, 0.0, 0.0, 0.5, + 0.0, -0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 }; + + OUT.texCoord = IN.uv0; + OUT.tex2 = mul( texGenTest, OUT.hpos ); + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/VolFogGlowP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/VolFogGlowP.hlsl new file mode 100644 index 000000000..c3adb3b55 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/VolFogGlowP.hlsl @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2014 R.G.S. - Richards Game Studio, the Netherlands +// http://www.richardsgamestudio.com/ +// +// If you find this code useful or you are feeling particularly generous I +// would ask that you please go to http://www.richardsgamestudio.com/ then +// choose Donations from the menu on the left side and make a donation to +// Richards Game Studio. It will be highly appreciated. +// +// The MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Volumetric Fog Glow postFx pixel shader V1.00 + +#include "./postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0); +uniform float strength; + +struct VertToPix +{ + float4 hpos : TORQUE_POSITION; + + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + float2 uv3 : TEXCOORD3; + + float2 uv4 : TEXCOORD4; + float2 uv5 : TEXCOORD5; + float2 uv6 : TEXCOORD6; + float2 uv7 : TEXCOORD7; +}; + +float4 main( VertToPix IN ) : TORQUE_TARGET0 +{ + float4 kernel = float4( 0.175, 0.275, 0.375, 0.475 ) * strength; + + float4 OUT = 0; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv0 ) * kernel.x; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv1 ) * kernel.y; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv2 ) * kernel.z; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv3 ) * kernel.w; + + OUT += TORQUE_TEX2D( diffuseMap, IN.uv4 ) * kernel.x; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv5 ) * kernel.y; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv6 ) * kernel.z; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv7 ) * kernel.w; + + // Calculate a lumenance value in the alpha so we + // can use alpha test to save fillrate. + float3 rgb2lum = float3( 0.30, 0.59, 0.11 ); + OUT.a = dot( OUT.rgb, rgb2lum ); + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/caustics/causticsP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/caustics/causticsP.hlsl new file mode 100644 index 000000000..d2f4a058a --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/caustics/causticsP.hlsl @@ -0,0 +1,77 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" +#include "../../shaderModelAutoGen.hlsl" + +uniform float accumTime; +uniform float3 eyePosWorld; +uniform float4 rtParams0; +uniform float4 waterFogPlane; + +TORQUE_UNIFORM_SAMPLER2D(prepassTex, 0); +TORQUE_UNIFORM_SAMPLER2D(causticsTex0, 1); +TORQUE_UNIFORM_SAMPLER2D(causticsTex1, 2); + +float distanceToPlane(float4 plane, float3 pos) +{ + return (plane.x * pos.x + plane.y * pos.y + plane.z * pos.z) + plane.w; +} + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + //Sample the pre-pass + float4 prePass = TORQUE_PREPASS_UNCONDITION( prepassTex, IN.uv0 ); + + //Get depth + float depth = prePass.w; + if(depth > 0.9999) + return float4(0,0,0,0); + + //Get world position + float3 pos = eyePosWorld + IN.wsEyeRay * depth; + + // Check the water depth + float waterDepth = -distanceToPlane(waterFogPlane, pos); + if(waterDepth < 0) + return float4(0,0,0,0); + waterDepth = saturate(waterDepth); + + //Use world position X and Y to calculate caustics UV + float2 causticsUV0 = (abs(pos.xy * 0.25) % float2(1, 1)); + float2 causticsUV1 = (abs(pos.xy * 0.2) % float2(1, 1)); + + //Animate uvs + float timeSin = sin(accumTime); + causticsUV0.xy += float2(accumTime*0.1, timeSin*0.2); + causticsUV1.xy -= float2(accumTime*0.15, timeSin*0.15); + + //Sample caustics texture + float4 caustics = TORQUE_TEX2D(causticsTex0, causticsUV0); + caustics *= TORQUE_TEX2D(causticsTex1, causticsUV1); + + //Use normal Z to modulate caustics + //float waterDepth = 1 - saturate(pos.z + waterFogPlane.w + 1); + caustics *= saturate(prePass.z) * pow(abs(1-depth), 64) * waterDepth; + + return caustics; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/caustics/gl/causticsP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/caustics/gl/causticsP.glsl new file mode 100644 index 000000000..2d2a54154 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/caustics/gl/causticsP.glsl @@ -0,0 +1,87 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "../../gl/postFX.glsl" +#include "shadergen:/autogenConditioners.h" + +uniform vec3 eyePosWorld; +uniform vec4 rtParams0; +uniform vec4 waterFogPlane; +uniform float accumTime; + +uniform sampler2D prepassTex; +uniform sampler2D causticsTex0; +uniform sampler2D causticsTex1; +uniform vec2 targetSize; + +out vec4 OUT_col; + +float distanceToPlane(vec4 plane, vec3 pos) +{ + return (plane.x * pos.x + plane.y * pos.y + plane.z * pos.z) + plane.w; +} + +void main() +{ + //Sample the pre-pass + vec4 prePass = prepassUncondition( prepassTex, IN_uv0 ); + + //Get depth + float depth = prePass.w; + if(depth > 0.9999) + { + OUT_col = vec4(0,0,0,0); + return; + } + + //Get world position + vec3 pos = eyePosWorld + IN_wsEyeRay * depth; + + // Check the water depth + float waterDepth = -distanceToPlane(waterFogPlane, pos); + if(waterDepth < 0) + { + OUT_col = vec4(0,0,0,0); + return; + } + waterDepth = saturate(waterDepth); + + //Use world position X and Y to calculate caustics UV + vec2 causticsUV0 = mod(abs(pos.xy * 0.25), vec2(1, 1)); + vec2 causticsUV1 = mod(abs(pos.xy * 0.2), vec2(1, 1)); + + //Animate uvs + float timeSin = sin(accumTime); + causticsUV0.xy += vec2(accumTime*0.1, timeSin*0.2); + causticsUV1.xy -= vec2(accumTime*0.15, timeSin*0.15); + + //Sample caustics texture + vec4 caustics = texture(causticsTex0, causticsUV0); + caustics *= texture(causticsTex1, causticsUV1); + + //Use normal Z to modulate caustics + //float waterDepth = 1 - saturate(pos.z + waterFogPlane.w + 1); + caustics *= saturate(prePass.z) * pow(1-depth, 64) * waterDepth; + + OUT_col = caustics; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/chromaticLens.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/chromaticLens.hlsl new file mode 100644 index 000000000..8fdca72b7 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/chromaticLens.hlsl @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Based on 'Cubic Lens Distortion HLSL Shader' by François Tarlier +// www.francois-tarlier.com/blog/index.php/2009/11/cubic-lens-distortion-shader + +#include "./postFx.hlsl" +#include "./../torque.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(backBuffer, 0); +uniform float distCoeff; +uniform float cubeDistort; +uniform float3 colorDistort; + + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float2 tex = IN.uv0; + + float f = 0; + float r2 = (tex.x - 0.5) * (tex.x - 0.5) + (tex.y - 0.5) * (tex.y - 0.5); + + // Only compute the cubic distortion if necessary. + if ( cubeDistort == 0.0 ) + f = 1 + r2 * distCoeff; + else + f = 1 + r2 * (distCoeff + cubeDistort * sqrt(r2)); + + // Distort each color channel seperately to get a chromatic distortion effect. + float3 outColor; + float3 distort = f.xxx + colorDistort; + + for ( int i=0; i < 3; i++ ) + { + float x = distort[i] * ( tex.x - 0.5 ) + 0.5; + float y = distort[i] * ( tex.y - 0.5 ) + 0.5; + outColor[i] = TORQUE_TEX2DLOD( backBuffer, float4(x,y,0,0) )[i]; + } + + return float4( outColor.rgb, 1 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_CalcCoC_P.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_CalcCoC_P.hlsl new file mode 100644 index 000000000..2f5835fc2 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_CalcCoC_P.hlsl @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" + +// These are set by the game engine. +TORQUE_UNIFORM_SAMPLER2D(shrunkSampler, 0); // Output of DofDownsample() +TORQUE_UNIFORM_SAMPLER2D(blurredSampler, 1); // Blurred version of the shrunk sampler + + +// This is the pixel shader function that calculates the actual +// value used for the near circle of confusion. +// "texCoords" are 0 at the bottom left pixel and 1 at the top right. +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float3 color; + float coc; + half4 blurred; + half4 shrunk; + + shrunk = half4(TORQUE_TEX2D( shrunkSampler, IN.uv0 )); + blurred = half4(TORQUE_TEX2D( blurredSampler, IN.uv1 )); + color = shrunk.rgb; + //coc = shrunk.a; + //coc = blurred.a; + //coc = max( blurred.a, shrunk.a ); + coc = 2 * max( blurred.a, shrunk.a ) - shrunk.a; + + + //return float4( coc.rrr, 1.0 ); + //return float4( color, 1.0 ); + return float4( color, coc ); + //return float4( 1.0, 0.0, 1.0, 1.0 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_CalcCoC_V.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_CalcCoC_V.hlsl new file mode 100644 index 000000000..8131e45cd --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_CalcCoC_V.hlsl @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + +uniform float4 rtParams0; +uniform float4 rtParams1; +uniform float4 rtParams2; +uniform float4 rtParams3; + +PFXVertToPix main( PFXVert IN ) +{ + PFXVertToPix OUT; + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv; + OUT.uv1 = IN.uv; + OUT.uv2 = IN.uv; + OUT.uv3 = IN.uv; + */ + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv + rtParams0.xy; + OUT.uv1 = IN.uv + rtParams1.xy; + OUT.uv2 = IN.uv + rtParams2.xy; + OUT.uv3 = IN.uv + rtParams3.xy; + */ + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv * rtParams0.zw; + OUT.uv1 = IN.uv * rtParams1.zw; + OUT.uv2 = IN.uv * rtParams2.zw; + OUT.uv3 = IN.uv * rtParams3.zw; + */ + + + OUT.hpos = float4(IN.pos,1.0); + OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + OUT.uv1 = viewportCoordToRenderTarget( IN.uv, rtParams1 ); + OUT.uv2 = viewportCoordToRenderTarget( IN.uv, rtParams2 ); + OUT.uv3 = viewportCoordToRenderTarget( IN.uv, rtParams3 ); + + + OUT.wsEyeRay = IN.wsEyeRay; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_DownSample_P.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_DownSample_P.hlsl new file mode 100644 index 000000000..8c9028654 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_DownSample_P.hlsl @@ -0,0 +1,143 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../shaderModel.hlsl" +#include "../../shaderModelAutoGen.hlsl" + +// These are set by the game engine. +// The render target size is one-quarter the scene rendering size. +TORQUE_UNIFORM_SAMPLER2D(colorSampler, 0); +TORQUE_UNIFORM_SAMPLER2D(depthSampler, 1); +uniform float2 dofEqWorld; +uniform float2 targetSize; +uniform float depthOffset; +uniform float maxWorldCoC; +//uniform float2 dofEqWeapon; +//uniform float2 dofRowDelta; // float2( 0, 0.25 / renderTargetHeight ) + +struct Pixel +{ + float4 position : TORQUE_POSITION; + float2 tcColor0 : TEXCOORD0; + float2 tcColor1 : TEXCOORD1; + float2 tcDepth0 : TEXCOORD2; + float2 tcDepth1 : TEXCOORD3; + float2 tcDepth2 : TEXCOORD4; + float2 tcDepth3 : TEXCOORD5; +}; + +half4 main( Pixel IN ) : TORQUE_TARGET0 +{ + //return float4( 1.0, 0.0, 1.0, 1.0 ); + + float2 dofRowDelta = float2( 0, 0.25 / targetSize.y ); + + //float2 dofEqWorld = float2( -60, 1.0 ); + + half3 color; + half maxCoc; + float4 depth; + half4 viewCoc; + half4 sceneCoc; + half4 curCoc; + half4 coc; + float2 rowOfs[4]; + + // "rowOfs" reduces how many moves PS2.0 uses to emulate swizzling. + rowOfs[0] = 0; + rowOfs[1] = dofRowDelta.xy; + rowOfs[2] = dofRowDelta.xy * 2; + rowOfs[3] = dofRowDelta.xy * 3; + + // Use bilinear filtering to average 4 color samples for free. + color = 0; + color += half3(TORQUE_TEX2D( colorSampler, IN.tcColor0.xy + rowOfs[0] ).rgb); + color += half3(TORQUE_TEX2D(colorSampler, IN.tcColor1.xy + rowOfs[0]).rgb); + color += half3(TORQUE_TEX2D(colorSampler, IN.tcColor0.xy + rowOfs[2]).rgb); + color += half3(TORQUE_TEX2D(colorSampler, IN.tcColor1.xy + rowOfs[2]).rgb); + color /= 4; + + //declare thse here to save doing it in each loop below + half4 zero4 = half4(0, 0, 0, 0); + coc = zero4; + half4 dofEqWorld4X = half4(dofEqWorld.xxxx); + half4 dofEqWorld4Y = half4(dofEqWorld.yyyy); + half4 maxWorldCoC4 = half4(maxWorldCoC, maxWorldCoC, maxWorldCoC, maxWorldCoC); + // Process 4 samples at a time to use vector hardware efficiently. + // The CoC will be 1 if the depth is negative, so use "min" to pick + // between "sceneCoc" and "viewCoc". + [unroll] // coc[i] causes this anyway + for (int i = 0; i < 4; i++) + { + depth[0] = TORQUE_PREPASS_UNCONDITION(depthSampler, (IN.tcDepth0.xy + rowOfs[i])).w; + depth[1] = TORQUE_PREPASS_UNCONDITION(depthSampler, (IN.tcDepth1.xy + rowOfs[i])).w; + depth[2] = TORQUE_PREPASS_UNCONDITION(depthSampler, (IN.tcDepth2.xy + rowOfs[i])).w; + depth[3] = TORQUE_PREPASS_UNCONDITION(depthSampler, (IN.tcDepth3.xy + rowOfs[i])).w; + + coc = max(coc, clamp(dofEqWorld4X * half4(depth)+dofEqWorld4Y, zero4, maxWorldCoC4)); + } + + /* + depth[0] = TORQUE_TEX2D( depthSampler, pixel.tcDepth0.xy + rowOfs[0] ).r; + depth[1] = TORQUE_TEX2D( depthSampler, pixel.tcDepth1.xy + rowOfs[0] ).r; + depth[2] = TORQUE_TEX2D( depthSampler, pixel.tcDepth2.xy + rowOfs[0] ).r; + depth[3] = TORQUE_TEX2D( depthSampler, pixel.tcDepth3.xy + rowOfs[0] ).r; + viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y ); + sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y ); + curCoc = min( viewCoc, sceneCoc ); + coc = curCoc; + + depth[0] = TORQUE_TEX2D( depthSampler, pixel.tcDepth0.xy + rowOfs[1] ).r; + depth[1] = TORQUE_TEX2D( depthSampler, pixel.tcDepth1.xy + rowOfs[1] ).r; + depth[2] = TORQUE_TEX2D( depthSampler, pixel.tcDepth2.xy + rowOfs[1] ).r; + depth[3] = TORQUE_TEX2D( depthSampler, pixel.tcDepth3.xy + rowOfs[1] ).r; + viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y ); + sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y ); + curCoc = min( viewCoc, sceneCoc ); + coc = max( coc, curCoc ); + + depth[0] = TORQUE_TEX2D( depthSampler, pixel.tcDepth0.xy + rowOfs[2] ).r; + depth[1] = TORQUE_TEX2D( depthSampler, pixel.tcDepth1.xy + rowOfs[2] ).r; + depth[2] = TORQUE_TEX2D( depthSampler, pixel.tcDepth2.xy + rowOfs[2] ).r; + depth[3] = TORQUE_TEX2D( depthSampler, pixel.tcDepth3.xy + rowOfs[2] ).r; + viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y ); + sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y ); + curCoc = min( viewCoc, sceneCoc ); + coc = max( coc, curCoc ); + + depth[0] = TORQUE_TEX2D( depthSampler, pixel.tcDepth0.xy + rowOfs[3] ).r; + depth[1] = TORQUE_TEX2D( depthSampler, pixel.tcDepth1.xy + rowOfs[3] ).r; + depth[2] = TORQUE_TEX2D( depthSampler, pixel.tcDepth2.xy + rowOfs[3] ).r; + depth[3] = TORQUE_TEX2D( depthSampler, pixel.tcDepth3.xy + rowOfs[3] ).r; + viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y ); + sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y ); + curCoc = min( viewCoc, sceneCoc ); + coc = max( coc, curCoc ); + */ + + maxCoc = max( max( coc[0], coc[1] ), max( coc[2], coc[3] ) ); + + //return half4( 1.0, 0.0, 1.0, 1.0 ); + return half4( color, maxCoc ); + //return half4( color, 1.0f ); + //return half4( maxCoc.rrr, 1.0 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_DownSample_V.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_DownSample_V.hlsl new file mode 100644 index 000000000..0b3ec01e2 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_DownSample_V.hlsl @@ -0,0 +1,61 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + +struct Vert +{ + float3 pos : POSITION; + float2 tc : TEXCOORD0; + float3 wsEyeRay : TEXCOORD1; +}; + +struct Pixel +{ + float4 position : TORQUE_POSITION; + float2 tcColor0 : TEXCOORD0; + float2 tcColor1 : TEXCOORD1; + float2 tcDepth0 : TEXCOORD2; + float2 tcDepth1 : TEXCOORD3; + float2 tcDepth2 : TEXCOORD4; + float2 tcDepth3 : TEXCOORD5; +}; + +uniform float4 rtParams0; +uniform float2 oneOverTargetSize; + +Pixel main( Vert IN ) +{ + Pixel OUT; + OUT.position = float4(IN.pos,1.0); + + float2 uv = viewportCoordToRenderTarget( IN.tc, rtParams0 ); + //OUT.position = mul( IN.pos, modelView ); + OUT.tcColor1 = uv + float2( +1.0, -0.0 ) * oneOverTargetSize; + OUT.tcColor0 = uv + float2( -1.0, -0.0 ) * oneOverTargetSize; + OUT.tcDepth0 = uv + float2( -0.5, -0.0 ) * oneOverTargetSize; + OUT.tcDepth1 = uv + float2( -1.5, -0.0 ) * oneOverTargetSize; + OUT.tcDepth2 = uv + float2( +1.5, -0.0 ) * oneOverTargetSize; + OUT.tcDepth3 = uv + float2( +2.5, -0.0 ) * oneOverTargetSize; + return OUT; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_Final_P.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_Final_P.hlsl new file mode 100644 index 000000000..cb7342d40 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_Final_P.hlsl @@ -0,0 +1,145 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../shaderModelAutoGen.hlsl" +#include "./../postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(colorSampler,0); // Original source image +TORQUE_UNIFORM_SAMPLER2D(smallBlurSampler,1); // Output of SmallBlurPS() +TORQUE_UNIFORM_SAMPLER2D(largeBlurSampler,2); // Blurred output of DofDownsample() +TORQUE_UNIFORM_SAMPLER2D(depthSampler,3); + +uniform float2 oneOverTargetSize; +uniform float4 dofLerpScale; +uniform float4 dofLerpBias; +uniform float3 dofEqFar; +uniform float maxFarCoC; + +//static float d0 = 0.1; +//static float d1 = 0.1; +//static float d2 = 0.8; +//static float4 dofLerpScale = float4( -1.0 / d0, -1.0 / d1, -1.0 / d2, 1.0 / d2 ); +//static float4 dofLerpBias = float4( 1.0, (1.0 - d2) / d1, 1.0 / d2, (d2 - 1.0) / d2 ); +//static float3 dofEqFar = float3( 2.0, 0.0, 1.0 ); + +float4 tex2Doffset(TORQUE_SAMPLER2D(s), float2 tc, float2 offset) +{ + return TORQUE_TEX2D( s, tc + offset * oneOverTargetSize ); +} + +half3 GetSmallBlurSample( float2 tc ) +{ + half3 sum; + const half weight = 4.0 / 17; + sum = 0; // Unblurred sample done by alpha blending + //sum += weight * tex2Doffset( colorSampler, tc, float2( 0, 0 ) ).rgb; + sum += weight * half3(tex2Doffset(TORQUE_SAMPLER2D_MAKEARG(colorSampler), tc, float2(+0.5, -1.5)).rgb); + sum += weight * half3(tex2Doffset(TORQUE_SAMPLER2D_MAKEARG(colorSampler), tc, float2(-1.5, -0.5)).rgb); + sum += weight * half3(tex2Doffset(TORQUE_SAMPLER2D_MAKEARG(colorSampler), tc, float2(-0.5, +1.5)).rgb); + sum += weight * half3(tex2Doffset(TORQUE_SAMPLER2D_MAKEARG(colorSampler), tc, float2(+1.5, +0.5)).rgb); + return sum; +} + +half4 InterpolateDof( half3 small, half3 med, half3 large, half t ) +{ + //t = 2; + half4 weights; + half3 color; + half alpha; + + // Efficiently calculate the cross-blend weights for each sample. + // Let the unblurred sample to small blur fade happen over distance + // d0, the small to medium blur over distance d1, and the medium to + // large blur over distance d2, where d0 + d1 + d2 = 1. + //float4 dofLerpScale = float4( -1 / d0, -1 / d1, -1 / d2, 1 / d2 ); + //float4 dofLerpBias = float4( 1, (1 – d2) / d1, 1 / d2, (d2 – 1) / d2 ); + + weights = half4(saturate( t * dofLerpScale + dofLerpBias )); + weights.yz = min( weights.yz, 1 - weights.xy ); + + // Unblurred sample with weight "weights.x" done by alpha blending + color = weights.y * small + weights.z * med + weights.w * large; + //color = med; + alpha = dot( weights.yzw, half3( 16.0 / 17, 1.0, 1.0 ) ); + //alpha = 0.0; + + return half4( color, alpha ); +} + +half4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + //return half4( 1,0,1,1 ); + //return half4( TORQUE_TEX2D( colorSampler, IN.uv0 ).rgb, 1.0 ); + //return half4( TORQUE_TEX2D( colorSampler, texCoords ).rgb, 0 ); + half3 small; + half4 med; + half3 large; + half depth; + half nearCoc; + half farCoc; + half coc; + + small = GetSmallBlurSample( IN.uv0 ); + //small = half3( 1,0,0 ); + //return half4( small, 1.0 ); + med = half4(TORQUE_TEX2D( smallBlurSampler, IN.uv1 )); + //med.rgb = half3( 0,1,0 ); + //return half4(med.rgb, 0.0); + large = half3(TORQUE_TEX2D(largeBlurSampler, IN.uv2).rgb); + //large = half3( 0,0,1 ); + //return large; + //return half4(large.rgb,1.0); + nearCoc = med.a; + + // Since the med blur texture is screwed up currently + // replace it with the large, but this needs to be fixed. + //med.rgb = large; + + //nearCoc = 0; + depth = half(TORQUE_PREPASS_UNCONDITION( depthSampler, IN.uv3 ).w); + //return half4(depth.rrr,1); + //return half4(nearCoc.rrr,1.0); + + if (depth > 0.999 ) + { + coc = nearCoc; // We don't want to blur the sky. + //coc = 0; + } + else + { + // dofEqFar.x and dofEqFar.y specify the linear ramp to convert + // to depth for the distant out-of-focus region. + // dofEqFar.z is the ratio of the far to the near blur radius. + farCoc = half(clamp( dofEqFar.x * depth + dofEqFar.y, 0.0, maxFarCoC )); + coc = half(max( nearCoc, farCoc * dofEqFar.z )); + //coc = nearCoc; + } + + //coc = nearCoc; + //coc = farCoc; + //return half4(coc.rrr,0.5); + //return half4(farCoc.rrr,1); + //return half4(nearCoc.rrr,1); + + //return half4( 1,0,1,0 ); + return InterpolateDof( small, med.rgb, large, coc ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_Final_V.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_Final_V.hlsl new file mode 100644 index 000000000..86c93701a --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_Final_V.hlsl @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + +uniform float4 rtParams0; +uniform float4 rtParams1; +uniform float4 rtParams2; +uniform float4 rtParams3; +uniform float2 oneOverTargetSize; + +PFXVertToPix main( PFXVert IN ) +{ + PFXVertToPix OUT; + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv; + OUT.uv1 = IN.uv; + OUT.uv2 = IN.uv; + OUT.uv3 = IN.uv; + */ + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv + rtParams0.xy; + OUT.uv1 = IN.uv + rtParams1.xy; + OUT.uv2 = IN.uv + rtParams2.xy; + OUT.uv3 = IN.uv + rtParams3.xy; + */ + + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv * rtParams0.zw; + OUT.uv1 = IN.uv * rtParams1.zw; + OUT.uv2 = IN.uv * rtParams2.zw; + OUT.uv3 = IN.uv * rtParams3.zw; + */ + + + OUT.hpos = float4(IN.pos,1.0); + OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + OUT.uv1 = viewportCoordToRenderTarget( IN.uv, rtParams1 ); // + float2( -5, 1 ) * oneOverTargetSize; + OUT.uv2 = viewportCoordToRenderTarget( IN.uv, rtParams2 ); + OUT.uv3 = viewportCoordToRenderTarget( IN.uv, rtParams3 ); + + + OUT.wsEyeRay = IN.wsEyeRay; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_Gausian_P.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_Gausian_P.hlsl new file mode 100644 index 000000000..f4d29f3e1 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_Gausian_P.hlsl @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0); + +struct VertToPix +{ + float4 hpos : TORQUE_POSITION; + + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + float2 uv3 : TEXCOORD3; + + float2 uv4 : TEXCOORD4; + float2 uv5 : TEXCOORD5; + float2 uv6 : TEXCOORD6; + float2 uv7 : TEXCOORD7; +}; + +float4 main( VertToPix IN ) : TORQUE_TARGET0 +{ + float4 kernel = float4( 0.175, 0.275, 0.375, 0.475 ) * 0.5 / 1.3; //25f; + + float4 OUT = 0; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv0 ) * kernel.x; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv1 ) * kernel.y; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv2 ) * kernel.z; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv3 ) * kernel.w; + + OUT += TORQUE_TEX2D( diffuseMap, IN.uv4 ) * kernel.x; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv5 ) * kernel.y; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv6 ) * kernel.z; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv7 ) * kernel.w; + + // Calculate a lumenance value in the alpha so we + // can use alpha test to save fillrate. + //float3 rgb2lum = float3( 0.30, 0.59, 0.11 ); + //OUT.a = dot( OUT.rgb, rgb2lum ); + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_Gausian_V.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_Gausian_V.hlsl new file mode 100644 index 000000000..b2d4582e0 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_Gausian_V.hlsl @@ -0,0 +1,80 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + + +uniform float4 rtParams0; +uniform float2 texSize0; +uniform float2 oneOverTargetSize; + +struct VertToPix +{ + float4 hpos : TORQUE_POSITION; + + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + float2 uv3 : TEXCOORD3; + + float2 uv4 : TEXCOORD4; + float2 uv5 : TEXCOORD5; + float2 uv6 : TEXCOORD6; + float2 uv7 : TEXCOORD7; +}; + +VertToPix main( PFXVert IN ) +{ + VertToPix OUT; + + OUT.hpos = float4(IN.pos,1.0); + + IN.uv = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + + // I don't know why this offset is necessary, but it is. + //IN.uv = IN.uv * oneOverTargetSize; + + OUT.uv0 = IN.uv + ( ( BLUR_DIR * 3.5f ) / texSize0 ); + OUT.uv1 = IN.uv + ( ( BLUR_DIR * 2.5f ) / texSize0 ); + OUT.uv2 = IN.uv + ( ( BLUR_DIR * 1.5f ) / texSize0 ); + OUT.uv3 = IN.uv + ( ( BLUR_DIR * 0.5f ) / texSize0 ); + + OUT.uv4 = IN.uv - ( ( BLUR_DIR * 3.5f ) / texSize0 ); + OUT.uv5 = IN.uv - ( ( BLUR_DIR * 2.5f ) / texSize0 ); + OUT.uv6 = IN.uv - ( ( BLUR_DIR * 1.5f ) / texSize0 ); + OUT.uv7 = IN.uv - ( ( BLUR_DIR * 0.5f ) / texSize0 ); + + /* + OUT.uv0 = viewportCoordToRenderTarget( OUT.uv0, rtParams0 ); + OUT.uv1 = viewportCoordToRenderTarget( OUT.uv1, rtParams0 ); + OUT.uv2 = viewportCoordToRenderTarget( OUT.uv2, rtParams0 ); + OUT.uv3 = viewportCoordToRenderTarget( OUT.uv3, rtParams0 ); + + OUT.uv4 = viewportCoordToRenderTarget( OUT.uv4, rtParams0 ); + OUT.uv5 = viewportCoordToRenderTarget( OUT.uv5, rtParams0 ); + OUT.uv6 = viewportCoordToRenderTarget( OUT.uv6, rtParams0 ); + OUT.uv7 = viewportCoordToRenderTarget( OUT.uv7, rtParams0 ); + */ + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_Passthrough_V.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_Passthrough_V.hlsl new file mode 100644 index 000000000..8131e45cd --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_Passthrough_V.hlsl @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + +uniform float4 rtParams0; +uniform float4 rtParams1; +uniform float4 rtParams2; +uniform float4 rtParams3; + +PFXVertToPix main( PFXVert IN ) +{ + PFXVertToPix OUT; + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv; + OUT.uv1 = IN.uv; + OUT.uv2 = IN.uv; + OUT.uv3 = IN.uv; + */ + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv + rtParams0.xy; + OUT.uv1 = IN.uv + rtParams1.xy; + OUT.uv2 = IN.uv + rtParams2.xy; + OUT.uv3 = IN.uv + rtParams3.xy; + */ + + /* + OUT.hpos = IN.pos; + OUT.uv0 = IN.uv * rtParams0.zw; + OUT.uv1 = IN.uv * rtParams1.zw; + OUT.uv2 = IN.uv * rtParams2.zw; + OUT.uv3 = IN.uv * rtParams3.zw; + */ + + + OUT.hpos = float4(IN.pos,1.0); + OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + OUT.uv1 = viewportCoordToRenderTarget( IN.uv, rtParams1 ); + OUT.uv2 = viewportCoordToRenderTarget( IN.uv, rtParams2 ); + OUT.uv3 = viewportCoordToRenderTarget( IN.uv, rtParams3 ); + + + OUT.wsEyeRay = IN.wsEyeRay; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_SmallBlur_P.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_SmallBlur_P.hlsl new file mode 100644 index 000000000..175525a91 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_SmallBlur_P.hlsl @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// This vertex and pixel shader applies a 3 x 3 blur to the image in +// colorMapSampler, which is the same size as the render target. +// The sample weights are 1/16 in the corners, 2/16 on the edges, +// and 4/16 in the center. +#include "../../shaderModel.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(colorSampler, 0); // Output of DofNearCoc() + +struct Pixel +{ + float4 position : TORQUE_POSITION; + float4 texCoords : TEXCOORD0; +}; + +float4 main( Pixel IN ) : TORQUE_TARGET0 +{ + float4 color; + color = 0.0; + color += TORQUE_TEX2D( colorSampler, IN.texCoords.xz ); + color += TORQUE_TEX2D( colorSampler, IN.texCoords.yz ); + color += TORQUE_TEX2D( colorSampler, IN.texCoords.xw ); + color += TORQUE_TEX2D( colorSampler, IN.texCoords.yw ); + return color / 4.0; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_SmallBlur_V.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_SmallBlur_V.hlsl new file mode 100644 index 000000000..3edb1ec2a --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/DOF_SmallBlur_V.hlsl @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// This vertex and pixel shader applies a 3 x 3 blur to the image in +// colorMapSampler, which is the same size as the render target. +// The sample weights are 1/16 in the corners, 2/16 on the edges, +// and 4/16 in the center. + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + +struct Vert +{ + float3 position : POSITION; + float2 texCoords : TEXCOORD0; +}; + +struct Pixel +{ + float4 position : TORQUE_POSITION; + float4 texCoords : TEXCOORD0; +}; + +uniform float2 oneOverTargetSize; +uniform float4 rtParams0; + +Pixel main( Vert IN ) +{ + Pixel OUT; + const float4 halfPixel = { -0.5, 0.5, -0.5, 0.5 }; + OUT.position = float4(IN.position,1.0); //Transform_ObjectToClip( IN.position ); + + //float2 uv = IN.texCoords + rtParams0.xy; + float2 uv = viewportCoordToRenderTarget( IN.texCoords, rtParams0 ); + OUT.texCoords = uv.xxyy + halfPixel * oneOverTargetSize.xxyy; + return OUT; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_CalcCoC_P.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_CalcCoC_P.glsl new file mode 100644 index 000000000..38cb099c4 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_CalcCoC_P.glsl @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "../../gl/postFX.glsl" + +// These are set by the game engine. +uniform sampler2D shrunkSampler; // Output of DofDownsample() +uniform sampler2D blurredSampler; // Blurred version of the shrunk sampler + +out vec4 OUT_col; + +// This is the pixel shader function that calculates the actual +// value used for the near circle of confusion. +// "texCoords" are 0 at the bottom left pixel and 1 at the top right. +void main() +{ + vec3 color; + float coc; + half4 blurred; + half4 shrunk; + + shrunk = texture( shrunkSampler, IN_uv0 ); + blurred = texture( blurredSampler, IN_uv1 ); + color = shrunk.rgb; + //coc = shrunk.a; + //coc = blurred.a; + //coc = max( blurred.a, shrunk.a ); + coc = 2 * max( blurred.a, shrunk.a ) - shrunk.a; + + + //OUT_col = vec4( coc.rrr, 1.0 ); + //OUT_col = vec4( color, 1.0 ); + OUT_col = vec4( color, coc ); + //OUT_col = vec4( 1.0, 0.0, 1.0, 1.0 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_CalcCoC_V.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_CalcCoC_V.glsl new file mode 100644 index 000000000..d02ce6551 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_CalcCoC_V.glsl @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "../../../gl/torque.glsl" +#include "../../gl/postFX.glsl" + +uniform vec4 rtParams0; +uniform vec4 rtParams1; +uniform vec4 rtParams2; +uniform vec4 rtParams3; + +void main() +{ + /* + OUT_hpos = IN.pos; + OUT_uv0 = IN_uv; + OUT_uv1 = IN_uv; + OUT_uv2 = IN_uv; + OUT_uv3 = IN_uv; + */ + + /* + OUT_hpos = IN_pos; + OUT_uv0 = IN_uv + rtParams0.xy; + OUT_uv1 = IN_uv + rtParams1.xy; + OUT_uv2 = IN_uv + rtParams2.xy; + OUT_uv3 = IN_uv + rtParams3.xy; + */ + + /* + OUT_hpos = IN_pos; + OUT_uv0 = IN_uv * rtParams0.zw; + OUT_uv1 = IN_uv * rtParams1.zw; + OUT_uv2 = IN_uv * rtParams2.zw; + OUT_uv3 = IN_uv * rtParams3.zw; + */ + + + OUT_hpos = IN_pos; + OUT_uv0 = viewportCoordToRenderTarget( IN_uv, rtParams0 ); + OUT_uv1 = viewportCoordToRenderTarget( IN_uv, rtParams1 ); + OUT_uv2 = viewportCoordToRenderTarget( IN_uv, rtParams2 ); + OUT_uv3 = viewportCoordToRenderTarget( IN_uv, rtParams3 ); + + + OUT_wsEyeRay = IN_wsEyeRay; + + correctSSP(gl_Position);; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_DownSample_P.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_DownSample_P.glsl new file mode 100644 index 000000000..17f23e487 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_DownSample_P.glsl @@ -0,0 +1,143 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" + +// These are set by the game engine. +// The render target size is one-quarter the scene rendering size. +uniform sampler2D colorSampler; +uniform sampler2D depthSampler; +uniform vec2 dofEqWorld; +uniform float depthOffset; +uniform vec2 targetSize; +uniform float maxWorldCoC; +//uniform vec2 dofEqWeapon; +//uniform vec2 dofRowDelta; // vec2( 0, 0.25 / renderTargetHeight ) + +in vec2 tcColor0; +#define IN_tcColor0 tcColor0 +in vec2 tcColor1; +#define IN_tcColor1 tcColor1 +in vec2 tcDepth0; +#define IN_tcDepth0 tcDepth0 +in vec2 tcDepth1; +#define IN_tcDepth1 tcDepth1 +in vec2 tcDepth2; +#define IN_tcDepth2 tcDepth2 +in vec2 tcDepth3; +#define IN_tcDepth3 tcDepth3 + +out vec4 OUT_col; + +void main() +{ + //return vec4( 1.0, 0.0, 1.0, 1.0 ); + + vec2 dofRowDelta = vec2( 0, 0.25 / targetSize.y ); + + //vec2 dofEqWorld = vec2( -60, 1.0 ); + + half3 color; + half maxCoc; + vec4 depth; + half4 viewCoc; + half4 sceneCoc; + half4 curCoc; + half4 coc; + vec2 rowOfs[4]; + + // "rowOfs" reduces how many moves PS2.0 uses to emulate swizzling. + rowOfs[0] = vec2(0); + rowOfs[1] = dofRowDelta.xy; + rowOfs[2] = dofRowDelta.xy * 2; + rowOfs[3] = dofRowDelta.xy * 3; + + // Use bilinear filtering to average 4 color samples for free. + color = half3(0); + color += texture( colorSampler, IN_tcColor0.xy + rowOfs[0] ).rgb; + color += texture( colorSampler, IN_tcColor1.xy + rowOfs[0] ).rgb; + color += texture( colorSampler, IN_tcColor0.xy + rowOfs[2] ).rgb; + color += texture( colorSampler, IN_tcColor1.xy + rowOfs[2] ).rgb; + color /= 4; + + // Process 4 samples at a time to use vector hardware efficiently. + // The CoC will be 1 if the depth is negative, so use "min" to pick + // between "sceneCoc" and "viewCoc". + + coc = half4(0); + for ( int i = 0; i < 4; i++ ) + { + depth[0] = prepassUncondition( depthSampler, ( IN_tcDepth0.xy + rowOfs[i] ) ).w; + depth[1] = prepassUncondition( depthSampler, ( IN_tcDepth1.xy + rowOfs[i] ) ).w; + depth[2] = prepassUncondition( depthSampler, ( IN_tcDepth2.xy + rowOfs[i] ) ).w; + depth[3] = prepassUncondition( depthSampler, ( IN_tcDepth3.xy + rowOfs[i] ) ).w; + + // @todo OPENGL INTEL need review + coc = max( coc, clamp( half4(dofEqWorld.x) * depth + half4(dofEqWorld.y), half4(0.0), half4(maxWorldCoC) ) ); + } + + /* + depth[0] = texture( depthSampler, pixel.tcDepth0.xy + rowOfs[0] ).r; + depth[1] = texture( depthSampler, pixel.tcDepth1.xy + rowOfs[0] ).r; + depth[2] = texture( depthSampler, pixel.tcDepth2.xy + rowOfs[0] ).r; + depth[3] = texture( depthSampler, pixel.tcDepth3.xy + rowOfs[0] ).r; + viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y ); + sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y ); + curCoc = min( viewCoc, sceneCoc ); + coc = curCoc; + + depth[0] = texture( depthSampler, pixel.tcDepth0.xy + rowOfs[1] ).r; + depth[1] = texture( depthSampler, pixel.tcDepth1.xy + rowOfs[1] ).r; + depth[2] = texture( depthSampler, pixel.tcDepth2.xy + rowOfs[1] ).r; + depth[3] = texture( depthSampler, pixel.tcDepth3.xy + rowOfs[1] ).r; + viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y ); + sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y ); + curCoc = min( viewCoc, sceneCoc ); + coc = max( coc, curCoc ); + + depth[0] = texture( depthSampler, pixel.tcDepth0.xy + rowOfs[2] ).r; + depth[1] = texture( depthSampler, pixel.tcDepth1.xy + rowOfs[2] ).r; + depth[2] = texture( depthSampler, pixel.tcDepth2.xy + rowOfs[2] ).r; + depth[3] = texture( depthSampler, pixel.tcDepth3.xy + rowOfs[2] ).r; + viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y ); + sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y ); + curCoc = min( viewCoc, sceneCoc ); + coc = max( coc, curCoc ); + + depth[0] = texture( depthSampler, pixel.tcDepth0.xy + rowOfs[3] ).r; + depth[1] = texture( depthSampler, pixel.tcDepth1.xy + rowOfs[3] ).r; + depth[2] = texture( depthSampler, pixel.tcDepth2.xy + rowOfs[3] ).r; + depth[3] = texture( depthSampler, pixel.tcDepth3.xy + rowOfs[3] ).r; + viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y ); + sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y ); + curCoc = min( viewCoc, sceneCoc ); + coc = max( coc, curCoc ); + */ + + maxCoc = max( max( coc[0], coc[1] ), max( coc[2], coc[3] ) ); + + //OUT_col = half4( 1.0, 0.0, 1.0, 1.0 ); + OUT_col = half4( color, maxCoc ); + //OUT_col = half4( color, 1.0f ); + //OUT_col = half4( maxCoc.rrr, 1.0 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_DownSample_V.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_DownSample_V.glsl new file mode 100644 index 000000000..b8e840c9e --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_DownSample_V.glsl @@ -0,0 +1,67 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "../../../gl/torque.glsl" + +in vec4 vPosition; +in vec2 vTexCoord0; +in vec3 vTexCoord1; + +#define IN_pos vPosition +#define IN_tc vTexCoord0 +#define IN_wsEyeRay vTexCoord1 + +#define OUT_position gl_Position + +out vec2 tcColor0; +#define OUT_tcColor0 tcColor0 +out vec2 tcColor1; +#define OUT_tcColor1 tcColor1 +out vec2 tcDepth0; +#define OUT_tcDepth0 tcDepth0 +out vec2 tcDepth1; +#define OUT_tcDepth1 tcDepth1 +out vec2 tcDepth2; +#define OUT_tcDepth2 tcDepth2 +out vec2 tcDepth3; +#define OUT_tcDepth3 tcDepth3 + + +uniform vec4 rtParams0; +uniform vec2 oneOverTargetSize; + +void main() +{ + OUT_position = IN_pos; + + vec2 uv = viewportCoordToRenderTarget( IN_tc, rtParams0 ); + //OUT_position = tMul( IN_pos, modelView ); + OUT_tcColor1 = uv + vec2( +1.0, -0.0 ) * oneOverTargetSize; + OUT_tcColor0 = uv + vec2( -1.0, -0.0 ) * oneOverTargetSize; + OUT_tcDepth0 = uv + vec2( -0.5, -0.0 ) * oneOverTargetSize; + OUT_tcDepth1 = uv + vec2( -1.5, -0.0 ) * oneOverTargetSize; + OUT_tcDepth2 = uv + vec2( +1.5, -0.0 ) * oneOverTargetSize; + OUT_tcDepth3 = uv + vec2( +2.5, -0.0 ) * oneOverTargetSize; + + correctSSP(gl_Position); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_Final_P.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_Final_P.glsl new file mode 100644 index 000000000..40b71bc27 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_Final_P.glsl @@ -0,0 +1,147 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../gl/postFX.glsl" + +uniform sampler2D colorSampler; // Original source image +uniform sampler2D smallBlurSampler; // Output of SmallBlurPS() +uniform sampler2D largeBlurSampler; // Blurred output of DofDownsample() +uniform sampler2D depthSampler; // +uniform vec2 oneOverTargetSize; +uniform vec4 dofLerpScale; +uniform vec4 dofLerpBias; +uniform vec3 dofEqFar; +uniform float maxFarCoC; + +//static float d0 = 0.1; +//static float d1 = 0.1; +//static float d2 = 0.8; +//static vec4 dofLerpScale = vec4( -1.0 / d0, -1.0 / d1, -1.0 / d2, 1.0 / d2 ); +//static vec4 dofLerpBias = vec4( 1.0, (1.0 - d2) / d1, 1.0 / d2, (d2 - 1.0) / d2 ); +//static vec3 dofEqFar = vec3( 2.0, 0.0, 1.0 ); + +out vec4 OUT_col; + +vec4 tex2Doffset( sampler2D s, vec2 tc, vec2 offset ) +{ + return texture( s, tc + offset * oneOverTargetSize ); +} + +half3 GetSmallBlurSample( vec2 tc ) +{ + half3 sum; + const half weight = 4.0 / 17; + sum = half3(0); // Unblurred sample done by alpha blending + //sum += weight * tex2Doffset( colorSampler, tc, vec2( 0, 0 ) ).rgb; + sum += weight * tex2Doffset( colorSampler, tc, vec2( +0.5, -1.5 ) ).rgb; + sum += weight * tex2Doffset( colorSampler, tc, vec2( -1.5, -0.5 ) ).rgb; + sum += weight * tex2Doffset( colorSampler, tc, vec2( -0.5, +1.5 ) ).rgb; + sum += weight * tex2Doffset( colorSampler, tc, vec2( +1.5, +0.5 ) ).rgb; + return sum; +} + +half4 InterpolateDof( half3 small, half3 med, half3 large, half t ) +{ + //t = 2; + half4 weights; + half3 color; + half alpha; + + // Efficiently calculate the cross-blend weights for each sample. + // Let the unblurred sample to small blur fade happen over distance + // d0, the small to medium blur over distance d1, and the medium to + // large blur over distance d2, where d0 + d1 + d2 = 1. + //vec4 dofLerpScale = vec4( -1 / d0, -1 / d1, -1 / d2, 1 / d2 ); + //vec4 dofLerpBias = vec4( 1, (1 – d2) / d1, 1 / d2, (d2 – 1) / d2 ); + + weights = saturate( t * dofLerpScale + dofLerpBias ); + weights.yz = min( weights.yz, 1 - weights.xy ); + + // Unblurred sample with weight "weights.x" done by alpha blending + color = weights.y * small + weights.z * med + weights.w * large; + //color = med; + alpha = dot( weights.yzw, half3( 16.0 / 17, 1.0, 1.0 ) ); + //alpha = 0.0; + + return half4( color, alpha ); +} + +void main() +{ + //return half4( 1,0,1,1 ); + //return half4( texture( colorSampler, IN_uv0 ).rgb, 1.0 ); + //return half4( texture( colorSampler, texCoords ).rgb, 0 ); + half3 small; + half4 med; + half3 large; + half depth; + half nearCoc; + half farCoc; + half coc; + + small = GetSmallBlurSample( IN_uv0 ); + //small = half3( 1,0,0 ); + //return half4( small, 1.0 ); + med = texture( smallBlurSampler, IN_uv1 ); + //med.rgb = half3( 0,1,0 ); + //return half4(med.rgb, 0.0); + large = texture( largeBlurSampler, IN_uv2 ).rgb; + //large = half3( 0,0,1 ); + //return large; + //return half4(large.rgb,1.0); + nearCoc = med.a; + + // Since the med blur texture is screwed up currently + // replace it with the large, but this needs to be fixed. + //med.rgb = large; + + //nearCoc = 0; + depth = prepassUncondition( depthSampler, IN_uv3 ).w; + //return half4(depth.rrr,1); + //return half4(nearCoc.rrr,1.0); + + if (depth > 0.999 ) + { + coc = nearCoc; // We don't want to blur the sky. + //coc = 0; + } + else + { + // dofEqFar.x and dofEqFar.y specify the linear ramp to convert + // to depth for the distant out-of-focus region. + // dofEqFar.z is the ratio of the far to the near blur radius. + farCoc = clamp( dofEqFar.x * depth + dofEqFar.y, 0.0, maxFarCoC ); + coc = max( nearCoc, farCoc * dofEqFar.z ); + //coc = nearCoc; + } + + //coc = nearCoc; + //coc = farCoc; + //return half4(coc.rrr,0.5); + //return half4(farCoc.rrr,1); + //return half4(nearCoc.rrr,1); + + //return half4( 1,0,1,0 ); + OUT_col = InterpolateDof( small, med.rgb, large, coc ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_Final_V.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_Final_V.glsl new file mode 100644 index 000000000..abc91246e --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_Final_V.glsl @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "../../../gl/torque.glsl" +#include "../../gl/postFX.glsl" + +uniform vec4 rtParams0; +uniform vec4 rtParams1; +uniform vec4 rtParams2; +uniform vec4 rtParams3; +uniform vec2 oneOverTargetSize; + +void main() +{ + /* + OUT.hpos = IN_pos; + OUT_uv0 = IN_uv; + OUT_uv1 = IN_uv; + OUT_uv2 = IN_uv; + OUT_uv3 = IN_uv; + */ + + /* + OUT_hpos = IN_pos; + OUT_uv0 = IN_uv + rtParams0.xy; + OUT_uv1 = IN_uv + rtParams1.xy; + OUT_uv2 = IN_uv + rtParams2.xy; + OUT_uv3 = IN_uv + rtParams3.xy; + */ + + + /* + OUT_hpos = IN_pos; + OUT_uv0 = IN_uv * rtParams0.zw; + OUT_uv1 = IN_uv * rtParams1.zw; + OUT_uv2 = IN_uv * rtParams2.zw; + OUT_uv3 = IN_uv * rtParams3.zw; + */ + + + OUT_hpos = IN_pos; + OUT_uv0 = viewportCoordToRenderTarget( IN_uv, rtParams0 ); + OUT_uv1 = viewportCoordToRenderTarget( IN_uv, rtParams1 ); // + vec2( -5, 1 ) * oneOverTargetSize; + OUT_uv2 = viewportCoordToRenderTarget( IN_uv, rtParams2 ); + OUT_uv3 = viewportCoordToRenderTarget( IN_uv, rtParams3 ); + + + OUT_wsEyeRay = IN_wsEyeRay; + + correctSSP(gl_Position); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_Gausian_P.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_Gausian_P.glsl new file mode 100644 index 000000000..61e7697af --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_Gausian_P.glsl @@ -0,0 +1,68 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" + +in vec3 wsEyeRay; +#define IN_wsEyeRay wsEyeRay +in vec2 uv0; +#define IN_uv0 uv0 +in vec2 uv1; +#define IN_uv1 uv1 +in vec2 uv2; +#define IN_uv2 uv2 +in vec2 uv3; +#define IN_uv3 uv3 +in vec2 uv4; +#define IN_uv4 uv4 +in vec2 uv5; +#define IN_uv5 uv5 +in vec2 uv6; +#define IN_uv6 uv6 +in vec2 uv7; +#define IN_uv7 uv7 + +out vec4 OUT_col; + +uniform sampler2D diffuseMap; + +void main() +{ + vec4 kernel = vec4( 0.175, 0.275, 0.375, 0.475 ) * 0.5 / 1.3; //25f; + + OUT_col = vec4(0); + OUT_col += texture( diffuseMap, IN_uv0 ) * kernel.x; + OUT_col += texture( diffuseMap, IN_uv1 ) * kernel.y; + OUT_col += texture( diffuseMap, IN_uv2 ) * kernel.z; + OUT_col += texture( diffuseMap, IN_uv3 ) * kernel.w; + + OUT_col += texture( diffuseMap, IN_uv4 ) * kernel.x; + OUT_col += texture( diffuseMap, IN_uv5 ) * kernel.y; + OUT_col += texture( diffuseMap, IN_uv6 ) * kernel.z; + OUT_col += texture( diffuseMap, IN_uv7 ) * kernel.w; + + // Calculate a lumenance value in the alpha so we + // can use alpha test to save fillrate. + //vec3 rgb2lum = vec3( 0.30, 0.59, 0.11 ); + //OUT_col.a = dot( OUT_col.rgb, rgb2lum ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_Gausian_V.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_Gausian_V.glsl new file mode 100644 index 000000000..c77e23c53 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_Gausian_V.glsl @@ -0,0 +1,91 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "../../../gl/torque.glsl" + +in vec4 vPosition; +in vec2 vTexCoord0; +in vec3 vTexCoord1; + +#define IN_pos vPosition +#define _IN_uv vTexCoord0 +#define IN_wsEyeRay vTexCoord1 + +#define OUT_hpos gl_Position +out vec3 wsEyeRay; +#define OUT_wsEyeRay wsEyeRay +out vec2 uv0; +#define OUT_uv0 uv0 +out vec2 uv1; +#define OUT_uv1 uv1 +out vec2 uv2; +#define OUT_uv2 uv2 +out vec2 uv3; +#define OUT_uv3 uv3 +out vec2 uv4; +#define OUT_uv4 uv4 +out vec2 uv5; +#define OUT_uv5 uv5 +out vec2 uv6; +#define OUT_uv6 uv6 +out vec2 uv7; +#define OUT_uv7 uv7 + +uniform vec2 texSize0; +uniform vec4 rtParams0; +uniform vec2 oneOverTargetSize; + + +void main() +{ + OUT_hpos = IN_pos; + + vec2 IN_uv = viewportCoordToRenderTarget( _IN_uv, rtParams0 ); + + // I don't know why this offset is necessary, but it is. + //IN_uv = IN_uv * oneOverTargetSize; + + OUT_uv0 = IN_uv + ( ( BLUR_DIR * 3.5f ) / texSize0 ); + OUT_uv1 = IN_uv + ( ( BLUR_DIR * 2.5f ) / texSize0 ); + OUT_uv2 = IN_uv + ( ( BLUR_DIR * 1.5f ) / texSize0 ); + OUT_uv3 = IN_uv + ( ( BLUR_DIR * 0.5f ) / texSize0 ); + + OUT_uv4 = IN_uv - ( ( BLUR_DIR * 3.5f ) / texSize0 ); + OUT_uv5 = IN_uv - ( ( BLUR_DIR * 2.5f ) / texSize0 ); + OUT_uv6 = IN_uv - ( ( BLUR_DIR * 1.5f ) / texSize0 ); + OUT_uv7 = IN_uv - ( ( BLUR_DIR * 0.5f ) / texSize0 ); + + /* + OUT_uv0 = viewportCoordToRenderTarget( OUT_uv0, rtParams0 ); + OUT_uv1 = viewportCoordToRenderTarget( OUT_uv1, rtParams0 ); + OUT_uv2 = viewportCoordToRenderTarget( OUT_uv2, rtParams0 ); + OUT_uv3 = viewportCoordToRenderTarget( OUT_uv3, rtParams0 ); + + OUT_uv4 = viewportCoordToRenderTarget( OUT_uv4, rtParams0 ); + OUT_uv5 = viewportCoordToRenderTarget( OUT_uv5, rtParams0 ); + OUT_uv6 = viewportCoordToRenderTarget( OUT_uv6, rtParams0 ); + OUT_uv7 = viewportCoordToRenderTarget( OUT_uv7, rtParams0 ); + */ + + correctSSP(gl_Position); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_Passthrough_V.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_Passthrough_V.glsl new file mode 100644 index 000000000..bd02fb7d4 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_Passthrough_V.glsl @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "../../../gl/torque.glsl" +#include "../../gl/postFX.glsl" + +uniform vec4 rtParams0; +uniform vec4 rtParams1; +uniform vec4 rtParams2; +uniform vec4 rtParams3; + +void main() +{ + /* + OUT.hpos = IN_pos; + OUT_uv0 = IN_uv; + OUT_uv1 = IN_uv; + OUT_uv2 = IN_uv; + OUT_uv3 = IN_uv; + */ + + /* + OUT_hpos = IN_pos; + OUT_uv0 = IN_uv + rtParams0.xy; + OUT_uv1 = IN_uv + rtParams1.xy; + OUT_uv2 = IN_uv + rtParams2.xy; + OUT_uv3 = IN_uv + rtParams3.xy; + */ + + /* + OUT_hpos = IN_pos; + OUT_uv0 = IN_uv * rtParams0.zw; + OUT_uv1 = IN_uv * rtParams1.zw; + OUT_uv2 = IN_uv * rtParams2.zw; + OUT_uv3 = IN_uv * rtParams3.zw; + */ + + + OUT_hpos = IN_pos; + OUT_uv0 = viewportCoordToRenderTarget( IN_uv, rtParams0 ); + OUT_uv1 = viewportCoordToRenderTarget( IN_uv, rtParams1 ); + OUT_uv2 = viewportCoordToRenderTarget( IN_uv, rtParams2 ); + OUT_uv3 = viewportCoordToRenderTarget( IN_uv, rtParams3 ); + + + OUT_wsEyeRay = IN_wsEyeRay; + + correctSSP(gl_Position); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_SmallBlur_P.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_SmallBlur_P.glsl new file mode 100644 index 000000000..ae94edd78 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_SmallBlur_P.glsl @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// This vertex and pixel shader applies a 3 x 3 blur to the image in +// colorMapSampler, which is the same size as the render target. +// The sample weights are 1/16 in the corners, 2/16 on the edges, +// and 4/16 in the center. + +#include "../../../gl/hlslCompat.glsl" + +uniform sampler2D colorSampler; // Output of DofNearCoc() + +in vec4 texCoords; +#define IN_texCoords texCoords + +out vec4 OUT_col; + +void main() +{ + vec4 color; + color = vec4(0.0); + color += texture( colorSampler, IN_texCoords.xz ); + color += texture( colorSampler, IN_texCoords.yz ); + color += texture( colorSampler, IN_texCoords.xw ); + color += texture( colorSampler, IN_texCoords.yw ); + OUT_col = color / 4.0; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_SmallBlur_V.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_SmallBlur_V.glsl new file mode 100644 index 000000000..413abd352 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/dof/gl/DOF_SmallBlur_V.glsl @@ -0,0 +1,54 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// This vertex and pixel shader applies a 3 x 3 blur to the image in +// colorMapSampler, which is the same size as the render target. +// The sample weights are 1/16 in the corners, 2/16 on the edges, +// and 4/16 in the center. + +#include "../../../gl/hlslCompat.glsl" +#include "../../../gl/torque.glsl" + +in vec4 vPosition; +in vec2 vTexCoord0; + +#define IN_position vPosition +#define IN_texCoords vTexCoord0 + +#define OUT_position gl_Position +out vec4 texCoords; +#define OUT_texCoords texCoords + +uniform vec2 oneOverTargetSize; +uniform vec4 rtParams0; + +void main() +{ + const vec4 halfPixel = vec4( -0.5, 0.5, -0.5, 0.5 ); + OUT_position = IN_position; //Transform_ObjectToClip( IN_position ); + + //vec2 uv = IN_texCoords + rtParams0.xy; + vec2 uv = viewportCoordToRenderTarget( IN_texCoords, rtParams0 ); + OUT_texCoords = uv.xxyy + halfPixel * oneOverTargetSize.xxyy; + + correctSSP(gl_Position); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/dbgEdgeDisplayP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/dbgEdgeDisplayP.hlsl new file mode 100644 index 000000000..fbd529031 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/dbgEdgeDisplayP.hlsl @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(edgeBuffer); + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + return float4( TORQUE_TEX2D( edgeBuffer, IN.uv0 ).rrr, 1.0 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/edgeAAP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/edgeAAP.hlsl new file mode 100644 index 000000000..f5a71687d --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/edgeAAP.hlsl @@ -0,0 +1,66 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(edgeBuffer,0); +TORQUE_UNIFORM_SAMPLER2D(backBuffer, 1); +uniform float2 targetSize; + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float2 pixelSize = 1.0 / targetSize; + + // Sample edge buffer, bail if not on an edge + float edgeSample = TORQUE_TEX2D(edgeBuffer, IN.uv0).r; + clip(edgeSample - 1e-6); + + // Ok we're on an edge, so multi-tap sample, average, and return + float2 offsets[9] = { + float2( 0.0, 0.0), + float2(-1.0, -1.0), + float2( 0.0, -1.0), + float2( 1.0, -1.0), + float2( 1.0, 0.0), + float2( 1.0, 1.0), + float2( 0.0, 1.0), + float2(-1.0, 1.0), + float2(-1.0, 0.0), + }; + + float4 accumColor = 0; + for(int i = 0; i < 9; i++) + { + // Multiply the intensity of the edge, by the UV, so that things which maybe + // aren't quite full edges get sub-pixel sampling to reduce artifacts + + // Scaling offsets by 0.5 to reduce the range bluriness from extending to + // far outward from the edge. + + float2 offsetUV = IN.uv1 + edgeSample * ( offsets[i] * 0.5 ) * pixelSize;//rtWidthHeightInvWidthNegHeight.zw; + //offsetUV *= 0.999; + accumColor += TORQUE_TEX2D(backBuffer, offsetUV); + } + accumColor /= 9.0; + + return accumColor; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/edgeAAV.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/edgeAAV.hlsl new file mode 100644 index 000000000..4718b40f5 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/edgeAAV.hlsl @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + + +uniform float4 rtParams0; +uniform float4 rtParams1; +uniform float4 rtParams2; +uniform float4 rtParams3; + +PFXVertToPix main( PFXVert IN ) +{ + PFXVertToPix OUT; + + OUT.hpos = IN.pos; + OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + OUT.uv1 = viewportCoordToRenderTarget( IN.uv, rtParams1 ); + OUT.uv2 = viewportCoordToRenderTarget( IN.uv, rtParams2 ); + OUT.uv3 = viewportCoordToRenderTarget( IN.uv, rtParams3 ); + + OUT.wsEyeRay = IN.wsEyeRay; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/edgeDetectP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/edgeDetectP.hlsl new file mode 100644 index 000000000..2277126a8 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/edgeDetectP.hlsl @@ -0,0 +1,93 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" +#include "../../shaderModelAutoGen.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(prepassBuffer,0); + +// GPU Gems 3, pg 443-444 +float GetEdgeWeight(float2 uv0, in float2 targetSize) +{ + float2 offsets[9] = { + float2( 0.0, 0.0), + float2(-1.0, -1.0), + float2( 0.0, -1.0), + float2( 1.0, -1.0), + float2( 1.0, 0.0), + float2( 1.0, 1.0), + float2( 0.0, 1.0), + float2(-1.0, 1.0), + float2(-1.0, 0.0), + }; + + + float2 PixelSize = 1.0 / targetSize; + + float Depth[9]; + float3 Normal[9]; + + [unroll] //no getting around this, may as well save the annoying warning message + for(int i = 0; i < 9; i++) + { + float2 uv = uv0 + offsets[i] * PixelSize; + float4 gbSample = TORQUE_PREPASS_UNCONDITION( prepassBuffer, uv ); + Depth[i] = gbSample.a; + Normal[i] = gbSample.rgb; + } + + float4 Deltas1 = float4(Depth[1], Depth[2], Depth[3], Depth[4]); + float4 Deltas2 = float4(Depth[5], Depth[6], Depth[7], Depth[8]); + + Deltas1 = abs(Deltas1 - Depth[0]); + Deltas2 = abs(Depth[0] - Deltas2); + + float4 maxDeltas = max(Deltas1, Deltas2); + float4 minDeltas = max(min(Deltas1, Deltas2), 0.00001); + + float4 depthResults = step(minDeltas * 25.0, maxDeltas); + + Deltas1.x = dot(Normal[1], Normal[0]); + Deltas1.y = dot(Normal[2], Normal[0]); + Deltas1.z = dot(Normal[3], Normal[0]); + Deltas1.w = dot(Normal[4], Normal[0]); + + Deltas2.x = dot(Normal[5], Normal[0]); + Deltas2.y = dot(Normal[6], Normal[0]); + Deltas2.z = dot(Normal[7], Normal[0]); + Deltas2.w = dot(Normal[8], Normal[0]); + + Deltas1 = abs(Deltas1 - Deltas2); + + float4 normalResults = step(0.4, Deltas1); + + normalResults = max(normalResults, depthResults); + + return dot(normalResults, float4(1.0, 1.0, 1.0, 1.0)) * 0.25; +} + +uniform float2 targetSize; + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + return GetEdgeWeight(IN.uv0, targetSize);//rtWidthHeightInvWidthNegHeight.zw); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/gl/dbgEdgeDisplayP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/gl/dbgEdgeDisplayP.glsl new file mode 100644 index 000000000..ccc3b8ba5 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/gl/dbgEdgeDisplayP.glsl @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" + +in vec2 uv0; +#define IN_uv0 uv0 + +uniform sampler2D edgeBuffer; + +out vec4 OUT_col; + +void main() +{ + OUT_col = vec4( texture( edgeBuffer, IN_uv0 ).rrr, 1.0 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/gl/edgeAAP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/gl/edgeAAP.glsl new file mode 100644 index 000000000..216dc8725 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/gl/edgeAAP.glsl @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../gl/postFX.glsl" + +uniform sampler2D edgeBuffer; +uniform sampler2D backBuffer; +uniform vec2 targetSize; + +out vec4 OUT_col; + +void main() +{ + vec2 pixelSize = 1.0 / targetSize; + + // Sample edge buffer, bail if not on an edge + float edgeSample = texture(edgeBuffer, IN_uv0).r; + clip(edgeSample - 1e-6); + + // Ok we're on an edge, so multi-tap sample, average, and return + vec2 offsets[9] = vec2[]( + vec2( 0.0, 0.0), + vec2(-1.0, -1.0), + vec2( 0.0, -1.0), + vec2( 1.0, -1.0), + vec2( 1.0, 0.0), + vec2( 1.0, 1.0), + vec2( 0.0, 1.0), + vec2(-1.0, 1.0), + vec2(-1.0, 0.0) + ); + + vec4 accumColor = vec4(0.0); + for(int i = 0; i < 9; i++) + { + // Multiply the intensity of the edge, by the UV, so that things which maybe + // aren't quite full edges get sub-pixel sampling to reduce artifacts + + // Scaling offsets by 0.5 to reduce the range bluriness from extending to + // far outward from the edge. + + vec2 offsetUV = IN_uv1 + edgeSample * ( offsets[i] * 0.5 ) * pixelSize;//rtWidthHeightInvWidthNegHeight.zw; + //offsetUV *= 0.999; + accumColor+= texture(backBuffer, offsetUV); + } + accumColor /= 9.0; + + OUT_col = accumColor; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/gl/edgeAAV.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/gl/edgeAAV.glsl new file mode 100644 index 000000000..975532272 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/gl/edgeAAV.glsl @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "../../../gl/torque.glsl" +#include "../../gl/postFX.glsl" + +uniform vec4 rtParams0; +uniform vec4 rtParams1; +uniform vec4 rtParams2; +uniform vec4 rtParams3; + +void main() +{ + OUT_hpos = IN_pos; + OUT_uv0 = viewportCoordToRenderTarget( IN_uv, rtParams0 ); + OUT_uv1 = viewportCoordToRenderTarget( IN_uv, rtParams1 ); + OUT_uv2 = viewportCoordToRenderTarget( IN_uv, rtParams2 ); + OUT_uv3 = viewportCoordToRenderTarget( IN_uv, rtParams3 ); + + OUT_wsEyeRay = IN_wsEyeRay; + + correctSSP(gl_Position); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/gl/edgeDetectP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/gl/edgeDetectP.glsl new file mode 100644 index 000000000..d1856ecde --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/edgeaa/gl/edgeDetectP.glsl @@ -0,0 +1,96 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" + +// GPU Gems 3, pg 443-444 +float GetEdgeWeight(vec2 uv0, in sampler2D prepassBuffer, in vec2 targetSize) +{ + vec2 offsets[9] = vec2[]( + vec2( 0.0, 0.0), + vec2(-1.0, -1.0), + vec2( 0.0, -1.0), + vec2( 1.0, -1.0), + vec2( 1.0, 0.0), + vec2( 1.0, 1.0), + vec2( 0.0, 1.0), + vec2(-1.0, 1.0), + vec2(-1.0, 0.0) + ); + + + vec2 PixelSize = 1.0 / targetSize; + + float Depth[9]; + vec3 Normal[9]; + + for(int i = 0; i < 9; i++) + { + vec2 uv = uv0 + offsets[i] * PixelSize; + vec4 gbSample = prepassUncondition( prepassBuffer, uv ); + Depth[i] = gbSample.a; + Normal[i] = gbSample.rgb; + } + + vec4 Deltas1 = vec4(Depth[1], Depth[2], Depth[3], Depth[4]); + vec4 Deltas2 = vec4(Depth[5], Depth[6], Depth[7], Depth[8]); + + Deltas1 = abs(Deltas1 - Depth[0]); + Deltas2 = abs(Depth[0] - Deltas2); + + vec4 maxDeltas = max(Deltas1, Deltas2); + vec4 minDeltas = max(min(Deltas1, Deltas2), 0.00001); + + vec4 depthResults = step(minDeltas * 25.0, maxDeltas); + + Deltas1.x = dot(Normal[1], Normal[0]); + Deltas1.y = dot(Normal[2], Normal[0]); + Deltas1.z = dot(Normal[3], Normal[0]); + Deltas1.w = dot(Normal[4], Normal[0]); + + Deltas2.x = dot(Normal[5], Normal[0]); + Deltas2.y = dot(Normal[6], Normal[0]); + Deltas2.z = dot(Normal[7], Normal[0]); + Deltas2.w = dot(Normal[8], Normal[0]); + + Deltas1 = abs(Deltas1 - Deltas2); + + vec4 normalResults = step(0.4, Deltas1); + + normalResults = max(normalResults, depthResults); + + return dot(normalResults, vec4(1.0, 1.0, 1.0, 1.0)) * 0.25; +} + +in vec2 uv0; +#define IN_uv0 uv0 + +uniform sampler2D prepassBuffer; +uniform vec2 targetSize; + +out vec4 OUT_col; + +void main() +{ + OUT_col = vec4( GetEdgeWeight(IN_uv0, prepassBuffer, targetSize ) );//rtWidthHeightInvWidthNegHeight.zw); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/flashP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/flashP.hlsl new file mode 100644 index 000000000..93daf3c26 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/flashP.hlsl @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./postFx.hlsl" +#include "../torque.hlsl" + +uniform float damageFlash; +uniform float whiteOut; +TORQUE_UNIFORM_SAMPLER2D(backBuffer, 0); + +float4 main(PFXVertToPix IN) : TORQUE_TARGET0 +{ + float4 color1 = TORQUE_TEX2D(backBuffer, IN.uv0); + float4 color2 = color1 * MUL_COLOR; + float4 damage = lerp(color1,color2,damageFlash); + return lerp(damage,WHITE_COLOR,whiteOut); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/fogP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/fogP.hlsl new file mode 100644 index 000000000..de5fd65dc --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/fogP.hlsl @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +#include "./postFx.hlsl" +#include "./../torque.hlsl" +#include "./../shaderModelAutoGen.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(prepassTex, 0); +uniform float3 eyePosWorld; +uniform float4 fogColor; +uniform float3 fogData; +uniform float4 rtParams0; + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + //float2 prepassCoord = ( IN.uv0.xy * rtParams0.zw ) + rtParams0.xy; + float depth = TORQUE_PREPASS_UNCONDITION( prepassTex, IN.uv0 ).w; + //return float4( depth, 0, 0, 0.7 ); + + float factor = computeSceneFog( eyePosWorld, + eyePosWorld + ( IN.wsEyeRay * depth ), + fogData.x, + fogData.y, + fogData.z ); + + return hdrEncode( float4( toLinear(fogColor.rgb), 1.0 - saturate( factor ) ) ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/fxaa/Fxaa3_11.h b/Templates/BaseGame/game/data/shaders/common/postFx/fxaa/Fxaa3_11.h new file mode 100644 index 000000000..9ca7627d4 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/fxaa/Fxaa3_11.h @@ -0,0 +1,2047 @@ +/*============================================================================ + + + NVIDIA FXAA 3.11 by TIMOTHY LOTTES + + +------------------------------------------------------------------------------ +COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED. +------------------------------------------------------------------------------ +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED +*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA +OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR +CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR +LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, +OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE +THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + +------------------------------------------------------------------------------ + INTEGRATION CHECKLIST +------------------------------------------------------------------------------ +(1.) +In the shader source, setup defines for the desired configuration. +When providing multiple shaders (for different presets), +simply setup the defines differently in multiple files. +Example, + + #define FXAA_PC 1 + #define FXAA_HLSL_5 1 + #define FXAA_QUALITY__PRESET 12 + +Or, + + #define FXAA_360 1 + +Or, + + #define FXAA_PS3 1 + +Etc. + +(2.) +Then include this file, + + include "Fxaa3_11.h" + +(3.) +Then call the FXAA pixel shader from within your desired shader. +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. +As for FXAA 3.11 all inputs for all shaders are the same +to enable easy porting between platforms. + + return FxaaPixelShader(...); + +(4.) +Insure pass prior to FXAA outputs RGBL (see next section). +Or use, + + #define FXAA_GREEN_AS_LUMA 1 + +(5.) +Setup engine to provide the following constants +which are used in the FxaaPixelShader() inputs, + + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir + +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. + +(6.) +Have FXAA vertex shader run as a full screen triangle, +and output "pos" and "fxaaConsolePosPos" +such that inputs in the pixel shader provide, + + // {xy} = center of pixel + FxaaFloat2 pos, + + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + +(7.) +Insure the texture sampler(s) used by FXAA are set to bilinear filtering. + + +------------------------------------------------------------------------------ + INTEGRATION - RGBL AND COLORSPACE +------------------------------------------------------------------------------ +FXAA3 requires RGBL as input unless the following is set, + + #define FXAA_GREEN_AS_LUMA 1 + +In which case the engine uses green in place of luma, +and requires RGB input is in a non-linear colorspace. + +RGB should be LDR (low dynamic range). +Specifically do FXAA after tonemapping. + +RGB data as returned by a texture fetch can be non-linear, +or linear when FXAA_GREEN_AS_LUMA is not set. +Note an "sRGB format" texture counts as linear, +because the result of a texture fetch is linear data. +Regular "RGBA8" textures in the sRGB colorspace are non-linear. + +If FXAA_GREEN_AS_LUMA is not set, +luma must be stored in the alpha channel prior to running FXAA. +This luma should be in a perceptual space (could be gamma 2.0). +Example pass before FXAA where output is gamma 2.0 encoded, + + color.rgb = ToneMap(color.rgb); // linear color output + color.rgb = sqrt(color.rgb); // gamma 2.0 color output + return color; + +To use FXAA, + + color.rgb = ToneMap(color.rgb); // linear color output + color.rgb = sqrt(color.rgb); // gamma 2.0 color output + color.a = dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114)); // compute luma + return color; + +Another example where output is linear encoded, +say for instance writing to an sRGB formated render target, +where the render target does the conversion back to sRGB after blending, + + color.rgb = ToneMap(color.rgb); // linear color output + return color; + +To use FXAA, + + color.rgb = ToneMap(color.rgb); // linear color output + color.a = sqrt(dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114))); // compute luma + return color; + +Getting luma correct is required for the algorithm to work correctly. + + +------------------------------------------------------------------------------ + BEING LINEARLY CORRECT? +------------------------------------------------------------------------------ +Applying FXAA to a framebuffer with linear RGB color will look worse. +This is very counter intuitive, but happends to be true in this case. +The reason is because dithering artifacts will be more visiable +in a linear colorspace. + + +------------------------------------------------------------------------------ + COMPLEX INTEGRATION +------------------------------------------------------------------------------ +Q. What if the engine is blending into RGB before wanting to run FXAA? + +A. In the last opaque pass prior to FXAA, + have the pass write out luma into alpha. + Then blend into RGB only. + FXAA should be able to run ok + assuming the blending pass did not any add aliasing. + This should be the common case for particles and common blending passes. + +A. Or use FXAA_GREEN_AS_LUMA. + +============================================================================*/ + +/*============================================================================ + + INTEGRATION KNOBS + +============================================================================*/ +// +// FXAA_PS3 and FXAA_360 choose the console algorithm (FXAA3 CONSOLE). +// FXAA_360_OPT is a prototype for the new optimized 360 version. +// +// 1 = Use API. +// 0 = Don't use API. +// +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PS3 + #define FXAA_PS3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360 + #define FXAA_360 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360_OPT + #define FXAA_360_OPT 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_PC + // + // FXAA Quality + // The high quality PC algorithm. + // + #define FXAA_PC 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PC_CONSOLE + // + // The console algorithm for PC is included + // for developers targeting really low spec machines. + // Likely better to just run FXAA_PC, and use a really low preset. + // + #define FXAA_PC_CONSOLE 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_120 + #define FXAA_GLSL_120 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_130 + #define FXAA_GLSL_130 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_3 + #define FXAA_HLSL_3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_4 + #define FXAA_HLSL_4 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_5 + #define FXAA_HLSL_5 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_GREEN_AS_LUMA + // + // For those using non-linear color, + // and either not able to get luma in alpha, or not wanting to, + // this enables FXAA to run using green as a proxy for luma. + // So with this enabled, no need to pack luma in alpha. + // + // This will turn off AA on anything which lacks some amount of green. + // Pure red and blue or combination of only R and B, will get no AA. + // + // Might want to lower the settings for both, + // fxaaConsoleEdgeThresholdMin + // fxaaQualityEdgeThresholdMin + // In order to insure AA does not get turned off on colors + // which contain a minor amount of green. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_GREEN_AS_LUMA 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_EARLY_EXIT + // + // Controls algorithm's early exit path. + // On PS3 turning this ON adds 2 cycles to the shader. + // On 360 turning this OFF adds 10ths of a millisecond to the shader. + // Turning this off on console will result in a more blurry image. + // So this defaults to on. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_EARLY_EXIT 1 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_DISCARD + // + // Only valid for PC OpenGL currently. + // Probably will not work when FXAA_GREEN_AS_LUMA = 1. + // + // 1 = Use discard on pixels which don't need AA. + // For APIs which enable concurrent TEX+ROP from same surface. + // 0 = Return unchanged color on pixels which don't need AA. + // + #define FXAA_DISCARD 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_FAST_PIXEL_OFFSET + // + // Used for GLSL 120 only. + // + // 1 = GL API supports fast pixel offsets + // 0 = do not use fast pixel offsets + // + #ifdef GL_EXT_gpu_shader4 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifdef GL_NV_gpu_shader5 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifdef GL_ARB_gpu_shader5 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifndef FXAA_FAST_PIXEL_OFFSET + #define FXAA_FAST_PIXEL_OFFSET 0 + #endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GATHER4_ALPHA + // + // 1 = API supports gather4 on alpha channel. + // 0 = API does not support gather4 on alpha channel. + // + #if (FXAA_HLSL_5 == 1) + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifdef GL_ARB_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifdef GL_NV_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifndef FXAA_GATHER4_ALPHA + #define FXAA_GATHER4_ALPHA 0 + #endif +#endif + +/*============================================================================ + FXAA CONSOLE PS3 - TUNING KNOBS +============================================================================*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS + // + // Consoles the sharpness of edges on PS3 only. + // Non-PS3 tuning is done with shader input. + // + // Due to the PS3 being ALU bound, + // there are only two safe values here: 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // + // 8.0 is sharper + // 4.0 is softer + // 2.0 is really soft (good for vector graphics inputs) + // + #if 1 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0 + #endif + #if 0 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0 + #endif + #if 0 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0 + #endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD + // + // Only effects PS3. + // Non-PS3 tuning is done with shader input. + // + // The minimum amount of local contrast required to apply algorithm. + // The console setting has a different mapping than the quality setting. + // + // This only applies when FXAA_EARLY_EXIT is 1. + // + // Due to the PS3 being ALU bound, + // there are only two safe values here: 0.25 and 0.125. + // These options use the shaders ability to a free *|/ by 2|4|8. + // + // 0.125 leaves less aliasing, but is softer + // 0.25 leaves more aliasing, and is sharper + // + #if 1 + #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125 + #else + #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25 + #endif +#endif + +/*============================================================================ + FXAA QUALITY - TUNING KNOBS +------------------------------------------------------------------------------ +NOTE the other tuning knobs are now in the shader function inputs! +============================================================================*/ +#ifndef FXAA_QUALITY__PRESET + // + // Choose the quality preset. + // This needs to be compiled into the shader as it effects code. + // Best option to include multiple presets is to + // in each shader define the preset, then include this file. + // + // OPTIONS + // ----------------------------------------------------------------------- + // 10 to 15 - default medium dither (10=fastest, 15=highest quality) + // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality) + // 39 - no dither, very expensive + // + // NOTES + // ----------------------------------------------------------------------- + // 12 = slightly faster then FXAA 3.9 and higher edge quality (default) + // 13 = about same speed as FXAA 3.9 and better than 12 + // 23 = closest to FXAA 3.9 visually and performance wise + // _ = the lowest digit is directly related to performance + // _ = the highest digit is directly related to style + // + #define FXAA_QUALITY__PRESET 12 +#endif + + +/*============================================================================ + + FXAA QUALITY - PRESETS + +============================================================================*/ + +/*============================================================================ + FXAA QUALITY - MEDIUM DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 10) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 3.0 + #define FXAA_QUALITY__P2 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 11) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 3.0 + #define FXAA_QUALITY__P3 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 12) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 4.0 + #define FXAA_QUALITY__P4 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 13) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 4.0 + #define FXAA_QUALITY__P5 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 14) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 4.0 + #define FXAA_QUALITY__P6 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 15) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 12.0 +#endif + +/*============================================================================ + FXAA QUALITY - LOW DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 20) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 2.0 + #define FXAA_QUALITY__P2 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 21) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 22) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 23) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 24) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 3.0 + #define FXAA_QUALITY__P6 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 25) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 26) + #define FXAA_QUALITY__PS 9 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 4.0 + #define FXAA_QUALITY__P8 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 27) + #define FXAA_QUALITY__PS 10 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 4.0 + #define FXAA_QUALITY__P9 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 28) + #define FXAA_QUALITY__PS 11 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 4.0 + #define FXAA_QUALITY__P10 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 29) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + +/*============================================================================ + FXAA QUALITY - EXTREME QUALITY +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 39) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.0 + #define FXAA_QUALITY__P2 1.0 + #define FXAA_QUALITY__P3 1.0 + #define FXAA_QUALITY__P4 1.0 + #define FXAA_QUALITY__P5 1.5 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + + + +/*============================================================================ + + API PORTING + +============================================================================*/ +#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1) + #define FxaaBool bool + #define FxaaDiscard discard + #define FxaaFloat float + #define FxaaFloat2 vec2 + #define FxaaFloat3 vec3 + #define FxaaFloat4 vec4 + #define FxaaHalf float + #define FxaaHalf2 vec2 + #define FxaaHalf3 vec3 + #define FxaaHalf4 vec4 + #define FxaaInt2 ivec2 + #define FxaaSat(x) clamp(x, 0.0, 1.0) + #define FxaaTex sampler2D +#else + #define FxaaBool bool + #define FxaaDiscard clip(-1) + #define FxaaFloat float + #define FxaaFloat2 float2 + #define FxaaFloat3 float3 + #define FxaaFloat4 float4 + #define FxaaHalf half + #define FxaaHalf2 half2 + #define FxaaHalf3 half3 + #define FxaaHalf4 half4 + #define FxaaSat(x) saturate(x) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_120 == 1) + // Requires, + // #version 120 + // And at least, + // #extension GL_EXT_gpu_shader4 : enable + // (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9) + #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0) + #if (FXAA_FAST_PIXEL_OFFSET == 1) + #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o) + #else + #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0) + #endif + #if (FXAA_GATHER4_ALPHA == 1) + // use #extension GL_ARB_gpu_shader5 : enable + #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) + #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) + #define FxaaTexGreen4(t, p) textureGather(t, p, 1) + #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) + #endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_130 == 1) + // Requires "#version 130" or better + #define FxaaTexTop(t, p) textureLod(t, p, 0.0) + #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o) + #if (FXAA_GATHER4_ALPHA == 1) + // use #extension GL_ARB_gpu_shader5 : enable + #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) + #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) + #define FxaaTexGreen4(t, p) textureGather(t, p, 1) + #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) + #endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1) + #define FxaaInt2 float2 + #define FxaaTex sampler2D + #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0)) + #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0)) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_4 == 1) + #define FxaaInt2 int2 + struct FxaaTex { SamplerState smpl; Texture2D tex; }; + #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) + #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_5 == 1) + #define FxaaInt2 int2 + struct FxaaTex { SamplerState smpl; Texture2D tex; }; + #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) + #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) + #define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p) + #define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o) + #define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p) + #define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o) +#endif + + +/*============================================================================ + GREEN AS LUMA OPTION SUPPORT FUNCTION +============================================================================*/ +#if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; } +#else + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; } +#endif + + + + +/*============================================================================ + + FXAA3 QUALITY - PC + +============================================================================*/ +#if (FXAA_PC == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy} = center of pixel + FxaaFloat2 pos, + // + // Used only for FXAA Console, and not used on the 360 version. + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + // + // Input color texture. + // {rgb_} = color in linear or perceptual color space + // if (FXAA_GREEN_AS_LUMA == 0) + // {___a} = luma in perceptual color space (not linear) + FxaaTex tex, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 2nd sampler. + // This sampler needs to have an exponent bias of -1. + FxaaTex fxaaConsole360TexExpBiasNegOne, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 3nd sampler. + // This sampler needs to have an exponent bias of -2. + FxaaTex fxaaConsole360TexExpBiasNegTwo, + // + // Only used on FXAA Quality. + // This must be from a constant/uniform. + // {x_} = 1.0/screenWidthInPixels + // {_y} = 1.0/screenHeightInPixels + FxaaFloat2 fxaaQualityRcpFrame, + // + // Only used on FXAA Console. + // This must be from a constant/uniform. + // This effects sub-pixel AA quality and inversely sharpness. + // Where N ranges between, + // N = 0.50 (default) + // N = 0.33 (sharper) + // {x___} = -N/screenWidthInPixels + // {_y__} = -N/screenHeightInPixels + // {__z_} = N/screenWidthInPixels + // {___w} = N/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt, + // + // Only used on FXAA Console. + // Not used on 360, but used on PS3 and PC. + // This must be from a constant/uniform. + // {x___} = -2.0/screenWidthInPixels + // {_y__} = -2.0/screenHeightInPixels + // {__z_} = 2.0/screenWidthInPixels + // {___w} = 2.0/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + // + // Only used on FXAA Console. + // Only used on 360 in place of fxaaConsoleRcpFrameOpt2. + // This must be from a constant/uniform. + // {x___} = 8.0/screenWidthInPixels + // {_y__} = 8.0/screenHeightInPixels + // {__z_} = -4.0/screenWidthInPixels + // {___w} = -4.0/screenHeightInPixels + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__SUBPIX define. + // It is here now to allow easier tuning. + // Choose the amount of sub-pixel aliasing removal. + // This can effect sharpness. + // 1.00 - upper limit (softer) + // 0.75 - default amount of filtering + // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) + // 0.25 - almost off + // 0.00 - completely off + FxaaFloat fxaaQualitySubpix, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // The minimum amount of local contrast required to apply algorithm. + // 0.333 - too little (faster) + // 0.250 - low quality + // 0.166 - default + // 0.125 - high quality + // 0.063 - overkill (slower) + FxaaFloat fxaaQualityEdgeThreshold, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // 0.0833 - upper limit (default, the start of visible unfiltered edges) + // 0.0625 - high quality (faster) + // 0.0312 - visible limit (slower) + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaQualityEdgeThresholdMin, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. + // Due to the PS3 being ALU bound, + // there are only three safe values here: 2 and 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // For all other platforms can be a non-power of two. + // 8.0 is sharper (default!!!) + // 4.0 is softer + // 2.0 is really soft (good only for vector graphics inputs) + FxaaFloat fxaaConsoleEdgeSharpness, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3. + // Due to the PS3 being ALU bound, + // there are only two safe values here: 1/4 and 1/8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // The console setting has a different mapping than the quality setting. + // Other platforms can use other values. + // 0.125 leaves less aliasing, but is softer (default!!!) + // 0.25 leaves more aliasing, and is sharper + FxaaFloat fxaaConsoleEdgeThreshold, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // The console setting has a different mapping than the quality setting. + // This only applies when FXAA_EARLY_EXIT is 1. + // This does not apply to PS3, + // PS3 was simplified to avoid more shader instructions. + // 0.06 - faster but more aliasing in darks + // 0.05 - default + // 0.04 - slower and less aliasing in darks + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaConsoleEdgeThresholdMin, + // + // Extra constants for 360 FXAA Console only. + // Use zeros or anything else for other platforms. + // These must be in physical constant registers and NOT immedates. + // Immedates will result in compiler un-optimizing. + // {xyzw} = float4(1.0, -1.0, 0.25, -0.25) + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posM; + posM.x = pos.x; + posM.y = pos.y; + #if (FXAA_GATHER4_ALPHA == 1) + #if (FXAA_DISCARD == 0) + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); + #if (FXAA_GREEN_AS_LUMA == 0) + #define lumaM rgbyM.w + #else + #define lumaM rgbyM.y + #endif + #endif + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1)); + #else + FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1)); + #endif + #if (FXAA_DISCARD == 1) + #define lumaM luma4A.w + #endif + #define lumaE luma4A.z + #define lumaS luma4A.x + #define lumaSE luma4A.y + #define lumaNW luma4B.w + #define lumaN luma4B.z + #define lumaW luma4B.x + #else + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); + #if (FXAA_GREEN_AS_LUMA == 0) + #define lumaM rgbyM.w + #else + #define lumaM rgbyM.y + #endif + FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy)); + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat maxSM = max(lumaS, lumaM); + FxaaFloat minSM = min(lumaS, lumaM); + FxaaFloat maxESM = max(lumaE, maxSM); + FxaaFloat minESM = min(lumaE, minSM); + FxaaFloat maxWN = max(lumaN, lumaW); + FxaaFloat minWN = min(lumaN, lumaW); + FxaaFloat rangeMax = max(maxWN, maxESM); + FxaaFloat rangeMin = min(minWN, minESM); + FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold; + FxaaFloat range = rangeMax - rangeMin; + FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled); + FxaaBool earlyExit = range < rangeMaxClamped; +/*--------------------------------------------------------------------------*/ + if(earlyExit) + #if (FXAA_DISCARD == 1) + FxaaDiscard; + #else + return rgbyM; + #endif +/*--------------------------------------------------------------------------*/ + #if (FXAA_GATHER4_ALPHA == 0) + FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); + #else + FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNS = lumaN + lumaS; + FxaaFloat lumaWE = lumaW + lumaE; + FxaaFloat subpixRcpRange = 1.0/range; + FxaaFloat subpixNSWE = lumaNS + lumaWE; + FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS; + FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNESE = lumaNE + lumaSE; + FxaaFloat lumaNWNE = lumaNW + lumaNE; + FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE; + FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNWSW = lumaNW + lumaSW; + FxaaFloat lumaSWSE = lumaSW + lumaSE; + FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2); + FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2); + FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW; + FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE; + FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4; + FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4; +/*--------------------------------------------------------------------------*/ + FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE; + FxaaFloat lengthSign = fxaaQualityRcpFrame.x; + FxaaBool horzSpan = edgeHorz >= edgeVert; + FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE; +/*--------------------------------------------------------------------------*/ + if(!horzSpan) lumaN = lumaW; + if(!horzSpan) lumaS = lumaE; + if(horzSpan) lengthSign = fxaaQualityRcpFrame.y; + FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM; +/*--------------------------------------------------------------------------*/ + FxaaFloat gradientN = lumaN - lumaM; + FxaaFloat gradientS = lumaS - lumaM; + FxaaFloat lumaNN = lumaN + lumaM; + FxaaFloat lumaSS = lumaS + lumaM; + FxaaBool pairN = abs(gradientN) >= abs(gradientS); + FxaaFloat gradient = max(abs(gradientN), abs(gradientS)); + if(pairN) lengthSign = -lengthSign; + FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange); +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posB; + posB.x = posM.x; + posB.y = posM.y; + FxaaFloat2 offNP; + offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x; + offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y; + if(!horzSpan) posB.x += lengthSign * 0.5; + if( horzSpan) posB.y += lengthSign * 0.5; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posN; + posN.x = posB.x - offNP.x * FXAA_QUALITY__P0; + posN.y = posB.y - offNP.y * FXAA_QUALITY__P0; + FxaaFloat2 posP; + posP.x = posB.x + offNP.x * FXAA_QUALITY__P0; + posP.y = posB.y + offNP.y * FXAA_QUALITY__P0; + FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0; + FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN)); + FxaaFloat subpixE = subpixC * subpixC; + FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP)); +/*--------------------------------------------------------------------------*/ + if(!pairN) lumaNN = lumaSS; + FxaaFloat gradientScaled = gradient * 1.0/4.0; + FxaaFloat lumaMM = lumaM - lumaNN * 0.5; + FxaaFloat subpixF = subpixD * subpixE; + FxaaBool lumaMLTZero = lumaMM < 0.0; +/*--------------------------------------------------------------------------*/ + lumaEndN -= lumaNN * 0.5; + lumaEndP -= lumaNN * 0.5; + FxaaBool doneN = abs(lumaEndN) >= gradientScaled; + FxaaBool doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1; + FxaaBool doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1; +/*--------------------------------------------------------------------------*/ + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 3) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 4) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 5) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 6) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 7) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 8) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 9) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 10) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 11) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 12) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12; +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } +/*--------------------------------------------------------------------------*/ + FxaaFloat dstN = posM.x - posN.x; + FxaaFloat dstP = posP.x - posM.x; + if(!horzSpan) dstN = posM.y - posN.y; + if(!horzSpan) dstP = posP.y - posM.y; +/*--------------------------------------------------------------------------*/ + FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero; + FxaaFloat spanLength = (dstP + dstN); + FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero; + FxaaFloat spanLengthRcp = 1.0/spanLength; +/*--------------------------------------------------------------------------*/ + FxaaBool directionN = dstN < dstP; + FxaaFloat dst = min(dstN, dstP); + FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP; + FxaaFloat subpixG = subpixF * subpixF; + FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5; + FxaaFloat subpixH = subpixG * fxaaQualitySubpix; +/*--------------------------------------------------------------------------*/ + FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0; + FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH); + if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign; + if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign; + #if (FXAA_DISCARD == 1) + return FxaaTexTop(tex, posM); + #else + return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM); + #endif +} +/*==========================================================================*/ +#endif + + + + +/*============================================================================ + + FXAA3 CONSOLE - PC VERSION + +------------------------------------------------------------------------------ +Instead of using this on PC, I'd suggest just using FXAA Quality with + #define FXAA_QUALITY__PRESET 10 +Or + #define FXAA_QUALITY__PRESET 20 +Either are higher qualilty and almost as fast as this on modern PC GPUs. +============================================================================*/ +#if (FXAA_PC_CONSOLE == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy)); + FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw)); + FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy)); + FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw)); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy); + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat lumaM = rgbyM.w; + #else + FxaaFloat lumaM = rgbyM.y; + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw); + lumaNe += 1.0/384.0; + FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe); + FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw); + FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMinM = min(lumaMin, lumaM); + FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled); + FxaaFloat lumaMaxM = max(lumaMax, lumaM); + FxaaFloat dirSwMinusNe = lumaSw - lumaNe; + FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM; + FxaaFloat dirSeMinusNw = lumaSe - lumaNw; + if(lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir; + dir.x = dirSwMinusNe + dirSeMinusNw; + dir.y = dirSwMinusNe - dirSeMinusNw; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir1 = normalize(dir.xy); + FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw); + FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw); +/*--------------------------------------------------------------------------*/ + FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness; + FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw); + FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyA = rgbyN1 + rgbyP1; + FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25); +/*--------------------------------------------------------------------------*/ + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax); + #else + FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax); + #endif + if(twoTap) rgbyB.xyz = rgbyA.xyz * 0.5; + return rgbyB; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + + FXAA3 CONSOLE - 360 PIXEL SHADER + +------------------------------------------------------------------------------ +This optimized version thanks to suggestions from Andy Luedke. +Should be fully tex bound in all cases. +As of the FXAA 3.11 release, I have still not tested this code, +however I fixed a bug which was in both FXAA 3.9 and FXAA 3.10. +And note this is replacing the old unoptimized version. +If it does not work, please let me know so I can fix it. +============================================================================*/ +#if (FXAA_360 == 1) +/*--------------------------------------------------------------------------*/ +[reduceTempRegUsage(4)] +float4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + float4 lumaNwNeSwSe; + #if (FXAA_GREEN_AS_LUMA == 0) + asm { + tfetch2D lumaNwNeSwSe.w___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe._w__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.__w_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.___w, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false + }; + #else + asm { + tfetch2D lumaNwNeSwSe.y___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe._y__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.__y_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.___y, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false + }; + #endif +/*--------------------------------------------------------------------------*/ + lumaNwNeSwSe.y += 1.0/384.0; + float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); + float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); + float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y); + float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y); +/*--------------------------------------------------------------------------*/ + float4 rgbyM = tex2Dlod(tex, float4(pos.xy, 0.0, 0.0)); + #if (FXAA_GREEN_AS_LUMA == 0) + float lumaMinM = min(lumaMin, rgbyM.w); + float lumaMaxM = max(lumaMax, rgbyM.w); + #else + float lumaMinM = min(lumaMin, rgbyM.y); + float lumaMaxM = max(lumaMax, rgbyM.y); + #endif + if((lumaMaxM - lumaMinM) < max(fxaaConsoleEdgeThresholdMin, lumaMax * fxaaConsoleEdgeThreshold)) return rgbyM; +/*--------------------------------------------------------------------------*/ + float2 dir; + dir.x = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.yyxx); + dir.y = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.xyxy); + dir = normalize(dir); +/*--------------------------------------------------------------------------*/ + float4 dir1 = dir.xyxy * fxaaConsoleRcpFrameOpt.xyzw; +/*--------------------------------------------------------------------------*/ + float4 dir2; + float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)) * fxaaConsoleEdgeSharpness; + dir2 = saturate(fxaaConsole360ConstDir.zzww * dir.xyxy / dirAbsMinTimesC + 0.5); + dir2 = dir2 * fxaaConsole360RcpFrameOpt2.xyxy + fxaaConsole360RcpFrameOpt2.zwzw; +/*--------------------------------------------------------------------------*/ + float4 rgbyN1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.xy, 0.0, 0.0)); + float4 rgbyP1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.zw, 0.0, 0.0)); + float4 rgbyN2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.xy, 0.0, 0.0)); + float4 rgbyP2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.zw, 0.0, 0.0)); +/*--------------------------------------------------------------------------*/ + float4 rgbyA = rgbyN1 + rgbyP1; + float4 rgbyB = rgbyN2 + rgbyP2 + rgbyA * 0.5; +/*--------------------------------------------------------------------------*/ + float4 rgbyR = ((FxaaLuma(rgbyB) - lumaMax) > 0.0) ? rgbyA : rgbyB; + rgbyR = ((FxaaLuma(rgbyB) - lumaMin) > 0.0) ? rgbyR : rgbyA; + return rgbyR; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + + FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (NO EARLY EXIT) + +============================================================================== +The code below does not exactly match the assembly. +I have a feeling that 12 cycles is possible, but was not able to get there. +Might have to increase register count to get full performance. +Note this shader does not use perspective interpolation. + +Use the following cgc options, + + --fenable-bx2 --fastmath --fastprecision --nofloatbindings + +------------------------------------------------------------------------------ + NVSHADERPERF OUTPUT +------------------------------------------------------------------------------ +For reference and to aid in debug, output of NVShaderPerf should match this, + +Shader to schedule: + 0: texpkb h0.w(TRUE), v5.zyxx, #0 + 2: addh h2.z(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x + 4: texpkb h0.w(TRUE), v5.xwxx, #0 + 6: addh h0.z(TRUE), -h2, h0.w + 7: texpkb h1.w(TRUE), v5, #0 + 9: addh h0.x(TRUE), h0.z, -h1.w + 10: addh h3.w(TRUE), h0.z, h1 + 11: texpkb h2.w(TRUE), v5.zwzz, #0 + 13: addh h0.z(TRUE), h3.w, -h2.w + 14: addh h0.x(TRUE), h2.w, h0 + 15: nrmh h1.xz(TRUE), h0_n + 16: minh_m8 h0.x(TRUE), |h1|, |h1.z| + 17: maxh h4.w(TRUE), h0, h1 + 18: divx h2.xy(TRUE), h1_n.xzzw, h0_n + 19: movr r1.zw(TRUE), v4.xxxy + 20: madr r2.xz(TRUE), -h1, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zzww, r1.zzww + 22: minh h5.w(TRUE), h0, h1 + 23: texpkb h0(TRUE), r2.xzxx, #0 + 25: madr r0.zw(TRUE), h1.xzxz, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w), r1 + 27: maxh h4.x(TRUE), h2.z, h2.w + 28: texpkb h1(TRUE), r0.zwzz, #0 + 30: addh_d2 h1(TRUE), h0, h1 + 31: madr r0.xy(TRUE), -h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 33: texpkb h0(TRUE), r0, #0 + 35: minh h4.z(TRUE), h2, h2.w + 36: fenct TRUE + 37: madr r1.xy(TRUE), h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 39: texpkb h2(TRUE), r1, #0 + 41: addh_d2 h0(TRUE), h0, h2 + 42: maxh h2.w(TRUE), h4, h4.x + 43: minh h2.x(TRUE), h5.w, h4.z + 44: addh_d2 h0(TRUE), h0, h1 + 45: slth h2.x(TRUE), h0.w, h2 + 46: sgth h2.w(TRUE), h0, h2 + 47: movh h0(TRUE), h0 + 48: addx.c0 rc(TRUE), h2, h2.w + 49: movh h0(c0.NE.x), h1 + +IPU0 ------ Simplified schedule: -------- +Pass | Unit | uOp | PC: Op +-----+--------+------+------------------------- + 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | SCB1 | add | 2: ADDh h2.z, h0.--w-, const.--x-; + | | | + 2 | SCT0/1 | mov | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; + | TEX | txl | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; + | SCB1 | add | 6: ADDh h0.z,-h2, h0.--w-; + | | | + 3 | SCT0/1 | mov | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; + | TEX | txl | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; + | SCB0 | add | 9: ADDh h0.x, h0.z---,-h1.w---; + | SCB1 | add | 10: ADDh h3.w, h0.---z, h1; + | | | + 4 | SCT0/1 | mov | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | TEX | txl | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | SCB0 | add | 14: ADDh h0.x, h2.w---, h0; + | SCB1 | add | 13: ADDh h0.z, h3.--w-,-h2.--w-; + | | | + 5 | SCT1 | mov | 15: NRMh h1.xz, h0; + | SRB | nrm | 15: NRMh h1.xz, h0; + | SCB0 | min | 16: MINh*8 h0.x, |h1|, |h1.z---|; + | SCB1 | max | 17: MAXh h4.w, h0, h1; + | | | + 6 | SCT0 | div | 18: DIVx h2.xy, h1.xz--, h0; + | SCT1 | mov | 19: MOVr r1.zw, g[TEX0].--xy; + | SCB0 | mad | 20: MADr r2.xz,-h1, const.z-w-, r1.z-w-; + | SCB1 | min | 22: MINh h5.w, h0, h1; + | | | + 7 | SCT0/1 | mov | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; + | TEX | txl | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; + | SCB0 | max | 27: MAXh h4.x, h2.z---, h2.w---; + | SCB1 | mad | 25: MADr r0.zw, h1.--xz, const, r1; + | | | + 8 | SCT0/1 | mov | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; + | TEX | txl | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; + | SCB0/1 | add | 30: ADDh/2 h1, h0, h1; + | | | + 9 | SCT0 | mad | 31: MADr r0.xy,-h2, const.xy--, r1.zw--; + | SCT1 | mov | 33: TXLr h0, r0, const.zzzz, TEX0; + | TEX | txl | 33: TXLr h0, r0, const.zzzz, TEX0; + | SCB1 | min | 35: MINh h4.z, h2, h2.--w-; + | | | + 10 | SCT0 | mad | 37: MADr r1.xy, h2, const.xy--, r1.zw--; + | SCT1 | mov | 39: TXLr h2, r1, const.zzzz, TEX0; + | TEX | txl | 39: TXLr h2, r1, const.zzzz, TEX0; + | SCB0/1 | add | 41: ADDh/2 h0, h0, h2; + | | | + 11 | SCT0 | min | 43: MINh h2.x, h5.w---, h4.z---; + | SCT1 | max | 42: MAXh h2.w, h4, h4.---x; + | SCB0/1 | add | 44: ADDh/2 h0, h0, h1; + | | | + 12 | SCT0 | set | 45: SLTh h2.x, h0.w---, h2; + | SCT1 | set | 46: SGTh h2.w, h0, h2; + | SCB0/1 | mul | 47: MOVh h0, h0; + | | | + 13 | SCT0 | mad | 48: ADDxc0_s rc, h2, h2.w---; + | SCB0/1 | mul | 49: MOVh h0(NE0.xxxx), h1; + +Pass SCT TEX SCB + 1: 0% 100% 25% + 2: 0% 100% 25% + 3: 0% 100% 50% + 4: 0% 100% 50% + 5: 0% 0% 50% + 6: 100% 0% 75% + 7: 0% 100% 75% + 8: 0% 100% 100% + 9: 0% 100% 25% + 10: 0% 100% 100% + 11: 50% 0% 100% + 12: 50% 0% 100% + 13: 25% 0% 100% + +MEAN: 17% 61% 67% + +Pass SCT0 SCT1 TEX SCB0 SCB1 + 1: 0% 0% 100% 0% 100% + 2: 0% 0% 100% 0% 100% + 3: 0% 0% 100% 100% 100% + 4: 0% 0% 100% 100% 100% + 5: 0% 0% 0% 100% 100% + 6: 100% 100% 0% 100% 100% + 7: 0% 0% 100% 100% 100% + 8: 0% 0% 100% 100% 100% + 9: 0% 0% 100% 0% 100% + 10: 0% 0% 100% 100% 100% + 11: 100% 100% 0% 100% 100% + 12: 100% 100% 0% 100% 100% + 13: 100% 0% 0% 100% 100% + +MEAN: 30% 23% 61% 76% 100% +Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 +Results 13 cycles, 3 r regs, 923,076,923 pixels/s +============================================================================*/ +#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 0) +/*--------------------------------------------------------------------------*/ +#pragma regcount 7 +#pragma disablepc all +#pragma option O3 +#pragma option OutColorPrec=fp16 +#pragma texformat default RGBA8 +/*==========================================================================*/ +half4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ +// (1) + half4 dir; + half4 lumaNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + lumaNe.w += half(1.0/512.0); + dir.x = -lumaNe.w; + dir.z = -lumaNe.w; + #else + lumaNe.y += half(1.0/512.0); + dir.x = -lumaNe.y; + dir.z = -lumaNe.y; + #endif +/*--------------------------------------------------------------------------*/ +// (2) + half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x += lumaSw.w; + dir.z += lumaSw.w; + #else + dir.x += lumaSw.y; + dir.z += lumaSw.y; + #endif +/*--------------------------------------------------------------------------*/ +// (3) + half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x -= lumaNw.w; + dir.z += lumaNw.w; + #else + dir.x -= lumaNw.y; + dir.z += lumaNw.y; + #endif +/*--------------------------------------------------------------------------*/ +// (4) + half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x += lumaSe.w; + dir.z -= lumaSe.w; + #else + dir.x += lumaSe.y; + dir.z -= lumaSe.y; + #endif +/*--------------------------------------------------------------------------*/ +// (5) + half4 dir1_pos; + dir1_pos.xy = normalize(dir.xyz).xz; + half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); +/*--------------------------------------------------------------------------*/ +// (6) + half4 dir2_pos; + dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0)); + dir1_pos.zw = pos.xy; + dir2_pos.zw = pos.xy; + half4 temp1N; + temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; +/*--------------------------------------------------------------------------*/ +// (7) + temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); + half4 rgby1; + rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; +/*--------------------------------------------------------------------------*/ +// (8) + rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); + rgby1 = (temp1N + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (9) + half4 temp2N; + temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); +/*--------------------------------------------------------------------------*/ +// (10) + half4 rgby2; + rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); + rgby2 = (temp2N + rgby2) * 0.5; +/*--------------------------------------------------------------------------*/ +// (11) + // compilier moves these scalar ops up to other cycles + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w)); + half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w)); + #else + half lumaMin = min(min(lumaNw.y, lumaSw.y), min(lumaNe.y, lumaSe.y)); + half lumaMax = max(max(lumaNw.y, lumaSw.y), max(lumaNe.y, lumaSe.y)); + #endif + rgby2 = (rgby2 + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (12) + #if (FXAA_GREEN_AS_LUMA == 0) + bool twoTapLt = rgby2.w < lumaMin; + bool twoTapGt = rgby2.w > lumaMax; + #else + bool twoTapLt = rgby2.y < lumaMin; + bool twoTapGt = rgby2.y > lumaMax; + #endif +/*--------------------------------------------------------------------------*/ +// (13) + if(twoTapLt || twoTapGt) rgby2 = rgby1; +/*--------------------------------------------------------------------------*/ + return rgby2; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + + FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (WITH EARLY EXIT) + +============================================================================== +The code mostly matches the assembly. +I have a feeling that 14 cycles is possible, but was not able to get there. +Might have to increase register count to get full performance. +Note this shader does not use perspective interpolation. + +Use the following cgc options, + + --fenable-bx2 --fastmath --fastprecision --nofloatbindings + +Use of FXAA_GREEN_AS_LUMA currently adds a cycle (16 clks). +Will look at fixing this for FXAA 3.12. +------------------------------------------------------------------------------ + NVSHADERPERF OUTPUT +------------------------------------------------------------------------------ +For reference and to aid in debug, output of NVShaderPerf should match this, + +Shader to schedule: + 0: texpkb h0.w(TRUE), v5.zyxx, #0 + 2: addh h2.y(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x + 4: texpkb h1.w(TRUE), v5.xwxx, #0 + 6: addh h0.x(TRUE), h1.w, -h2.y + 7: texpkb h2.w(TRUE), v5.zwzz, #0 + 9: minh h4.w(TRUE), h2.y, h2 + 10: maxh h5.x(TRUE), h2.y, h2.w + 11: texpkb h0.w(TRUE), v5, #0 + 13: addh h3.w(TRUE), -h0, h0.x + 14: addh h0.x(TRUE), h0.w, h0 + 15: addh h0.z(TRUE), -h2.w, h0.x + 16: addh h0.x(TRUE), h2.w, h3.w + 17: minh h5.y(TRUE), h0.w, h1.w + 18: nrmh h2.xz(TRUE), h0_n + 19: minh_m8 h2.w(TRUE), |h2.x|, |h2.z| + 20: divx h4.xy(TRUE), h2_n.xzzw, h2_n.w + 21: movr r1.zw(TRUE), v4.xxxy + 22: maxh h2.w(TRUE), h0, h1 + 23: fenct TRUE + 24: madr r0.xy(TRUE), -h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz + 26: texpkb h0(TRUE), r0, #0 + 28: maxh h5.x(TRUE), h2.w, h5 + 29: minh h5.w(TRUE), h5.y, h4 + 30: madr r1.xy(TRUE), h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz + 32: texpkb h2(TRUE), r1, #0 + 34: addh_d2 h2(TRUE), h0, h2 + 35: texpkb h1(TRUE), v4, #0 + 37: maxh h5.y(TRUE), h5.x, h1.w + 38: minh h4.w(TRUE), h1, h5 + 39: madr r0.xy(TRUE), -h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 41: texpkb h0(TRUE), r0, #0 + 43: addh_m8 h5.z(TRUE), h5.y, -h4.w + 44: madr r2.xy(TRUE), h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 46: texpkb h3(TRUE), r2, #0 + 48: addh_d2 h0(TRUE), h0, h3 + 49: addh_d2 h3(TRUE), h0, h2 + 50: movh h0(TRUE), h3 + 51: slth h3.x(TRUE), h3.w, h5.w + 52: sgth h3.w(TRUE), h3, h5.x + 53: addx.c0 rc(TRUE), h3.x, h3 + 54: slth.c0 rc(TRUE), h5.z, h5 + 55: movh h0(c0.NE.w), h2 + 56: movh h0(c0.NE.x), h1 + +IPU0 ------ Simplified schedule: -------- +Pass | Unit | uOp | PC: Op +-----+--------+------+------------------------- + 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | SCB0 | add | 2: ADDh h2.y, h0.-w--, const.-x--; + | | | + 2 | SCT0/1 | mov | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; + | TEX | txl | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; + | SCB0 | add | 6: ADDh h0.x, h1.w---,-h2.y---; + | | | + 3 | SCT0/1 | mov | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | TEX | txl | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | SCB0 | max | 10: MAXh h5.x, h2.y---, h2.w---; + | SCB1 | min | 9: MINh h4.w, h2.---y, h2; + | | | + 4 | SCT0/1 | mov | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; + | TEX | txl | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; + | SCB0 | add | 14: ADDh h0.x, h0.w---, h0; + | SCB1 | add | 13: ADDh h3.w,-h0, h0.---x; + | | | + 5 | SCT0 | mad | 16: ADDh h0.x, h2.w---, h3.w---; + | SCT1 | mad | 15: ADDh h0.z,-h2.--w-, h0.--x-; + | SCB0 | min | 17: MINh h5.y, h0.-w--, h1.-w--; + | | | + 6 | SCT1 | mov | 18: NRMh h2.xz, h0; + | SRB | nrm | 18: NRMh h2.xz, h0; + | SCB1 | min | 19: MINh*8 h2.w, |h2.---x|, |h2.---z|; + | | | + 7 | SCT0 | div | 20: DIVx h4.xy, h2.xz--, h2.ww--; + | SCT1 | mov | 21: MOVr r1.zw, g[TEX0].--xy; + | SCB1 | max | 22: MAXh h2.w, h0, h1; + | | | + 8 | SCT0 | mad | 24: MADr r0.xy,-h2.xz--, const.zw--, r1.zw--; + | SCT1 | mov | 26: TXLr h0, r0, const.xxxx, TEX0; + | TEX | txl | 26: TXLr h0, r0, const.xxxx, TEX0; + | SCB0 | max | 28: MAXh h5.x, h2.w---, h5; + | SCB1 | min | 29: MINh h5.w, h5.---y, h4; + | | | + 9 | SCT0 | mad | 30: MADr r1.xy, h2.xz--, const.zw--, r1.zw--; + | SCT1 | mov | 32: TXLr h2, r1, const.xxxx, TEX0; + | TEX | txl | 32: TXLr h2, r1, const.xxxx, TEX0; + | SCB0/1 | add | 34: ADDh/2 h2, h0, h2; + | | | + 10 | SCT0/1 | mov | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; + | TEX | txl | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; + | SCB0 | max | 37: MAXh h5.y, h5.-x--, h1.-w--; + | SCB1 | min | 38: MINh h4.w, h1, h5; + | | | + 11 | SCT0 | mad | 39: MADr r0.xy,-h4, const.xy--, r1.zw--; + | SCT1 | mov | 41: TXLr h0, r0, const.zzzz, TEX0; + | TEX | txl | 41: TXLr h0, r0, const.zzzz, TEX0; + | SCB0 | mad | 44: MADr r2.xy, h4, const.xy--, r1.zw--; + | SCB1 | add | 43: ADDh*8 h5.z, h5.--y-,-h4.--w-; + | | | + 12 | SCT0/1 | mov | 46: TXLr h3, r2, const.xxxx, TEX0; + | TEX | txl | 46: TXLr h3, r2, const.xxxx, TEX0; + | SCB0/1 | add | 48: ADDh/2 h0, h0, h3; + | | | + 13 | SCT0/1 | mad | 49: ADDh/2 h3, h0, h2; + | SCB0/1 | mul | 50: MOVh h0, h3; + | | | + 14 | SCT0 | set | 51: SLTh h3.x, h3.w---, h5.w---; + | SCT1 | set | 52: SGTh h3.w, h3, h5.---x; + | SCB0 | set | 54: SLThc0 rc, h5.z---, h5; + | SCB1 | add | 53: ADDxc0_s rc, h3.---x, h3; + | | | + 15 | SCT0/1 | mul | 55: MOVh h0(NE0.wwww), h2; + | SCB0/1 | mul | 56: MOVh h0(NE0.xxxx), h1; + +Pass SCT TEX SCB + 1: 0% 100% 25% + 2: 0% 100% 25% + 3: 0% 100% 50% + 4: 0% 100% 50% + 5: 50% 0% 25% + 6: 0% 0% 25% + 7: 100% 0% 25% + 8: 0% 100% 50% + 9: 0% 100% 100% + 10: 0% 100% 50% + 11: 0% 100% 75% + 12: 0% 100% 100% + 13: 100% 0% 100% + 14: 50% 0% 50% + 15: 100% 0% 100% + +MEAN: 26% 60% 56% + +Pass SCT0 SCT1 TEX SCB0 SCB1 + 1: 0% 0% 100% 100% 0% + 2: 0% 0% 100% 100% 0% + 3: 0% 0% 100% 100% 100% + 4: 0% 0% 100% 100% 100% + 5: 100% 100% 0% 100% 0% + 6: 0% 0% 0% 0% 100% + 7: 100% 100% 0% 0% 100% + 8: 0% 0% 100% 100% 100% + 9: 0% 0% 100% 100% 100% + 10: 0% 0% 100% 100% 100% + 11: 0% 0% 100% 100% 100% + 12: 0% 0% 100% 100% 100% + 13: 100% 100% 0% 100% 100% + 14: 100% 100% 0% 100% 100% + 15: 100% 100% 0% 100% 100% + +MEAN: 33% 33% 60% 86% 80% +Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 +Results 15 cycles, 3 r regs, 800,000,000 pixels/s +============================================================================*/ +#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 1) +/*--------------------------------------------------------------------------*/ +#pragma regcount 7 +#pragma disablepc all +#pragma option O2 +#pragma option OutColorPrec=fp16 +#pragma texformat default RGBA8 +/*==========================================================================*/ +half4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ +// (1) + half4 rgbyNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaNe = rgbyNe.w + half(1.0/512.0); + #else + half lumaNe = rgbyNe.y + half(1.0/512.0); + #endif +/*--------------------------------------------------------------------------*/ +// (2) + half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaSwNegNe = lumaSw.w - lumaNe; + #else + half lumaSwNegNe = lumaSw.y - lumaNe; + #endif +/*--------------------------------------------------------------------------*/ +// (3) + half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxNwSw = max(lumaNw.w, lumaSw.w); + half lumaMinNwSw = min(lumaNw.w, lumaSw.w); + #else + half lumaMaxNwSw = max(lumaNw.y, lumaSw.y); + half lumaMinNwSw = min(lumaNw.y, lumaSw.y); + #endif +/*--------------------------------------------------------------------------*/ +// (4) + half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half dirZ = lumaNw.w + lumaSwNegNe; + half dirX = -lumaNw.w + lumaSwNegNe; + #else + half dirZ = lumaNw.y + lumaSwNegNe; + half dirX = -lumaNw.y + lumaSwNegNe; + #endif +/*--------------------------------------------------------------------------*/ +// (5) + half3 dir; + dir.y = 0.0; + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x = lumaSe.w + dirX; + dir.z = -lumaSe.w + dirZ; + half lumaMinNeSe = min(lumaNe, lumaSe.w); + #else + dir.x = lumaSe.y + dirX; + dir.z = -lumaSe.y + dirZ; + half lumaMinNeSe = min(lumaNe, lumaSe.y); + #endif +/*--------------------------------------------------------------------------*/ +// (6) + half4 dir1_pos; + dir1_pos.xy = normalize(dir).xz; + half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); +/*--------------------------------------------------------------------------*/ +// (7) + half4 dir2_pos; + dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimes8, half(-2.0), half(2.0)); + dir1_pos.zw = pos.xy; + dir2_pos.zw = pos.xy; + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxNeSe = max(lumaNe, lumaSe.w); + #else + half lumaMaxNeSe = max(lumaNe, lumaSe.y); + #endif +/*--------------------------------------------------------------------------*/ +// (8) + half4 temp1N; + temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; + temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); + half lumaMax = max(lumaMaxNwSw, lumaMaxNeSe); + half lumaMin = min(lumaMinNwSw, lumaMinNeSe); +/*--------------------------------------------------------------------------*/ +// (9) + half4 rgby1; + rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; + rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); + rgby1 = (temp1N + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (10) + half4 rgbyM = h4tex2Dlod(tex, half4(pos.xy, 0.0, 0.0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxM = max(lumaMax, rgbyM.w); + half lumaMinM = min(lumaMin, rgbyM.w); + #else + half lumaMaxM = max(lumaMax, rgbyM.y); + half lumaMinM = min(lumaMin, rgbyM.y); + #endif +/*--------------------------------------------------------------------------*/ +// (11) + half4 temp2N; + temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); + half4 rgby2; + rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__PS3_EDGE_THRESHOLD; +/*--------------------------------------------------------------------------*/ +// (12) + rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); + rgby2 = (temp2N + rgby2) * 0.5; +/*--------------------------------------------------------------------------*/ +// (13) + rgby2 = (rgby2 + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (14) + #if (FXAA_GREEN_AS_LUMA == 0) + bool twoTapLt = rgby2.w < lumaMin; + bool twoTapGt = rgby2.w > lumaMax; + #else + bool twoTapLt = rgby2.y < lumaMin; + bool twoTapGt = rgby2.y > lumaMax; + #endif + bool earlyExit = lumaRangeM < lumaMax; + bool twoTap = twoTapLt || twoTapGt; +/*--------------------------------------------------------------------------*/ +// (15) + if(twoTap) rgby2 = rgby1; + if(earlyExit) rgby2 = rgbyM; +/*--------------------------------------------------------------------------*/ + return rgby2; } +/*==========================================================================*/ +#endif diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/fxaa/fxaaP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/fxaa/fxaaP.hlsl new file mode 100644 index 000000000..269bfea67 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/fxaa/fxaaP.hlsl @@ -0,0 +1,143 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../shaderModel.hlsl" + +#define FXAA_PC 1 +#if (TORQUE_SM <= 30) +#define FXAA_HLSL_3 1 +#elif TORQUE_SM < 49 +#define FXAA_HLSL_4 1 +#elif TORQUE_SM >=50 +#define FXAA_HLSL_5 1 +#endif +#define FXAA_QUALITY__PRESET 12 +#define FXAA_GREEN_AS_LUMA 1 + +#include "Fxaa3_11.h" + +struct VertToPix +{ + float4 hpos : TORQUE_POSITION; + float2 uv0 : TEXCOORD0; +}; + +TORQUE_UNIFORM_SAMPLER2D(colorTex, 0); + +uniform float2 oneOverTargetSize; + + +float4 main( VertToPix IN ) : TORQUE_TARGET0 +{ +#if (TORQUE_SM >= 10 && TORQUE_SM <=30) + FxaaTex tex = colorTex; +#elif TORQUE_SM >=40 + FxaaTex tex; + tex.smpl = colorTex; + tex.tex = texture_colorTex; +#endif + + return FxaaPixelShader( + + IN.uv0, // vertex position + + 0, // Unused... console stuff + + tex, // The color back buffer + + tex, // Used for 360 optimization + + tex, // Used for 360 optimization + + oneOverTargetSize, + + 0, // Unused... console stuff + + 0, // Unused... console stuff + + 0, // Unused... console stuff + + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__SUBPIX define. + // It is here now to allow easier tuning. + // Choose the amount of sub-pixel aliasing removal. + // This can effect sharpness. + // 1.00 - upper limit (softer) + // 0.75 - default amount of filtering + // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) + // 0.25 - almost off + // 0.00 - completely off + 0.75, + + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // The minimum amount of local contrast required to apply algorithm. + // 0.333 - too little (faster) + // 0.250 - low quality + // 0.166 - default + // 0.125 - high quality + // 0.063 - overkill (slower) + 0.166, + + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // 0.0833 - upper limit (default, the start of visible unfiltered edges) + // 0.0625 - high quality (faster) + // 0.0312 - visible limit (slower) + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + 0, + + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. + // Due to the PS3 being ALU bound, + // there are only three safe values here: 2 and 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // For all other platforms can be a non-power of two. + // 8.0 is sharper (default!!!) + // 4.0 is softer + // 2.0 is really soft (good only for vector graphics inputs) + 8, + + 0, // Unused... console stuff + + 0, // Unused... console stuff + + 0 // Unused... console stuff + + ); +} + diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/fxaa/fxaaV.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/fxaa/fxaaV.hlsl new file mode 100644 index 000000000..3bef0a4d3 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/fxaa/fxaaV.hlsl @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./../../torque.hlsl" +#include "./../postFX.hlsl" + +struct VertToPix +{ + float4 hpos : TORQUE_POSITION; + float2 uv0 : TEXCOORD0; +}; + +uniform float4 rtParams0; + +VertToPix main( PFXVert IN ) +{ + VertToPix OUT; + + OUT.hpos = float4(IN.pos,1); + OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/fxaa/gl/fxaaP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/fxaa/gl/fxaaP.glsl new file mode 100644 index 000000000..19d76ef42 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/fxaa/gl/fxaaP.glsl @@ -0,0 +1,125 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#define FXAA_PC 1 +#define FXAA_GLSL_130 1 +#define FXAA_QUALITY__PRESET 12 +#define FXAA_GREEN_AS_LUMA 1 + +#include "../Fxaa3_11.h" +#include "../../../gl/hlslCompat.glsl" + +uniform sampler2D colorTex ; +uniform vec2 oneOverTargetSize; + +in vec4 hpos; +in vec2 uv0; + +out vec4 OUT_col; + +void main() +{ + OUT_col = FxaaPixelShader( + + uv0, // vertex position + + vec4(0), // Unused... console stuff + + colorTex, // The color back buffer + + colorTex, // Used for 360 optimization + + colorTex, // Used for 360 optimization + + oneOverTargetSize, + + vec4(0), // Unused... console stuff + + vec4(0), // Unused... console stuff + + vec4(0), // Unused... console stuff + + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__SUBPIX define. + // It is here now to allow easier tuning. + // Choose the amount of sub-pixel aliasing removal. + // This can effect sharpness. + // 1.00 - upper limit (softer) + // 0.75 - default amount of filtering + // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) + // 0.25 - almost off + // 0.00 - completely off + 0.75, + + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // The minimum amount of local contrast required to apply algorithm. + // 0.333 - too little (faster) + // 0.250 - low quality + // 0.166 - default + // 0.125 - high quality + // 0.063 - overkill (slower) + 0.166, + + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // 0.0833 - upper limit (default, the start of visible unfiltered edges) + // 0.0625 - high quality (faster) + // 0.0312 - visible limit (slower) + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + 0, + + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. + // Due to the PS3 being ALU bound, + // there are only three safe values here: 2 and 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // For all other platforms can be a non-power of two. + // 8.0 is sharper (default!!!) + // 4.0 is softer + // 2.0 is really soft (good only for vector graphics inputs) + 8, + + 0, // Unused... console stuff + + 0, // Unused... console stuff + + vec4(0) // Unused... console stuff + + ); +} + diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/fxaa/gl/fxaaV.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/fxaa/gl/fxaaV.glsl new file mode 100644 index 000000000..55d445d91 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/fxaa/gl/fxaaV.glsl @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" +#include "../../../gl/torque.glsl" + +in vec4 vPosition; +in vec2 vTexCoord0; + +uniform vec4 rtParams0; + +out vec4 hpos; +out vec2 uv0; + +void main() +{ + gl_Position = vPosition; + hpos = gl_Position; + uv0 = viewportCoordToRenderTarget( vTexCoord0, rtParams0 ); + + correctSSP(gl_Position); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/gammaP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/gammaP.hlsl new file mode 100644 index 000000000..21b86fe4e --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/gammaP.hlsl @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "shadergen:/autogenConditioners.h" +#include "./postFx.hlsl" +#include "../torque.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(backBuffer, 0); +TORQUE_UNIFORM_SAMPLER1D(colorCorrectionTex, 1); + +uniform float OneOverGamma; +uniform float Brightness; +uniform float Contrast; + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float4 color = TORQUE_TEX2D(backBuffer, IN.uv0.xy); + + // Apply the color correction. + color.r = TORQUE_TEX1D( colorCorrectionTex, color.r ).r; + color.g = TORQUE_TEX1D( colorCorrectionTex, color.g ).g; + color.b = TORQUE_TEX1D( colorCorrectionTex, color.b ).b; + + // Apply gamma correction + color.rgb = pow( saturate(color.rgb), OneOverGamma ); + + // Apply contrast + color.rgb = ((color.rgb - 0.5f) * Contrast) + 0.5f; + + // Apply brightness + color.rgb += Brightness; + + return color; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/gl/VolFogGlowP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/gl/VolFogGlowP.glsl new file mode 100644 index 000000000..01b072dd9 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/gl/VolFogGlowP.glsl @@ -0,0 +1,67 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2014 R.G.S. - Richards Game Studio, the Netherlands +// http://www.richardsgamestudio.com/ +// +// If you find this code useful or you are feeling particularly generous I +// would ask that you please go to http://www.richardsgamestudio.com/ then +// choose Donations from the menu on the left side and make a donation to +// Richards Game Studio. It will be highly appreciated. +// +// The MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Volumetric Fog Glow postFx pixel shader V1.00 + +uniform sampler2D diffuseMap; +uniform float strength; + +out vec4 OUT_col; + +in vec2 uv0; +in vec2 uv1; +in vec2 uv2; +in vec2 uv3; + +in vec2 uv4; +in vec2 uv5; +in vec2 uv6; +in vec2 uv7; + +void main() +{ + vec4 kernel = vec4( 0.175, 0.275, 0.375, 0.475 ) * strength; + + OUT_col = vec4(0); + OUT_col += texture( diffuseMap, uv0 ) * kernel.x; + OUT_col += texture( diffuseMap, uv1 ) * kernel.y; + OUT_col += texture( diffuseMap, uv2 ) * kernel.z; + OUT_col += texture( diffuseMap, uv3 ) * kernel.w; + + OUT_col += texture( diffuseMap, uv4 ) * kernel.x; + OUT_col += texture( diffuseMap, uv5 ) * kernel.y; + OUT_col += texture( diffuseMap, uv6 ) * kernel.z; + OUT_col += texture( diffuseMap, uv7 ) * kernel.w; + + // Calculate a lumenance value in the alpha so we + // can use alpha test to save fillrate. + vec3 rgb2lum = vec3( 0.30, 0.59, 0.11 ); + OUT_col.a = dot( OUT_col.rgb, rgb2lum ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/gl/chromaticLens.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/gl/chromaticLens.glsl new file mode 100644 index 000000000..fdb85ba00 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/gl/chromaticLens.glsl @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Based on 'Cubic Lens Distortion HLSL Shader' by François Tarlier +// www.francois-tarlier.com/blog/index.php/2009/11/cubic-lens-distortion-shader + +#include "./postFX.glsl" +#include "../../gl/torque.glsl" +#include "../../gl/hlslCompat.glsl" + +uniform sampler2D backBuffer; +uniform float distCoeff; +uniform float cubeDistort; +uniform vec3 colorDistort; + +out vec4 OUT_col; + +void main() +{ + vec2 tex = IN_uv0; + + float f = 0; + float r2 = (tex.x - 0.5) * (tex.x - 0.5) + (tex.y - 0.5) * (tex.y - 0.5); + + // Only compute the cubic distortion if necessary. + if ( cubeDistort == 0.0 ) + f = 1 + r2 * distCoeff; + else + f = 1 + r2 * (distCoeff + cubeDistort * sqrt(r2)); + + // Distort each color channel seperately to get a chromatic distortion effect. + vec3 outColor; + vec3 distort = vec3(f) + colorDistort; + + for ( int i=0; i < 3; i++ ) + { + float x = distort[i] * ( tex.x - 0.5 ) + 0.5; + float y = distort[i] * ( tex.y - 0.5 ) + 0.5; + outColor[i] = tex2Dlod( backBuffer, vec4(x,y,0,0) )[i]; + } + + OUT_col = vec4( outColor.rgb, 1 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/gl/flashP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/gl/flashP.glsl new file mode 100644 index 000000000..fc5072e6d --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/gl/flashP.glsl @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./postFX.glsl" +#include "../../gl/torque.glsl" +#include "../../gl/hlslCompat.glsl" + +uniform float damageFlash; +uniform float whiteOut; +uniform sampler2D backBuffer; + +out vec4 OUT_col; + +void main() +{ + vec4 color1 = texture(backBuffer, IN_uv0); + vec4 color2 = color1 * MUL_COLOR; + vec4 damage = mix(color1,color2,damageFlash); + OUT_col = mix(damage,WHITE_COLOR,whiteOut); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/gl/fogP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/gl/fogP.glsl new file mode 100644 index 000000000..dd16f8b46 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/gl/fogP.glsl @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../gl/hlslCompat.glsl" + +#include "shadergen:/autogenConditioners.h" +#include "../../gl/torque.glsl" + +uniform sampler2D prepassTex ; +uniform vec3 eyePosWorld; +uniform vec4 fogColor; +uniform vec3 fogData; +uniform vec4 rtParams0; + +in vec2 uv0; +in vec3 wsEyeRay; + +out vec4 OUT_col; + +void main() +{ + //vec2 prepassCoord = ( uv0.xy * rtParams0.zw ) + rtParams0.xy; + float depth = prepassUncondition( prepassTex, uv0 ).w; + //return vec4( depth, 0, 0, 0.7 ); + + float factor = computeSceneFog( eyePosWorld, + eyePosWorld + ( wsEyeRay * depth ), + fogData.x, + fogData.y, + fogData.z ); + + OUT_col = hdrEncode( vec4( toLinear(fogColor.rgb), 1.0 - saturate( factor ) ) ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/gl/gammaP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/gl/gammaP.glsl new file mode 100644 index 000000000..a170bf39f --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/gl/gammaP.glsl @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../gl/hlslCompat.glsl" +#include "../../gl/torque.glsl" +#include "shadergen:/autogenConditioners.h" + +uniform sampler2D backBuffer; +uniform sampler1D colorCorrectionTex; + +uniform float OneOverGamma; +uniform float Brightness; +uniform float Contrast; + +in vec2 uv0; + +out vec4 OUT_col; + +void main() +{ + vec4 color = texture(backBuffer, uv0.xy); + + // Apply the color correction. + color.r = texture( colorCorrectionTex, color.r ).r; + color.g = texture( colorCorrectionTex, color.g ).g; + color.b = texture( colorCorrectionTex, color.b ).b; + + // Apply gamma correction + color.rgb = pow( clamp(color.rgb, vec3(0.0),vec3(1.0)), vec3(OneOverGamma) ); + + // Apply contrast + color.rgb = ((color.rgb - 0.5f) * Contrast) + 0.5f; + + // Apply brightness + color.rgb += Brightness; + + OUT_col = color; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/gl/glowBlurP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/gl/glowBlurP.glsl new file mode 100644 index 000000000..9ebca32fa --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/gl/glowBlurP.glsl @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../gl/hlslCompat.glsl" + +uniform sampler2D diffuseMap ; + +in vec4 hpos; //POSITION; +in vec2 uv0; //TEXCOORD0; +in vec2 uv1; //TEXCOORD1; +in vec2 uv2; //TEXCOORD2; +in vec2 uv3; //TEXCOORD3; +in vec2 uv4; //TEXCOORD4; +in vec2 uv5; //TEXCOORD5; +in vec2 uv6; //TEXCOORD6; +in vec2 uv7; //TEXCOORD7; + +out vec4 OUT_col; + +void main() +{ + vec4 kernel = vec4( 0.175, 0.275, 0.375, 0.475 ) * 0.5f; + + OUT_col = vec4(0); + OUT_col += texture( diffuseMap, uv0 ) * kernel.x; + OUT_col += texture( diffuseMap, uv1 ) * kernel.y; + OUT_col += texture( diffuseMap, uv2 ) * kernel.z; + OUT_col += texture( diffuseMap, uv3 ) * kernel.w; + + OUT_col += texture( diffuseMap, uv4 ) * kernel.x; + OUT_col += texture( diffuseMap, uv5 ) * kernel.y; + OUT_col += texture( diffuseMap, uv6 ) * kernel.z; + OUT_col += texture( diffuseMap, uv7 ) * kernel.w; + + // Calculate a lumenance value in the alpha so we + // can use alpha test to save fillrate. + vec3 rgb2lum = vec3( 0.30, 0.59, 0.11 ); + OUT_col.a = dot( OUT_col.rgb, rgb2lum ); + +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/gl/glowBlurV.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/gl/glowBlurV.glsl new file mode 100644 index 000000000..70445d7fe --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/gl/glowBlurV.glsl @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../gl/hlslCompat.glsl" +#include "../../gl/torque.glsl" + +in vec4 vPosition; +in vec2 vTexCoord0; + +uniform vec2 texSize0; + +out vec4 hpos; //POSITION; +out vec2 uv0; //TEXCOORD0; +out vec2 uv1; //TEXCOORD1; +out vec2 uv2; //TEXCOORD2; +out vec2 uv3; //TEXCOORD3; +out vec2 uv4; //TEXCOORD4; +out vec2 uv5; //TEXCOORD5; +out vec2 uv6; //TEXCOORD6; +out vec2 uv7; //TEXCOORD7; + +void main() +{ + gl_Position = vPosition; + hpos = gl_Position; + + vec2 uv = vTexCoord0 + (0.5f / texSize0); + + uv0 = uv + ( ( BLUR_DIR * 3.5f ) / texSize0 ); + uv1 = uv + ( ( BLUR_DIR * 2.5f ) / texSize0 ); + uv2 = uv + ( ( BLUR_DIR * 1.5f ) / texSize0 ); + uv3 = uv + ( ( BLUR_DIR * 0.5f ) / texSize0 ); + + uv4 = uv - ( ( BLUR_DIR * 3.5f ) / texSize0 ); + uv5 = uv - ( ( BLUR_DIR * 2.5f ) / texSize0 ); + uv6 = uv - ( ( BLUR_DIR * 1.5f ) / texSize0 ); + uv7 = uv - ( ( BLUR_DIR * 0.5f ) / texSize0 ); + + correctSSP(gl_Position); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/gl/motionBlurP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/gl/motionBlurP.glsl new file mode 100644 index 000000000..56333e776 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/gl/motionBlurP.glsl @@ -0,0 +1,78 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../gl/hlslCompat.glsl" +#include "../../gl/torque.glsl" +#include "shadergen:/autogenConditioners.h" +#include "postFX.glsl" + +#undef IN_uv0 +#define _IN_uv0 uv0 + +uniform mat4 matPrevScreenToWorld; +uniform mat4 matWorldToScreen; + +// Passed in from setShaderConsts() +uniform float velocityMultiplier; + +uniform sampler2D backBuffer; +uniform sampler2D prepassTex; + +out vec4 OUT_col; + +void main() +{ + vec2 IN_uv0 = _IN_uv0; + float samples = 5; + + // First get the prepass texture for uv channel 0 + vec4 prepass = prepassUncondition( prepassTex, IN_uv0 ); + + // Next extract the depth + float depth = prepass.a; + + // Create the screen position + vec4 screenPos = vec4(IN_uv0.x*2-1, IN_uv0.y*2-1, depth*2-1, 1); + + // Calculate the world position + vec4 D = tMul(screenPos, matWorldToScreen); + vec4 worldPos = D / D.w; + + // Now calculate the previous screen position + vec4 previousPos = tMul( worldPos, matPrevScreenToWorld ); + previousPos /= previousPos.w; + + // Calculate the XY velocity + vec2 velocity = ((screenPos - previousPos) / velocityMultiplier).xy; + + // Generate the motion blur + vec4 color = texture(backBuffer, IN_uv0); + IN_uv0 += velocity; + + for(int i = 1; i 0 ) + { + rayStart.z -= ( startSide ); + //return vec4( 1, 0, 0, 1 ); + } + + vec3 hitPos; + vec3 ray = rayEnd - rayStart; + float rayLen = length( ray ); + vec3 rayDir = normalize( ray ); + + float endSide = dot( plane.xyz, rayEnd ) + plane.w; + float planeDist; + + if ( endSide < -0.005 ) + { + //return vec4( 0, 0, 1, 1 ); + hitPos = rayEnd; + planeDist = endSide; + } + else + { + //return vec4( 0, 0, 0, 0 ); + float den = dot( ray, plane.xyz ); + + // Parallal to the plane, return the endPnt. + //if ( den == 0.0f ) + // return endPnt; + + float dist = -( dot( plane.xyz, rayStart ) + plane.w ) / den; + if ( dist < 0.0 ) + dist = 0.0; + //return vec4( 1, 0, 0, 1 ); + //return vec4( ( dist ).rrr, 1 ); + + + hitPos = mix( rayStart, rayEnd, dist ); + + planeDist = dist; + } + + float delta = length( hitPos - rayStart ); + + float fogAmt = 1.0 - saturate( exp( -FOG_DENSITY * ( delta - FOG_DENSITY_OFFSET ) ) ); + //return vec4( fogAmt.rrr, 1 ); + + // Calculate the water "base" color based on depth. + vec4 fogColor = waterColor * texture( waterDepthGradMap, saturate( delta / waterDepthGradMax ) ); + // Modulate baseColor by the ambientColor. + fogColor *= vec4( ambientColor.rgb, 1 ); + + vec3 inColor = hdrDecode( texture( backbuffer, IN_uv0 ).rgb ); + inColor.rgb *= 1.0 - saturate( abs( planeDist ) / WET_DEPTH ) * WET_DARKENING; + //return vec4( inColor, 1 ); + + vec3 outColor = mix( inColor, fogColor.rgb, fogAmt ); + + OUT_col = vec4( hdrEncode( outColor ), 1 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/glowBlurP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/glowBlurP.hlsl new file mode 100644 index 000000000..80f8ed02d --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/glowBlurP.hlsl @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0); + +struct VertToPix +{ + float4 hpos : TORQUE_POSITION; + + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + float2 uv3 : TEXCOORD3; + + float2 uv4 : TEXCOORD4; + float2 uv5 : TEXCOORD5; + float2 uv6 : TEXCOORD6; + float2 uv7 : TEXCOORD7; +}; + +float4 main( VertToPix IN ) : TORQUE_TARGET0 +{ + float4 kernel = float4( 0.175, 0.275, 0.375, 0.475 ) * 0.5f; + + float4 OUT = 0; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv0 ) * kernel.x; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv1 ) * kernel.y; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv2 ) * kernel.z; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv3 ) * kernel.w; + + OUT += TORQUE_TEX2D( diffuseMap, IN.uv4 ) * kernel.x; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv5 ) * kernel.y; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv6 ) * kernel.z; + OUT += TORQUE_TEX2D( diffuseMap, IN.uv7 ) * kernel.w; + + // Calculate a lumenance value in the alpha so we + // can use alpha test to save fillrate. + float3 rgb2lum = float3( 0.30, 0.59, 0.11 ); + OUT.a = dot( OUT.rgb, rgb2lum ); + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/glowBlurV.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/glowBlurV.hlsl new file mode 100644 index 000000000..b8f5cf9c2 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/glowBlurV.hlsl @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./postFx.hlsl" +#include "./../torque.hlsl" + + +uniform float2 texSize0; + +struct VertToPix +{ + float4 hpos : TORQUE_POSITION; + + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + float2 uv3 : TEXCOORD3; + + float2 uv4 : TEXCOORD4; + float2 uv5 : TEXCOORD5; + float2 uv6 : TEXCOORD6; + float2 uv7 : TEXCOORD7; +}; + +VertToPix main( PFXVert IN ) +{ + VertToPix OUT; + + OUT.hpos = float4(IN.pos,1.0); + + float2 uv = IN.uv + (0.5f / texSize0); + + OUT.uv0 = uv + ( ( BLUR_DIR * 3.5f ) / texSize0 ); + OUT.uv1 = uv + ( ( BLUR_DIR * 2.5f ) / texSize0 ); + OUT.uv2 = uv + ( ( BLUR_DIR * 1.5f ) / texSize0 ); + OUT.uv3 = uv + ( ( BLUR_DIR * 0.5f ) / texSize0 ); + + OUT.uv4 = uv - ( ( BLUR_DIR * 3.5f ) / texSize0 ); + OUT.uv5 = uv - ( ( BLUR_DIR * 2.5f ) / texSize0 ); + OUT.uv6 = uv - ( ( BLUR_DIR * 1.5f ) / texSize0 ); + OUT.uv7 = uv - ( ( BLUR_DIR * 0.5f ) / texSize0 ); + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/bloomGaussBlurHP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/bloomGaussBlurHP.hlsl new file mode 100644 index 000000000..77f4b9915 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/bloomGaussBlurHP.hlsl @@ -0,0 +1,68 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(inputTex, 0); +uniform float2 oneOverTargetSize; +uniform float gaussMultiplier; +uniform float gaussMean; +uniform float gaussStdDev; + +#define PI 3.141592654 + +float computeGaussianValue( float x, float mean, float std_deviation ) +{ + // The gaussian equation is defined as such: + /* + -(x - mean)^2 + ------------- + 1.0 2*std_dev^2 + f(x,mean,std_dev) = -------------------- * e^ + sqrt(2*pi*std_dev^2) + + */ + + float tmp = ( 1.0f / sqrt( 2.0f * PI * std_deviation * std_deviation ) ); + float tmp2 = exp( ( -( ( x - mean ) * ( x - mean ) ) ) / ( 2.0f * std_deviation * std_deviation ) ); + return tmp * tmp2; +} + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float4 color = { 0.0f, 0.0f, 0.0f, 0.0f }; + float offset = 0; + float weight = 0; + float x = 0; + float fI = 0; + + for( int i = 0; i < 9; i++ ) + { + fI = (float)i; + offset = (i - 4.0) * oneOverTargetSize.x; + x = (i - 4.0) / 4.0; + weight = gaussMultiplier * computeGaussianValue( x, gaussMean, gaussStdDev ); + color += (TORQUE_TEX2D( inputTex, IN.uv0 + float2( offset, 0.0f ) ) * weight ); + } + + return float4( color.rgb, 1.0f ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/bloomGaussBlurVP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/bloomGaussBlurVP.hlsl new file mode 100644 index 000000000..8381f6a5d --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/bloomGaussBlurVP.hlsl @@ -0,0 +1,67 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(inputTex, 0); +uniform float2 oneOverTargetSize; +uniform float gaussMultiplier; +uniform float gaussMean; +uniform float gaussStdDev; + +#define D3DX_PI 3.141592654 + +float computeGaussianValue( float x, float mean, float std_deviation ) +{ + // The gaussian equation is defined as such: + /* + -(x - mean)^2 + ------------- + 1.0 2*std_dev^2 + f(x,mean,std_dev) = -------------------- * e^ + sqrt(2*pi*std_dev^2) + + */ + float tmp = ( 1.0f / sqrt( 2.0f * D3DX_PI * std_deviation * std_deviation ) ); + float tmp2 = exp( ( -( ( x - mean ) * ( x - mean ) ) ) / ( 2.0f * std_deviation * std_deviation ) ); + return tmp * tmp2; +} + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float4 color = { 0.0f, 0.0f, 0.0f, 0.0f }; + float offset = 0; + float weight = 0; + float x = 0; + float fI = 0; + + for( int i = 0; i < 9; i++ ) + { + fI = (float)i; + offset = (fI - 4.0) * oneOverTargetSize.y; + x = (fI - 4.0) / 4.0; + weight = gaussMultiplier * computeGaussianValue( x, gaussMean, gaussStdDev ); + color += (TORQUE_TEX2D( inputTex, IN.uv0 + float2( 0.0f, offset ) ) * weight ); + } + + return float4( color.rgb, 1.0f ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/brightPassFilterP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/brightPassFilterP.hlsl new file mode 100644 index 000000000..9a8a93e97 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/brightPassFilterP.hlsl @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" +#include "../../torque.hlsl" + + +TORQUE_UNIFORM_SAMPLER2D(inputTex, 0); +TORQUE_UNIFORM_SAMPLER2D(luminanceTex, 1); +uniform float2 oneOverTargetSize; +uniform float brightPassThreshold; +uniform float g_fMiddleGray; + +static const float3 LUMINANCE_VECTOR = float3(0.3125f, 0.6154f, 0.0721f); + + +static float2 gTapOffsets[4] = +{ + { -0.5, 0.5 }, { 0.5, -0.5 }, + { -0.5, -0.5 }, { 0.5, 0.5 } +}; + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float4 average = { 0.0f, 0.0f, 0.0f, 0.0f }; + + // Combine and average 4 samples from the source HDR texture. + for( int i = 0; i < 4; i++ ) + average += hdrDecode( TORQUE_TEX2D( inputTex, IN.uv0 + ( gTapOffsets[i] * oneOverTargetSize ) ) ); + average *= 0.25f; + + // Determine the brightness of this particular pixel. + float adaptedLum = TORQUE_TEX2D( luminanceTex, float2( 0.5f, 0.5f ) ).r; + float lum = (g_fMiddleGray / (adaptedLum + 0.0001)) * hdrLuminance( average.rgb ); + //float lum = hdrLuminance( average.rgb ); + + // Determine whether this pixel passes the test... + if ( lum < brightPassThreshold ) + average = float4( 0.0f, 0.0f, 0.0f, 1.0f ); + + // Write the colour to the bright-pass render target + return hdrEncode( average ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/calculateAdaptedLumP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/calculateAdaptedLumP.hlsl new file mode 100644 index 000000000..0f895070a --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/calculateAdaptedLumP.hlsl @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(currLum, 0); +TORQUE_UNIFORM_SAMPLER2D(lastAdaptedLum, 1); + +uniform float adaptRate; +uniform float deltaTime; + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float fAdaptedLum = TORQUE_TEX2D( lastAdaptedLum, float2(0.5f, 0.5f) ).r; + float fCurrentLum = TORQUE_TEX2D( currLum, float2(0.5f, 0.5f) ).r; + + // The user's adapted luminance level is simulated by closing the gap between + // adapted luminance and current luminance by 2% every frame, based on a + // 30 fps rate. This is not an accurate model of human adaptation, which can + // take longer than half an hour. + float diff = fCurrentLum - fAdaptedLum; + float fNewAdaptation = fAdaptedLum + ( diff * ( 1.0 - exp( -deltaTime * adaptRate ) ) ); + + return float4( fNewAdaptation, 0.0, 0.0, 1.0f ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/downScale4x4P.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/downScale4x4P.hlsl new file mode 100644 index 000000000..01998af0b --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/downScale4x4P.hlsl @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#define IN_HLSL +#include "../../shdrConsts.h" +#include "../postFx.hlsl" + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +struct VertIn +{ + float4 hpos : TORQUE_POSITION; + float4 texCoords[8] : TEXCOORD0; +}; + +TORQUE_UNIFORM_SAMPLER2D(inputTex, 0); + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +float4 main( VertIn IN) : TORQUE_TARGET0 +{ + // We calculate the texture coords + // in the vertex shader as an optimization. + float4 sample = 0.0f; + for ( int i = 0; i < 8; i++ ) + { + sample += TORQUE_TEX2D( inputTex, IN.texCoords[i].xy ); + sample += TORQUE_TEX2D( inputTex, IN.texCoords[i].zw ); + } + + return sample / 16; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/downScale4x4V.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/downScale4x4V.hlsl new file mode 100644 index 000000000..c9a34b7f4 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/downScale4x4V.hlsl @@ -0,0 +1,138 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#define IN_HLSL +#include "../../shdrConsts.h" +#include "../postFx.hlsl" +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- + +struct Conn +{ + float4 hpos : TORQUE_POSITION; + float4 texCoords[8] : TEXCOORD0; +}; + +uniform float2 targetSize; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Conn main( PFXVert In ) +{ + Conn Out; + + Out.hpos = float4(In.pos,1.0); + + // Sample from the 16 surrounding points. Since the center point will be in + // the exact center of 16 texels, a 0.5f offset is needed to specify a texel + // center. + float2 texSize = float2( 1.0 / (targetSize.x - 1.0), 1.0 / (targetSize.y - 1.0) ); + + float4 uv; + uv.xy = In.uv.xy; + uv.zw = In.uv.xy; + + Out.texCoords[0] = uv; + Out.texCoords[0].x += texSize.x; + Out.texCoords[0].y += texSize.y; + Out.texCoords[0].z += texSize.x; + Out.texCoords[0].w += texSize.y; + Out.texCoords[0].x += ( 0 - 1.5 ) * texSize.x; + Out.texCoords[0].y += ( 0 - 1.5 ) * texSize.y; + Out.texCoords[0].z += ( 1 - 1.5 ) * texSize.x; + Out.texCoords[0].w += ( 0 - 1.5 ) * texSize.y; + + Out.texCoords[1] = uv; + Out.texCoords[1].x += texSize.x; + Out.texCoords[1].y += texSize.y; + Out.texCoords[1].z += texSize.x; + Out.texCoords[1].w += texSize.y; + Out.texCoords[1].x += ( 2 - 1.5 ) * texSize.x; + Out.texCoords[1].y += ( 0 - 1.5 ) * texSize.y; + Out.texCoords[1].z += ( 3 - 1.5 ) * texSize.x; + Out.texCoords[1].w += ( 0 - 1.5 ) * texSize.y; + + Out.texCoords[2] = uv; + Out.texCoords[2].x += texSize.x; + Out.texCoords[2].y += texSize.y; + Out.texCoords[2].z += texSize.x; + Out.texCoords[2].w += texSize.y; + Out.texCoords[2].x += ( 0 - 1.5 ) * texSize.x; + Out.texCoords[2].y += ( 1 - 1.5 ) * texSize.y; + Out.texCoords[2].z += ( 1 - 1.5 ) * texSize.x; + Out.texCoords[2].w += ( 1 - 1.5 ) * texSize.y; + + Out.texCoords[3] = uv; + Out.texCoords[3].x += texSize.x; + Out.texCoords[3].y += texSize.y; + Out.texCoords[3].z += texSize.x; + Out.texCoords[3].w += texSize.y; + Out.texCoords[3].x += ( 2 - 1.5 ) * texSize.x; + Out.texCoords[3].y += ( 1 - 1.5 ) * texSize.y; + Out.texCoords[3].z += ( 3 - 1.5 ) * texSize.x; + Out.texCoords[3].w += ( 1 - 1.5 ) * texSize.y; + + Out.texCoords[4] = uv; + Out.texCoords[4].x += texSize.x; + Out.texCoords[4].y += texSize.y; + Out.texCoords[4].z += texSize.x; + Out.texCoords[4].w += texSize.y; + Out.texCoords[4].x += ( 0 - 1.5 ) * texSize.x; + Out.texCoords[4].y += ( 2 - 1.5 ) * texSize.y; + Out.texCoords[4].z += ( 1 - 1.5 ) * texSize.x; + Out.texCoords[4].w += ( 2 - 1.5 ) * texSize.y; + + Out.texCoords[5] = uv; + Out.texCoords[5].x += texSize.x; + Out.texCoords[5].y += texSize.y; + Out.texCoords[5].z += texSize.x; + Out.texCoords[5].w += texSize.y; + Out.texCoords[5].x += ( 2 - 1.5 ) * texSize.x; + Out.texCoords[5].y += ( 2 - 1.5 ) * texSize.y; + Out.texCoords[5].z += ( 3 - 1.5 ) * texSize.x; + Out.texCoords[5].w += ( 2 - 1.5 ) * texSize.y; + + Out.texCoords[6] = uv; + Out.texCoords[6].x += texSize.x; + Out.texCoords[6].y += texSize.y; + Out.texCoords[6].z += texSize.x; + Out.texCoords[6].w += texSize.y; + Out.texCoords[6].x += ( 0 - 1.5 ) * texSize.x; + Out.texCoords[6].y += ( 3 - 1.5 ) * texSize.y; + Out.texCoords[6].z += ( 1 - 1.5 ) * texSize.x; + Out.texCoords[6].w += ( 3 - 1.5 ) * texSize.y; + + Out.texCoords[7] = uv; + Out.texCoords[7].x += texSize.x; + Out.texCoords[7].y += texSize.y; + Out.texCoords[7].z += texSize.x; + Out.texCoords[7].w += texSize.y; + Out.texCoords[7].x += ( 2 - 1.5 ) * texSize.x; + Out.texCoords[7].y += ( 3 - 1.5 ) * texSize.y; + Out.texCoords[7].z += ( 3 - 1.5 ) * texSize.x; + Out.texCoords[7].w += ( 3 - 1.5 ) * texSize.y; + + return Out; +} + diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/finalPassCombineP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/finalPassCombineP.hlsl new file mode 100644 index 000000000..f87616a6e --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/finalPassCombineP.hlsl @@ -0,0 +1,101 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../torque.hlsl" +#include "../postFx.hlsl" +#include "../../shaderModelAutoGen.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(sceneTex, 0); +TORQUE_UNIFORM_SAMPLER2D(luminanceTex, 1); +TORQUE_UNIFORM_SAMPLER2D(bloomTex, 2); +TORQUE_UNIFORM_SAMPLER1D(colorCorrectionTex, 3); + +uniform float2 texSize0; +uniform float2 texSize2; + +uniform float g_fEnableToneMapping; +uniform float g_fMiddleGray; +uniform float g_fWhiteCutoff; +uniform float g_fEnableBlueShift; + +uniform float3 g_fBlueShiftColor; +uniform float g_fBloomScale; +uniform float g_fOneOverGamma; +uniform float Brightness; +uniform float Contrast; + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float4 sample = hdrDecode( TORQUE_TEX2D( sceneTex, IN.uv0 ) ); + float adaptedLum = TORQUE_TEX2D( luminanceTex, float2( 0.5f, 0.5f ) ).r; + float4 bloom = TORQUE_TEX2D( bloomTex, IN.uv0 ); + + // For very low light conditions, the rods will dominate the perception + // of light, and therefore color will be desaturated and shifted + // towards blue. + if ( g_fEnableBlueShift > 0.0f ) + { + const float3 LUMINANCE_VECTOR = float3(0.2125f, 0.7154f, 0.0721f); + + // Define a linear blending from -1.5 to 2.6 (log scale) which + // determines the lerp amount for blue shift + float coef = 1.0f - ( adaptedLum + 1.5 ) / 4.1; + coef = saturate( coef * g_fEnableBlueShift ); + + // Lerp between current color and blue, desaturated copy + float3 rodColor = dot( sample.rgb, LUMINANCE_VECTOR ) * g_fBlueShiftColor; + sample.rgb = lerp( sample.rgb, rodColor, coef ); + + rodColor = dot( bloom.rgb, LUMINANCE_VECTOR ) * g_fBlueShiftColor; + bloom.rgb = lerp( bloom.rgb, rodColor, coef ); + } + + // Add the bloom effect. + sample += g_fBloomScale * bloom; + + // Map the high range of color values into a range appropriate for + // display, taking into account the user's adaptation level, + // white point, and selected value for for middle gray. + if ( g_fEnableToneMapping > 0.0f ) + { + float Lp = (g_fMiddleGray / (adaptedLum + 0.0001)) * hdrLuminance( sample.rgb ); + //float toneScalar = ( Lp * ( 1.0 + ( Lp / ( g_fWhiteCutoff ) ) ) ) / ( 1.0 + Lp ); + float toneScalar = Lp; + sample.rgb = lerp( sample.rgb, sample.rgb * toneScalar, g_fEnableToneMapping ); + } + + // Apply the color correction. + sample.r = TORQUE_TEX1D( colorCorrectionTex, sample.r ).r; + sample.g = TORQUE_TEX1D( colorCorrectionTex, sample.g ).g; + sample.b = TORQUE_TEX1D( colorCorrectionTex, sample.b ).b; + + // Apply gamma correction + sample.rgb = pow( saturate(sample.rgb), g_fOneOverGamma ); + + // Apply contrast + sample.rgb = ((sample.rgb - 0.5f) * Contrast) + 0.5f; + + // Apply brightness + sample.rgb += Brightness; + + return sample; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/bloomGaussBlurHP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/bloomGaussBlurHP.glsl new file mode 100644 index 000000000..1d9a2df3e --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/bloomGaussBlurHP.glsl @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../gl/postFX.glsl" + +uniform sampler2D inputTex ; +uniform vec2 oneOverTargetSize; +uniform float gaussMultiplier; +uniform float gaussMean; +uniform float gaussStdDev; + +out vec4 OUT_col; + +#define PI 3.141592654 + +float computeGaussianValue( float x, float mean, float std_deviation ) +{ + // The gaussian equation is defined as such: + /* + -(x - mean)^2 + ------------- + 1.0 2*std_dev^2 + f(x,mean,std_dev) = -------------------- * e^ + sqrt(2*pi*std_dev^2) + + */ + + float tmp = ( 1.0f / sqrt( 2.0f * PI * std_deviation * std_deviation ) ); + float tmp2 = exp( ( -( ( x - mean ) * ( x - mean ) ) ) / ( 2.0f * std_deviation * std_deviation ) ); + return tmp * tmp2; +} + +void main() +{ + vec4 color = vec4( 0.0f, 0.0f, 0.0f, 0.0f ); + float offset = 0; + float weight = 0; + float x = 0; + float fI = 0; + + for( int i = 0; i < 9; i++ ) + { + fI = float(i); + offset = (i - 4.0) * oneOverTargetSize.x; + x = (i - 4.0) / 4.0; + weight = gaussMultiplier * computeGaussianValue( x, gaussMean, gaussStdDev ); + color += (texture( inputTex, IN_uv0 + vec2( offset, 0.0f ) ) * weight ); + } + + OUT_col = vec4( color.rgb, 1.0f ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/bloomGaussBlurVP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/bloomGaussBlurVP.glsl new file mode 100644 index 000000000..68f34b164 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/bloomGaussBlurVP.glsl @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../gl/postFX.glsl" + +uniform sampler2D inputTex ; +uniform vec2 oneOverTargetSize; +uniform float gaussMultiplier; +uniform float gaussMean; +uniform float gaussStdDev; + +out vec4 OUT_col; + +#define D3DX_PI 3.141592654 + +float computeGaussianValue( float x, float mean, float std_deviation ) +{ + // The gaussian equation is defined as such: + /* + -(x - mean)^2 + ------------- + 1.0 2*std_dev^2 + f(x,mean,std_dev) = -------------------- * e^ + sqrt(2*pi*std_dev^2) + + */ + float tmp = ( 1.0f / sqrt( 2.0f * D3DX_PI * std_deviation * std_deviation ) ); + float tmp2 = exp( ( -( ( x - mean ) * ( x - mean ) ) ) / ( 2.0f * std_deviation * std_deviation ) ); + return tmp * tmp2; +} + +void main() +{ + vec4 color = vec4( 0.0f, 0.0f, 0.0f, 0.0f ); + float offset = 0; + float weight = 0; + float x = 0; + float fI = 0; + + for( int i = 0; i < 9; i++ ) + { + fI = float(i); + offset = (fI - 4.0) * oneOverTargetSize.y; + x = (fI - 4.0) / 4.0; + weight = gaussMultiplier * computeGaussianValue( x, gaussMean, gaussStdDev ); + color += (texture( inputTex, IN_uv0 + vec2( 0.0f, offset ) ) * weight ); + } + + OUT_col = vec4( color.rgb, 1.0f ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/brightPassFilterP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/brightPassFilterP.glsl new file mode 100644 index 000000000..f220ca1e7 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/brightPassFilterP.glsl @@ -0,0 +1,65 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/torque.glsl" +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../gl/postFX.glsl" + +uniform sampler2D inputTex ; +uniform sampler2D luminanceTex ; +uniform vec2 oneOverTargetSize; +uniform float brightPassThreshold; +uniform float g_fMiddleGray; + +const vec3 LUMINANCE_VECTOR = vec3(0.3125f, 0.6154f, 0.0721f); + +out vec4 OUT_col; + + +const vec2 gTapOffsets[4] = vec2[] +( + vec2( -0.5, 0.5 ), vec2( 0.5, -0.5 ), + vec2( -0.5, -0.5 ), vec2( 0.5, 0.5 ) +); + +void main() +{ + vec4 average = vec4( 0.0f, 0.0f, 0.0f, 0.0f ); + + // Combine and average 4 samples from the source HDR texture. + for( int i = 0; i < 4; i++ ) + average += hdrDecode( texture( inputTex, IN_uv0 + ( gTapOffsets[i] * oneOverTargetSize ) ) ); + average *= 0.25f; + + // Determine the brightness of this particular pixel. + float adaptedLum = texture( luminanceTex, vec2( 0.5f, 0.5f ) ).r; + float lum = (g_fMiddleGray / (adaptedLum + 0.0001)) * hdrLuminance( average.rgb ); + //float lum = hdrLuminance( average.rgb ); + + // Determine whether this pixel passes the test... + if ( lum < brightPassThreshold ) + average = vec4( 0.0f, 0.0f, 0.0f, 1.0f ); + + // Write the colour to the bright-pass render target + OUT_col = hdrEncode( average ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/calculateAdaptedLumP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/calculateAdaptedLumP.glsl new file mode 100644 index 000000000..96ee9d6df --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/calculateAdaptedLumP.glsl @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../gl/postFX.glsl" + +uniform sampler2D currLum; +uniform sampler2D lastAdaptedLum; + +uniform float adaptRate; +uniform float deltaTime; + +out vec4 OUT_col; + +void main() +{ + float fAdaptedLum = texture( lastAdaptedLum, vec2(0.5f, 0.5f) ).r; + float fCurrentLum = texture( currLum, vec2(0.5f, 0.5f) ).r; + + // The user's adapted luminance level is simulated by closing the gap between + // adapted luminance and current luminance by 2% every frame, based on a + // 30 fps rate. This is not an accurate model of human adaptation, which can + // take longer than half an hour. + float diff = fCurrentLum - fAdaptedLum; + float fNewAdaptation = fAdaptedLum + ( diff * ( 1.0 - exp( -deltaTime * adaptRate ) ) ); + + OUT_col = vec4( fNewAdaptation, 0.0, 0.0, 1.0f ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/downScale4x4P.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/downScale4x4P.glsl new file mode 100644 index 000000000..131671760 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/downScale4x4P.glsl @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#define IN_GLSL +#include "../../../shdrConsts.h" +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" + +in vec4 texCoords[8]; +#define IN_texCoords texCoords + +uniform sampler2D inputTex; + +out vec4 OUT_col; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + // We calculate the texture coords + // in the vertex shader as an optimization. + vec4 _sample = vec4(0.0f); + for ( int i = 0; i < 8; i++ ) + { + _sample += texture( inputTex, IN_texCoords[i].xy ); + _sample += texture( inputTex, IN_texCoords[i].zw ); + } + + OUT_col = _sample / 16; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/downScale4x4V.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/downScale4x4V.glsl new file mode 100644 index 000000000..51f1da896 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/downScale4x4V.glsl @@ -0,0 +1,141 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#define IN_GLSL +#include "../../../shdrConsts.h" +#include "../../../gl/hlslCompat.glsl" + +in vec4 vPosition; +in vec2 vTexCoord0; + +#define In_pos vPosition +#define In_uv vTexCoord0 + +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- +out vec4 texCoords[8]; +#define Out_texCoords texCoords + +#define Out_hpos gl_Position + +uniform vec2 targetSize; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + Out_hpos = In_pos; + + // Sample from the 16 surrounding points. Since the center point will be in + // the exact center of 16 texels, a 0.5f offset is needed to specify a texel + // center. + vec2 texSize = vec2( 1.0 / (targetSize.x - 1.0), 1.0 / (targetSize.y - 1.0) ); + + vec4 uv; + uv.xy = In_uv.xy; + uv.zw = In_uv.xy; + + Out_texCoords[0] = uv; + Out_texCoords[0].x += texSize.x; + Out_texCoords[0].y += texSize.y; + Out_texCoords[0].z += texSize.x; + Out_texCoords[0].w += texSize.y; + Out_texCoords[0].x += ( 0 - 1.5 ) * texSize.x; + Out_texCoords[0].y += ( 0 - 1.5 ) * texSize.y; + Out_texCoords[0].z += ( 1 - 1.5 ) * texSize.x; + Out_texCoords[0].w += ( 0 - 1.5 ) * texSize.y; + + Out_texCoords[1] = uv; + Out_texCoords[1].x += texSize.x; + Out_texCoords[1].y += texSize.y; + Out_texCoords[1].z += texSize.x; + Out_texCoords[1].w += texSize.y; + Out_texCoords[1].x += ( 2 - 1.5 ) * texSize.x; + Out_texCoords[1].y += ( 0 - 1.5 ) * texSize.y; + Out_texCoords[1].z += ( 3 - 1.5 ) * texSize.x; + Out_texCoords[1].w += ( 0 - 1.5 ) * texSize.y; + + Out_texCoords[2] = uv; + Out_texCoords[2].x += texSize.x; + Out_texCoords[2].y += texSize.y; + Out_texCoords[2].z += texSize.x; + Out_texCoords[2].w += texSize.y; + Out_texCoords[2].x += ( 0 - 1.5 ) * texSize.x; + Out_texCoords[2].y += ( 1 - 1.5 ) * texSize.y; + Out_texCoords[2].z += ( 1 - 1.5 ) * texSize.x; + Out_texCoords[2].w += ( 1 - 1.5 ) * texSize.y; + + Out_texCoords[3] = uv; + Out_texCoords[3].x += texSize.x; + Out_texCoords[3].y += texSize.y; + Out_texCoords[3].z += texSize.x; + Out_texCoords[3].w += texSize.y; + Out_texCoords[3].x += ( 2 - 1.5 ) * texSize.x; + Out_texCoords[3].y += ( 1 - 1.5 ) * texSize.y; + Out_texCoords[3].z += ( 3 - 1.5 ) * texSize.x; + Out_texCoords[3].w += ( 1 - 1.5 ) * texSize.y; + + Out_texCoords[4] = uv; + Out_texCoords[4].x += texSize.x; + Out_texCoords[4].y += texSize.y; + Out_texCoords[4].z += texSize.x; + Out_texCoords[4].w += texSize.y; + Out_texCoords[4].x += ( 0 - 1.5 ) * texSize.x; + Out_texCoords[4].y += ( 2 - 1.5 ) * texSize.y; + Out_texCoords[4].z += ( 1 - 1.5 ) * texSize.x; + Out_texCoords[4].w += ( 2 - 1.5 ) * texSize.y; + + Out_texCoords[5] = uv; + Out_texCoords[5].x += texSize.x; + Out_texCoords[5].y += texSize.y; + Out_texCoords[5].z += texSize.x; + Out_texCoords[5].w += texSize.y; + Out_texCoords[5].x += ( 2 - 1.5 ) * texSize.x; + Out_texCoords[5].y += ( 2 - 1.5 ) * texSize.y; + Out_texCoords[5].z += ( 3 - 1.5 ) * texSize.x; + Out_texCoords[5].w += ( 2 - 1.5 ) * texSize.y; + + Out_texCoords[6] = uv; + Out_texCoords[6].x += texSize.x; + Out_texCoords[6].y += texSize.y; + Out_texCoords[6].z += texSize.x; + Out_texCoords[6].w += texSize.y; + Out_texCoords[6].x += ( 0 - 1.5 ) * texSize.x; + Out_texCoords[6].y += ( 3 - 1.5 ) * texSize.y; + Out_texCoords[6].z += ( 1 - 1.5 ) * texSize.x; + Out_texCoords[6].w += ( 3 - 1.5 ) * texSize.y; + + Out_texCoords[7] = uv; + Out_texCoords[7].x += texSize.x; + Out_texCoords[7].y += texSize.y; + Out_texCoords[7].z += texSize.x; + Out_texCoords[7].w += texSize.y; + Out_texCoords[7].x += ( 2 - 1.5 ) * texSize.x; + Out_texCoords[7].y += ( 3 - 1.5 ) * texSize.y; + Out_texCoords[7].z += ( 3 - 1.5 ) * texSize.x; + Out_texCoords[7].w += ( 3 - 1.5 ) * texSize.y; + + correctSSP(gl_Position); +} + diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/finalPassCombineP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/finalPassCombineP.glsl new file mode 100644 index 000000000..8437cb04b --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/finalPassCombineP.glsl @@ -0,0 +1,106 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/torque.glsl" +#include "../../../gl/hlslCompat.glsl" +#include "../../gl/postFX.glsl" +#include "shadergen:/autogenConditioners.h" + +uniform sampler2D sceneTex; +uniform sampler2D luminanceTex; +uniform sampler2D bloomTex; +uniform sampler1D colorCorrectionTex; + +uniform vec2 texSize0; +uniform vec2 texSize2; + +uniform float g_fEnableToneMapping; +uniform float g_fMiddleGray; +uniform float g_fWhiteCutoff; + +uniform float g_fEnableBlueShift; +uniform vec3 g_fBlueShiftColor; + +uniform float g_fBloomScale; + +uniform float g_fOneOverGamma; +uniform float Brightness; +uniform float Contrast; + +out vec4 OUT_col; + +void main() +{ + vec4 _sample = hdrDecode( texture( sceneTex, IN_uv0 ) ); + float adaptedLum = texture( luminanceTex, vec2( 0.5f, 0.5f ) ).r; + vec4 bloom = texture( bloomTex, IN_uv0 ); + + // For very low light conditions, the rods will dominate the perception + // of light, and therefore color will be desaturated and shifted + // towards blue. + if ( g_fEnableBlueShift > 0.0f ) + { + const vec3 LUMINANCE_VECTOR = vec3(0.2125f, 0.7154f, 0.0721f); + + // Define a linear blending from -1.5 to 2.6 (log scale) which + // determines the mix amount for blue shift + float coef = 1.0f - ( adaptedLum + 1.5 ) / 4.1; + coef = saturate( coef * g_fEnableBlueShift ); + + // Lerp between current color and blue, desaturated copy + vec3 rodColor = dot( _sample.rgb, LUMINANCE_VECTOR ) * g_fBlueShiftColor; + _sample.rgb = mix( _sample.rgb, rodColor, coef ); + + rodColor = dot( bloom.rgb, LUMINANCE_VECTOR ) * g_fBlueShiftColor; + bloom.rgb = mix( bloom.rgb, rodColor, coef ); + } + + // Add the bloom effect. + _sample += g_fBloomScale * bloom; + + // Map the high range of color values into a range appropriate for + // display, taking into account the user's adaptation level, + // white point, and selected value for for middle gray. + if ( g_fEnableToneMapping > 0.0f ) + { + float Lp = (g_fMiddleGray / (adaptedLum + 0.0001)) * hdrLuminance( _sample.rgb ); + //float toneScalar = ( Lp * ( 1.0 + ( Lp / ( g_fWhiteCutoff ) ) ) ) / ( 1.0 + Lp ); + float toneScalar = Lp; + _sample.rgb = mix( _sample.rgb, _sample.rgb * toneScalar, g_fEnableToneMapping ); + } + + // Apply the color correction. + _sample.r = texture( colorCorrectionTex, _sample.r ).r; + _sample.g = texture( colorCorrectionTex, _sample.g ).g; + _sample.b = texture( colorCorrectionTex, _sample.b ).b; + + // Apply gamma correction + _sample.rgb = pow( _sample.rgb, vec3(g_fOneOverGamma) ); + + // Apply contrast + _sample.rgb = ((_sample.rgb - 0.5f) * Contrast) + 0.5f; + + // Apply brightness + _sample.rgb += Brightness; + + OUT_col = _sample; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/luminanceVisP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/luminanceVisP.glsl new file mode 100644 index 000000000..ee9c28c87 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/luminanceVisP.glsl @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/torque.glsl" +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../gl/postFX.glsl" + +uniform sampler2D inputTex; +uniform float brightPassThreshold; + +out vec4 OUT_col; + +void main() +{ + vec4 _sample = hdrDecode( texture( inputTex, IN_uv0 ) ); + + // Determine the brightness of this particular pixel. + float lum = hdrLuminance( _sample.rgb ); + + // Write the colour to the bright-pass render target + OUT_col = ( vec4( lum.rrr, 1 ) ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/sampleLumInitialP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/sampleLumInitialP.glsl new file mode 100644 index 000000000..8a2b9b318 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/sampleLumInitialP.glsl @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/torque.glsl" +#include "../../../gl/hlslCompat.glsl" +#include "../../gl/postFX.glsl" + +uniform sampler2D inputTex; +uniform vec2 texSize0; + +uniform float g_fMinLuminace; + +out vec4 OUT_col; + +const vec2 gTapOffsets[9] = vec2[] +( + vec2( -1.0, -1.0 ), vec2( 0.0, -1.0 ), vec2( 1.0, -1.0 ), + vec2( -1.0, 0.0 ), vec2( 0.0, 0.0 ), vec2( 1.0, 0.0 ), + vec2( -1.0, 1.0 ), vec2( 0.0, 1.0 ), vec2( 1.0, 1.0 ) +); + + +void main() +{ + vec2 tsize = 1.0 / texSize0; + + vec3 _sample; + float average = 0.0; + + for ( int i = 0; i < 9; i++ ) + { + // Decode the hdr value. + _sample = hdrDecode( texture( inputTex, IN_uv0 + ( gTapOffsets[i] * tsize ) ).rgb ); + + // Get the luminance and add it to the average. + float lum = max( hdrLuminance( _sample ), g_fMinLuminace ); + average += log( lum ); + } + + average = exp( average / 9.0 ); + + OUT_col = vec4( average, 0.0, 0.0, 1.0 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/sampleLumIterativeP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/sampleLumIterativeP.glsl new file mode 100644 index 000000000..2e800d612 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/gl/sampleLumIterativeP.glsl @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "../../gl/postFX.glsl" + +uniform sampler2D inputTex; +uniform vec2 oneOverTargetSize; + +out vec4 OUT_col; + +const vec2 gTapOffsets[16] = vec2[] +( + vec2( -1.5, -1.5 ), vec2( -0.5, -1.5 ), vec2( 0.5, -1.5 ), vec2( 1.5, -1.5 ), + vec2( -1.5, -0.5 ), vec2( -0.5, -0.5 ), vec2( 0.5, -0.5 ), vec2( 1.5, -0.5 ), + vec2( -1.5, 0.5 ), vec2( -0.5, 0.5 ), vec2( 0.5, 0.5 ), vec2( 1.5, 0.5 ), + vec2( -1.5, 1.5 ), vec2( -0.5, 1.5 ), vec2( 0.5, 1.5 ), vec2( 1.5, 1.5 ) +); + +void main() +{ + vec2 pixelSize = oneOverTargetSize; + + float average = 0.0; + + for ( int i = 0; i < 16; i++ ) + { + float lum = texture( inputTex, IN_uv0 + ( gTapOffsets[i] * pixelSize ) ).r; + average += lum; + } + + OUT_col = vec4( average / 16.0, 0.0, 0.0, 1.0 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/luminanceVisP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/luminanceVisP.hlsl new file mode 100644 index 000000000..505d1b825 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/luminanceVisP.hlsl @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" +#include "../../torque.hlsl" + + +TORQUE_UNIFORM_SAMPLER2D(inputTex, 0); +uniform float brightPassThreshold; + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float4 sample = hdrDecode( TORQUE_TEX2D( inputTex, IN.uv0 ) ); + + // Determine the brightness of this particular pixel. + float lum = hdrLuminance( sample.rgb ); + + // Write the colour to the bright-pass render target + return ( float4( lum.rrr, 1 ) ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/sampleLumInitialP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/sampleLumInitialP.hlsl new file mode 100644 index 000000000..2e23ece1f --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/sampleLumInitialP.hlsl @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../torque.hlsl" +#include "../postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(inputTex, 0); +uniform float2 texSize0; + +uniform float g_fMinLuminace; + +static float2 gTapOffsets[9] = +{ + { -1.0, -1.0 }, { 0.0, -1.0 }, { 1.0, -1.0 }, + { -1.0, 0.0 }, { 0.0, 0.0 }, { 1.0, 0.0 }, + { -1.0, 1.0 }, { 0.0, 1.0 }, { 1.0, 1.0 } +}; + + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float2 tsize = 1.0 / texSize0; + + float3 sample; + float average = 0.0; + + for ( int i = 0; i < 9; i++ ) + { + // Decode the hdr value. + sample = hdrDecode( TORQUE_TEX2D( inputTex, IN.uv0 + ( gTapOffsets[i] * tsize ) ).rgb ); + + // Get the luminance and add it to the average. + float lum = max( hdrLuminance( sample ), g_fMinLuminace ); + average += log( lum ); + } + + average = exp( average / 9.0 ); + + return float4( average, 0.0, 0.0, 1.0 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/hdr/sampleLumIterativeP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/sampleLumIterativeP.hlsl new file mode 100644 index 000000000..46ed6fc70 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/hdr/sampleLumIterativeP.hlsl @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(inputTex, 0); +uniform float2 oneOverTargetSize; + + +static float2 gTapOffsets[16] = +{ + { -1.5, -1.5 }, { -0.5, -1.5 }, { 0.5, -1.5 }, { 1.5, -1.5 }, + { -1.5, -0.5 }, { -0.5, -0.5 }, { 0.5, -0.5 }, { 1.5, -0.5 }, + { -1.5, 0.5 }, { -0.5, 0.5 }, { 0.5, 0.5 }, { 1.5, 0.5 }, + { -1.5, 1.5 }, { -0.5, 1.5 }, { 0.5, 1.5 }, { 1.5, 1.5 } +}; + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float2 pixelSize = oneOverTargetSize; + + float average = 0.0; + + for ( int i = 0; i < 16; i++ ) + { + float lum = TORQUE_TEX2D( inputTex, IN.uv0 + ( gTapOffsets[i] * pixelSize ) ).r; + average += lum; + } + + return float4( average / 16.0, 0.0, 0.0, 1.0 ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/lightRay/gl/lightRayOccludeP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/lightRay/gl/lightRayOccludeP.glsl new file mode 100644 index 000000000..a7917b328 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/lightRay/gl/lightRayOccludeP.glsl @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../gl/postFX.glsl" + +uniform sampler2D backBuffer; // The original backbuffer. +uniform sampler2D prepassTex; // The pre-pass depth and normals. + +uniform float brightScalar; + +const vec3 LUMINANCE_VECTOR = vec3(0.3125f, 0.6154f, 0.0721f); + +out vec4 OUT_col; + +void main() +{ + vec4 col = vec4( 0, 0, 0, 1 ); + + // Get the depth at this pixel. + float depth = prepassUncondition( prepassTex, IN_uv0 ).w; + + // If the depth is equal to 1.0, read from the backbuffer + // and perform the exposure calculation on the result. + if ( depth >= 0.999 ) + { + col = texture( backBuffer, IN_uv0 ); + + //col = 1 - exp(-120000 * col); + col += dot( vec3(col), LUMINANCE_VECTOR ) + 0.0001f; + col *= brightScalar; + } + + OUT_col = col; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/lightRay/gl/lightRayP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/lightRay/gl/lightRayP.glsl new file mode 100644 index 000000000..6d78f4eae --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/lightRay/gl/lightRayP.glsl @@ -0,0 +1,94 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "../../gl/postFX.glsl" + +uniform sampler2D frameSampler; +uniform sampler2D backBuffer; + +uniform vec3 camForward; +uniform vec3 lightDirection; +uniform vec2 screenSunPos; +uniform vec2 oneOverTargetSize; +uniform int numSamples; +uniform float density; +uniform float weight; +uniform float decay; +uniform float exposure; + +out vec4 OUT_col; + +void main() +{ + vec4 texCoord = vec4( IN_uv0.xy, 0, 0 ); + + // Store initial sample. + half3 color = half3(texture( frameSampler, texCoord.xy ).rgb); + + // Store original bb color. + vec4 bbCol = texture( backBuffer, IN_uv1 ); + + // Set up illumination decay factor. + half illuminationDecay = 1.0; + + float amount = saturate( dot( -lightDirection, camForward ) ); + + int samples = int(numSamples * amount); + + if ( samples <= 0 ) + { + OUT_col = bbCol; + return; + } + + // Calculate vector from pixel to light source in screen space. + half2 deltaTexCoord = half2( texCoord.xy - screenSunPos ); + + // Divide by number of samples and scale by control factor. + deltaTexCoord *= 1.0 / half(samples * density); + + // Evaluate summation from Equation 3 NUM_SAMPLES iterations. + for ( int i = 0; i < samples; i++ ) + { + // Step sample location along ray. + texCoord.xy -= deltaTexCoord; + + // Retrieve sample at new location. + half3 sample_ = half3(tex2Dlod( frameSampler, texCoord )); + + // Apply sample attenuation scale/decay factors. + sample_ *= illuminationDecay * weight; + + // Accumulate combined color. + color += sample_; + + // Update exponential decay factor. + illuminationDecay *= decay; + } + + //return saturate( amount ) * color * Exposure; + //return bbCol * decay; + + // Output final color with a further scale control factor. + OUT_col = saturate( amount ) * vec4( color * exposure, 1 ) + bbCol; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/lightRay/lightRayOccludeP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/lightRay/lightRayOccludeP.hlsl new file mode 100644 index 000000000..b70bafa98 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/lightRay/lightRayOccludeP.hlsl @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../shaderModelAutoGen.hlsl" +#include "../postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(backBuffer, 0); +TORQUE_UNIFORM_SAMPLER2D(prepassTex, 1); + +uniform float brightScalar; + +static const float3 LUMINANCE_VECTOR = float3(0.3125f, 0.6154f, 0.0721f); + + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float4 col = float4( 0, 0, 0, 1 ); + + // Get the depth at this pixel. + float depth = TORQUE_PREPASS_UNCONDITION( prepassTex, IN.uv0 ).w; + + // If the depth is equal to 1.0, read from the backbuffer + // and perform the exposure calculation on the result. + if ( depth >= 0.999 ) + { + col = TORQUE_TEX2D( backBuffer, IN.uv0 ); + + //col = 1 - exp(-120000 * col); + col += dot( col.rgb, LUMINANCE_VECTOR ) + 0.0001f; + col *= brightScalar; + } + + return col; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/lightRay/lightRayP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/lightRay/lightRayP.hlsl new file mode 100644 index 000000000..032894710 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/lightRay/lightRayP.hlsl @@ -0,0 +1,89 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(frameSampler, 0); +TORQUE_UNIFORM_SAMPLER2D(backBuffer, 1); + + +uniform float3 camForward; +uniform int numSamples; +uniform float3 lightDirection; +uniform float density; +uniform float2 screenSunPos; +uniform float2 oneOverTargetSize; +uniform float weight; +uniform float decay; +uniform float exposure; + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float4 texCoord = float4( IN.uv0.xy, 0, 0 ); + + // Store initial sample. + half3 color = (half3)TORQUE_TEX2D( frameSampler, texCoord.xy ).rgb; + + // Store original bb color. + float4 bbCol = TORQUE_TEX2D( backBuffer, IN.uv1 ); + + // Set up illumination decay factor. + half illuminationDecay = 1.0; + + float amount = saturate( dot( -lightDirection, camForward ) ); + + int samples = numSamples * amount; + + if ( samples <= 0 ) + return bbCol; + + // Calculate vector from pixel to light source in screen space. + half2 deltaTexCoord = (half2)( texCoord.xy - screenSunPos ); + + // Divide by number of samples and scale by control factor. + deltaTexCoord *= (half)(1.0 / samples * density); + + // Evaluate summation from Equation 3 NUM_SAMPLES iterations. + for ( int i = 0; i < samples; i++ ) + { + // Step sample location along ray. + texCoord.xy -= deltaTexCoord; + + // Retrieve sample at new location. + half3 sample = (half3)TORQUE_TEX2DLOD( frameSampler, texCoord ); + + // Apply sample attenuation scale/decay factors. + sample *= half(illuminationDecay * weight); + + // Accumulate combined color. + color += sample; + + // Update exponential decay factor. + illuminationDecay *= half(decay); + } + + //return saturate( amount ) * color * Exposure; + //return bbCol * decay; + + // Output final color with a further scale control factor. + return saturate( amount ) * float4( color * exposure, 1 ) + bbCol; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/blendWeightCalculationP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/blendWeightCalculationP.hlsl new file mode 100644 index 000000000..2c4777c36 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/blendWeightCalculationP.hlsl @@ -0,0 +1,78 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + + +uniform sampler2D edgesMap : register(S0); +uniform sampler2D edgesMapL : register(S1); +uniform sampler2D areaMap : register(S2); + +#include "./functions.hlsl" + + +float4 main(float2 texcoord : TEXCOORD0) : COLOR0 +{ + float4 areas = 0.0; + + float2 e = tex2D(edgesMap, texcoord).rg; + + [branch] + if (e.g) // Edge at north + { + // Search distances to the left and to the right: + float2 d = float2(SearchXLeft(texcoord), SearchXRight(texcoord)); + + // Now fetch the crossing edges. Instead of sampling between edgels, we + // sample at -0.25, to be able to discern what value has each edgel: + float4 coords = mad(float4(d.x, -0.25, d.y + 1.0, -0.25), + PIXEL_SIZE.xyxy, texcoord.xyxy); + float e1 = tex2Dlevel0(edgesMapL, coords.xy).r; + float e2 = tex2Dlevel0(edgesMapL, coords.zw).r; + + // Ok, we know how this pattern looks like, now it is time for getting + // the actual area: + areas.rg = Area(abs(d), e1, e2); + } + + [branch] + if (e.r) // Edge at west + { + // Search distances to the top and to the bottom: + float2 d = float2(SearchYUp(texcoord), SearchYDown(texcoord)); + + // Now fetch the crossing edges (yet again): + float4 coords = mad(float4(-0.25, d.x, -0.25, d.y + 1.0), + PIXEL_SIZE.xyxy, texcoord.xyxy); + float e1 = tex2Dlevel0(edgesMapL, coords.xy).g; + float e2 = tex2Dlevel0(edgesMapL, coords.zw).g; + + // Get the area for this direction: + areas.ba = Area(abs(d), e1, e2); + } + + return areas; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/edgeDetectionP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/edgeDetectionP.hlsl new file mode 100644 index 000000000..364bd948f --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/edgeDetectionP.hlsl @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + +#include "shadergen:/autogenConditioners.h" + +uniform sampler2D colorMapG : register(S0); +uniform sampler2D prepassMap : register(S1); + +uniform float3 lumaCoefficients; +uniform float threshold; +uniform float depthThreshold; + + +float4 main( float2 texcoord : TEXCOORD0, + float4 offset[2]: TEXCOORD1) : COLOR0 +{ + // Luma calculation requires gamma-corrected colors (texture 'colorMapG'). + // + // Note that there is a lot of overlapped luma calculations; performance + // can be improved if this luma calculation is performed in the main pass, + // which may give you an edge if used in conjunction with a z prepass. + + float L = dot(tex2D(colorMapG, texcoord).rgb, lumaCoefficients); + + float Lleft = dot(tex2D(colorMapG, offset[0].xy).rgb, lumaCoefficients); + float Ltop = dot(tex2D(colorMapG, offset[0].zw).rgb, lumaCoefficients); + float Lright = dot(tex2D(colorMapG, offset[1].xy).rgb, lumaCoefficients); + float Lbottom = dot(tex2D(colorMapG, offset[1].zw).rgb, lumaCoefficients); + + float4 delta = abs(L.xxxx - float4(Lleft, Ltop, Lright, Lbottom)); + float4 edges = step(threshold, delta); + + // Add depth edges to color edges + float D = prepassUncondition(prepassMap, texcoord).w; + float Dleft = prepassUncondition(prepassMap, offset[0].xy).w; + float Dtop = prepassUncondition(prepassMap, offset[0].zw).w; + float Dright = prepassUncondition(prepassMap, offset[1].xy).w; + float Dbottom = prepassUncondition(prepassMap, offset[1].zw).w; + + delta = abs(D.xxxx - float4(Dleft, Dtop, Dright, Dbottom)); + edges += step(depthThreshold, delta); + + if (dot(edges, 1.0) == 0.0) + discard; + + return edges; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/functions.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/functions.hlsl new file mode 100644 index 000000000..9935a5e30 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/functions.hlsl @@ -0,0 +1,145 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + + +uniform float2 texSize0; + +#if !defined(PIXEL_SIZE) +#define PIXEL_SIZE (1.0 / texSize0) +#define MAX_SEARCH_STEPS 8 +#define MAX_DISTANCE 33 +#endif + +// Typical Multiply-Add operation to ease translation to assembly code. + +float4 mad(float4 m, float4 a, float4 b) +{ + #if defined(XBOX) + float4 result; + asm { + mad result, m, a, b + }; + return result; + #else + return m * a + b; + #endif +} + + +// This one just returns the first level of a mip map chain, which allow us to +// avoid the nasty ddx/ddy warnings, even improving the performance a little +// bit. +float4 tex2Dlevel0(sampler2D map, float2 texcoord) +{ + return tex2Dlod(map, float4(texcoord, 0.0, 0.0)); +} + + +// Same as above, this eases translation to assembly code; +float4 tex2Doffset(sampler2D map, float2 texcoord, float2 offset) +{ + #if defined(XBOX) && MAX_SEARCH_STEPS < 6 + float4 result; + float x = offset.x; + float y = offset.y; + asm { + tfetch2D result, texcoord, map, OffsetX = x, OffsetY = y + }; + return result; + #else + return tex2Dlevel0(map, texcoord + PIXEL_SIZE * offset); + #endif +} + + +// Ok, we have the distance and both crossing edges, can you please return +// the float2 blending weights? +float2 Area(float2 distance, float e1, float e2) +{ + // * By dividing by areaSize - 1.0 below we are implicitely offsetting to + // always fall inside of a pixel + // * Rounding prevents bilinear access precision problems + float areaSize = MAX_DISTANCE * 5.0; + float2 pixcoord = MAX_DISTANCE * round(4.0 * float2(e1, e2)) + distance; + float2 texcoord = pixcoord / (areaSize - 1.0); + return tex2Dlevel0(areaMap, texcoord).rg; +} + + +// Search functions for the 2nd pass. +float SearchXLeft(float2 texcoord) +{ + // We compare with 0.9 to prevent bilinear access precision problems. + float i; + float e = 0.0; + for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0) + { + e = tex2Doffset(edgesMapL, texcoord, float2(i, 0.0)).g; + [flatten] if (e < 0.9) break; + } + return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS); +} + +// Search functions for the 2nd pass. +float SearchXRight(float2 texcoord) +{ + float i; + float e = 0.0; + for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0) + { + e = tex2Doffset(edgesMapL, texcoord, float2(i, 0.0)).g; + [flatten] if (e < 0.9) break; + } + return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS); +} + +// Search functions for the 2nd pass. +float SearchYUp(float2 texcoord) +{ + float i; + float e = 0.0; + for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0) + { + e = tex2Doffset(edgesMapL, texcoord, float2(i, 0.0).yx).r; + [flatten] if (e < 0.9) break; + } + return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS); +} + +// Search functions for the 2nd pass. +float SearchYDown(float2 texcoord) +{ + float i; + float e = 0.0; + for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0) + { + e = tex2Doffset(edgesMapL, texcoord, float2(i, 0.0).yx).r; + [flatten] if (e < 0.9) break; + } + return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/blendWeightCalculationP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/blendWeightCalculationP.glsl new file mode 100644 index 000000000..af01ce6f9 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/blendWeightCalculationP.glsl @@ -0,0 +1,83 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + +#include "../../../gl/hlslCompat.glsl" + +in vec2 texcoord; + +uniform sampler2D edgesMap; +uniform sampler2D edgesMapL; +uniform sampler2D areaMap; + +out vec4 OUT_col; + +#include "./functions.glsl" + + +void main() +{ + vec4 areas = vec4(0.0); + + vec2 e = texture(edgesMap, texcoord).rg; + + //[branch] + if (bool(e.g)) // Edge at north + { + // Search distances to the left and to the right: + vec2 d = vec2(SearchXLeft(texcoord), SearchXRight(texcoord)); + + // Now fetch the crossing edges. Instead of sampling between edgels, we + // sample at -0.25, to be able to discern what value has each edgel: + vec4 coords = mad(vec4(d.x, -0.25, d.y + 1.0, -0.25), + PIXEL_SIZE.xyxy, texcoord.xyxy); + float e1 = tex2Dlevel0(edgesMapL, coords.xy).r; + float e2 = tex2Dlevel0(edgesMapL, coords.zw).r; + + // Ok, we know how this pattern looks like, now it is time for getting + // the actual area: + areas.rg = Area(abs(d), e1, e2); + } + + //[branch] + if (bool(e.r)) // Edge at west + { + // Search distances to the top and to the bottom: + vec2 d = vec2(SearchYUp(texcoord), SearchYDown(texcoord)); + + // Now fetch the crossing edges (yet again): + vec4 coords = mad(vec4(-0.25, d.x, -0.25, d.y + 1.0), + PIXEL_SIZE.xyxy, texcoord.xyxy); + float e1 = tex2Dlevel0(edgesMapL, coords.xy).g; + float e2 = tex2Dlevel0(edgesMapL, coords.zw).g; + + // Get the area for this direction: + areas.ba = Area(abs(d), e1, e2); + } + + OUT_col = areas; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/edgeDetectionP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/edgeDetectionP.glsl new file mode 100644 index 000000000..362f29b5c --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/edgeDetectionP.glsl @@ -0,0 +1,76 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" + +uniform sampler2D colorMapG; +uniform sampler2D prepassMap; + +uniform vec3 lumaCoefficients; +uniform float threshold; +uniform float depthThreshold; + +in vec2 texcoord; +in vec4 offset[2]; + +out vec4 OUT_col; + +void main() +{ + // Luma calculation requires gamma-corrected colors (texture 'colorMapG'). + // + // Note that there is a lot of overlapped luma calculations; performance + // can be improved if this luma calculation is performed in the main pass, + // which may give you an edge if used in conjunction with a z prepass. + + float L = dot(texture(colorMapG, texcoord).rgb, lumaCoefficients); + + float Lleft = dot(texture(colorMapG, offset[0].xy).rgb, lumaCoefficients); + float Ltop = dot(texture(colorMapG, offset[0].zw).rgb, lumaCoefficients); + float Lright = dot(texture(colorMapG, offset[1].xy).rgb, lumaCoefficients); + float Lbottom = dot(texture(colorMapG, offset[1].zw).rgb, lumaCoefficients); + + vec4 delta = abs(vec4(L) - vec4(Lleft, Ltop, Lright, Lbottom)); + vec4 edges = step(threshold, delta); + + // Add depth edges to color edges + float D = prepassUncondition(prepassMap, texcoord).w; + float Dleft = prepassUncondition(prepassMap, offset[0].xy).w; + float Dtop = prepassUncondition(prepassMap, offset[0].zw).w; + float Dright = prepassUncondition(prepassMap, offset[1].xy).w; + float Dbottom = prepassUncondition(prepassMap, offset[1].zw).w; + + delta = abs(vec4(D) - vec4(Dleft, Dtop, Dright, Dbottom)); + edges += step(depthThreshold, delta); + + if (dot(edges, vec4(1.0)) == 0.0) + discard; + + OUT_col = edges; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/functions.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/functions.glsl new file mode 100644 index 000000000..3ff56fb1a --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/functions.glsl @@ -0,0 +1,145 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + + +uniform vec2 texSize0; + +#if !defined(PIXEL_SIZE) +#define PIXEL_SIZE (1.0 / texSize0) +#define MAX_SEARCH_STEPS 8 +#define MAX_DISTANCE 33 +#endif + +// Typical Multiply-Add operation to ease translation to assembly code. + +vec4 mad(vec4 m, vec4 a, vec4 b) +{ + #if defined(XBOX) + vec4 result; + asm { + mad result, m, a, b + }; + return result; + #else + return m * a + b; + #endif +} + + +// This one just returns the first level of a mip map chain, which allow us to +// avoid the nasty ddx/ddy warnings, even improving the performance a little +// bit. +vec4 tex2Dlevel0(sampler2D map, vec2 texcoord) +{ + return tex2Dlod(map, vec4(texcoord, 0.0, 0.0)); +} + + +// Same as above, this eases translation to assembly code; +vec4 tex2Doffset(sampler2D map, vec2 texcoord, vec2 offset) +{ + #if defined(XBOX) && MAX_SEARCH_STEPS < 6 + vec4 result; + float x = offset.x; + float y = offset.y; + asm { + tfetch2D result, texcoord, map, OffsetX = x, OffsetY = y + }; + return result; + #else + return tex2Dlevel0(map, texcoord + PIXEL_SIZE * offset); + #endif +} + + +// Ok, we have the distance and both crossing edges, can you please return +// the vec2 blending weights? +vec2 Area(vec2 distance, float e1, float e2) +{ + // * By dividing by areaSize - 1.0 below we are implicitely offsetting to + // always fall inside of a pixel + // * Rounding prevents bilinear access precision problems + float areaSize = MAX_DISTANCE * 5.0; + vec2 pixcoord = MAX_DISTANCE * round(4.0 * vec2(e1, e2)) + distance; + vec2 texcoord = pixcoord / (areaSize - 1.0); + return tex2Dlevel0(areaMap, texcoord).rg; +} + + +// Search functions for the 2nd pass. +float SearchXLeft(vec2 texcoord) +{ + // We compare with 0.9 to prevent bilinear access precision problems. + float i; + float e = 0.0; + for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0) + { + e = tex2Doffset(edgesMapL, texcoord, vec2(i, 0.0)).g; + /*[flatten]*/ if (e < 0.9) break; + } + return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS); +} + +// Search functions for the 2nd pass. +float SearchXRight(vec2 texcoord) +{ + float i; + float e = 0.0; + for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0) + { + e = tex2Doffset(edgesMapL, texcoord, vec2(i, 0.0)).g; + /*[flatten]*/ if (e < 0.9) break; + } + return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS); +} + +// Search functions for the 2nd pass. +float SearchYUp(vec2 texcoord) +{ + float i; + float e = 0.0; + for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0) + { + e = tex2Doffset(edgesMapL, texcoord, vec2(i, 0.0).yx).r; + /*[flatten]*/ if (e < 0.9) break; + } + return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS); +} + +// Search functions for the 2nd pass. +float SearchYDown(vec2 texcoord) +{ + float i; + float e = 0.0; + for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0) + { + e = tex2Doffset(edgesMapL, texcoord, vec2(i, 0.0).yx).r; + /*[flatten]*/ if (e < 0.9) break; + } + return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/neighborhoodBlendingP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/neighborhoodBlendingP.glsl new file mode 100644 index 000000000..eddbcc47c --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/neighborhoodBlendingP.glsl @@ -0,0 +1,88 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + +#include "../../../gl/hlslCompat.glsl" + +in vec2 texcoord; +in vec4 offset[2]; + +uniform sampler2D blendMap; +uniform sampler2D colorMapL; +uniform sampler2D colorMap; + +// Dummy sampers to please include. +uniform sampler2D areaMap; +uniform sampler2D edgesMapL; +#include "./functions.glsl" + +out vec4 OUT_col; + +void main() +{ + // Fetch the blending weights for current pixel: + vec4 topLeft = texture(blendMap, texcoord); + float bottom = texture(blendMap, offset[1].zw).g; + float right = texture(blendMap, offset[1].xy).a; + vec4 a = vec4(topLeft.r, bottom, topLeft.b, right); + + // Up to 4 lines can be crossing a pixel (one in each edge). So, we perform + // a weighted average, where the weight of each line is 'a' cubed, which + // favors blending and works well in practice. + vec4 w = a * a * a; + + // There is some blending weight with a value greater than 0.0? + float sum = dot(w, vec4(1.0)); + if (sum < 1e-5) + discard; + + vec4 color = vec4(0.0); + + // Add the contributions of the possible 4 lines that can cross this pixel: + #ifdef BILINEAR_FILTER_TRICK + vec4 coords = mad(vec4( 0.0, -a.r, 0.0, a.g), PIXEL_SIZE.yyyy, texcoord.xyxy); + color = mad(texture(colorMapL, coords.xy), vec4(w.r), color); + color = mad(texture(colorMapL, coords.zw), vec4(w.g), color); + + coords = mad(vec4(-a.b, 0.0, a.a, 0.0), PIXEL_SIZE.xxxx, texcoord.xyxy); + color = mad(texture(colorMapL, coords.xy), vec4(w.b), color); + color = mad(texture(colorMapL, coords.zw), vec4(w.a), color); + #else + vec4 C = texture(colorMap, texcoord); + vec4 Cleft = texture(colorMap, offset[0].xy); + vec4 Ctop = texture(colorMap, offset[0].zw); + vec4 Cright = texture(colorMap, offset[1].xy); + vec4 Cbottom = texture(colorMap, offset[1].zw); + color = mad(mix(C, Ctop, a.r), vec4(w.r), color); + color = mad(mix(C, Cbottom, a.g), vec4(w.g), color); + color = mad(mix(C, Cleft, a.b), vec4(w.b), color); + color = mad(mix(C, Cright, a.a), vec4(w.a), color); + #endif + + // Normalize the resulting color and we are finished! + OUT_col = color / sum; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/offsetV.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/offsetV.glsl new file mode 100644 index 000000000..53d927c29 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/offsetV.glsl @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + +#include "../../../gl/hlslCompat.glsl" + +in vec4 vPosition; +in vec2 vTexCoord0; + +#define IN_position vPosition +#define IN_texcoord vTexCoord0 + +#define OUT_position gl_Position +out vec2 texcoord; +#define OUT_texcoord texcoord +out vec4 offset[2]; +#define OUT_offset offset + +uniform vec2 texSize0; + +void main() +{ + OUT_position = IN_position; + vec2 PIXEL_SIZE = 1.0 / texSize0; + + OUT_texcoord = IN_texcoord; + OUT_texcoord.xy += PIXEL_SIZE * 0.5; + + OUT_offset[0] = OUT_texcoord.xyxy + PIXEL_SIZE.xyxy * vec4(-1.0, 0.0, 0.0, -1.0); + OUT_offset[1] = OUT_texcoord.xyxy + PIXEL_SIZE.xyxy * vec4( 1.0, 0.0, 0.0, 1.0); + + correctSSP(gl_Position); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/passthruV.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/passthruV.glsl new file mode 100644 index 000000000..1aa64112c --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/gl/passthruV.glsl @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + +#include "../../../gl/hlslCompat.glsl" + +in vec4 vPosition; +in vec2 vTexCoord0; + +#define IN_position vPosition +#define IN_texcoord vTexCoord0 + +#define OUT_position gl_Position +out vec2 texcoord; +#define OUT_texcoord texcoord + +uniform vec2 texSize0; + +void main() +{ + OUT_position = IN_position; + vec2 PIXEL_SIZE = 1.0 / texSize0; + + OUT_texcoord = IN_texcoord; + texcoord.xy += PIXEL_SIZE * 0.5; + + correctSSP(gl_Position); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/neighborhoodBlendingP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/neighborhoodBlendingP.hlsl new file mode 100644 index 000000000..aaaacafe2 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/neighborhoodBlendingP.hlsl @@ -0,0 +1,84 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + + +uniform sampler2D blendMap : register(S0); +uniform sampler2D colorMapL : register(S1); +uniform sampler2D colorMap : register(S2); + +// Dummy sampers to please include. +sampler2D areaMap; +sampler2D edgesMapL; +#include "./functions.hlsl" + + +float4 main( float2 texcoord : TEXCOORD0, + float4 offset[2]: TEXCOORD1 ) : COLOR0 +{ + // Fetch the blending weights for current pixel: + float4 topLeft = tex2D(blendMap, texcoord); + float bottom = tex2D(blendMap, offset[1].zw).g; + float right = tex2D(blendMap, offset[1].xy).a; + float4 a = float4(topLeft.r, bottom, topLeft.b, right); + + // Up to 4 lines can be crossing a pixel (one in each edge). So, we perform + // a weighted average, where the weight of each line is 'a' cubed, which + // favors blending and works well in practice. + float4 w = a * a * a; + + // There is some blending weight with a value greater than 0.0? + float sum = dot(w, 1.0); + if (sum < 1e-5) + discard; + + float4 color = 0.0; + + // Add the contributions of the possible 4 lines that can cross this pixel: + #ifdef BILINEAR_FILTER_TRICK + float4 coords = mad(float4( 0.0, -a.r, 0.0, a.g), PIXEL_SIZE.yyyy, texcoord.xyxy); + color = mad(tex2D(colorMapL, coords.xy), w.r, color); + color = mad(tex2D(colorMapL, coords.zw), w.g, color); + + coords = mad(float4(-a.b, 0.0, a.a, 0.0), PIXEL_SIZE.xxxx, texcoord.xyxy); + color = mad(tex2D(colorMapL, coords.xy), w.b, color); + color = mad(tex2D(colorMapL, coords.zw), w.a, color); + #else + float4 C = tex2D(colorMap, texcoord); + float4 Cleft = tex2D(colorMap, offset[0].xy); + float4 Ctop = tex2D(colorMap, offset[0].zw); + float4 Cright = tex2D(colorMap, offset[1].xy); + float4 Cbottom = tex2D(colorMap, offset[1].zw); + color = mad(lerp(C, Ctop, a.r), w.r, color); + color = mad(lerp(C, Cbottom, a.g), w.g, color); + color = mad(lerp(C, Cleft, a.b), w.b, color); + color = mad(lerp(C, Cright, a.a), w.a, color); + #endif + + // Normalize the resulting color and we are finished! + return color / sum; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/offsetV.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/offsetV.hlsl new file mode 100644 index 000000000..d9c922afd --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/offsetV.hlsl @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + + +uniform float2 texSize0; + +void main( inout float4 position : POSITION0, + inout float2 texcoord : TEXCOORD0, + out float4 offset[2] : TEXCOORD1 ) +{ + float2 PIXEL_SIZE = 1.0 / texSize0; + + texcoord.xy += PIXEL_SIZE * 0.5; + + offset[0] = texcoord.xyxy + PIXEL_SIZE.xyxy * float4(-1.0, 0.0, 0.0, -1.0); + offset[1] = texcoord.xyxy + PIXEL_SIZE.xyxy * float4( 1.0, 0.0, 0.0, 1.0); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/passthruV.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/passthruV.hlsl new file mode 100644 index 000000000..24ef534fd --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/mlaa/passthruV.hlsl @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// An implementation of "Practical Morphological Anti-Aliasing" from +// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria, +// Fernando Navarro, and Diego Gutierrez. +// +// http://www.iryoku.com/mlaa/ + + +uniform float2 texSize0; + +void main( inout float4 position : POSITION0, + inout float2 texcoord : TEXCOORD0) +{ + float2 PIXEL_SIZE = 1.0 / texSize0; + texcoord.xy += PIXEL_SIZE * 0.5; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/motionBlurP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/motionBlurP.hlsl new file mode 100644 index 000000000..8bc65fbc6 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/motionBlurP.hlsl @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./postFx.hlsl" +#include "../torque.hlsl" +#include "../shaderModelAutoGen.hlsl" + +uniform float4x4 matPrevScreenToWorld; +uniform float4x4 matWorldToScreen; + +// Passed in from setShaderConsts() +uniform float velocityMultiplier; +TORQUE_UNIFORM_SAMPLER2D(backBuffer, 0); +TORQUE_UNIFORM_SAMPLER2D(prepassTex, 1); + +float4 main(PFXVertToPix IN) : TORQUE_TARGET0 +{ + float samples = 5; + + // First get the prepass texture for uv channel 0 + float4 prepass = TORQUE_PREPASS_UNCONDITION( prepassTex, IN.uv0 ); + + // Next extract the depth + float depth = prepass.a; + + // Create the screen position + float4 screenPos = float4(IN.uv0.x*2-1, IN.uv0.y*2-1, depth*2-1, 1); + + // Calculate the world position + float4 D = mul(screenPos, matWorldToScreen); + float4 worldPos = D / D.w; + + // Now calculate the previous screen position + float4 previousPos = mul( worldPos, matPrevScreenToWorld ); + previousPos /= previousPos.w; + + // Calculate the XY velocity + float2 velocity = ((screenPos - previousPos) / velocityMultiplier).xy; + + // Generate the motion blur + float4 color = TORQUE_TEX2D(backBuffer, IN.uv0); + IN.uv0 += velocity; + + for(int i = 1; i blurNormalTol ) + { + usedCount++; + total += weight; + occlusion += TORQUE_TEX2D( occludeMap, uv ).r * weight; + } + } +} + +float4 main( VertToPix IN ) : TORQUE_TARGET0 +{ + //float4 centerTap; + float4 centerTap = TORQUE_PREPASS_UNCONDITION( prepassMap, IN.uv0.zw ); + + //return centerTap; + + //float centerOcclude = TORQUE_TEX2D( occludeMap, IN.uv0.zw ).r; + //return float4( centerOcclude.rrr, 1 ); + + float4 kernel = float4( 0.175, 0.275, 0.375, 0.475 ); //25f; + + float occlusion = 0; + int usedCount = 0; + float total = 0.0; + + sample( IN.uv0.xy, kernel.x, centerTap, usedCount, occlusion, total ); + sample( IN.uv1, kernel.y, centerTap, usedCount, occlusion, total ); + sample( IN.uv2, kernel.z, centerTap, usedCount, occlusion, total ); + sample( IN.uv3, kernel.w, centerTap, usedCount, occlusion, total ); + + sample( IN.uv4, kernel.x, centerTap, usedCount, occlusion, total ); + sample( IN.uv5, kernel.y, centerTap, usedCount, occlusion, total ); + sample( IN.uv6, kernel.z, centerTap, usedCount, occlusion, total ); + sample( IN.uv7, kernel.w, centerTap, usedCount, occlusion, total ); + + occlusion += TORQUE_TEX2D( occludeMap, IN.uv0.zw ).r * 0.5; + total += 0.5; + //occlusion /= 3.0; + + //occlusion /= (float)usedCount / 8.0; + occlusion /= total; + + return float4( occlusion.rrr, 1 ); + + + //return float4( 0,0,0,occlusion ); + + //float3 color = TORQUE_TEX2D( colorMap, IN.uv0.zw ); + + //return float4( color, occlusion ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/ssao/SSAO_Blur_V.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/SSAO_Blur_V.hlsl new file mode 100644 index 000000000..6ab278900 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/SSAO_Blur_V.hlsl @@ -0,0 +1,86 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + + +uniform float2 texSize0; +uniform float2 oneOverTargetSize; +uniform float4 rtParams0; + +struct VertToPix +{ + float4 hpos : TORQUE_POSITION; + + float4 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + float2 uv3 : TEXCOORD3; + + float2 uv4 : TEXCOORD4; + float2 uv5 : TEXCOORD5; + float2 uv6 : TEXCOORD6; + float2 uv7 : TEXCOORD7; +}; + +VertToPix main( PFXVert IN ) +{ + VertToPix OUT; + + OUT.hpos = float4(IN.pos,1.0); + + IN.uv = viewportCoordToRenderTarget( IN.uv, rtParams0 ); + + //float4 step = float4( 3.5, 2.5, 1.5, 0.5 ); + //float4 step = float4( 4.0, 3.0, 2.0, 1.0 ); + float4 step = float4( 9.0, 5.0, 2.5, 0.5 ); + + // I don't know why this offset is necessary, but it is. + //IN.uv = IN.uv * oneOverTargetSize; + + OUT.uv0.xy = IN.uv + ( ( BLUR_DIR * step.x ) / texSize0 ); + OUT.uv1 = IN.uv + ( ( BLUR_DIR * step.y ) / texSize0 ); + OUT.uv2 = IN.uv + ( ( BLUR_DIR * step.z ) / texSize0 ); + OUT.uv3 = IN.uv + ( ( BLUR_DIR * step.w ) / texSize0 ); + + OUT.uv4 = IN.uv - ( ( BLUR_DIR * step.x ) / texSize0 ); + OUT.uv5 = IN.uv - ( ( BLUR_DIR * step.y ) / texSize0 ); + OUT.uv6 = IN.uv - ( ( BLUR_DIR * step.z ) / texSize0 ); + OUT.uv7 = IN.uv - ( ( BLUR_DIR * step.w ) / texSize0 ); + + OUT.uv0.zw = IN.uv; + + /* + OUT.uv0 = viewportCoordToRenderTarget( OUT.uv0, rtParams0 ); + OUT.uv1 = viewportCoordToRenderTarget( OUT.uv1, rtParams0 ); + OUT.uv2 = viewportCoordToRenderTarget( OUT.uv2, rtParams0 ); + OUT.uv3 = viewportCoordToRenderTarget( OUT.uv3, rtParams0 ); + + OUT.uv4 = viewportCoordToRenderTarget( OUT.uv4, rtParams0 ); + OUT.uv5 = viewportCoordToRenderTarget( OUT.uv5, rtParams0 ); + OUT.uv6 = viewportCoordToRenderTarget( OUT.uv6, rtParams0 ); + OUT.uv7 = viewportCoordToRenderTarget( OUT.uv7, rtParams0 ); + */ + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/ssao/SSAO_P.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/SSAO_P.hlsl new file mode 100644 index 000000000..cb3ee2fe4 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/SSAO_P.hlsl @@ -0,0 +1,272 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../ShaderModelAutoGen.hlsl" +#include "./../postFx.hlsl" + +#define DOSMALL +#define DOLARGE + +TORQUE_UNIFORM_SAMPLER2D(prepassMap,0); +TORQUE_UNIFORM_SAMPLER2D(randNormalTex,1); +TORQUE_UNIFORM_SAMPLER1D(powTable,2); + +uniform float2 nearFar; +uniform float2 worldToScreenScale; +uniform float2 texSize0; +uniform float2 texSize1; +uniform float2 targetSize; + +// Script-set constants. + +uniform float overallStrength; + +uniform float sRadius; +uniform float sStrength; +uniform float sDepthMin; +uniform float sDepthMax; +uniform float sDepthPow; +uniform float sNormalTol; +uniform float sNormalPow; + +uniform float lRadius; +uniform float lStrength; +uniform float lDepthMin; +uniform float lDepthMax; +uniform float lDepthPow; +uniform float lNormalTol; +uniform float lNormalPow; + + +#ifndef QUALITY + #define QUALITY 2 +#endif + + +#if QUALITY == 0 + #define sSampleCount 4 + #define totalSampleCount 12 +#elif QUALITY == 1 + #define sSampleCount 6 + #define totalSampleCount 24 +#elif QUALITY == 2 + #define sSampleCount 8 + #define totalSampleCount 32 +#endif + + +float getOcclusion( float depthDiff, float depthMin, float depthMax, float depthPow, + float normalDiff, float dt, float normalTol, float normalPow ) +{ + if ( depthDiff < 0.0 ) + return 0.0; + + float delta = abs( depthDiff ); + + if ( delta < depthMin || delta > depthMax ) + return 0.0; + + delta = saturate( delta / depthMax ); + + if ( dt > 0.0 ) + normalDiff *= dt; + else + normalDiff = 1.0; + + + normalDiff *= 1.0 - ( dt * 0.5 + 0.5 ); + + return ( 1.0 - TORQUE_TEX1D( powTable, delta ).r ) * normalDiff; +} + + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float3 ptSphere[32] = + { + float3( 0.295184, 0.077723, 0.068429 ), + float3( -0.271976, -0.365221, -0.838363 ), + float3( 0.547713, 0.467576, 0.488515 ), + float3( 0.662808, -0.031733, -0.584758 ), + float3( -0.025717, 0.218955, -0.657094 ), + float3( -0.310153, -0.365223, -0.370701 ), + float3( -0.101407, -0.006313, -0.747665 ), + float3( -0.769138, 0.360399, -0.086847 ), + float3( -0.271988, -0.275140, -0.905353 ), + float3( 0.096740, -0.566901, 0.700151 ), + float3( 0.562872, -0.735136, -0.094647 ), + float3( 0.379877, 0.359278, 0.190061 ), + float3( 0.519064, -0.023055, 0.405068 ), + float3( -0.301036, 0.114696, -0.088885 ), + float3( -0.282922, 0.598305, 0.487214 ), + float3( -0.181859, 0.251670, -0.679702 ), + float3( -0.191463, -0.635818, -0.512919 ), + float3( -0.293655, 0.427423, 0.078921 ), + float3( -0.267983, 0.680534, -0.132880 ), + float3( 0.139611, 0.319637, 0.477439 ), + float3( -0.352086, 0.311040, 0.653913 ), + float3( 0.321032, 0.805279, 0.487345 ), + float3( 0.073516, 0.820734, -0.414183 ), + float3( -0.155324, 0.589983, -0.411460 ), + float3( 0.335976, 0.170782, -0.527627 ), + float3( 0.463460, -0.355658, -0.167689 ), + float3( 0.222654, 0.596550, -0.769406 ), + float3( 0.922138, -0.042070, 0.147555 ), + float3( -0.727050, -0.329192, 0.369826 ), + float3( -0.090731, 0.533820, 0.463767 ), + float3( -0.323457, -0.876559, -0.238524 ), + float3( -0.663277, -0.372384, -0.342856 ) + }; + + // Sample a random normal for reflecting the + // sphere vector later in our loop. + float4 noiseMapUV = float4( ( IN.uv1 * ( targetSize / texSize1 ) ).xy, 0, 0 ); + float3 reflectNormal = normalize( TORQUE_TEX2DLOD( randNormalTex, noiseMapUV ).xyz * 2.0 - 1.0 ); + //return float4( reflectNormal, 1 ); + + float4 prepass = TORQUE_PREPASS_UNCONDITION( prepassMap, IN.uv0 ); + float3 normal = prepass.xyz; + float depth = prepass.a; + //return float4( ( depth ).xxx, 1 ); + + // Early out if too far away. + if ( depth > 0.99999999 ) + return float4( 0,0,0,0 ); + + // current fragment coords in screen space + float3 ep = float3( IN.uv0, depth ); + + float bl; + float3 baseRay, ray, se, occNorm, projRadius; + float normalDiff = 0; + float depthMin, depthMax, dt, depthDiff; + float4 occluderFragment; + int i; + float sOcclusion = 0.0; + float lOcclusion = 0.0; + + //------------------------------------------------------------ + // Small radius + //------------------------------------------------------------ + +#ifdef DOSMALL + + bl = 0.0; + + projRadius.xy = ( float2( sRadius.rr ) / ( depth * nearFar.y ) ) * ( worldToScreenScale / texSize0 ); + projRadius.z = sRadius / nearFar.y; + + depthMin = projRadius.z * sDepthMin; + depthMax = projRadius.z * sDepthMax; + + //float maxr = 1; + //radiusDepth = clamp( radiusDepth, 0.0001, maxr.rrr ); + //if ( radiusDepth.x < 1.0 / targetSize.x ) + // return color; + //radiusDepth.xyz = 0.0009; + + for ( i = 0; i < sSampleCount; i++ ) + { + baseRay = reflect( ptSphere[i], reflectNormal ); + + dt = dot( baseRay.xyz, normal ); + + baseRay *= sign( dt ); + + ray = ( projRadius * baseRay.xzy ); + ray.y = -ray.y; + + se = ep + ray; + + occluderFragment = TORQUE_PREPASS_UNCONDITION( prepassMap, se.xy ); + + depthDiff = se.z - occluderFragment.a; + + dt = dot( occluderFragment.xyz, baseRay.xyz ); + normalDiff = dot( occluderFragment.xyz, normal ); + + bl += getOcclusion( depthDiff, depthMin, depthMax, sDepthPow, normalDiff, dt, sNormalTol, sNormalPow ); + } + + sOcclusion = sStrength * ( bl / (float)sSampleCount ); + +#endif // DOSMALL + + + //------------------------------------------------------------ + // Large radius + //------------------------------------------------------------ + +#ifdef DOLARGE + + bl = 0.0; + + projRadius.xy = ( float2( lRadius.rr ) / ( depth * nearFar.y ) ) * ( worldToScreenScale / texSize0 ); + projRadius.z = lRadius / nearFar.y; + + depthMin = projRadius.z * lDepthMin; + depthMax = projRadius.z * lDepthMax; + + //projRadius.xy = clamp( projRadius.xy, 0.0, 0.01 ); + //float maxr = 1; + //radiusDepth = clamp( radiusDepth, 0.0001, maxr.rrr ); + //if ( radiusDepth.x < 1.0 / targetSize.x ) + // return color; + //radiusDepth.xyz = 0.0009; + + for ( i = sSampleCount; i < totalSampleCount; i++ ) + { + baseRay = reflect( ptSphere[i], reflectNormal ); + + dt = dot( baseRay.xyz, normal ); + + baseRay *= sign( dt ); + + ray = ( projRadius * baseRay.xzy ); + ray.y = -ray.y; + + se = ep + ray; + + occluderFragment = TORQUE_PREPASS_UNCONDITION( prepassMap, se.xy ); + + depthDiff = se.z - occluderFragment.a; + + normalDiff = dot( occluderFragment.xyz, normal ); + dt = dot( occluderFragment.xyz, baseRay.xyz ); + + bl += getOcclusion( depthDiff, depthMin, depthMax, lDepthPow, normalDiff, dt, lNormalTol, lNormalPow ); + } + + lOcclusion = lStrength * ( bl / (float)( totalSampleCount - sSampleCount ) ); + +#endif // DOLARGE + + float occlusion = saturate( max( sOcclusion, lOcclusion ) * overallStrength ); + + // Note black is unoccluded and white is fully occluded. This + // seems backwards, but it makes it simple to deal with the SSAO + // being disabled in the lighting shaders. + + return occlusion; +} + + diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/ssao/SSAO_PowerTable_P.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/SSAO_PowerTable_P.hlsl new file mode 100644 index 000000000..696947d3e --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/SSAO_PowerTable_P.hlsl @@ -0,0 +1,29 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float power = pow( max( IN.uv0.x, 0 ), 0.1 ); + return float4( power, 0, 0, 1 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/ssao/SSAO_PowerTable_V.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/SSAO_PowerTable_V.hlsl new file mode 100644 index 000000000..76f67e711 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/SSAO_PowerTable_V.hlsl @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./../postFx.hlsl" +#include "./../../torque.hlsl" + + +uniform float4 rtParams0; +uniform float4 rtParams1; +uniform float4 rtParams2; +uniform float4 rtParams3; + +PFXVertToPix main( PFXVert IN ) +{ + PFXVertToPix OUT; + + OUT.hpos = float4(IN.pos,1.0); + OUT.uv0 = IN.uv; //viewportCoordToRenderTarget( IN.uv, rtParams0 ); + OUT.uv1 = IN.uv; //viewportCoordToRenderTarget( IN.uv, rtParams1 ); + OUT.uv2 = IN.uv; //viewportCoordToRenderTarget( IN.uv, rtParams2 ); + OUT.uv3 = IN.uv; //viewportCoordToRenderTarget( IN.uv, rtParams3 ); + + OUT.wsEyeRay = IN.wsEyeRay; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/ssao/gl/SSAO_Blur_P.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/gl/SSAO_Blur_P.glsl new file mode 100644 index 000000000..f0de9396f --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/gl/SSAO_Blur_P.glsl @@ -0,0 +1,108 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" + +in vec4 uv0; +#define IN_uv0 uv0 +in vec2 uv1; +#define IN_uv1 uv1 +in vec2 uv2; +#define IN_uv2 uv2 +in vec2 uv3; +#define IN_uv3 uv3 + +in vec2 uv4; +#define IN_uv4 uv4 +in vec2 uv5; +#define IN_uv5 uv5 +in vec2 uv6; +#define IN_uv6 uv6 +in vec2 uv7; +#define IN_uv7 uv7 + +uniform sampler2D occludeMap ; +uniform sampler2D prepassMap ; +uniform float blurDepthTol; +uniform float blurNormalTol; + +out vec4 OUT_col; + +void _sample( vec2 uv, float weight, vec4 centerTap, inout int usedCount, inout float occlusion, inout float total ) +{ + //return; + vec4 tap = prepassUncondition( prepassMap, uv ); + + if ( abs( tap.a - centerTap.a ) < blurDepthTol ) + { + if ( dot( tap.xyz, centerTap.xyz ) > blurNormalTol ) + { + usedCount++; + total += weight; + occlusion += texture( occludeMap, uv ).r * weight; + } + } +} + +void main() +{ + //vec4 centerTap; + vec4 centerTap = prepassUncondition( prepassMap, IN_uv0.zw ); + + //return centerTap; + + //float centerOcclude = texture( occludeMap, IN_uv0.zw ).r; + //return vec4( centerOcclude.rrr, 1 ); + + vec4 kernel = vec4( 0.175, 0.275, 0.375, 0.475 ); //25f; + + float occlusion = 0; + int usedCount = 0; + float total = 0.0; + + _sample( IN_uv0.xy, kernel.x, centerTap, usedCount, occlusion, total ); + _sample( IN_uv1, kernel.y, centerTap, usedCount, occlusion, total ); + _sample( IN_uv2, kernel.z, centerTap, usedCount, occlusion, total ); + _sample( IN_uv3, kernel.w, centerTap, usedCount, occlusion, total ); + + _sample( IN_uv4, kernel.x, centerTap, usedCount, occlusion, total ); + _sample( IN_uv5, kernel.y, centerTap, usedCount, occlusion, total ); + _sample( IN_uv6, kernel.z, centerTap, usedCount, occlusion, total ); + _sample( IN_uv7, kernel.w, centerTap, usedCount, occlusion, total ); + + occlusion += texture( occludeMap, IN_uv0.zw ).r * 0.5; + total += 0.5; + //occlusion /= 3.0; + + //occlusion /= (float)usedCount / 8.0; + occlusion /= total; + + OUT_col = vec4( vec3(occlusion), 1 ); + + + //return vec4( 0,0,0,occlusion ); + + //vec3 color = texture( colorMap, IN_uv0.zw ); + + //return vec4( color, occlusion ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/ssao/gl/SSAO_Blur_V.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/gl/SSAO_Blur_V.glsl new file mode 100644 index 000000000..45a52e890 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/gl/SSAO_Blur_V.glsl @@ -0,0 +1,96 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +#include "../../../gl/torque.glsl" +#include "../../../gl/hlslCompat.glsl" + +in vec4 vPosition; +in vec2 vTexCoord0; + +#define IN_pos vPosition +#define _IN_uv vTexCoord0 + +uniform vec2 texSize0; +uniform vec4 rtParams0; +uniform vec2 oneOverTargetSize; + +#define OUT_hpos gl_Position + +out vec4 uv0; +#define OUT_uv0 uv0 +out vec2 uv1; +#define OUT_uv1 uv1 +out vec2 uv2; +#define OUT_uv2 uv2 +out vec2 uv3; +#define OUT_uv3 uv3 + +out vec2 uv4; +#define OUT_uv4 uv4 +out vec2 uv5; +#define OUT_uv5 uv5 +out vec2 uv6; +#define OUT_uv6 uv6 +out vec2 uv7; +#define OUT_uv7 uv7 + + +void main() +{ + OUT_hpos = IN_pos; + + vec2 IN_uv = viewportCoordToRenderTarget( _IN_uv, rtParams0 ); + + //vec4 step = vec4( 3.5, 2.5, 1.5, 0.5 ); + //vec4 step = vec4( 4.0, 3.0, 2.0, 1.0 ); + vec4 step = vec4( 9.0, 5.0, 2.5, 0.5 ); + + // I don't know why this offset is necessary, but it is. + //IN_uv = IN_uv * oneOverTargetSize; + + OUT_uv0.xy = IN_uv + ( ( BLUR_DIR * step.x ) / texSize0 ); + OUT_uv1 = IN_uv + ( ( BLUR_DIR * step.y ) / texSize0 ); + OUT_uv2 = IN_uv + ( ( BLUR_DIR * step.z ) / texSize0 ); + OUT_uv3 = IN_uv + ( ( BLUR_DIR * step.w ) / texSize0 ); + + OUT_uv4 = IN_uv - ( ( BLUR_DIR * step.x ) / texSize0 ); + OUT_uv5 = IN_uv - ( ( BLUR_DIR * step.y ) / texSize0 ); + OUT_uv6 = IN_uv - ( ( BLUR_DIR * step.z ) / texSize0 ); + OUT_uv7 = IN_uv - ( ( BLUR_DIR * step.w ) / texSize0 ); + + OUT_uv0.zw = IN_uv; + + /* + OUT_uv0 = viewportCoordToRenderTarget( OUT_uv0, rtParams0 ); + OUT_uv1 = viewportCoordToRenderTarget( OUT_uv1, rtParams0 ); + OUT_uv2 = viewportCoordToRenderTarget( OUT_uv2, rtParams0 ); + OUT_uv3 = viewportCoordToRenderTarget( OUT_uv3, rtParams0 ); + + OUT_uv4 = viewportCoordToRenderTarget( OUT_uv4, rtParams0 ); + OUT_uv5 = viewportCoordToRenderTarget( OUT_uv5, rtParams0 ); + OUT_uv6 = viewportCoordToRenderTarget( OUT_uv6, rtParams0 ); + OUT_uv7 = viewportCoordToRenderTarget( OUT_uv7, rtParams0 ); + */ + + correctSSP(gl_Position); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/ssao/gl/SSAO_P.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/gl/SSAO_P.glsl new file mode 100644 index 000000000..7ee6a412a --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/gl/SSAO_P.glsl @@ -0,0 +1,278 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../gl/postFX.glsl" + +#define DOSMALL +#define DOLARGE + +uniform sampler2D prepassMap ; +uniform sampler2D randNormalTex ; +uniform sampler1D powTable ; + +uniform vec2 nearFar; +uniform vec2 worldToScreenScale; +uniform vec2 texSize0; +uniform vec2 texSize1; +uniform vec2 targetSize; + +// Script-set constants. + +uniform float overallStrength; + +uniform float sRadius; +uniform float sStrength; +uniform float sDepthMin; +uniform float sDepthMax; +uniform float sDepthPow; +uniform float sNormalTol; +uniform float sNormalPow; + +uniform float lRadius; +uniform float lStrength; +uniform float lDepthMin; +uniform float lDepthMax; +uniform float lDepthPow; +uniform float lNormalTol; +uniform float lNormalPow; + +out vec4 OUT_col; + + +#ifndef QUALITY + #define QUALITY 2 +#endif + + +#if QUALITY == 0 + #define sSampleCount 4 + #define totalSampleCount 12 +#elif QUALITY == 1 + #define sSampleCount 6 + #define totalSampleCount 24 +#elif QUALITY == 2 + #define sSampleCount 8 + #define totalSampleCount 32 +#endif + + +float getOcclusion( float depthDiff, float depthMin, float depthMax, float depthPow, + float normalDiff, float dt, float normalTol, float normalPow ) +{ + if ( depthDiff < 0.0 ) + return 0.0; + + float delta = abs( depthDiff ); + + if ( delta < depthMin || delta > depthMax ) + return 0.0; + + delta = saturate( delta / depthMax ); + + if ( dt > 0.0 ) + normalDiff *= dt; + else + normalDiff = 1.0; + + + normalDiff *= 1.0 - ( dt * 0.5 + 0.5 ); + + return ( 1.0 - texture( powTable, delta ).r ) * normalDiff; +} + + +void main() +{ + const vec3 ptSphere[32] = vec3[] + ( + vec3( 0.295184, 0.077723, 0.068429 ), + vec3( -0.271976, -0.365221, -0.838363 ), + vec3( 0.547713, 0.467576, 0.488515 ), + vec3( 0.662808, -0.031733, -0.584758 ), + vec3( -0.025717, 0.218955, -0.657094 ), + vec3( -0.310153, -0.365223, -0.370701 ), + vec3( -0.101407, -0.006313, -0.747665 ), + vec3( -0.769138, 0.360399, -0.086847 ), + vec3( -0.271988, -0.275140, -0.905353 ), + vec3( 0.096740, -0.566901, 0.700151 ), + vec3( 0.562872, -0.735136, -0.094647 ), + vec3( 0.379877, 0.359278, 0.190061 ), + vec3( 0.519064, -0.023055, 0.405068 ), + vec3( -0.301036, 0.114696, -0.088885 ), + vec3( -0.282922, 0.598305, 0.487214 ), + vec3( -0.181859, 0.251670, -0.679702 ), + vec3( -0.191463, -0.635818, -0.512919 ), + vec3( -0.293655, 0.427423, 0.078921 ), + vec3( -0.267983, 0.680534, -0.132880 ), + vec3( 0.139611, 0.319637, 0.477439 ), + vec3( -0.352086, 0.311040, 0.653913 ), + vec3( 0.321032, 0.805279, 0.487345 ), + vec3( 0.073516, 0.820734, -0.414183 ), + vec3( -0.155324, 0.589983, -0.411460 ), + vec3( 0.335976, 0.170782, -0.527627 ), + vec3( 0.463460, -0.355658, -0.167689 ), + vec3( 0.222654, 0.596550, -0.769406 ), + vec3( 0.922138, -0.042070, 0.147555 ), + vec3( -0.727050, -0.329192, 0.369826 ), + vec3( -0.090731, 0.533820, 0.463767 ), + vec3( -0.323457, -0.876559, -0.238524 ), + vec3( -0.663277, -0.372384, -0.342856 ) + ); + + // Sample a random normal for reflecting the + // sphere vector later in our loop. + vec4 noiseMapUV = vec4( ( IN_uv1 * ( targetSize / texSize1 ) ).xy, 0, 0 ); + vec3 reflectNormal = normalize( tex2Dlod( randNormalTex, noiseMapUV ).xyz * 2.0 - 1.0 ); + //return vec4( reflectNormal, 1 ); + + vec4 prepass = prepassUncondition( prepassMap, IN_uv0 ); + vec3 normal = prepass.xyz; + float depth = prepass.a; + //return vec4( ( depth ).xxx, 1 ); + + // Early out if too far away. + if ( depth > 0.99999999 ) + { + OUT_col = vec4( 0,0,0,0 ); + return; + } + + // current fragment coords in screen space + vec3 ep = vec3( IN_uv0, depth ); + + float bl; + vec3 baseRay, ray, se, occNorm, projRadius; + float normalDiff = 0; + float depthMin, depthMax, dt, depthDiff; + vec4 occluderFragment; + int i; + float sOcclusion = 0.0; + float lOcclusion = 0.0; + + //------------------------------------------------------------ + // Small radius + //------------------------------------------------------------ + +#ifdef DOSMALL + + bl = 0.0; + + projRadius.xy = ( vec2( sRadius ) / ( depth * nearFar.y ) ) * ( worldToScreenScale / texSize0 ); + projRadius.z = sRadius / nearFar.y; + + depthMin = projRadius.z * sDepthMin; + depthMax = projRadius.z * sDepthMax; + + //float maxr = 1; + //radiusDepth = clamp( radiusDepth, 0.0001, maxr.rrr ); + //if ( radiusDepth.x < 1.0 / targetSize.x ) + // return color; + //radiusDepth.xyz = 0.0009; + + for ( i = 0; i < sSampleCount; i++ ) + { + baseRay = reflect( ptSphere[i], reflectNormal ); + + dt = dot( baseRay.xyz, normal ); + + baseRay *= sign( dt ); + + ray = ( projRadius * baseRay.xzy ); + ray.y = -ray.y; + + se = ep + ray; + + occluderFragment = prepassUncondition( prepassMap, se.xy ); + + depthDiff = se.z - occluderFragment.a; + + dt = dot( occluderFragment.xyz, baseRay.xyz ); + normalDiff = dot( occluderFragment.xyz, normal ); + + bl += getOcclusion( depthDiff, depthMin, depthMax, sDepthPow, normalDiff, dt, sNormalTol, sNormalPow ); + } + + sOcclusion = sStrength * ( bl / float(sSampleCount) ); + +#endif // DOSMALL + + + //------------------------------------------------------------ + // Large radius + //------------------------------------------------------------ + +#ifdef DOLARGE + + bl = 0.0; + + projRadius.xy = ( vec2( lRadius ) / ( depth * nearFar.y ) ) * ( worldToScreenScale / texSize0 ); + projRadius.z = lRadius / nearFar.y; + + depthMin = projRadius.z * lDepthMin; + depthMax = projRadius.z * lDepthMax; + + //projRadius.xy = clamp( projRadius.xy, 0.0, 0.01 ); + //float maxr = 1; + //radiusDepth = clamp( radiusDepth, 0.0001, maxr.rrr ); + //if ( radiusDepth.x < 1.0 / targetSize.x ) + // return color; + //radiusDepth.xyz = 0.0009; + + for ( i = sSampleCount; i < totalSampleCount; i++ ) + { + baseRay = reflect( ptSphere[i], reflectNormal ); + + dt = dot( baseRay.xyz, normal ); + + baseRay *= sign( dt ); + + ray = ( projRadius * baseRay.xzy ); + ray.y = -ray.y; + + se = ep + ray; + + occluderFragment = prepassUncondition( prepassMap, se.xy ); + + depthDiff = se.z - occluderFragment.a; + + normalDiff = dot( occluderFragment.xyz, normal ); + dt = dot( occluderFragment.xyz, baseRay.xyz ); + + bl += getOcclusion( depthDiff, depthMin, depthMax, lDepthPow, normalDiff, dt, lNormalTol, lNormalPow ); + } + + lOcclusion = lStrength * ( bl / float( totalSampleCount - sSampleCount ) ); + +#endif // DOLARGE + + float occlusion = saturate( max( sOcclusion, lOcclusion ) * overallStrength ); + + // Note black is unoccluded and white is fully occluded. This + // seems backwards, but it makes it simple to deal with the SSAO + // being disabled in the lighting shaders. + + OUT_col = vec4(occlusion, vec3(0.0)); +} + + diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/ssao/gl/SSAO_PowerTable_P.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/gl/SSAO_PowerTable_P.glsl new file mode 100644 index 000000000..4f49479ba --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/gl/SSAO_PowerTable_P.glsl @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" + +in vec2 uv0; +#define IN_uv0 uv0 + +out vec4 OUT_col; + +void main() +{ + float power = pow( max( IN_uv0.x, 0 ), 0.1 ); + OUT_col = vec4( power, 0, 0, 1 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/ssao/gl/SSAO_PowerTable_V.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/gl/SSAO_PowerTable_V.glsl new file mode 100644 index 000000000..a193f63ce --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/ssao/gl/SSAO_PowerTable_V.glsl @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/torque.glsl" +#include "../../../gl/hlslCompat.glsl" +#include "../../gl/postFX.glsl" + +void main() +{ + OUT_hpos = IN_pos; + OUT_uv0 = IN_uv; //viewportCoordToRenderTarget( IN_uv, rtParams0 ); + OUT_uv1 = IN_uv; //viewportCoordToRenderTarget( IN_uv, rtParams1 ); + OUT_uv2 = IN_uv; //viewportCoordToRenderTarget( IN_uv, rtParams2 ); + OUT_uv3 = IN_uv; //viewportCoordToRenderTarget( IN_uv, rtParams3 ); + + OUT_wsEyeRay = IN_wsEyeRay; + + correctSSP(gl_Position); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/turbulenceP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/turbulenceP.hlsl new file mode 100644 index 000000000..c8c572ae7 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/turbulenceP.hlsl @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./postFx.hlsl" + +uniform float accumTime; +uniform float2 projectionOffset; +uniform float4 targetViewport; +TORQUE_UNIFORM_SAMPLER2D(inputTex, 0); + + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + float speed = 2.0; + float distortion = 6.0; + + float y = IN.uv0.y + (cos((IN.uv0.y+projectionOffset.y) * distortion + accumTime * speed) * 0.01); + float x = IN.uv0.x + (sin((IN.uv0.x+projectionOffset.x) * distortion + accumTime * speed) * 0.01); + + // Clamp the calculated uv values to be within the target's viewport + y = clamp(y, targetViewport.y, targetViewport.w); + x = clamp(x, targetViewport.x, targetViewport.z); + + return TORQUE_TEX2D(inputTex, float2(x, y)); +} diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/underwaterFogP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/underwaterFogP.hlsl new file mode 100644 index 000000000..80a8c4c77 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/underwaterFogP.hlsl @@ -0,0 +1,138 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "./postFx.hlsl" +#include "../torque.hlsl" +#include "../shaderModelAutoGen.hlsl" +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +// oceanFogData +#define FOG_DENSITY waterFogData[0] +#define FOG_DENSITY_OFFSET waterFogData[1] +#define WET_DEPTH waterFogData[2] +#define WET_DARKENING waterFogData[3] + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- + +TORQUE_UNIFORM_SAMPLER2D(prepassTex, 0); +TORQUE_UNIFORM_SAMPLER2D(backbuffer, 1); +TORQUE_UNIFORM_SAMPLER1D(waterDepthGradMap, 2); + +uniform float3 eyePosWorld; +uniform float waterDepthGradMax; +uniform float3 ambientColor; +uniform float4 waterColor; +uniform float4 waterFogData; +uniform float4 waterFogPlane; +uniform float2 nearFar; +uniform float4 rtParams0; + + +float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 +{ + //float2 prepassCoord = IN.uv0; + //IN.uv0 = ( IN.uv0.xy * rtParams0.zw ) + rtParams0.xy; + float depth = TORQUE_PREPASS_UNCONDITION( prepassTex, IN.uv0 ).w; + //return float4( depth.rrr, 1 ); + + // Skip fogging the extreme far plane so that + // the canvas clear color always appears. + //clip( 0.9 - depth ); + + // We assume that the eye position is below water because + // otherwise this shader/posteffect should not be active. + + depth *= nearFar.y; + + float3 eyeRay = normalize( IN.wsEyeRay ); + + float3 rayStart = eyePosWorld; + float3 rayEnd = eyePosWorld + ( eyeRay * depth ); + //return float4( rayEnd, 1 ); + + float4 plane = waterFogPlane; //float4( 0, 0, 1, -waterHeight ); + //plane.w -= 0.15; + + float startSide = dot( plane.xyz, rayStart ) + plane.w; + if ( startSide > 0 ) + { + rayStart.z -= ( startSide ); + //return float4( 1, 0, 0, 1 ); + } + + float3 hitPos; + float3 ray = rayEnd - rayStart; + float rayLen = length( ray ); + float3 rayDir = normalize( ray ); + + float endSide = dot( plane.xyz, rayEnd ) + plane.w; + float planeDist; + + if ( endSide < -0.005 ) + { + //return float4( 0, 0, 1, 1 ); + hitPos = rayEnd; + planeDist = endSide; + } + else + { + //return float4( 0, 0, 0, 0 ); + float den = dot( ray, plane.xyz ); + + // Parallal to the plane, return the endPnt. + //if ( den == 0.0f ) + // return endPnt; + + float dist = -( dot( plane.xyz, rayStart ) + plane.w ) / den; + if ( dist < 0.0 ) + dist = 0.0; + //return float4( 1, 0, 0, 1 ); + //return float4( ( dist ).rrr, 1 ); + + + hitPos = lerp( rayStart, rayEnd, dist ); + + planeDist = dist; + } + + float delta = length( hitPos - rayStart ); + + float fogAmt = 1.0 - saturate( exp( -FOG_DENSITY * ( delta - FOG_DENSITY_OFFSET ) ) ); + //return float4( fogAmt.rrr, 1 ); + + // Calculate the water "base" color based on depth. + float4 fogColor = waterColor * TORQUE_TEX1D( waterDepthGradMap, saturate( delta / waterDepthGradMax ) ); + // Modulate baseColor by the ambientColor. + fogColor *= float4( ambientColor.rgb, 1 ); + + float3 inColor = hdrDecode( TORQUE_TEX2D( backbuffer, IN.uv0 ).rgb ); + inColor.rgb *= 1.0 - saturate( abs( planeDist ) / WET_DEPTH ) * WET_DARKENING; + //return float4( inColor, 1 ); + + float3 outColor = lerp( inColor, fogColor.rgb, fogAmt ); + + return float4( hdrEncode( outColor ), 1 ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/vignette/VignetteP.hlsl b/Templates/BaseGame/game/data/shaders/common/postFx/vignette/VignetteP.hlsl new file mode 100644 index 000000000..c518a2145 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/vignette/VignetteP.hlsl @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../postFx.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(backBuffer, 0); +uniform float Vmax; +uniform float Vmin; + +float4 main(PFXVertToPix IN) : TORQUE_TARGET0 +{ + float4 base = TORQUE_TEX2D(backBuffer, IN.uv0); + float dist = distance(IN.uv0, float2(0.5,0.5)); + base.rgb *= smoothstep(Vmax, Vmin, dist); + return base; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/postFx/vignette/gl/VignetteP.glsl b/Templates/BaseGame/game/data/shaders/common/postFx/vignette/gl/VignetteP.glsl new file mode 100644 index 000000000..35de95c34 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/postFx/vignette/gl/VignetteP.glsl @@ -0,0 +1,41 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" + +uniform sampler2D backBuffer; +uniform float Vmax; +uniform float Vmin; + +in vec2 uv0; +#define IN_uv0 uv0 + +out vec4 OUT_col; + +void main() +{ + vec4 base = texture(backBuffer, IN_uv0); + float dist = distance(IN_uv0, vec2(0.5,0.5)); + base.rgb *= smoothstep(Vmax, Vmin, dist); + OUT_col = base; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/precipP.hlsl b/Templates/BaseGame/game/data/shaders/common/precipP.hlsl new file mode 100644 index 000000000..069ba4992 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/precipP.hlsl @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- + +#include "shaderModel.hlsl" + +struct Conn +{ + float4 position : TORQUE_POSITION; + float2 texCoord : TEXCOORD0; + float4 color : COLOR0; +}; + +struct Frag +{ + float4 col : TORQUE_TARGET0; +}; + +TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0); + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Frag main( Conn In) +{ + Frag Out; + + Out.col = TORQUE_TEX2D(diffuseMap, In.texCoord) * In.color; + + return Out; +} diff --git a/Templates/BaseGame/game/data/shaders/common/precipV.hlsl b/Templates/BaseGame/game/data/shaders/common/precipV.hlsl new file mode 100644 index 000000000..3c40942c7 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/precipV.hlsl @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//***************************************************************************** +// Precipitation vertex shader +//***************************************************************************** +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- + +#include "shaderModel.hlsl" + +struct Vert +{ + float3 position : POSITION; + float2 texCoord : TEXCOORD0; + float4 color : COLOR0; +}; + +struct Conn +{ + float4 position : TORQUE_POSITION; + float2 texCoord : TEXCOORD0; + float4 color : COLOR0; +}; + +uniform float4x4 modelview : register(C0); +uniform float2 fadeStartEnd : register(C4); +uniform float3 cameraPos : register(C5); +uniform float3 ambient : register(C6); + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Conn main( Vert In ) +{ + Conn Out; + + Out.position = mul(modelview, float4(In.position,1.0)); + Out.texCoord = In.texCoord; + Out.color = float4( ambient.r, ambient.g, ambient.b, 1 ); + + // Do we need to do a distance fade? + if ( fadeStartEnd.x < fadeStartEnd.y ) { + + float distance = length( cameraPos - In.position ); + Out.color.a = abs( clamp( ( distance - fadeStartEnd.x ) / ( fadeStartEnd.y - fadeStartEnd.x ), 0, 1 ) - 1 ); + } + + return Out; +} + diff --git a/Templates/BaseGame/game/data/shaders/common/projectedShadowP.hlsl b/Templates/BaseGame/game/data/shaders/common/projectedShadowP.hlsl new file mode 100644 index 000000000..88713bd52 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/projectedShadowP.hlsl @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "shaderModel.hlsl" + +struct Conn +{ + float4 position : TORQUE_POSITION; + float4 color : COLOR0; + float2 texCoord : TEXCOORD0; + float fade : TEXCOORD1; +}; + +TORQUE_UNIFORM_SAMPLER2D(inputTex, 0); +uniform float4 ambient; + +float4 main( Conn IN ) : TORQUE_TARGET0 +{ + float shadow = TORQUE_TEX2D( inputTex, IN.texCoord ).a * IN.color.a; + return ( ambient * shadow ) + ( 1 - shadow ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/projectedShadowV.hlsl b/Templates/BaseGame/game/data/shaders/common/projectedShadowV.hlsl new file mode 100644 index 000000000..38b1bd3e2 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/projectedShadowV.hlsl @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "shaderModel.hlsl" + +struct Vert +{ + float3 position : POSITION; + float3 normal : NORMAL; + float3 T : TANGENT; + float4 color : COLOR0; + float2 texCoord : TEXCOORD0; +}; + +struct Conn +{ + float4 position : TORQUE_POSITION; + float4 color : COLOR0; + float2 texCoord : TEXCOORD0; + float fade : TEXCOORD1; +}; + +uniform float4x4 modelview; +uniform float shadowLength; +uniform float3 shadowCasterPosition; + +Conn main( Vert In ) +{ + Conn Out; + + // Decals are in world space. + Out.position = mul( modelview, float4( In.position, 1.0 ) ); + + Out.color = In.color; + Out.texCoord = In.texCoord; + + float fromCasterDist = length( In.position - shadowCasterPosition ) - shadowLength; + Out.fade = 1.0 - saturate( fromCasterDist / shadowLength ); + + return Out; +} diff --git a/Templates/BaseGame/game/data/shaders/common/ribbons/basicRibbonShaderP.hlsl b/Templates/BaseGame/game/data/shaders/common/ribbons/basicRibbonShaderP.hlsl new file mode 100644 index 000000000..f4c6c7b04 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/ribbons/basicRibbonShaderP.hlsl @@ -0,0 +1,19 @@ +#define IN_HLSL +#include "../shdrConsts.h" +#include "../shaderModel.hlsl" + +struct v2f +{ + float4 hpos : TORQUE_POSITION; + float4 color : COLOR0; + float2 texCoord : TEXCOORD0; + float2 shiftdata : TEXCOORD1; +}; + +float4 main(v2f IN) : TORQUE_TARGET0 +{ + float fade = 1.0 - abs(IN.shiftdata.y - 0.5) * 2.0; + IN.color.xyz = IN.color.xyz + pow(fade, 4) / 10; + IN.color.a = IN.color.a * fade; + return IN.color; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/ribbons/basicRibbonShaderV.hlsl b/Templates/BaseGame/game/data/shaders/common/ribbons/basicRibbonShaderV.hlsl new file mode 100644 index 000000000..1a6bc85e4 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/ribbons/basicRibbonShaderV.hlsl @@ -0,0 +1,35 @@ +#define IN_HLSL +#include "../shdrConsts.h" +#include "../shaderModel.hlsl" + +struct a2v +{ + float3 position : POSITION; + float3 normal : NORMAL; + float4 color : COLOR0; + float2 texCoord : TEXCOORD0; + float2 shiftdata : TEXCOORD1; +}; + +struct v2f +{ + float4 hpos : TORQUE_POSITION; + float4 color : COLOR0; + float2 texCoord : TEXCOORD0; + float2 shiftdata : TEXCOORD1; +}; + +uniform float4x4 modelview; +uniform float3 eyePos; + +v2f main(a2v IN) +{ + v2f OUT; + + OUT.hpos = mul(modelview, float4(IN.position, 1.0)); + OUT.color = IN.color; + OUT.texCoord = IN.texCoord; + OUT.shiftdata = IN.shiftdata; + + return OUT; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/ribbons/gl/basicRibbonShaderP.glsl b/Templates/BaseGame/game/data/shaders/common/ribbons/gl/basicRibbonShaderP.glsl new file mode 100644 index 000000000..f3f83ce30 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/ribbons/gl/basicRibbonShaderP.glsl @@ -0,0 +1,20 @@ +#include "../../gl/hlslCompat.glsl" + +in float4 _hpos; +in float2 _texCoord; +in float2 _shiftdata; +in float4 _color; + +#define IN_hpos _hpos +#define IN_texCoord _texCoord +#define IN_shiftdata _shiftdata +#define IN_color _color + +out float4 OUT_col; + +void main() +{ + float fade = 1.0 - abs(IN_shiftdata.y - 0.5) * 2.0; + OUT_col.xyz = IN_color.xyz + pow(fade, 4) / 10; + OUT_col.a = IN_color.a * fade; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/ribbons/gl/basicRibbonShaderV.glsl b/Templates/BaseGame/game/data/shaders/common/ribbons/gl/basicRibbonShaderV.glsl new file mode 100644 index 000000000..9f6826d55 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/ribbons/gl/basicRibbonShaderV.glsl @@ -0,0 +1,37 @@ +#include "../../gl/hlslCompat.glsl" + +in float2 vTexCoord0; +in float2 vTexCoord1; +in float3 vNormal; +in float4 vPosition; +in float4 vColor; + +#define IN_texCoord vTexCoord0 +#define IN_shiftdata vTexCoord1 +#define IN_normal vNormal +#define IN_position vPosition +#define IN_color vColor + +out float4 _hpos; +out float2 _texCoord; +out float2 _shiftdata; +out float4 _color; + +#define OUT_hpos _hpos +#define OUT_texCoord _texCoord +#define OUT_shiftdata _shiftdata +#define OUT_color _color + +uniform float4x4 modelview; +uniform float3 eyePos; + +void main() +{ + OUT_hpos = tMul(modelview, IN_position); + OUT_color = IN_color; + OUT_texCoord = IN_texCoord; + OUT_shiftdata = IN_shiftdata; + + gl_Position = OUT_hpos; + correctSSP(gl_Position); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/ribbons/gl/texRibbonShaderP.glsl b/Templates/BaseGame/game/data/shaders/common/ribbons/gl/texRibbonShaderP.glsl new file mode 100644 index 000000000..cd3e72d43 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/ribbons/gl/texRibbonShaderP.glsl @@ -0,0 +1,22 @@ +#include "../../gl/hlslCompat.glsl" +#include "../../gl/torque.glsl" + +in float4 _hpos; +in float2 _texCoord; +in float2 _shiftdata; +in float4 _color; + +#define IN_hpos _hpos +#define IN_texCoord _texCoord +#define IN_shiftdata _shiftdata +#define IN_color _color + +out float4 OUT_col; +uniform sampler2D ribTex; + +void main() +{ + float4 Tex = tex2D(ribTex,IN_texCoord); + Tex.a *= IN_color.a; + OUT_col = hdrEncode(Tex); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/ribbons/gl/texRibbonShaderV.glsl b/Templates/BaseGame/game/data/shaders/common/ribbons/gl/texRibbonShaderV.glsl new file mode 100644 index 000000000..9f6826d55 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/ribbons/gl/texRibbonShaderV.glsl @@ -0,0 +1,37 @@ +#include "../../gl/hlslCompat.glsl" + +in float2 vTexCoord0; +in float2 vTexCoord1; +in float3 vNormal; +in float4 vPosition; +in float4 vColor; + +#define IN_texCoord vTexCoord0 +#define IN_shiftdata vTexCoord1 +#define IN_normal vNormal +#define IN_position vPosition +#define IN_color vColor + +out float4 _hpos; +out float2 _texCoord; +out float2 _shiftdata; +out float4 _color; + +#define OUT_hpos _hpos +#define OUT_texCoord _texCoord +#define OUT_shiftdata _shiftdata +#define OUT_color _color + +uniform float4x4 modelview; +uniform float3 eyePos; + +void main() +{ + OUT_hpos = tMul(modelview, IN_position); + OUT_color = IN_color; + OUT_texCoord = IN_texCoord; + OUT_shiftdata = IN_shiftdata; + + gl_Position = OUT_hpos; + correctSSP(gl_Position); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/ribbons/texRibbonShaderP.hlsl b/Templates/BaseGame/game/data/shaders/common/ribbons/texRibbonShaderP.hlsl new file mode 100644 index 000000000..55bae76fd --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/ribbons/texRibbonShaderP.hlsl @@ -0,0 +1,21 @@ +#define IN_HLSL +#include "../shdrConsts.h" +#include "../torque.hlsl" + + +TORQUE_UNIFORM_SAMPLER2D(ribTex, 0); + +struct v2f +{ + float4 hpos : TORQUE_POSITION; + float4 color : COLOR0; + float2 texCoord : TEXCOORD0; + float2 shiftdata : TEXCOORD1; +}; + +float4 main(v2f IN) : TORQUE_TARGET0 +{ + float4 Tex = TORQUE_TEX2D(ribTex,IN.texCoord); + Tex.a *= IN.color.a; + return hdrEncode(Tex); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/ribbons/texRibbonShaderV.hlsl b/Templates/BaseGame/game/data/shaders/common/ribbons/texRibbonShaderV.hlsl new file mode 100644 index 000000000..2ce4f62fd --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/ribbons/texRibbonShaderV.hlsl @@ -0,0 +1,35 @@ +#define IN_HLSL +#include "../shdrConsts.h" +#include "../shaderModel.hlsl" + +struct a2v +{ + float3 position : POSITION; + float4 color : COLOR0; + float3 normal : NORMAL; + float2 texCoord : TEXCOORD0; + float2 shiftdata : TEXCOORD1; +}; + +struct v2f +{ + float4 hpos : TORQUE_POSITION; + float4 color : COLOR0; + float2 texCoord : TEXCOORD0; + float2 shiftdata : TEXCOORD1; +}; + +uniform float4x4 modelview; +uniform float3 eyePos; + +v2f main(a2v IN) +{ + v2f OUT; + + OUT.hpos = mul(modelview, float4(IN.position,1.0)); + OUT.color = IN.color; + OUT.texCoord = IN.texCoord; + OUT.shiftdata = IN.shiftdata; + + return OUT; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/scatterSkyP.hlsl b/Templates/BaseGame/game/data/shaders/common/scatterSkyP.hlsl new file mode 100644 index 000000000..84e0854e0 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/scatterSkyP.hlsl @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "shaderModel.hlsl" +#include "torque.hlsl" + +struct Conn +{ + float4 hpos : TORQUE_POSITION; + float4 rayleighColor : TEXCOORD0; + float4 mieColor : TEXCOORD1; + float3 v3Direction : TEXCOORD2; + float3 pos : TEXCOORD3; +}; + +TORQUE_UNIFORM_SAMPLERCUBE(nightSky, 0); +uniform float4 nightColor; +uniform float2 nightInterpAndExposure; +uniform float useCubemap; +uniform float3 lightDir; +uniform float3 sunDir; + +float4 main( Conn In ) : TORQUE_TARGET0 +{ + + float fCos = dot( lightDir, In.v3Direction ) / length(In.v3Direction); + float fCos2 = fCos*fCos; + + float g = -0.991; + float g2 = -0.991 * -0.991; + + float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(abs(1.0 + g2 - 2.0*g*fCos), 1.5); + + float4 color = In.rayleighColor + fMiePhase * In.mieColor; + color.a = color.b; + + float4 Out; + + float4 nightSkyColor = TORQUE_TEXCUBE(nightSky, -In.v3Direction); + nightSkyColor = lerp( nightColor, nightSkyColor, useCubemap ); + + float fac = dot( normalize( In.pos ), sunDir ); + fac = max( nightInterpAndExposure.y, pow( saturate( fac ), 2 ) ); + Out = lerp( color, nightSkyColor, nightInterpAndExposure.y ); + + Out.a = 1; + Out = saturate(Out); + + return hdrEncode( Out ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/scatterSkyV.hlsl b/Templates/BaseGame/game/data/shaders/common/scatterSkyV.hlsl new file mode 100644 index 000000000..2052448db --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/scatterSkyV.hlsl @@ -0,0 +1,157 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "shaderModel.hlsl" + +// The scale equation calculated by Vernier's Graphical Analysis +float vernierScale(float fCos) +{ + float x = 1.0 - fCos; + float x5 = x * 5.25; + float x5p6 = (-6.80 + x5); + float xnew = (3.83 + x * x5p6); + float xfinal = (0.459 + x * xnew); + float xfinal2 = -0.00287 + x * xfinal; + float outx = exp( xfinal2 ); + return 0.25 * outx; +} + +// This is the shader input vertex structure. +struct Vert +{ + // .xyz = point + float3 position : POSITION; +}; + +// This is the shader output data. +struct Conn +{ + float4 position : TORQUE_POSITION; + float4 rayleighColor : TEXCOORD0; + float4 mieColor : TEXCOORD1; + float3 v3Direction : TEXCOORD2; + float3 pos : TEXCOORD3; +}; + +float3 desaturate(const float3 color, const float desaturation) +{ + const float3 gray_conv = float3 (0.30, 0.59, 0.11); + return lerp(color, dot(gray_conv , color), desaturation); +} + +uniform float4x4 modelView; +uniform float4 misc; +uniform float4 sphereRadii; +uniform float4 scatteringCoeffs; +uniform float4 colorize; +uniform float3 camPos; +uniform float3 lightDir; +uniform float4 invWaveLength; + +Conn main( Vert In ) +{ + // Pull some variables out: + float camHeight = misc.x; + float camHeightSqr = misc.y; + + float scale = misc.z; + float scaleOverScaleDepth = misc.w; + + float outerRadius = sphereRadii.x; + float outerRadiusSqr = sphereRadii.y; + + float innerRadius = sphereRadii.z; + float innerRadiusSqr = sphereRadii.w; + + float rayleighBrightness = scatteringCoeffs.x; // Kr * ESun + float rayleigh4PI = scatteringCoeffs.y; // Kr * 4 * PI + + float mieBrightness = scatteringCoeffs.z; // Km * ESun + float mie4PI = scatteringCoeffs.w; // Km * 4 * PI + + // Get the ray from the camera to the vertex, + // and its length (which is the far point of the ray + // passing through the atmosphere). + float4 v3Pos = float4(In.position,1.0) / 6378000.0; // outerRadius; + float3 newCamPos = float3( 0, 0, camHeight ); + v3Pos.z += innerRadius; + float3 v3Ray = v3Pos.xyz - newCamPos; + float fFar = length(v3Ray); + v3Ray /= fFar; + + // Calculate the ray's starting position, + // then calculate its scattering offset. + float3 v3Start = newCamPos; + float fHeight = length(v3Start); + float fDepth = exp(scaleOverScaleDepth * (innerRadius - camHeight)); + float fStartAngle = dot(v3Ray, v3Start) / fHeight; + + float fStartOffset = fDepth * vernierScale( fStartAngle ); + + // Initialize the scattering loop variables. + float fSampleLength = fFar / 2; + float fScaledLength = fSampleLength * scale; + float3 v3SampleRay = v3Ray * fSampleLength; + float3 v3SamplePoint = v3Start + v3SampleRay * 0.5; + + // Now loop through the sample rays + float3 v3FrontColor = float3(0.0, 0.0, 0.0); + for(int i=0; i<2; i++) + { + float fHeight = length(v3SamplePoint); + float fDepth = exp(scaleOverScaleDepth * (innerRadius - fHeight)); + float fLightAngle = dot(lightDir, v3SamplePoint) / fHeight; + float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight; + + float vscale3 = vernierScale( fCameraAngle ); + float vscale2 = vernierScale( fLightAngle ); + + float fScatter = (fStartOffset + fDepth*(vscale2 - vscale3)); + float3 v3Attenuate = exp(-fScatter * (invWaveLength.xyz * rayleigh4PI + mie4PI)); + v3FrontColor += v3Attenuate * (fDepth * fScaledLength); + v3SamplePoint += v3SampleRay; + } + + Conn Out; + + // Finally, scale the Mie and Rayleigh colors + // and set up the varying variables for the pixel shader. + Out.position = mul( modelView, float4(In.position,1.0) ); + Out.mieColor.rgb = v3FrontColor * mieBrightness; + Out.mieColor.a = 1.0f; + Out.rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness); + Out.rayleighColor.a = 1.0f; + Out.v3Direction = newCamPos - v3Pos.xyz; + Out.pos = In.position; + +#ifdef USE_COLORIZE + + Out.rayleighColor.rgb = desaturate(Out.rayleighColor.rgb, 1) * colorize.a; + + Out.rayleighColor.r *= colorize.r; + Out.rayleighColor.g *= colorize.g; + Out.rayleighColor.b *= colorize.b; + +#endif + + return Out; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/shaders/common/shaderModel.hlsl b/Templates/BaseGame/game/data/shaders/common/shaderModel.hlsl new file mode 100644 index 000000000..70ce3a02d --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/shaderModel.hlsl @@ -0,0 +1,97 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2015 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef _TORQUE_SHADERMODEL_ +#define _TORQUE_SHADERMODEL_ + +// Portability helpers for different shader models +//Shader model 1.0 - 3.0 +#if (TORQUE_SM >= 10 && TORQUE_SM <=30) + // Semantics + #define TORQUE_POSITION POSITION + #define TORQUE_DEPTH DEPTH + #define TORQUE_TARGET0 COLOR0 + #define TORQUE_TARGET1 COLOR1 + #define TORQUE_TARGET2 COLOR2 + #define TORQUE_TARGET3 COLOR3 + + // Sampler uniforms + #define TORQUE_UNIFORM_SAMPLER1D(tex,regist) uniform sampler1D tex : register(S##regist) + #define TORQUE_UNIFORM_SAMPLER2D(tex,regist) uniform sampler2D tex : register(S##regist) + #define TORQUE_UNIFORM_SAMPLER3D(tex,regist) uniform sampler3D tex : register(S##regist) + #define TORQUE_UNIFORM_SAMPLERCUBE(tex,regist) uniform samplerCUBE tex : register(S##regist) + // Sampling functions + #define TORQUE_TEX1D(tex,coords) tex1D(tex,coords) + #define TORQUE_TEX2D(tex,coords) tex2D(tex,coords) + #define TORQUE_TEX2DPROJ(tex,coords) tex2Dproj(tex,coords) //this really is sm 2 or later + #define TORQUE_TEX3D(tex,coords) tex3D(tex,coords) + #define TORQUE_TEXCUBE(tex,coords) texCUBE(tex,coords) + + //Shader model 3.0 only + #if TORQUE_SM == 30 + #define TORQUE_VPOS VPOS // This is a float2 + // The mipmap LOD is specified in coord.w + #define TORQUE_TEX2DLOD(tex,coords) tex2Dlod(tex,coords) + #endif + + //helper if you want to pass sampler/texture in a function + //2D + #define TORQUE_SAMPLER2D(tex) sampler2D tex + #define TORQUE_SAMPLER2D_MAKEARG(tex) tex + //Cube + #define TORQUE_SAMPLERCUBE(tex) samplerCUBE tex + #define TORQUE_SAMPLERCUBE_MAKEARG(tex) tex +// Shader model 4.0+ +#elif TORQUE_SM >= 40 + #define TORQUE_POSITION SV_Position + #define TORQUE_DEPTH SV_Depth + #define TORQUE_VPOS SV_Position //note float4 compared to SM 3 where it is a float2 + #define TORQUE_TARGET0 SV_Target0 + #define TORQUE_TARGET1 SV_Target1 + #define TORQUE_TARGET2 SV_Target2 + #define TORQUE_TARGET3 SV_Target3 + // Sampler uniforms + //1D is emulated to a 2D for now + #define TORQUE_UNIFORM_SAMPLER1D(tex,regist) uniform Texture2D texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist) + #define TORQUE_UNIFORM_SAMPLER2D(tex,regist) uniform Texture2D texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist) + #define TORQUE_UNIFORM_SAMPLER3D(tex,regist) uniform Texture3D texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist) + #define TORQUE_UNIFORM_SAMPLERCUBE(tex,regist) uniform TextureCube texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist) + // Sampling functions + #define TORQUE_TEX1D(tex,coords) texture_##tex.Sample(tex,coords) + #define TORQUE_TEX2D(tex,coords) texture_##tex.Sample(tex,coords) + #define TORQUE_TEX2DPROJ(tex,coords) texture_##tex.Sample(tex,coords.xy / coords.w) + #define TORQUE_TEX3D(tex,coords) texture_##tex.Sample(tex,coords) + #define TORQUE_TEXCUBE(tex,coords) texture_##tex.Sample(tex,coords) + // The mipmap LOD is specified in coord.w + #define TORQUE_TEX2DLOD(tex,coords) texture_##tex.SampleLevel(tex,coords.xy,coords.w) + + //helper if you want to pass sampler/texture in a function + //2D + #define TORQUE_SAMPLER2D(tex) Texture2D texture_##tex, SamplerState tex + #define TORQUE_SAMPLER2D_MAKEARG(tex) texture_##tex, tex + //Cube + #define TORQUE_SAMPLERCUBE(tex) TextureCube texture_##tex, SamplerState tex + #define TORQUE_SAMPLERCUBE_MAKEARG(tex) texture_##tex, tex +#endif + +#endif // _TORQUE_SHADERMODEL_ + diff --git a/Templates/BaseGame/game/data/shaders/common/shaderModelAutoGen.hlsl b/Templates/BaseGame/game/data/shaders/common/shaderModelAutoGen.hlsl new file mode 100644 index 000000000..4f2d8803f --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/shaderModelAutoGen.hlsl @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2015 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef _TORQUE_SHADERMODEL_AUTOGEN_ +#define _TORQUE_SHADERMODEL_AUTOGEN_ + +#include "shadergen:/autogenConditioners.h" + +// Portability helpers for autogenConditioners +#if (TORQUE_SM >= 10 && TORQUE_SM <=30) + #define TORQUE_PREPASS_UNCONDITION(tex, coords) prepassUncondition(tex, coords) +#elif TORQUE_SM >= 40 + #define TORQUE_PREPASS_UNCONDITION(tex, coords) prepassUncondition(tex, texture_##tex, coords) +#endif + +#endif //_TORQUE_SHADERMODEL_AUTOGEN_ diff --git a/Templates/BaseGame/game/data/shaders/common/shdrConsts.h b/Templates/BaseGame/game/data/shaders/common/shdrConsts.h new file mode 100644 index 000000000..8c262b76a --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/shdrConsts.h @@ -0,0 +1,117 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifdef IN_HLSL + +#define VC_WORLD_PROJ C0 + +#define VC_TEX_TRANS1 C4 +#define VC_LIGHT_TRANS C8 +#define VC_OBJ_TRANS C12 + +#define VC_CUBE_TRANS C16 +#define VC_CUBE_EYE_POS C19 // in cubemap space +#define VC_EYE_POS C20 // in object space +#define VC_MAT_SPECPOWER C21 + +#define VC_FOGDATA C22 + +#define VC_LIGHT_POS1 C23 +#define VC_LIGHT_DIR1 C24 +#define VC_LIGHT_DIFFUSE1 C25 +#define VC_LIGHT_SPEC1 C26 + +#define VC_LIGHT_POS2 C27 +//#define VC_LIGHT_DIR2 C28 +//#define VC_LIGHT_DIFFUSE2 C29 +//#define VC_LIGHT_SPEC2 C30 +#define VC_LIGHT_TRANS2 C31 + +//#define VC_LIGHT_POS4 C35 +//#define VC_LIGHT_DIR4 C36 +//#define VC_LIGHT_DIFFUSE4 C37 +//#define VC_LIGHT_SPEC4 C38 + +#define VC_DETAIL_SCALE C40 + + +#define PC_MAT_SPECCOLOR C0 +#define PC_MAT_SPECPOWER C1 +#define PC_DIFF_COLOR C2 +#define PC_AMBIENT_COLOR C3 +#define PC_ACCUM_TIME C4 +#define PC_DIFF_COLOR2 C5 +#define PC_VISIBILITY C6 +#define PC_COLORMULTIPLY C7 + +#define PC_USERDEF1 C8 + +// Mirror of above. Couldn't be cleaner because HLSL doesn't support function macros +#else + +#define VC_WORLD_PROJ 0 + +#define VC_TEX_TRANS1 4 +#define VC_LIGHT_TRANS 8 +#define VC_OBJ_TRANS 12 + +#define VC_CUBE_TRANS 16 +#define VC_CUBE_EYE_POS 19 // in cubemap space +#define VC_EYE_POS 20 // in object space +#define VC_MAT_SPECPOWER 21 + +#define VC_FOGDATA 22 + +#define VC_LIGHT_POS1 23 +#define VC_LIGHT_DIR1 24 +#define VC_LIGHT_DIFFUSE1 25 +#define VC_LIGHT_SPEC1 26 + +#define VC_LIGHT_POS2 27 +//#define VC_LIGHT_DIR2 28 +//#define VC_LIGHT_DIFFUSE2 29 +//#define VC_LIGHT_SPEC2 30 +#define VC_LIGHT_TRANS2 31 + +//#define VC_LIGHT_POS4 35 +//#define VC_LIGHT_DIR4 36 +//#define VC_LIGHT_DIFFUSE4 37 +//#define VC_LIGHT_SPEC4 38 + +#define VC_DETAIL_SCALE 40 + + + +#define PC_MAT_SPECCOLOR 0 +#define PC_MAT_SPECPOWER 1 +#define PC_DIFF_COLOR 2 +#define PC_AMBIENT_COLOR 3 +#define PC_ACCUM_TIME 4 +#define PC_DIFF_COLOR2 5 +#define PC_VISIBILITY 6 +#define PC_COLORMULTIPLY 7 + +#define PC_USERDEF1 8 + +#endif + + diff --git a/Templates/BaseGame/game/data/shaders/common/terrain/blendP.hlsl b/Templates/BaseGame/game/data/shaders/common/terrain/blendP.hlsl new file mode 100644 index 000000000..aeef9d6e3 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/terrain/blendP.hlsl @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "terrain.hlsl" +#include "../shaderModel.hlsl" + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float2 layerCoord : TEXCOORD0; + float2 texCoord : TEXCOORD1; +}; + +TORQUE_UNIFORM_SAMPLER2D(layerTex, 0); +TORQUE_UNIFORM_SAMPLER2D(textureMap, 1); + +uniform float texId; +uniform float layerSize; + +float4 main( ConnectData IN ) : TORQUE_TARGET0 +{ + float4 layerSample = round( TORQUE_TEX2D( layerTex, IN.layerCoord ) * 255.0f ); + + float blend = calcBlend( texId, IN.layerCoord, layerSize, layerSample ); + + clip( blend - 0.0001 ); + + return float4( TORQUE_TEX2D(textureMap, IN.texCoord).rgb, blend); +} diff --git a/Templates/BaseGame/game/data/shaders/common/terrain/blendV.hlsl b/Templates/BaseGame/game/data/shaders/common/terrain/blendV.hlsl new file mode 100644 index 000000000..9ccd33301 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/terrain/blendV.hlsl @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +/// The vertex shader used in the generation and caching of the +/// base terrain texture. + +#include "../shaderModel.hlsl" + +struct VertData +{ + float3 position : POSITION; + float2 texCoord : TEXCOORD0; +}; + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float2 layerCoord : TEXCOORD0; + float2 texCoord : TEXCOORD1; +}; + +uniform float2 texScale; + +ConnectData main( VertData IN ) +{ + ConnectData OUT; + + OUT.hpos = float4( IN.position, 1 ); + OUT.layerCoord = IN.texCoord; + OUT.texCoord = IN.texCoord * texScale; + + return OUT; +} diff --git a/Templates/BaseGame/game/data/shaders/common/terrain/gl/blendP.glsl b/Templates/BaseGame/game/data/shaders/common/terrain/gl/blendP.glsl new file mode 100644 index 000000000..3189ea01d --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/terrain/gl/blendP.glsl @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../terrain.glsl" +#include "../../gl/hlslCompat.glsl" + +in vec2 layerCoord; +#define IN_layerCoord layerCoord +in vec2 texCoord; +#define IN_texCoord texCoord + +uniform sampler2D layerTex; +uniform sampler2D textureMap; +uniform float texId; +uniform float layerSize; + +out vec4 OUT_col; + +void main() +{ + vec4 layerSample = round(texture( layerTex, IN_layerCoord ) * 255.0); + + float blend = calcBlend( texId, IN_layerCoord, layerSize, layerSample ); + + if(blend - 0.0001 < 0.0) + discard; + + OUT_col = vec4( texture( textureMap, IN_texCoord ).rgb, blend ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/terrain/gl/blendV.glsl b/Templates/BaseGame/game/data/shaders/common/terrain/gl/blendV.glsl new file mode 100644 index 000000000..dc7b7befa --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/terrain/gl/blendV.glsl @@ -0,0 +1,41 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +/// The vertex shader used in the generation and caching of the +/// base terrain texture. + +in vec4 vPosition; +in vec2 vTexCoord0; + +out vec2 layerCoord; +out vec2 texCoord; + +uniform vec2 texScale; + +void main() +{ + gl_Position = vec4(vPosition.xyz, 1.0); + layerCoord = vTexCoord0.st; + texCoord = vTexCoord0.st * texScale; + + gl_Position.y *= -1; +} diff --git a/Templates/BaseGame/game/data/shaders/common/terrain/terrain.glsl b/Templates/BaseGame/game/data/shaders/common/terrain/terrain.glsl new file mode 100644 index 000000000..756edd553 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/terrain/terrain.glsl @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +float calcBlend( float texId, vec2 layerCoord, float layerSize, vec4 layerSample ) +{ + // This is here to disable the blend if none of + // the neighbors equal the current id. + // + // We depend on the input layer samples being + // rounded to the correct integer ids. + // + vec4 diff = clamp( abs( layerSample - texId ), 0.0, 1.0 ); + float noBlend = float(any( bvec4(1 - diff) )); + + // Check if any of the layer samples + // match the current texture id. + vec4 factors = vec4(0); + for(int i = 0; i < 4; i++) + factors[i] = (layerSample[i] == texId) ? 1 : 0; // workaround for Intel + + // This is a custom bilinear filter. + + vec2 uv = layerCoord * layerSize; + vec2 xy = floor( uv ); + vec2 ratio = uv - xy; + vec2 opposite = 1 - ratio; + + float blend = ( factors.b * opposite.x + factors.g * ratio.x ) * opposite.y + + ( factors.r * opposite.x + factors.a * ratio.x ) * ratio.y; + + return noBlend * blend; +} diff --git a/Templates/BaseGame/game/data/shaders/common/terrain/terrain.hlsl b/Templates/BaseGame/game/data/shaders/common/terrain/terrain.hlsl new file mode 100644 index 000000000..b7c87e618 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/terrain/terrain.hlsl @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +float calcBlend( float texId, float2 layerCoord, float layerSize, float4 layerSample ) +{ + // This is here to disable the blend if none of + // the neighbors equal the current id. + // + // We depend on the input layer samples being + // rounded to the correct integer ids. + // + float4 diff = saturate( abs( layerSample - texId ) ); + float noBlend = any( 1 - diff ); + + // Check if any of the layer samples + // match the current texture id. + float4 factors = 0; + [unroll] + for(int i = 0; i < 4; i++) + if(layerSample[i] == texId) + factors[i] = 1; + + // This is a custom bilinear filter. + + float2 uv = layerCoord * layerSize; + float2 xy = floor( uv ); + float2 ratio = uv - xy; + float2 opposite = 1 - ratio; + + // NOTE: This will optimize down to two lerp operations. + float blend = ( factors.b * opposite.x + factors.g * ratio.x ) * opposite.y + + ( factors.r * opposite.x + factors.a * ratio.x ) * ratio.y; + + return noBlend * blend; +} diff --git a/Templates/BaseGame/game/data/shaders/common/torque.hlsl b/Templates/BaseGame/game/data/shaders/common/torque.hlsl new file mode 100644 index 000000000..7081c7153 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/torque.hlsl @@ -0,0 +1,342 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef _TORQUE_HLSL_ +#define _TORQUE_HLSL_ + +#include "./shaderModel.hlsl" + +static float M_HALFPI_F = 1.57079632679489661923f; +static float M_PI_F = 3.14159265358979323846f; +static float M_2PI_F = 6.28318530717958647692f; + + +/// Calculate fog based on a start and end positions in worldSpace. +float computeSceneFog( float3 startPos, + float3 endPos, + float fogDensity, + float fogDensityOffset, + float fogHeightFalloff ) +{ + float f = length( startPos - endPos ) - fogDensityOffset; + float h = 1.0 - ( endPos.z * fogHeightFalloff ); + return exp( -fogDensity * f * h ); +} + + +/// Calculate fog based on a start and end position and a height. +/// Positions do not need to be in worldSpace but height does. +float computeSceneFog( float3 startPos, + float3 endPos, + float height, + float fogDensity, + float fogDensityOffset, + float fogHeightFalloff ) +{ + float f = length( startPos - endPos ) - fogDensityOffset; + float h = 1.0 - ( height * fogHeightFalloff ); + return exp( -fogDensity * f * h ); +} + + +/// Calculate fog based on a distance, height is not used. +float computeSceneFog( float dist, float fogDensity, float fogDensityOffset ) +{ + float f = dist - fogDensityOffset; + return exp( -fogDensity * f ); +} + + +/// Convert a float4 uv in viewport space to render target space. +float2 viewportCoordToRenderTarget( float4 inCoord, float4 rtParams ) +{ + float2 outCoord = inCoord.xy / inCoord.w; + outCoord = ( outCoord * rtParams.zw ) + rtParams.xy; + return outCoord; +} + + +/// Convert a float2 uv in viewport space to render target space. +float2 viewportCoordToRenderTarget( float2 inCoord, float4 rtParams ) +{ + float2 outCoord = ( inCoord * rtParams.zw ) + rtParams.xy; + return outCoord; +} + + +/// Convert a float4 quaternion into a 3x3 matrix. +float3x3 quatToMat( float4 quat ) +{ + float xs = quat.x * 2.0f; + float ys = quat.y * 2.0f; + float zs = quat.z * 2.0f; + + float wx = quat.w * xs; + float wy = quat.w * ys; + float wz = quat.w * zs; + + float xx = quat.x * xs; + float xy = quat.x * ys; + float xz = quat.x * zs; + + float yy = quat.y * ys; + float yz = quat.y * zs; + float zz = quat.z * zs; + + float3x3 mat; + + mat[0][0] = 1.0f - (yy + zz); + mat[0][1] = xy - wz; + mat[0][2] = xz + wy; + + mat[1][0] = xy + wz; + mat[1][1] = 1.0f - (xx + zz); + mat[1][2] = yz - wx; + + mat[2][0] = xz - wy; + mat[2][1] = yz + wx; + mat[2][2] = 1.0f - (xx + yy); + + return mat; +} + + +/// The number of additional substeps we take when refining +/// the results of the offset parallax mapping function below. +/// +/// You should turn down the number of steps if your needing +/// more performance out of your parallax surfaces. Increasing +/// the number doesn't yeild much better results and is rarely +/// worth the additional cost. +/// +#define PARALLAX_REFINE_STEPS 3 + +/// Performs fast parallax offset mapping using +/// multiple refinement steps. +/// +/// @param texMap The texture map whos alpha channel we sample the parallax depth. +/// @param texCoord The incoming texture coordinate for sampling the parallax depth. +/// @param negViewTS The negative view vector in tangent space. +/// @param depthScale The parallax factor used to scale the depth result. +/// +float2 parallaxOffset(TORQUE_SAMPLER2D(texMap), float2 texCoord, float3 negViewTS, float depthScale) +{ + float depth = TORQUE_TEX2D(texMap, texCoord).a/(PARALLAX_REFINE_STEPS*2); + float2 offset = negViewTS.xy * (depth * depthScale)/(PARALLAX_REFINE_STEPS); + + for (int i = 0; i < PARALLAX_REFINE_STEPS; i++) + { + depth = (depth + TORQUE_TEX2D(texMap, texCoord + offset).a)/(PARALLAX_REFINE_STEPS*2); + offset = negViewTS.xy * (depth * depthScale)/(PARALLAX_REFINE_STEPS); + } + + return offset; +} + +/// Same as parallaxOffset but for dxtnm where depth is stored in the red channel instead of the alpha +float2 parallaxOffsetDxtnm(TORQUE_SAMPLER2D(texMap), float2 texCoord, float3 negViewTS, float depthScale) +{ + float depth = TORQUE_TEX2D(texMap, texCoord).r/(PARALLAX_REFINE_STEPS*2); + float2 offset = negViewTS.xy * (depth * depthScale)/(PARALLAX_REFINE_STEPS*2); + + for (int i = 0; i < PARALLAX_REFINE_STEPS; i++) + { + depth = (depth + TORQUE_TEX2D(texMap, texCoord + offset).r)/(PARALLAX_REFINE_STEPS*2); + offset = negViewTS.xy * (depth * depthScale)/(PARALLAX_REFINE_STEPS*2); + } + + return offset; +} + + +/// The maximum value for 16bit per component integer HDR encoding. +static const float HDR_RGB16_MAX = 100.0; + +/// The maximum value for 10bit per component integer HDR encoding. +static const float HDR_RGB10_MAX = 4.0; + +/// Encodes an HDR color for storage into a target. +float3 hdrEncode( float3 sample ) +{ + #if defined( TORQUE_HDR_RGB16 ) + + return sample / HDR_RGB16_MAX; + + #elif defined( TORQUE_HDR_RGB10 ) + + return sample / HDR_RGB10_MAX; + + #else + + // No encoding. + return sample; + + #endif +} + +/// Encodes an HDR color for storage into a target. +float4 hdrEncode( float4 sample ) +{ + return float4( hdrEncode( sample.rgb ), sample.a ); +} + +/// Decodes an HDR color from a target. +float3 hdrDecode( float3 sample ) +{ + #if defined( TORQUE_HDR_RGB16 ) + + return sample * HDR_RGB16_MAX; + + #elif defined( TORQUE_HDR_RGB10 ) + + return sample * HDR_RGB10_MAX; + + #else + + // No encoding. + return sample; + + #endif +} + +/// Decodes an HDR color from a target. +float4 hdrDecode( float4 sample ) +{ + return float4( hdrDecode( sample.rgb ), sample.a ); +} + +/// Returns the luminance for an HDR pixel. +float hdrLuminance( float3 sample ) +{ + // There are quite a few different ways to + // calculate luminance from an rgb value. + // + // If you want to use a different technique + // then plug it in here. + // + + //////////////////////////////////////////////////////////////////////////// + // + // Max component luminance. + // + //float lum = max( sample.r, max( sample.g, sample.b ) ); + + //////////////////////////////////////////////////////////////////////////// + // The perceptual relative luminance. + // + // See http://en.wikipedia.org/wiki/Luminance_(relative) + // + const float3 RELATIVE_LUMINANCE = float3( 0.2126, 0.7152, 0.0722 ); + float lum = dot( sample, RELATIVE_LUMINANCE ); + + //////////////////////////////////////////////////////////////////////////// + // + // The average component luminance. + // + //const float3 AVERAGE_LUMINANCE = float3( 0.3333, 0.3333, 0.3333 ); + //float lum = dot( sample, AVERAGE_LUMINANCE ); + + return lum; +} + +/// Called from the visibility feature to do screen +/// door transparency for fading of objects. +void fizzle(float2 vpos, float visibility) +{ + // NOTE: The magic values below are what give us + // the nice even pattern during the fizzle. + // + // These values can be changed to get different + // patterns... some better than others. + // + // Horizontal Blinds - { vpos.x, 0.916, vpos.y, 0 } + // Vertical Lines - { vpos.x, 12.9898, vpos.y, 78.233 } + // + // I'm sure there are many more patterns here to + // discover for different effects. + + float2x2 m = { vpos.x, 0.916, vpos.y, 0.350 }; + clip( visibility - frac( determinant( m ) ) ); +} + +// Deferred Shading: Material Info Flag Check +bool getFlag(float flags, int num) +{ + int process = round(flags * 255); + int squareNum = pow(2, num); + return (fmod(process, pow(2, squareNum)) >= squareNum); +} + +// #define TORQUE_STOCK_GAMMA +#ifdef TORQUE_STOCK_GAMMA +// Sample in linear space. Decodes gamma. +float4 toLinear(float4 tex) +{ + return tex; +} +// Encodes gamma. +float4 toGamma(float4 tex) +{ + return tex; +} +float3 toLinear(float3 tex) +{ + return tex; +} +// Encodes gamma. +float3 toGamma(float3 tex) +{ + return tex; +} +float3 toLinear(float3 tex) +{ + return tex; +} +// Encodes gamma. +float3 toLinear(float3 tex) +{ + return tex; +} +#else +// Sample in linear space. Decodes gamma. +float4 toLinear(float4 tex) +{ + return float4(pow(abs(tex.rgb), 2.2), tex.a); +} +// Encodes gamma. +float4 toGamma(float4 tex) +{ + return float4(pow(abs(tex.rgb), 1.0/2.2), tex.a); +} +// Sample in linear space. Decodes gamma. +float3 toLinear(float3 tex) +{ + return pow(abs(tex.rgb), 2.2); +} +// Encodes gamma. +float3 toGamma(float3 tex) +{ + return pow(abs(tex.rgb), 1.0/2.2); +} +#endif // + +#endif // _TORQUE_HLSL_ diff --git a/Templates/BaseGame/game/data/shaders/common/water/gl/waterBasicP.glsl b/Templates/BaseGame/game/data/shaders/common/water/gl/waterBasicP.glsl new file mode 100644 index 000000000..1d5a07c3f --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/water/gl/waterBasicP.glsl @@ -0,0 +1,217 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../gl/torque.glsl" +#include "../../gl/hlslCompat.glsl" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +// miscParams +#define FRESNEL_BIAS miscParams[0] +#define FRESNEL_POWER miscParams[1] +#define CLARITY miscParams[2] +#define ISRIVER miscParams[3] + +// reflectParams +#define REFLECT_PLANE_Z reflectParams[0] +#define REFLECT_MIN_DIST reflectParams[1] +#define REFLECT_MAX_DIST reflectParams[2] +#define NO_REFLECT reflectParams[3] + +// distortionParams +#define DISTORT_START_DIST distortionParams[0] +#define DISTORT_END_DIST distortionParams[1] +#define DISTORT_FULL_DEPTH distortionParams[2] + +// ConnectData.misc +#define LIGHT_VEC IN_misc.xyz +#define WORLD_Z IN_objPos.w + +// specularParams +#define SPEC_POWER specularParams[3] +#define SPEC_COLOR specularParams.xyz + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +// TexCoord 0 and 1 (xy,zw) for ripple texture lookup +in vec4 rippleTexCoord01; +#define IN_rippleTexCoord01 rippleTexCoord01 + +// TexCoord 2 for ripple texture lookup +in vec2 rippleTexCoord2; +#define IN_rippleTexCoord2 rippleTexCoord2 + +// Screenspace vert position BEFORE wave transformation +in vec4 posPreWave; +#define IN_posPreWave posPreWave + +// Screenspace vert position AFTER wave transformation +in vec4 posPostWave; +#define IN_posPostWave posPostWave + +// Worldspace unit distance/depth of this vertex/pixel +in float pixelDist; +#define IN_pixelDist pixelDist + +in vec4 objPos; +#define IN_objPos objPos + +in vec3 misc; +#define IN_misc misc + +//----------------------------------------------------------------------------- +// approximate Fresnel function +//----------------------------------------------------------------------------- +float fresnel(float NdotV, float bias, float power) +{ + return bias + (1.0-bias)*pow(abs(1.0 - max(NdotV, 0)), power); +} + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform sampler2D bumpMap; +//uniform sampler2D prepassTex; +uniform sampler2D reflectMap; +uniform sampler2D refractBuff; +uniform samplerCube skyMap; +//uniform sampler2D foamMap; +uniform vec4 baseColor; +uniform vec4 miscParams; +uniform vec4 reflectParams; +uniform vec3 ambientColor; +uniform vec3 eyePos; +uniform vec3 distortionParams; +uniform vec3 fogData; +uniform vec4 fogColor; +uniform vec4 rippleMagnitude; +uniform vec4 specularParams; +uniform mat4 modelMat; + +out vec4 OUT_col; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + // Modulate baseColor by the ambientColor. + vec4 waterBaseColor = baseColor * vec4( ambientColor.rgb, 1 ); + waterBaseColor = toLinear(waterBaseColor); + + // Get the bumpNorm... + vec3 bumpNorm = ( texture( bumpMap, IN_rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x; + bumpNorm += ( texture( bumpMap, IN_rippleTexCoord01.zw ).rgb * 2.0 - 1.0 ) * rippleMagnitude.y; + bumpNorm += ( texture( bumpMap, IN_rippleTexCoord2 ).rgb * 2.0 - 1.0 ) * rippleMagnitude.z; + + bumpNorm = normalize( bumpNorm ); + bumpNorm = mix( bumpNorm, vec3(0,0,1), 1.0 - rippleMagnitude.w ); + + // We subtract a little from it so that we don't + // distort where the water surface intersects the + // camera near plane. + float distortAmt = saturate( IN_pixelDist / 1.0 ) * 0.8; + + vec4 distortPos = IN_posPostWave; + distortPos.xy += bumpNorm.xy * distortAmt; + + #ifdef UNDERWATER + OUT_col = hdrEncode( textureProj( refractBuff, distortPos ) ); + #else + + vec3 eyeVec = IN_objPos.xyz - eyePos; + eyeVec = tMul( mat3(modelMat), eyeVec ); + vec3 reflectionVec = reflect( eyeVec, bumpNorm ); + + // Color that replaces the reflection color when we do not + // have one that is appropriate. + vec4 fakeColor = vec4(ambientColor,1); + + // Use fakeColor for ripple-normals that are angled towards the camera + eyeVec = -eyeVec; + eyeVec = normalize( eyeVec ); + float ang = saturate( dot( eyeVec, bumpNorm ) ); + float fakeColorAmt = ang; + + // Get reflection map color + vec4 refMapColor = hdrDecode( textureProj( reflectMap, distortPos ) ); + // If we do not have a reflection texture then we use the cubemap. + refMapColor = mix( refMapColor, texture( skyMap, reflectionVec ), NO_REFLECT ); + + // Combine reflection color and fakeColor. + vec4 reflectColor = mix( refMapColor, fakeColor, fakeColorAmt ); + //return refMapColor; + + // Get refract color + vec4 refractColor = hdrDecode( textureProj( refractBuff, distortPos ) ); + + // calc "diffuse" color by lerping from the water color + // to refraction image based on the water clarity. + vec4 diffuseColor = mix( refractColor, waterBaseColor, 1.0f - CLARITY ); + + // fresnel calculation + float fresnelTerm = fresnel( ang, FRESNEL_BIAS, FRESNEL_POWER ); + //return vec4( fresnelTerm.rrr, 1 ); + + // Also scale the frensel by our distance to the + // water surface. This removes the hard reflection + // when really close to the water surface. + fresnelTerm *= saturate( IN_pixelDist - 0.1 ); + + // Combine the diffuse color and reflection image via the + // fresnel term and set out output color. + vec4 OUT = mix( diffuseColor, reflectColor, fresnelTerm ); + + #ifdef WATER_SPEC + + // Get some specular reflection. + vec3 newbump = bumpNorm; + newbump.xy *= 3.5; + newbump = normalize( bumpNorm ); + half3 halfAng = normalize( eyeVec + -LIGHT_VEC ); + float specular = saturate( dot( newbump, halfAng ) ); + specular = pow( specular, SPEC_POWER ); + + OUT.rgb = OUT.rgb + ( SPEC_COLOR * specular.xxx ); + + #else // Disable fogging if spec is on because otherwise we run out of instructions. + + // Fog it. + float factor = computeSceneFog( eyePos, + IN_objPos.xyz, + WORLD_Z, + fogData.x, + fogData.y, + fogData.z ); + + //OUT.rgb = mix( OUT.rgb, fogColor.rgb, 1.0 - saturate( factor ) ); + + #endif + + OUT_col = hdrEncode( OUT ); + +#endif +} diff --git a/Templates/BaseGame/game/data/shaders/common/water/gl/waterBasicV.glsl b/Templates/BaseGame/game/data/shaders/common/water/gl/waterBasicV.glsl new file mode 100644 index 000000000..e92c948e9 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/water/gl/waterBasicV.glsl @@ -0,0 +1,243 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../gl/hlslCompat.glsl" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +// TexCoord 0 and 1 (xy,zw) for ripple texture lookup +out vec4 rippleTexCoord01; +#define OUT_rippleTexCoord01 rippleTexCoord01 + +// TexCoord 2 for ripple texture lookup +out vec2 rippleTexCoord2; +#define OUT_rippleTexCoord2 rippleTexCoord2 + +// Screenspace vert position BEFORE wave transformation +out vec4 posPreWave; +#define OUT_posPreWave posPreWave + +// Screenspace vert position AFTER wave transformation +out vec4 posPostWave; +#define OUT_posPostWave posPostWave + +// Worldspace unit distance/depth of this vertex/pixel +out float pixelDist; +#define OUT_pixelDist pixelDist + +out vec4 objPos; +#define OUT_objPos objPos + +out vec3 misc; +#define OUT_misc misc + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform mat4 modelMat; +uniform mat4 modelview; +uniform vec4 rippleMat[3]; +uniform vec3 eyePos; +uniform vec2 waveDir[3]; +uniform vec2 waveData[3]; +uniform vec2 rippleDir[3]; +uniform vec2 rippleTexScale[3]; +uniform vec3 rippleSpeed; +uniform vec3 inLightVec; +uniform vec3 reflectNormal; +uniform float gridElementSize; +uniform float elapsedTime; +uniform float undulateMaxDist; + +in vec4 vPosition; +in vec3 vNormal; +in vec2 vTexCoord0; +in vec4 vTexCoord1; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + vec4 IN_position = vPosition; + vec3 IN_normal = vNormal; + vec2 IN_undulateData = vTexCoord0; + vec4 IN_horizonFactor = vTexCoord1; + vec4 OUT_hpos = vec4(0); + + // use projection matrix for reflection / refraction texture coords + mat4 texGen = mat4FromRow( 0.5, 0.0, 0.0, 0.5, + 0.0, -0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 ); + + // Move the vertex based on the horizonFactor if specified to do so for this vert. + // if ( IN_horizonFactor.z > 0 ) + // { + // vec2 offsetXY = eyePos.xy - eyePos.xy % gridElementSize; + // IN_position.xy += offsetXY; + // IN_undulateData += offsetXY; + // } + + vec4 worldPos = tMul( modelMat, IN_position ); + + IN_position.z = mix( IN_position.z, eyePos.z, IN_horizonFactor.x ); + + //OUT_objPos = worldPos; + OUT_objPos.xyz = IN_position.xyz; + OUT_objPos.w = worldPos.z; + + // Send pre-undulation screenspace position + OUT_posPreWave = tMul( modelview, IN_position ); + OUT_posPreWave = tMul( texGen, OUT_posPreWave ); + + // Calculate the undulation amount for this vertex. + vec2 undulatePos = tMul( modelMat, vec4( IN_undulateData.xy, 0, 1 ) ).xy; + //if ( undulatePos.x < 0 ) + // undulatePos = IN_position.xy; + + float undulateAmt = 0.0; + + undulateAmt += waveData[0].y * sin( elapsedTime * waveData[0].x + + undulatePos.x * waveDir[0].x + + undulatePos.y * waveDir[0].y ); + undulateAmt += waveData[1].y * sin( elapsedTime * waveData[1].x + + undulatePos.x * waveDir[1].x + + undulatePos.y * waveDir[1].y ); + undulateAmt += waveData[2].y * sin( elapsedTime * waveData[2].x + + undulatePos.x * waveDir[2].x + + undulatePos.y * waveDir[2].y ); + + float undulateFade = 1; + + // Scale down wave magnitude amount based on distance from the camera. + float dist = distance( IN_position.xyz, eyePos ); + dist = clamp( dist, 1.0, undulateMaxDist ); + undulateFade *= ( 1 - dist / undulateMaxDist ); + + // Also scale down wave magnitude if the camera is very very close. + undulateFade *= saturate( ( distance( IN_position.xyz, eyePos ) - 0.5 ) / 10.0 ); + + undulateAmt *= undulateFade; + + //#endif + //undulateAmt = 0; + + // Apply wave undulation to the vertex. + OUT_posPostWave = IN_position; + OUT_posPostWave.xyz += IN_normal.xyz * undulateAmt; + + // Save worldSpace position of this pixel/vert + //OUT_worldPos = OUT_posPostWave.xyz; + //OUT_worldPos = tMul( modelMat, OUT_posPostWave.xyz ); + //OUT_worldPos.z += objTrans[2][2]; //91.16; + + // OUT_misc.w = tMul( modelMat, OUT_fogPos ).z; + // if ( IN_horizonFactor.x > 0 ) + // { + // vec3 awayVec = normalize( OUT_fogPos.xyz - eyePos ); + // OUT_fogPos.xy += awayVec.xy * 1000.0; + // } + + // Convert to screen + OUT_posPostWave = tMul( modelview, OUT_posPostWave ); // tMul( modelview, vec4( OUT_posPostWave.xyz, 1 ) ); + + // Setup the OUT position symantic variable + OUT_hpos = OUT_posPostWave; // tMul( modelview, vec4( IN_position.xyz, 1 ) ); //vec4( OUT_posPostWave.xyz, 1 ); + //OUT_hpos.z = mix( OUT_hpos.z, OUT_hpos.w, IN_horizonFactor.x ); + + // Save world space camera dist/depth of the outgoing pixel + OUT_pixelDist = OUT_hpos.z; + + // Convert to reflection texture space + OUT_posPostWave = tMul( texGen, OUT_posPostWave ); + + vec2 txPos = undulatePos; + if ( bool(IN_horizonFactor.x) ) + txPos = normalize( txPos ) * 50000.0; + + // set up tex coordinates for the 3 interacting normal maps + OUT_rippleTexCoord01.xy = txPos * rippleTexScale[0]; + OUT_rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x; + + mat2 texMat; + texMat[0][0] = rippleMat[0].x; + texMat[1][0] = rippleMat[0].y; + texMat[0][1] = rippleMat[0].z; + texMat[1][1] = rippleMat[0].w; + OUT_rippleTexCoord01.xy = tMul( texMat, OUT_rippleTexCoord01.xy ); + + OUT_rippleTexCoord01.zw = txPos * rippleTexScale[1]; + OUT_rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y; + + texMat[0][0] = rippleMat[1].x; + texMat[1][0] = rippleMat[1].y; + texMat[0][1] = rippleMat[1].z; + texMat[1][1] = rippleMat[1].w; + OUT_rippleTexCoord01.zw = tMul( texMat, OUT_rippleTexCoord01.zw ); + + OUT_rippleTexCoord2.xy = txPos * rippleTexScale[2]; + OUT_rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z; + + texMat[0][0] = rippleMat[2].x; + texMat[1][0] = rippleMat[2].y; + texMat[0][1] = rippleMat[2].z; + texMat[1][1] = rippleMat[2].w; + OUT_rippleTexCoord2.xy = tMul( texMat, OUT_rippleTexCoord2.xy ); + +#ifdef WATER_SPEC + + vec3 binormal = vec3( 1, 0, 0 ); + vec3 tangent = vec3( 0, 1, 0 ); + vec3 normal; + for ( int i = 0; i < 3; i++ ) + { + binormal.z += undulateFade * waveDir[i].x * waveData[i].y * cos( waveDir[i].x * IN_undulateData.x + waveDir[i].y * IN_undulateData.y + elapsedTime * waveData[i].x ); + tangent.z += undulateFade * waveDir[i].y * waveData[i].y * cos( waveDir[i].x * IN_undulateData.x + waveDir[i].y * IN_undulateData.y + elapsedTime * waveData[i].x ); + } + + binormal = normalize( binormal ); + tangent = normalize( tangent ); + normal = cross( binormal, tangent ); + + mat3 worldToTangent; + worldToTangent[0] = binormal; + worldToTangent[1] = tangent; + worldToTangent[2] = normal; + + worldToTangent = transpose(worldToTangent); + + OUT_misc.xyz = tMul( inLightVec, modelMat ); + OUT_misc.xyz = tMul( worldToTangent, OUT_misc.xyz ); + +#else + + OUT_misc.xyz = inLightVec; + +#endif + + gl_Position = OUT_hpos; + correctSSP(gl_Position); +} + diff --git a/Templates/BaseGame/game/data/shaders/common/water/gl/waterP.glsl b/Templates/BaseGame/game/data/shaders/common/water/gl/waterP.glsl new file mode 100644 index 000000000..5f722282c --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/water/gl/waterP.glsl @@ -0,0 +1,397 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../gl/torque.glsl" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +#define PIXEL_DIST IN_rippleTexCoord2.z +// miscParams +#define FRESNEL_BIAS miscParams[0] +#define FRESNEL_POWER miscParams[1] +// miscParams[2] is unused +#define ISRIVER miscParams[3] + +// reflectParams +#define REFLECT_PLANE_Z reflectParams[0] +#define REFLECT_MIN_DIST reflectParams[1] +#define REFLECT_MAX_DIST reflectParams[2] +#define NO_REFLECT reflectParams[3] + +// fogParams +#define FOG_DENSITY fogParams[0] +#define FOG_DENSITY_OFFSET fogParams[1] + +// wetnessParams +#define WET_DEPTH wetnessParams[0] +#define WET_COLOR_FACTOR wetnessParams[1] + +// distortionParams +#define DISTORT_START_DIST distortionParams[0] +#define DISTORT_END_DIST distortionParams[1] +#define DISTORT_FULL_DEPTH distortionParams[2] + +// foamParams +#define FOAM_OPACITY foamParams[0] +#define FOAM_MAX_DEPTH foamParams[1] +#define FOAM_AMBIENT_LERP foamParams[2] +#define FOAM_RIPPLE_INFLUENCE foamParams[3] + +// specularParams +#define SPEC_POWER specularParams[3] +#define SPEC_COLOR specularParams.xyz + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- + +//ConnectData IN + +in vec4 hpos; + +// TexCoord 0 and 1 (xy,zw) for ripple texture lookup +in vec4 rippleTexCoord01; + +// xy is TexCoord 2 for ripple texture lookup +// z is the Worldspace unit distance/depth of this vertex/pixel +// w is amount of the crestFoam ( more at crest of waves ). +in vec4 rippleTexCoord2; + +// Screenspace vert position BEFORE wave transformation +in vec4 posPreWave; + +// Screenspace vert position AFTER wave transformation +in vec4 posPostWave; + +// Objectspace vert position BEFORE wave transformation +// w coord is world space z position. +in vec4 objPos; + +in vec4 foamTexCoords; + +in mat3 tangentMat; + + +#define IN_hpos hpos +#define IN_rippleTexCoord01 rippleTexCoord01 +#define IN_rippleTexCoord2 rippleTexCoord2 +#define IN_posPreWave posPreWave +#define IN_posPostWave posPostWave +#define IN_objPos objPos +#define IN_foamTexCoords foamTexCoords +#define IN_tangentMat tangentMat + +//----------------------------------------------------------------------------- +// approximate Fresnel function +//----------------------------------------------------------------------------- +float fresnel(float NdotV, float bias, float power) +{ + return bias + (1.0-bias)*pow(abs(1.0 - max(NdotV, 0)), power); +} + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform sampler2D bumpMap; +uniform sampler2D prepassTex; +uniform sampler2D reflectMap; +uniform sampler2D refractBuff; +uniform samplerCube skyMap; +uniform sampler2D foamMap; +uniform sampler1D depthGradMap; +uniform vec4 specularParams; +uniform vec4 baseColor; +uniform vec4 miscParams; +uniform vec2 fogParams; +uniform vec4 reflectParams; +uniform vec3 reflectNormal; +uniform vec2 wetnessParams; +uniform float farPlaneDist; +uniform vec3 distortionParams; +uniform vec4 foamParams; +uniform vec3 ambientColor; +uniform vec3 eyePos; // This is in object space! +uniform vec3 fogData; +uniform vec4 fogColor; +uniform vec4 rippleMagnitude; +uniform vec4 rtParams1; +uniform float depthGradMax; +uniform vec3 inLightVec; +uniform mat4 modelMat; +uniform vec4 sunColor; +uniform float sunBrightness; +uniform float reflectivity; + +out vec4 OUT_col; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + // Get the bumpNorm... + vec3 bumpNorm = ( texture( bumpMap, IN_rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x; + bumpNorm += ( texture( bumpMap, IN_rippleTexCoord01.zw ).rgb * 2.0 - 1.0 ) * rippleMagnitude.y; + bumpNorm += ( texture( bumpMap, IN_rippleTexCoord2.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.z; + + bumpNorm = normalize( bumpNorm ); + bumpNorm = mix( bumpNorm, vec3(0,0,1), 1.0 - rippleMagnitude.w ); + bumpNorm = tMul( bumpNorm, IN_tangentMat ); + + // Get depth of the water surface (this pixel). + // Convert from WorldSpace to EyeSpace. + float pixelDepth = PIXEL_DIST / farPlaneDist; + + vec2 prepassCoord = viewportCoordToRenderTarget( IN_posPostWave, rtParams1 ); + + float startDepth = prepassUncondition( prepassTex, prepassCoord ).w; + + // The water depth in world units of the undistorted pixel. + float startDelta = ( startDepth - pixelDepth ); + startDelta = max( startDelta, 0.0 ); + startDelta *= farPlaneDist; + + // Calculate the distortion amount for the water surface. + // + // We subtract a little from it so that we don't + // distort where the water surface intersects the + // camera near plane. + float distortAmt = saturate( ( PIXEL_DIST - DISTORT_START_DIST ) / DISTORT_END_DIST ); + + // Scale down distortion in shallow water. + distortAmt *= saturate( startDelta / DISTORT_FULL_DEPTH ); + + // Do the intial distortion... we might remove it below. + vec2 distortDelta = bumpNorm.xy * distortAmt; + vec4 distortPos = IN_posPostWave; + distortPos.xy += distortDelta; + + prepassCoord = viewportCoordToRenderTarget( distortPos, rtParams1 ); + + // Get prepass depth at the position of this distorted pixel. + float prepassDepth = prepassUncondition( prepassTex, prepassCoord ).w; + if ( prepassDepth > 0.99 ) + prepassDepth = 5.0; + + float delta = ( prepassDepth - pixelDepth ) * farPlaneDist; + + if ( delta < 0.0 ) + { + // If we got a negative delta then the distorted + // sample is above the water surface. Mask it out + // by removing the distortion. + distortPos = IN_posPostWave; + delta = startDelta; + distortAmt = 0; + } + else + { + float diff = ( prepassDepth - startDepth ) * farPlaneDist; + + if ( diff < 0 ) + { + distortAmt = saturate( ( PIXEL_DIST - DISTORT_START_DIST ) / DISTORT_END_DIST ); + distortAmt *= saturate( delta / DISTORT_FULL_DEPTH ); + + distortDelta = bumpNorm.xy * distortAmt; + + distortPos = IN_posPostWave; + distortPos.xy += distortDelta; + + prepassCoord = viewportCoordToRenderTarget( distortPos, rtParams1 ); + + // Get prepass depth at the position of this distorted pixel. + prepassDepth = prepassUncondition( prepassTex, prepassCoord ).w; + if ( prepassDepth > 0.99 ) + prepassDepth = 5.0; + delta = ( prepassDepth - pixelDepth ) * farPlaneDist; + } + + if ( delta < 0.1 ) + { + // If we got a negative delta then the distorted + // sample is above the water surface. Mask it out + // by removing the distortion. + distortPos = IN_posPostWave; + delta = startDelta; + distortAmt = 0; + } + } + + vec4 temp = IN_posPreWave; + temp.xy += bumpNorm.xy * distortAmt; + vec2 reflectCoord = viewportCoordToRenderTarget( temp, rtParams1 ); + + vec2 refractCoord = viewportCoordToRenderTarget( distortPos, rtParams1 ); + + vec4 fakeColor = vec4(ambientColor,1); + vec3 eyeVec = IN_objPos.xyz - eyePos; + eyeVec = tMul( mat3(modelMat), eyeVec ); + eyeVec = tMul( IN_tangentMat, eyeVec ); + vec3 reflectionVec = reflect( eyeVec, bumpNorm ); + + // Use fakeColor for ripple-normals that are angled towards the camera + eyeVec = -eyeVec; + eyeVec = normalize( eyeVec ); + float ang = saturate( dot( eyeVec, bumpNorm ) ); + float fakeColorAmt = ang; + + // for verts far from the reflect plane z position + float rplaneDist = abs( REFLECT_PLANE_Z - IN_objPos.w ); + rplaneDist = saturate( ( rplaneDist - 1.0 ) / 2.0 ); + rplaneDist *= ISRIVER; + fakeColorAmt = max( fakeColorAmt, rplaneDist ); + +#ifndef UNDERWATER + + // Get foam color and amount + vec2 foamRippleOffset = bumpNorm.xy * FOAM_RIPPLE_INFLUENCE; + vec4 IN_foamTexCoords = IN_foamTexCoords; + IN_foamTexCoords.xy += foamRippleOffset; + IN_foamTexCoords.zw += foamRippleOffset; + + vec4 foamColor = texture( foamMap, IN_foamTexCoords.xy ); + foamColor += texture( foamMap, IN_foamTexCoords.zw ); + foamColor = saturate( foamColor ); + + // Modulate foam color by ambient color + // so we don't have glowing white foam at night. + foamColor.rgb = mix( foamColor.rgb, ambientColor.rgb, FOAM_AMBIENT_LERP ); + + float foamDelta = saturate( delta / FOAM_MAX_DEPTH ); + float foamAmt = 1 - pow( foamDelta, 2 ); + + // Fade out the foam in very very low depth, + // this improves the shoreline a lot. + float diff = 0.8 - foamAmt; + if ( diff < 0.0 ) + foamAmt -= foamAmt * abs( diff ) / 0.2; + + foamAmt *= FOAM_OPACITY * foamColor.a; + + foamColor.rgb *= FOAM_OPACITY * foamAmt * foamColor.a; + + // Get reflection map color. + vec4 refMapColor = texture( reflectMap, reflectCoord ); + + // If we do not have a reflection texture then we use the cubemap. + refMapColor = mix( refMapColor, texture( skyMap, reflectionVec ), NO_REFLECT ); + + fakeColor = ( texture( skyMap, reflectionVec ) ); + fakeColor.a = 1; + // Combine reflection color and fakeColor. + vec4 reflectColor = mix( refMapColor, fakeColor, fakeColorAmt ); + + // Get refract color + vec4 refractColor = hdrDecode( texture( refractBuff, refractCoord ) ); + + // We darken the refraction color a bit to make underwater + // elements look wet. We fade out this darkening near the + // surface in order to not have hard water edges. + // @param WET_DEPTH The depth in world units at which full darkening will be recieved. + // @param WET_COLOR_FACTOR The refract color is scaled down by this amount when at WET_DEPTH + refractColor.rgb *= 1.0f - ( saturate( delta / WET_DEPTH ) * WET_COLOR_FACTOR ); + + // Add Water fog/haze. + float fogDelta = delta - FOG_DENSITY_OFFSET; + + if ( fogDelta < 0.0 ) + fogDelta = 0.0; + float fogAmt = 1.0 - saturate( exp( -FOG_DENSITY * fogDelta ) ); + + // Calculate the water "base" color based on depth. + vec4 waterBaseColor = baseColor * texture( depthGradMap, saturate( delta / depthGradMax ) ); + waterBaseColor = toLinear(waterBaseColor); + + // Modulate baseColor by the ambientColor. + waterBaseColor *= vec4( ambientColor.rgb, 1 ); + + // calc "diffuse" color by lerping from the water color + // to refraction image based on the water clarity. + vec4 diffuseColor = mix( refractColor, waterBaseColor, fogAmt ); + + // fresnel calculation + float fresnelTerm = fresnel( ang, FRESNEL_BIAS, FRESNEL_POWER ); + + // Scale the frensel strength by fog amount + // so that parts that are very clear get very little reflection. + fresnelTerm *= fogAmt; + + // Also scale the frensel by our distance to the + // water surface. This removes the hard reflection + // when really close to the water surface. + fresnelTerm *= saturate( PIXEL_DIST - 0.1 ); + + fresnelTerm *= reflectivity; + + // Combine the diffuse color and reflection image via the + // fresnel term and set out output color. + vec4 OUT = mix( diffuseColor, reflectColor, fresnelTerm ); + + vec3 lightVec = inLightVec; + + // Get some specular reflection. + vec3 newbump = bumpNorm; + newbump.xy *= 3.5; + newbump = normalize( newbump ); + vec3 halfAng = normalize( eyeVec + -lightVec ); + float specular = saturate( dot( newbump, halfAng ) ); + specular = pow( specular, SPEC_POWER ); + + // Scale down specularity in very shallow water to improve the transparency of the shoreline. + specular *= saturate( delta / 2 ); + OUT.rgb = OUT.rgb + ( SPEC_COLOR * vec3(specular) ); + +#else + + vec4 refractColor = hdrDecode( texture( refractBuff, refractCoord ) ); + vec4 OUT = refractColor; + +#endif + +#ifndef UNDERWATER + + OUT.rgb = OUT.rgb + foamColor.rgb; + + float factor = computeSceneFog( eyePos, + IN_objPos.xyz, + IN_objPos.w, + fogData.x, + fogData.y, + fogData.z ); + + OUT.rgb = mix( OUT.rgb, fogColor.rgb, 1.0 - saturate( factor ) ); + + //OUT.rgb = fogColor.rgb; + +#endif + + OUT.a = 1.0; + + //return OUT; + + OUT_col = hdrEncode( OUT ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/water/gl/waterV.glsl b/Templates/BaseGame/game/data/shaders/common/water/gl/waterV.glsl new file mode 100644 index 000000000..490af63a7 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/water/gl/waterV.glsl @@ -0,0 +1,241 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct VertData +{ + vec4 position ;// POSITION; + vec3 normal ;// NORMAL; + vec2 undulateData ;// TEXCOORD0; + vec4 horizonFactor ;// TEXCOORD1; +}; + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- +//VertData IN +in vec4 vPosition; +in vec3 vNormal; +in vec2 vTexCoord0; +in vec4 vTexCoord1; + +#define IN_position_ vPosition +#define IN_normal vNormal +#define IN_undulateData vTexCoord0 +#define IN_horizonFactor vTexCoord1 + +//ConnectData OUT +// + out vec4 hpos ; + +// TexCoord 0 and 1 (xy,zw) for ripple texture lookup +out vec4 rippleTexCoord01; + + // xy is TexCoord 2 for ripple texture lookup + // z is the Worldspace unit distance/depth of this vertex/pixel + // w is amount of the crestFoam ( more at crest of waves ). + out vec4 rippleTexCoord2 ; + +// Screenspace vert position BEFORE wave transformation +out vec4 posPreWave; + +// Screenspace vert position AFTER wave transformation +out vec4 posPostWave; + + // Objectspace vert position BEFORE wave transformation + // w coord is world space z position. + out vec4 objPos ; + + out vec4 foamTexCoords ; + + out mat3 tangentMat ; +// + +#define OUT_hpos hpos +#define OUT_rippleTexCoord01 rippleTexCoord01 +#define OUT_rippleTexCoord2 rippleTexCoord2 +#define OUT_posPreWave posPreWave +#define OUT_posPostWave posPostWave +#define OUT_objPos objPos +#define OUT_foamTexCoords foamTexCoords +#define OUT_tangentMat tangentMat + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform mat4 modelMat; +uniform mat4 modelview; +uniform vec4 rippleMat[3]; +uniform vec3 eyePos; +uniform vec2 waveDir[3]; +uniform vec2 waveData[3]; +uniform vec2 rippleDir[3]; +uniform vec2 rippleTexScale[3]; +uniform vec3 rippleSpeed; +uniform vec4 foamDir; +uniform vec4 foamTexScale; +uniform vec2 foamSpeed; +uniform vec3 inLightVec; +uniform float gridElementSize; +uniform float elapsedTime; +uniform float undulateMaxDist; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + vec4 IN_position = IN_position_; + + // use projection matrix for reflection / refraction texture coords + mat4 texGen = mat4FromRow( 0.5, 0.0, 0.0, 0.5, + 0.0, -0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 ); + + IN_position.z = mix( IN_position.z, eyePos.z, IN_horizonFactor.x ); + + OUT_objPos = IN_position; + OUT_objPos.w = tMul( modelMat, IN_position ).z; + + // Send pre-undulation screenspace position + OUT_posPreWave = tMul( modelview, IN_position ); + OUT_posPreWave = tMul( texGen, OUT_posPreWave ); + + // Calculate the undulation amount for this vertex. + vec2 undulatePos = tMul( modelMat, vec4 ( IN_undulateData.xy, 0, 1 ) ).xy; + float undulateAmt = 0.0; + + undulateAmt += waveData[0].y * sin( elapsedTime * waveData[0].x + + undulatePos.x * waveDir[0].x + + undulatePos.y * waveDir[0].y ); + undulateAmt += waveData[1].y * sin( elapsedTime * waveData[1].x + + undulatePos.x * waveDir[1].x + + undulatePos.y * waveDir[1].y ); + undulateAmt += waveData[2].y * sin( elapsedTime * waveData[2].x + + undulatePos.x * waveDir[2].x + + undulatePos.y * waveDir[2].y ); + + float undulateFade = 1; + + // Scale down wave magnitude amount based on distance from the camera. + float dist = distance( IN_position.xyz, eyePos ); + dist = clamp( dist, 1.0, undulateMaxDist ); + undulateFade *= ( 1 - dist / undulateMaxDist ); + + // Also scale down wave magnitude if the camera is very very close. + undulateFade *= saturate( ( distance( IN_position.xyz, eyePos ) - 0.5 ) / 10.0 ); + + undulateAmt *= undulateFade; + + OUT_rippleTexCoord2.w = undulateAmt / ( waveData[0].y + waveData[1].y + waveData[2].y ); + OUT_rippleTexCoord2.w = saturate( OUT_rippleTexCoord2.w - 0.2 ) / 0.8; + + // Apply wave undulation to the vertex. + OUT_posPostWave = IN_position; + OUT_posPostWave.xyz += IN_normal.xyz * undulateAmt; + + // Convert to screen + OUT_posPostWave = tMul( modelview, OUT_posPostWave ); + + // Setup the OUT position symantic variable + OUT_hpos = OUT_posPostWave; + //OUT_hpos.z = mix( OUT_hpos.z, OUT_hpos.w, IN_horizonFactor.x ); + + // if ( IN_horizonFactor.x > 0 ) + // { + // vec3 awayVec = normalize( OUT_objPos.xyz - eyePos ); + // OUT_objPos.xy += awayVec.xy * 1000.0; + // } + + // Save world space camera dist/depth of the outgoing pixel + OUT_rippleTexCoord2.z = OUT_hpos.z; + + // Convert to reflection texture space + OUT_posPostWave = tMul( texGen, OUT_posPostWave ); + + vec2 txPos = undulatePos; + if ( bool(IN_horizonFactor.x) ) + txPos = normalize( txPos ) * 50000.0; + + // set up tex coordinates for the 3 interacting normal maps + OUT_rippleTexCoord01.xy = txPos * rippleTexScale[0]; + OUT_rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x; + + mat2 texMat; + texMat[0][0] = rippleMat[0].x; + texMat[1][0] = rippleMat[0].y; + texMat[0][1] = rippleMat[0].z; + texMat[1][1] = rippleMat[0].w; + OUT_rippleTexCoord01.xy = tMul( texMat, OUT_rippleTexCoord01.xy ); + + OUT_rippleTexCoord01.zw = txPos * rippleTexScale[1]; + OUT_rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y; + + texMat[0][0] = rippleMat[1].x; + texMat[1][0] = rippleMat[1].y; + texMat[0][1] = rippleMat[1].z; + texMat[1][1] = rippleMat[1].w; + OUT_rippleTexCoord01.zw = tMul( texMat, OUT_rippleTexCoord01.zw ); + + OUT_rippleTexCoord2.xy = txPos * rippleTexScale[2]; + OUT_rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z; + + texMat[0][0] = rippleMat[2].x; + texMat[1][0] = rippleMat[2].y; + texMat[0][1] = rippleMat[2].z; + texMat[1][1] = rippleMat[2].w; + OUT_rippleTexCoord2.xy = tMul( texMat, OUT_rippleTexCoord2.xy ); + + OUT_foamTexCoords.xy = txPos * foamTexScale.xy + foamDir.xy * foamSpeed.x * elapsedTime; + OUT_foamTexCoords.zw = txPos * foamTexScale.zw + foamDir.zw * foamSpeed.y * elapsedTime; + + + vec3 binormal = vec3 ( 1, 0, 0 ); + vec3 tangent = vec3 ( 0, 1, 0 ); + vec3 normal; + for ( int i = 0; i < 3; i++ ) + { + binormal.z += undulateFade * waveDir[i].x * waveData[i].y * cos( waveDir[i].x * undulatePos.x + waveDir[i].y * undulatePos.y + elapsedTime * waveData[i].x ); + tangent.z += undulateFade * waveDir[i].y * waveData[i].y * cos( waveDir[i].x * undulatePos.x + waveDir[i].y * undulatePos.y + elapsedTime * waveData[i].x ); + } + + binormal = binormal; + tangent = tangent; + normal = cross( binormal, tangent ); + + mat3 worldToTangent; + worldToTangent[0] = binormal; + worldToTangent[1] = tangent; + worldToTangent[2] = normal; + + OUT_tangentMat = transpose(worldToTangent); + + gl_Position = OUT_hpos; + correctSSP(gl_Position); +} + diff --git a/Templates/BaseGame/game/data/shaders/common/water/waterBasicP.hlsl b/Templates/BaseGame/game/data/shaders/common/water/waterBasicP.hlsl new file mode 100644 index 000000000..efb437779 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/water/waterBasicP.hlsl @@ -0,0 +1,214 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../torque.hlsl" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +// miscParams +#define FRESNEL_BIAS miscParams[0] +#define FRESNEL_POWER miscParams[1] +#define CLARITY miscParams[2] +#define ISRIVER miscParams[3] + +// reflectParams +#define REFLECT_PLANE_Z reflectParams[0] +#define REFLECT_MIN_DIST reflectParams[1] +#define REFLECT_MAX_DIST reflectParams[2] +#define NO_REFLECT reflectParams[3] + +// distortionParams +#define DISTORT_START_DIST distortionParams[0] +#define DISTORT_END_DIST distortionParams[1] +#define DISTORT_FULL_DEPTH distortionParams[2] + +// ConnectData.misc +#define LIGHT_VEC IN.misc.xyz +#define WORLD_Z IN.objPos.w + +// specularParams +#define SPEC_POWER specularParams[3] +#define SPEC_COLOR specularParams.xyz + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + + // TexCoord 0 and 1 (xy,zw) for ripple texture lookup + float4 rippleTexCoord01 : TEXCOORD0; + + // TexCoord 2 for ripple texture lookup + float2 rippleTexCoord2 : TEXCOORD1; + + // Screenspace vert position BEFORE wave transformation + float4 posPreWave : TEXCOORD2; + + // Screenspace vert position AFTER wave transformation + float4 posPostWave : TEXCOORD3; + + // Worldspace unit distance/depth of this vertex/pixel + float pixelDist : TEXCOORD4; + + // Objectspace vert position BEFORE wave transformation + // w coord is world space z position. + float4 objPos : TEXCOORD5; + + float3 misc : TEXCOORD6; +}; + +//----------------------------------------------------------------------------- +// approximate Fresnel function +//----------------------------------------------------------------------------- +float fresnel(float NdotV, float bias, float power) +{ + return bias + (1.0-bias)*pow(abs(1.0 - max(NdotV, 0)), power); +} + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +TORQUE_UNIFORM_SAMPLER2D(bumpMap,0); +//uniform sampler2D prepassTex : register( S1 ); +TORQUE_UNIFORM_SAMPLER2D(reflectMap,2); +TORQUE_UNIFORM_SAMPLER2D(refractBuff,3); +TORQUE_UNIFORM_SAMPLERCUBE(skyMap,4); +//uniform sampler foamMap : register( S5 ); +uniform float4 baseColor; +uniform float4 miscParams; +uniform float4 reflectParams; +uniform float3 ambientColor; +uniform float3 eyePos; +uniform float3 distortionParams; +uniform float3 fogData; +uniform float4 fogColor; +uniform float4 rippleMagnitude; +uniform float4 specularParams; +uniform float4x4 modelMat; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +float4 main( ConnectData IN ) : TORQUE_TARGET0 +{ + // Modulate baseColor by the ambientColor. + float4 waterBaseColor = baseColor * float4( ambientColor.rgb, 1 ); + waterBaseColor = toLinear(waterBaseColor); + + // Get the bumpNorm... + float3 bumpNorm = ( TORQUE_TEX2D( bumpMap, IN.rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x; + bumpNorm += ( TORQUE_TEX2D( bumpMap, IN.rippleTexCoord01.zw ).rgb * 2.0 - 1.0 ) * rippleMagnitude.y; + bumpNorm += ( TORQUE_TEX2D( bumpMap, IN.rippleTexCoord2 ).rgb * 2.0 - 1.0 ) * rippleMagnitude.z; + + bumpNorm = normalize( bumpNorm ); + bumpNorm = lerp( bumpNorm, float3(0,0,1), 1.0 - rippleMagnitude.w ); + + // We subtract a little from it so that we don't + // distort where the water surface intersects the + // camera near plane. + float distortAmt = saturate( IN.pixelDist / 1.0 ) * 0.8; + + float4 distortPos = IN.posPostWave; + distortPos.xy += bumpNorm.xy * distortAmt; + + #ifdef UNDERWATER + return hdrEncode( TORQUE_TEX2DPROJ( refractBuff, distortPos ) ); + #else + + float3 eyeVec = IN.objPos.xyz - eyePos; + eyeVec = mul( (float3x3)modelMat, eyeVec ); + float3 reflectionVec = reflect( eyeVec, bumpNorm ); + + // Color that replaces the reflection color when we do not + // have one that is appropriate. + float4 fakeColor = float4(ambientColor,1); + + // Use fakeColor for ripple-normals that are angled towards the camera + eyeVec = -eyeVec; + eyeVec = normalize( eyeVec ); + float ang = saturate( dot( eyeVec, bumpNorm ) ); + float fakeColorAmt = ang; + + // Get reflection map color + float4 refMapColor = hdrDecode( TORQUE_TEX2DPROJ( reflectMap, distortPos ) ); + // If we do not have a reflection texture then we use the cubemap. + refMapColor = lerp( refMapColor, TORQUE_TEXCUBE( skyMap, reflectionVec ), NO_REFLECT ); + + // Combine reflection color and fakeColor. + float4 reflectColor = lerp( refMapColor, fakeColor, fakeColorAmt ); + //return refMapColor; + + // Get refract color + float4 refractColor = hdrDecode( TORQUE_TEX2DPROJ( refractBuff, distortPos ) ); + + // calc "diffuse" color by lerping from the water color + // to refraction image based on the water clarity. + float4 diffuseColor = lerp( refractColor, waterBaseColor, 1.0f - CLARITY ); + + // fresnel calculation + float fresnelTerm = fresnel( ang, FRESNEL_BIAS, FRESNEL_POWER ); + //return float4( fresnelTerm.rrr, 1 ); + + // Also scale the frensel by our distance to the + // water surface. This removes the hard reflection + // when really close to the water surface. + fresnelTerm *= saturate( IN.pixelDist - 0.1 ); + + // Combine the diffuse color and reflection image via the + // fresnel term and set out output color. + float4 OUT = lerp( diffuseColor, reflectColor, fresnelTerm ); + + #ifdef WATER_SPEC + + // Get some specular reflection. + float3 newbump = bumpNorm; + newbump.xy *= 3.5; + newbump = normalize( bumpNorm ); + half3 halfAng = normalize( eyeVec + -LIGHT_VEC ); + float specular = saturate( dot( newbump, halfAng ) ); + specular = pow( specular, SPEC_POWER ); + + OUT.rgb = OUT.rgb + ( SPEC_COLOR * specular.xxx ); + + #else // Disable fogging if spec is on because otherwise we run out of instructions. + + // Fog it. + float factor = computeSceneFog( eyePos, + IN.objPos.xyz, + WORLD_Z, + fogData.x, + fogData.y, + fogData.z ); + + //OUT.rgb = lerp( OUT.rgb, fogColor.rgb, 1.0 - saturate( factor ) ); + + #endif + + return hdrEncode( OUT ); + +#endif +} diff --git a/Templates/BaseGame/game/data/shaders/common/water/waterBasicV.hlsl b/Templates/BaseGame/game/data/shaders/common/water/waterBasicV.hlsl new file mode 100644 index 000000000..310647c90 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/water/waterBasicV.hlsl @@ -0,0 +1,237 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../shaderModel.hlsl" +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct VertData +{ + float3 position : POSITION; + float3 normal : NORMAL; + float2 undulateData : TEXCOORD0; + float4 horizonFactor : TEXCOORD1; +}; + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + + // TexCoord 0 and 1 (xy,zw) for ripple texture lookup + float4 rippleTexCoord01 : TEXCOORD0; + + // TexCoord 2 for ripple texture lookup + float2 rippleTexCoord2 : TEXCOORD1; + + // Screenspace vert position BEFORE wave transformation + float4 posPreWave : TEXCOORD2; + + // Screenspace vert position AFTER wave transformation + float4 posPostWave : TEXCOORD3; + + // Worldspace unit distance/depth of this vertex/pixel + float pixelDist : TEXCOORD4; + + // Objectspace vert position BEFORE wave transformation + // w coord is world space z position. + float4 objPos : TEXCOORD5; + + float3 misc : TEXCOORD6; +}; + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform float4x4 modelMat; +uniform float4x4 modelview; +uniform float4 rippleMat[3]; +uniform float3 eyePos; +uniform float2 waveDir[3]; +uniform float2 waveData[3]; +uniform float2 rippleDir[3]; +uniform float2 rippleTexScale[3]; +uniform float3 rippleSpeed; +uniform float3 inLightVec; +uniform float3 reflectNormal; +uniform float gridElementSize; +uniform float elapsedTime; +uniform float undulateMaxDist; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN ) +{ + ConnectData OUT; + + // use projection matrix for reflection / refraction texture coords + float4x4 texGen = { 0.5, 0.0, 0.0, 0.5, + 0.0, -0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 }; + + // Move the vertex based on the horizonFactor if specified to do so for this vert. + // if ( IN.horizonFactor.z > 0 ) + // { + // float2 offsetXY = eyePos.xy - eyePos.xy % gridElementSize; + // IN.position.xy += offsetXY; + // IN.undulateData += offsetXY; + // } + float4 inPos = float4(IN.position, 1.0); + float4 worldPos = mul(modelMat, inPos); + + IN.position.z = lerp( IN.position.z, eyePos.z, IN.horizonFactor.x ); + + //OUT.objPos = worldPos; + OUT.objPos.xyz = IN.position; + OUT.objPos.w = worldPos.z; + + // Send pre-undulation screenspace position + OUT.posPreWave = mul( modelview, inPos ); + OUT.posPreWave = mul( texGen, OUT.posPreWave ); + + // Calculate the undulation amount for this vertex. + float2 undulatePos = mul( modelMat, float4( IN.undulateData.xy, 0, 1 )).xy; + //if ( undulatePos.x < 0 ) + // undulatePos = IN.position.xy; + + float undulateAmt = 0.0; + + undulateAmt += waveData[0].y * sin( elapsedTime * waveData[0].x + + undulatePos.x * waveDir[0].x + + undulatePos.y * waveDir[0].y ); + undulateAmt += waveData[1].y * sin( elapsedTime * waveData[1].x + + undulatePos.x * waveDir[1].x + + undulatePos.y * waveDir[1].y ); + undulateAmt += waveData[2].y * sin( elapsedTime * waveData[2].x + + undulatePos.x * waveDir[2].x + + undulatePos.y * waveDir[2].y ); + + float undulateFade = 1; + + // Scale down wave magnitude amount based on distance from the camera. + float dist = distance( IN.position, eyePos ); + dist = clamp( dist, 1.0, undulateMaxDist ); + undulateFade *= ( 1 - dist / undulateMaxDist ); + + // Also scale down wave magnitude if the camera is very very close. + undulateFade *= saturate( ( distance( IN.position, eyePos ) - 0.5 ) / 10.0 ); + + undulateAmt *= undulateFade; + + //#endif + //undulateAmt = 0; + + // Apply wave undulation to the vertex. + OUT.posPostWave = inPos; + OUT.posPostWave.xyz += IN.normal.xyz * undulateAmt; + + // Save worldSpace position of this pixel/vert + //OUT.worldPos = OUT.posPostWave.xyz; + //OUT.worldPos = mul( modelMat, OUT.posPostWave.xyz ); + //OUT.worldPos.z += objTrans[2][2]; //91.16; + + // OUT.misc.w = mul( modelMat, OUT.fogPos ).z; + // if ( IN.horizonFactor.x > 0 ) + // { + // float3 awayVec = normalize( OUT.fogPos.xyz - eyePos ); + // OUT.fogPos.xy += awayVec.xy * 1000.0; + // } + + // Convert to screen + OUT.posPostWave = mul( modelview, OUT.posPostWave ); // mul( modelview, float4( OUT.posPostWave.xyz, 1 ) ); + + // Setup the OUT position symantic variable + OUT.hpos = OUT.posPostWave; // mul( modelview, float4( IN.position.xyz, 1 ) ); //float4( OUT.posPostWave.xyz, 1 ); + //OUT.hpos.z = lerp( OUT.hpos.z, OUT.hpos.w, IN.horizonFactor.x ); + + // Save world space camera dist/depth of the outgoing pixel + OUT.pixelDist = OUT.hpos.z; + + // Convert to reflection texture space + OUT.posPostWave = mul( texGen, OUT.posPostWave ); + + float2 txPos = undulatePos; + if ( IN.horizonFactor.x ) + txPos = normalize( txPos ) * 50000.0; + + // set up tex coordinates for the 3 interacting normal maps + OUT.rippleTexCoord01.xy = txPos * rippleTexScale[0]; + OUT.rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x; + + float2x2 texMat; + texMat[0][0] = rippleMat[0].x; + texMat[0][1] = rippleMat[0].y; + texMat[1][0] = rippleMat[0].z; + texMat[1][1] = rippleMat[0].w; + OUT.rippleTexCoord01.xy = mul( texMat, OUT.rippleTexCoord01.xy ); + + OUT.rippleTexCoord01.zw = txPos * rippleTexScale[1]; + OUT.rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y; + + texMat[0][0] = rippleMat[1].x; + texMat[0][1] = rippleMat[1].y; + texMat[1][0] = rippleMat[1].z; + texMat[1][1] = rippleMat[1].w; + OUT.rippleTexCoord01.zw = mul( texMat, OUT.rippleTexCoord01.zw ); + + OUT.rippleTexCoord2.xy = txPos * rippleTexScale[2]; + OUT.rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z; + + texMat[0][0] = rippleMat[2].x; + texMat[0][1] = rippleMat[2].y; + texMat[1][0] = rippleMat[2].z; + texMat[1][1] = rippleMat[2].w; + OUT.rippleTexCoord2.xy = mul( texMat, OUT.rippleTexCoord2.xy ); + +#ifdef WATER_SPEC + + float3 binormal = float3( 1, 0, 0 ); + float3 tangent = float3( 0, 1, 0 ); + float3 normal; + for ( int i = 0; i < 3; i++ ) + { + binormal.z += undulateFade * waveDir[i].x * waveData[i].y * cos( waveDir[i].x * IN.undulateData.x + waveDir[i].y * IN.undulateData.y + elapsedTime * waveData[i].x ); + tangent.z += undulateFade * waveDir[i].y * waveData[i].y * cos( waveDir[i].x * IN.undulateData.x + waveDir[i].y * IN.undulateData.y + elapsedTime * waveData[i].x ); + } + + binormal = normalize( binormal ); + tangent = normalize( tangent ); + normal = cross( binormal, tangent ); + + float3x3 worldToTangent; + worldToTangent[0] = binormal; + worldToTangent[1] = tangent; + worldToTangent[2] = normal; + + OUT.misc.xyz = mul( inLightVec, modelMat ); + OUT.misc.xyz = mul( worldToTangent, OUT.misc.xyz ); + +#else + + OUT.misc.xyz = inLightVec; + +#endif + + return OUT; +} + diff --git a/Templates/BaseGame/game/data/shaders/common/water/waterP.hlsl b/Templates/BaseGame/game/data/shaders/common/water/waterP.hlsl new file mode 100644 index 000000000..d50c0b51c --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/water/waterP.hlsl @@ -0,0 +1,384 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../shaderModelAutoGen.hlsl" +#include "../torque.hlsl" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +#define PIXEL_DIST IN.rippleTexCoord2.z +// miscParams +#define FRESNEL_BIAS miscParams[0] +#define FRESNEL_POWER miscParams[1] +// miscParams[2] is unused +#define ISRIVER miscParams[3] + +// reflectParams +#define REFLECT_PLANE_Z reflectParams[0] +#define REFLECT_MIN_DIST reflectParams[1] +#define REFLECT_MAX_DIST reflectParams[2] +#define NO_REFLECT reflectParams[3] + +// fogParams +#define FOG_DENSITY fogParams[0] +#define FOG_DENSITY_OFFSET fogParams[1] + +// wetnessParams +#define WET_DEPTH wetnessParams[0] +#define WET_COLOR_FACTOR wetnessParams[1] + +// distortionParams +#define DISTORT_START_DIST distortionParams[0] +#define DISTORT_END_DIST distortionParams[1] +#define DISTORT_FULL_DEPTH distortionParams[2] + +// foamParams +#define FOAM_OPACITY foamParams[0] +#define FOAM_MAX_DEPTH foamParams[1] +#define FOAM_AMBIENT_LERP foamParams[2] +#define FOAM_RIPPLE_INFLUENCE foamParams[3] + +// specularParams +#define SPEC_POWER specularParams[3] +#define SPEC_COLOR specularParams.xyz + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + + // TexCoord 0 and 1 (xy,zw) for ripple texture lookup + float4 rippleTexCoord01 : TEXCOORD0; + + // xy is TexCoord 2 for ripple texture lookup + // z is the Worldspace unit distance/depth of this vertex/pixel + // w is amount of the crestFoam ( more at crest of waves ). + float4 rippleTexCoord2 : TEXCOORD1; + + // Screenspace vert position BEFORE wave transformation + float4 posPreWave : TEXCOORD2; + + // Screenspace vert position AFTER wave transformation + float4 posPostWave : TEXCOORD3; + + // Objectspace vert position BEFORE wave transformation + // w coord is world space z position. + float4 objPos : TEXCOORD4; + + float4 foamTexCoords : TEXCOORD5; + + float3x3 tangentMat : TEXCOORD6; +}; + +//----------------------------------------------------------------------------- +// approximate Fresnel function +//----------------------------------------------------------------------------- +float fresnel(float NdotV, float bias, float power) +{ + return bias + (1.0-bias)*pow(abs(1.0 - max(NdotV, 0)), power); +} + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +TORQUE_UNIFORM_SAMPLER2D(bumpMap,0); +TORQUE_UNIFORM_SAMPLER2D(prepassTex, 1); +TORQUE_UNIFORM_SAMPLER2D(reflectMap, 2); +TORQUE_UNIFORM_SAMPLER2D(refractBuff, 3); +TORQUE_UNIFORM_SAMPLERCUBE(skyMap, 4); +TORQUE_UNIFORM_SAMPLER2D(foamMap, 5); +TORQUE_UNIFORM_SAMPLER1D(depthGradMap, 6); +uniform float4 specularParams; +uniform float4 baseColor; +uniform float4 miscParams; +uniform float2 fogParams; +uniform float4 reflectParams; +uniform float3 reflectNormal; +uniform float2 wetnessParams; +uniform float farPlaneDist; +uniform float3 distortionParams; +uniform float4 foamParams; +uniform float3 ambientColor; +uniform float3 eyePos; // This is in object space! +uniform float3 fogData; +uniform float4 fogColor; +uniform float4 rippleMagnitude; +uniform float4 rtParams1; +uniform float depthGradMax; +uniform float3 inLightVec; +uniform float4x4 modelMat; +uniform float4 sunColor; +uniform float sunBrightness; +uniform float reflectivity; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +float4 main( ConnectData IN ) : TORQUE_TARGET0 +{ + // Get the bumpNorm... + float3 bumpNorm = ( TORQUE_TEX2D( bumpMap, IN.rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x; + bumpNorm += ( TORQUE_TEX2D( bumpMap, IN.rippleTexCoord01.zw ).rgb * 2.0 - 1.0 ) * rippleMagnitude.y; + bumpNorm += ( TORQUE_TEX2D( bumpMap, IN.rippleTexCoord2.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.z; + + bumpNorm = normalize( bumpNorm ); + bumpNorm = lerp( bumpNorm, float3(0,0,1), 1.0 - rippleMagnitude.w ); + bumpNorm = mul( bumpNorm, IN.tangentMat ); + + // Get depth of the water surface (this pixel). + // Convert from WorldSpace to EyeSpace. + float pixelDepth = PIXEL_DIST / farPlaneDist; + + float2 prepassCoord = viewportCoordToRenderTarget( IN.posPostWave, rtParams1 ); + + float startDepth = TORQUE_PREPASS_UNCONDITION( prepassTex, prepassCoord ).w; + + // The water depth in world units of the undistorted pixel. + float startDelta = ( startDepth - pixelDepth ); + startDelta = max( startDelta, 0.0 ); + startDelta *= farPlaneDist; + + // Calculate the distortion amount for the water surface. + // + // We subtract a little from it so that we don't + // distort where the water surface intersects the + // camera near plane. + float distortAmt = saturate( ( PIXEL_DIST - DISTORT_START_DIST ) / DISTORT_END_DIST ); + + // Scale down distortion in shallow water. + distortAmt *= saturate( startDelta / DISTORT_FULL_DEPTH ); + + // Do the intial distortion... we might remove it below. + float2 distortDelta = bumpNorm.xy * distortAmt; + float4 distortPos = IN.posPostWave; + distortPos.xy += distortDelta; + + prepassCoord = viewportCoordToRenderTarget( distortPos, rtParams1 ); + + // Get prepass depth at the position of this distorted pixel. + float prepassDepth = TORQUE_PREPASS_UNCONDITION( prepassTex, prepassCoord ).w; + if ( prepassDepth > 0.99 ) + prepassDepth = 5.0; + + float delta = ( prepassDepth - pixelDepth ) * farPlaneDist; + + if ( delta < 0.0 ) + { + // If we got a negative delta then the distorted + // sample is above the water surface. Mask it out + // by removing the distortion. + distortPos = IN.posPostWave; + delta = startDelta; + distortAmt = 0; + } + else + { + float diff = ( prepassDepth - startDepth ) * farPlaneDist; + + if ( diff < 0 ) + { + distortAmt = saturate( ( PIXEL_DIST - DISTORT_START_DIST ) / DISTORT_END_DIST ); + distortAmt *= saturate( delta / DISTORT_FULL_DEPTH ); + + distortDelta = bumpNorm.xy * distortAmt; + + distortPos = IN.posPostWave; + distortPos.xy += distortDelta; + + prepassCoord = viewportCoordToRenderTarget( distortPos, rtParams1 ); + + // Get prepass depth at the position of this distorted pixel. + prepassDepth = TORQUE_PREPASS_UNCONDITION( prepassTex, prepassCoord ).w; + if ( prepassDepth > 0.99 ) + prepassDepth = 5.0; + delta = ( prepassDepth - pixelDepth ) * farPlaneDist; + } + + if ( delta < 0.1 ) + { + // If we got a negative delta then the distorted + // sample is above the water surface. Mask it out + // by removing the distortion. + distortPos = IN.posPostWave; + delta = startDelta; + distortAmt = 0; + } + } + + float4 temp = IN.posPreWave; + temp.xy += bumpNorm.xy * distortAmt; + float2 reflectCoord = viewportCoordToRenderTarget( temp, rtParams1 ); + + float2 refractCoord = viewportCoordToRenderTarget( distortPos, rtParams1 ); + + float4 fakeColor = float4(ambientColor,1); + float3 eyeVec = IN.objPos.xyz - eyePos; + eyeVec = mul( (float3x3)modelMat, eyeVec ); + eyeVec = mul( IN.tangentMat, eyeVec ); + float3 reflectionVec = reflect( eyeVec, bumpNorm ); + + // Use fakeColor for ripple-normals that are angled towards the camera + eyeVec = -eyeVec; + eyeVec = normalize( eyeVec ); + float ang = saturate( dot( eyeVec, bumpNorm ) ); + float fakeColorAmt = ang; + + // for verts far from the reflect plane z position + float rplaneDist = abs( REFLECT_PLANE_Z - IN.objPos.w ); + rplaneDist = saturate( ( rplaneDist - 1.0 ) / 2.0 ); + rplaneDist *= ISRIVER; + fakeColorAmt = max( fakeColorAmt, rplaneDist ); + +#ifndef UNDERWATER + + // Get foam color and amount + float2 foamRippleOffset = bumpNorm.xy * FOAM_RIPPLE_INFLUENCE; + IN.foamTexCoords.xy += foamRippleOffset; + IN.foamTexCoords.zw += foamRippleOffset; + + float4 foamColor = TORQUE_TEX2D( foamMap, IN.foamTexCoords.xy ); + foamColor += TORQUE_TEX2D( foamMap, IN.foamTexCoords.zw ); + foamColor = saturate( foamColor ); + + // Modulate foam color by ambient color + // so we don't have glowing white foam at night. + foamColor.rgb = lerp( foamColor.rgb, ambientColor.rgb, FOAM_AMBIENT_LERP ); + + float foamDelta = saturate( delta / FOAM_MAX_DEPTH ); + float foamAmt = 1 - pow( foamDelta, 2 ); + + // Fade out the foam in very very low depth, + // this improves the shoreline a lot. + float diff = 0.8 - foamAmt; + if ( diff < 0.0 ) + foamAmt -= foamAmt * abs( diff ) / 0.2; + + foamAmt *= FOAM_OPACITY * foamColor.a; + + foamColor.rgb *= FOAM_OPACITY * foamAmt * foamColor.a; + + // Get reflection map color. + float4 refMapColor = TORQUE_TEX2D( reflectMap, reflectCoord ); + + // If we do not have a reflection texture then we use the cubemap. + refMapColor = lerp( refMapColor, TORQUE_TEXCUBE( skyMap, reflectionVec ), NO_REFLECT ); + + fakeColor = ( TORQUE_TEXCUBE( skyMap, reflectionVec ) ); + fakeColor.a = 1; + // Combine reflection color and fakeColor. + float4 reflectColor = lerp( refMapColor, fakeColor, fakeColorAmt ); + + // Get refract color + float4 refractColor = hdrDecode( TORQUE_TEX2D( refractBuff, refractCoord ) ); + + // We darken the refraction color a bit to make underwater + // elements look wet. We fade out this darkening near the + // surface in order to not have hard water edges. + // @param WET_DEPTH The depth in world units at which full darkening will be recieved. + // @param WET_COLOR_FACTOR The refract color is scaled down by this amount when at WET_DEPTH + refractColor.rgb *= 1.0f - ( saturate( delta / WET_DEPTH ) * WET_COLOR_FACTOR ); + + // Add Water fog/haze. + float fogDelta = delta - FOG_DENSITY_OFFSET; + + if ( fogDelta < 0.0 ) + fogDelta = 0.0; + float fogAmt = 1.0 - saturate( exp( -FOG_DENSITY * fogDelta ) ); + + // Calculate the water "base" color based on depth. + float4 waterBaseColor = baseColor * TORQUE_TEX1D( depthGradMap, saturate( delta / depthGradMax ) ); + waterBaseColor = toLinear(waterBaseColor); + + // Modulate baseColor by the ambientColor. + waterBaseColor *= float4( ambientColor.rgb, 1 ); + + // calc "diffuse" color by lerping from the water color + // to refraction image based on the water clarity. + float4 diffuseColor = lerp( refractColor, waterBaseColor, fogAmt ); + + // fresnel calculation + float fresnelTerm = fresnel( ang, FRESNEL_BIAS, FRESNEL_POWER ); + + // Scale the frensel strength by fog amount + // so that parts that are very clear get very little reflection. + fresnelTerm *= fogAmt; + + // Also scale the frensel by our distance to the + // water surface. This removes the hard reflection + // when really close to the water surface. + fresnelTerm *= saturate( PIXEL_DIST - 0.1 ); + + fresnelTerm *= reflectivity; + + // Combine the diffuse color and reflection image via the + // fresnel term and set out output color. + float4 OUT = lerp( diffuseColor, reflectColor, fresnelTerm ); + + float3 lightVec = inLightVec; + + // Get some specular reflection. + float3 newbump = bumpNorm; + newbump.xy *= 3.5; + newbump = normalize( newbump ); + float3 halfAng = normalize( eyeVec + -lightVec ); + float specular = saturate( dot( newbump, halfAng ) ); + specular = pow( specular, SPEC_POWER ); + + // Scale down specularity in very shallow water to improve the transparency of the shoreline. + specular *= saturate( delta / 2 ); + OUT.rgb = OUT.rgb + ( SPEC_COLOR * specular.xxx ); + +#else + + float4 refractColor = hdrDecode( TORQUE_TEX2D( refractBuff, refractCoord ) ); + float4 OUT = refractColor; + +#endif + +#ifndef UNDERWATER + + OUT.rgb = OUT.rgb + foamColor.rgb; + + float factor = computeSceneFog( eyePos, + IN.objPos.xyz, + IN.objPos.w, + fogData.x, + fogData.y, + fogData.z ); + + OUT.rgb = lerp( OUT.rgb, fogColor.rgb, 1.0 - saturate( factor ) ); + + //OUT.rgb = fogColor.rgb; + +#endif + + OUT.a = 1.0; + + //return OUT; + + return hdrEncode( OUT ); +} diff --git a/Templates/BaseGame/game/data/shaders/common/water/waterV.hlsl b/Templates/BaseGame/game/data/shaders/common/water/waterV.hlsl new file mode 100644 index 000000000..c869f0e9f --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/water/waterV.hlsl @@ -0,0 +1,216 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../shaderModel.hlsl" + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct VertData +{ + float3 position : POSITION; + float3 normal : NORMAL; + float2 undulateData : TEXCOORD0; + float4 horizonFactor : TEXCOORD1; +}; + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + + // TexCoord 0 and 1 (xy,zw) for ripple texture lookup + float4 rippleTexCoord01 : TEXCOORD0; + + // xy is TexCoord 2 for ripple texture lookup + // z is the Worldspace unit distance/depth of this vertex/pixel + // w is amount of the crestFoam ( more at crest of waves ). + float4 rippleTexCoord2 : TEXCOORD1; + + // Screenspace vert position BEFORE wave transformation + float4 posPreWave : TEXCOORD2; + + // Screenspace vert position AFTER wave transformation + float4 posPostWave : TEXCOORD3; + + // Objectspace vert position BEFORE wave transformation + // w coord is world space z position. + float4 objPos : TEXCOORD4; + + float4 foamTexCoords : TEXCOORD5; + + float3x3 tangentMat : TEXCOORD6; +}; + +//----------------------------------------------------------------------------- +// Uniforms +//----------------------------------------------------------------------------- +uniform float4x4 modelMat; +uniform float4x4 modelview; +uniform float4 rippleMat[3]; +uniform float3 eyePos; +uniform float2 waveDir[3]; +uniform float2 waveData[3]; +uniform float2 rippleDir[3]; +uniform float2 rippleTexScale[3]; +uniform float3 rippleSpeed; +uniform float4 foamDir; +uniform float4 foamTexScale; +uniform float2 foamSpeed; +uniform float3 inLightVec; +uniform float gridElementSize; +uniform float elapsedTime; +uniform float undulateMaxDist; + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +ConnectData main( VertData IN ) +{ + ConnectData OUT; + + // use projection matrix for reflection / refraction texture coords + float4x4 texGen = { 0.5, 0.0, 0.0, 0.5, + 0.0, -0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 }; + + IN.position.z = lerp( IN.position.z, eyePos.z, IN.horizonFactor.x ); + float4 inPos = float4( IN.position, 1.0); + OUT.objPos = inPos; + OUT.objPos.w = mul( modelMat, inPos ).z; + + // Send pre-undulation screenspace position + OUT.posPreWave = mul( modelview, inPos ); + OUT.posPreWave = mul( texGen, OUT.posPreWave ); + + // Calculate the undulation amount for this vertex. + float2 undulatePos = mul( modelMat, float4( IN.undulateData.xy, 0, 1 ) ).xy; + float undulateAmt = 0.0; + + undulateAmt += waveData[0].y * sin( elapsedTime * waveData[0].x + + undulatePos.x * waveDir[0].x + + undulatePos.y * waveDir[0].y ); + undulateAmt += waveData[1].y * sin( elapsedTime * waveData[1].x + + undulatePos.x * waveDir[1].x + + undulatePos.y * waveDir[1].y ); + undulateAmt += waveData[2].y * sin( elapsedTime * waveData[2].x + + undulatePos.x * waveDir[2].x + + undulatePos.y * waveDir[2].y ); + + float undulateFade = 1; + + // Scale down wave magnitude amount based on distance from the camera. + float dist = distance( IN.position.xyz, eyePos ); + dist = clamp( dist, 1.0, undulateMaxDist ); + undulateFade *= ( 1 - dist / undulateMaxDist ); + + // Also scale down wave magnitude if the camera is very very close. + undulateFade *= saturate( ( distance( IN.position.xyz, eyePos ) - 0.5 ) / 10.0 ); + + undulateAmt *= undulateFade; + + OUT.rippleTexCoord2.w = undulateAmt / ( waveData[0].y + waveData[1].y + waveData[2].y ); + OUT.rippleTexCoord2.w = saturate( OUT.rippleTexCoord2.w - 0.2 ) / 0.8; + + // Apply wave undulation to the vertex. + OUT.posPostWave = inPos; + OUT.posPostWave.xyz += IN.normal.xyz * undulateAmt; + + // Convert to screen + OUT.posPostWave = mul( modelview, OUT.posPostWave ); + + // Setup the OUT position symantic variable + OUT.hpos = OUT.posPostWave; + //OUT.hpos.z = lerp( OUT.hpos.z, OUT.hpos.w, IN.horizonFactor.x ); + + // if ( IN.horizonFactor.x > 0 ) + // { + // float3 awayVec = normalize( OUT.objPos.xyz - eyePos ); + // OUT.objPos.xy += awayVec.xy * 1000.0; + // } + + // Save world space camera dist/depth of the outgoing pixel + OUT.rippleTexCoord2.z = OUT.hpos.z; + + // Convert to reflection texture space + OUT.posPostWave = mul( texGen, OUT.posPostWave ); + + float2 txPos = undulatePos; + if ( IN.horizonFactor.x ) + txPos = normalize( txPos ) * 50000.0; + + // set up tex coordinates for the 3 interacting normal maps + OUT.rippleTexCoord01.xy = txPos * rippleTexScale[0]; + OUT.rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x; + + float2x2 texMat; + texMat[0][0] = rippleMat[0].x; + texMat[0][1] = rippleMat[0].y; + texMat[1][0] = rippleMat[0].z; + texMat[1][1] = rippleMat[0].w; + OUT.rippleTexCoord01.xy = mul( texMat, OUT.rippleTexCoord01.xy ); + + OUT.rippleTexCoord01.zw = txPos * rippleTexScale[1]; + OUT.rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y; + + texMat[0][0] = rippleMat[1].x; + texMat[0][1] = rippleMat[1].y; + texMat[1][0] = rippleMat[1].z; + texMat[1][1] = rippleMat[1].w; + OUT.rippleTexCoord01.zw = mul( texMat, OUT.rippleTexCoord01.zw ); + + OUT.rippleTexCoord2.xy = txPos * rippleTexScale[2]; + OUT.rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z; + + texMat[0][0] = rippleMat[2].x; + texMat[0][1] = rippleMat[2].y; + texMat[1][0] = rippleMat[2].z; + texMat[1][1] = rippleMat[2].w; + OUT.rippleTexCoord2.xy = mul( texMat, OUT.rippleTexCoord2.xy ); + + OUT.foamTexCoords.xy = txPos * foamTexScale.xy + foamDir.xy * foamSpeed.x * elapsedTime; + OUT.foamTexCoords.zw = txPos * foamTexScale.zw + foamDir.zw * foamSpeed.y * elapsedTime; + + + float3 binormal = float3( 1, 0, 0 ); + float3 tangent = float3( 0, 1, 0 ); + float3 normal; + for ( int i = 0; i < 3; i++ ) + { + binormal.z += undulateFade * waveDir[i].x * waveData[i].y * cos( waveDir[i].x * undulatePos.x + waveDir[i].y * undulatePos.y + elapsedTime * waveData[i].x ); + tangent.z += undulateFade * waveDir[i].y * waveData[i].y * cos( waveDir[i].x * undulatePos.x + waveDir[i].y * undulatePos.y + elapsedTime * waveData[i].x ); + } + + binormal = binormal; + tangent = tangent; + normal = cross( binormal, tangent ); + + float3x3 worldToTangent; + worldToTangent[0] = binormal; + worldToTangent[1] = tangent; + worldToTangent[2] = normal; + + OUT.tangentMat = worldToTangent; + + return OUT; +} + diff --git a/Templates/BaseGame/game/data/shaders/common/wavesP.hlsl b/Templates/BaseGame/game/data/shaders/common/wavesP.hlsl new file mode 100644 index 000000000..c51eb4b89 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/wavesP.hlsl @@ -0,0 +1,89 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#define IN_HLSL +#include "shdrConsts.h" +#include "shaderModel.hlsl" + +//----------------------------------------------------------------------------- +// Data +//----------------------------------------------------------------------------- +struct v2f +{ + float4 HPOS : TORQUE_POSITION; + float2 TEX0 : TEXCOORD0; + float4 tangentToCube0 : TEXCOORD1; + float4 tangentToCube1 : TEXCOORD2; + float4 tangentToCube2 : TEXCOORD3; + float4 lightVec : TEXCOORD4; + float3 pixPos : TEXCOORD5; + float3 eyePos : TEXCOORD6; +}; + + + +struct Fragout +{ + float4 col : TORQUE_TARGET0; +}; + +// Uniforms +TORQUE_UNIFORM_SAMPLER2D(diffMap,0); +//TORQUE_UNIFORM_SAMPLERCUBE(cubeMap, 1); not used? +TORQUE_UNIFORM_SAMPLER2D(bumpMap,2); + +uniform float4 specularColor : register(PC_MAT_SPECCOLOR); +uniform float4 ambient : register(PC_AMBIENT_COLOR); +uniform float specularPower : register(PC_MAT_SPECPOWER); +uniform float accumTime : register(PC_ACCUM_TIME); + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Fragout main(v2f IN) +{ + Fragout OUT; + + float2 texOffset; + float sinOffset1 = sin( accumTime * 1.5 + IN.TEX0.y * 6.28319 * 3.0 ) * 0.03; + float sinOffset2 = sin( accumTime * 3.0 + IN.TEX0.y * 6.28319 ) * 0.04; + + texOffset.x = IN.TEX0.x + sinOffset1 + sinOffset2; + texOffset.y = IN.TEX0.y + cos( accumTime * 3.0 + IN.TEX0.x * 6.28319 * 2.0 ) * 0.05; + + + float4 bumpNorm = TORQUE_TEX2D( bumpMap, texOffset ) * 2.0 - 1.0; + float4 diffuse = TORQUE_TEX2D( diffMap, texOffset ); + + OUT.col = diffuse * (saturate( dot( IN.lightVec, bumpNorm.xyz ) ) + ambient); + + float3 eyeVec = normalize(IN.eyePos - IN.pixPos); + float3 halfAng = normalize(eyeVec + IN.lightVec.xyz); + float specular = saturate( dot(bumpNorm, halfAng) ) * IN.lightVec.w; + specular = pow(abs(specular), specularPower); + OUT.col += specularColor * specular; + + + + return OUT; +} + diff --git a/Templates/BaseGame/game/data/shaders/common/wavesV.hlsl b/Templates/BaseGame/game/data/shaders/common/wavesV.hlsl new file mode 100644 index 000000000..fccef9d25 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/wavesV.hlsl @@ -0,0 +1,90 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#define IN_HLSL +#include "shdrConsts.h" +#include "hlslStructs.hlsl" + +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- + +struct Conn +{ + float4 HPOS : POSITION; + float2 TEX0 : TEXCOORD0; + float4 tangentToCube0 : TEXCOORD1; + float4 tangentToCube1 : TEXCOORD2; + float4 tangentToCube2 : TEXCOORD3; + float4 outLightVec : TEXCOORD4; + float3 pos : TEXCOORD5; + float3 outEyePos : TEXCOORD6; + +}; + + +uniform float4x4 modelview : register(VC_WORLD_PROJ); +uniform float3x3 cubeTrans : register(VC_CUBE_TRANS); +uniform float3 cubeEyePos : register(VC_CUBE_EYE_POS); +uniform float3 inLightVec : register(VC_LIGHT_DIR1); +uniform float3 eyePos : register(VC_EYE_POS); + +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +Conn main( VertexIn_PNTTTB In) +{ + Conn Out; + + Out.HPOS = mul(modelview, float4(In.pos,1.0)); + Out.TEX0 = In.uv0; + + + float3x3 objToTangentSpace; + objToTangentSpace[0] = In.T; + objToTangentSpace[1] = In.B; + objToTangentSpace[2] = In.normal; + + + Out.tangentToCube0.xyz = mul( objToTangentSpace, cubeTrans[0].xyz ); + Out.tangentToCube1.xyz = mul( objToTangentSpace, cubeTrans[1].xyz ); + Out.tangentToCube2.xyz = mul( objToTangentSpace, cubeTrans[2].xyz ); + + float3 pos = mul( cubeTrans, In.pos ).xyz; + float3 eye = cubeEyePos - pos; + normalize( eye ); + + Out.tangentToCube0.w = eye.x; + Out.tangentToCube1.w = eye.y; + Out.tangentToCube2.w = eye.z; + + Out.outLightVec.xyz = -inLightVec; + Out.outLightVec.xyz = mul(objToTangentSpace, Out.outLightVec); + Out.pos = mul(objToTangentSpace, In.pos.xyz / 100.0); + Out.outEyePos.xyz = mul(objToTangentSpace, eyePos.xyz / 100.0); + Out.outLightVec.w = step( 0.0, dot( -inLightVec, In.normal ) ); + + + return Out; +} + + diff --git a/Templates/BaseGame/game/data/shaders/common/wind.hlsl b/Templates/BaseGame/game/data/shaders/common/wind.hlsl new file mode 100644 index 000000000..b3fee7721 --- /dev/null +++ b/Templates/BaseGame/game/data/shaders/common/wind.hlsl @@ -0,0 +1,101 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// +// A tip of the hat.... +// +// The following wind effects were derived from the GPU Gems +// 3 chapter "Vegetation Procedural Animation and Shading in Crysis" +// by Tiago Sousa of Crytek. +// + +float4 smoothCurve( float4 x ) +{ + return x * x * ( 3.0 - 2.0 * x ); +} + +float4 triangleWave( float4 x ) +{ + return abs( frac( x + 0.5 ) * 2.0 - 1.0 ); +} + +float4 smoothTriangleWave( float4 x ) +{ + return smoothCurve( triangleWave( x ) ); +} + +float3 windTrunkBending( float3 vPos, float2 vWind, float fBendFactor ) +{ + // Smooth the bending factor and increase + // the near by height limit. + fBendFactor += 1.0; + fBendFactor *= fBendFactor; + fBendFactor = fBendFactor * fBendFactor - fBendFactor; + + // Displace the vert. + float3 vNewPos = vPos; + vNewPos.xy += vWind * fBendFactor; + + // Limit the length which makes the bend more + // spherical and prevents stretching. + float fLength = length( vPos ); + vPos = normalize( vNewPos ) * fLength; + + return vPos; +} + +float3 windBranchBending( float3 vPos, + float3 vNormal, + + float fTime, + float fWindSpeed, + + float fBranchPhase, + float fBranchAmp, + float fBranchAtten, + + float fDetailPhase, + float fDetailAmp, + float fDetailFreq, + + float fEdgeAtten ) +{ + float fVertPhase = dot( vPos, fDetailPhase + fBranchPhase ); + + float2 vWavesIn = fTime + float2( fVertPhase, fBranchPhase ); + + float4 vWaves = ( frac( vWavesIn.xxyy * + float4( 1.975, 0.793, 0.375, 0.193 ) ) * + 2.0 - 1.0 ) * fWindSpeed * fDetailFreq; + + vWaves = smoothTriangleWave( vWaves ); + + float2 vWavesSum = vWaves.xz + vWaves.yw; + + // We want the branches to bend both up and down. + vWavesSum.y = 1 - ( vWavesSum.y * 2 ); + + vPos += vWavesSum.xxy * float3( fEdgeAtten * fDetailAmp * vNormal.xy, + fBranchAtten * fBranchAmp ); + + return vPos; +} diff --git a/Templates/BaseGame/game/data/splash.png b/Templates/BaseGame/game/data/splash.png new file mode 100644 index 000000000..333df9eb3 Binary files /dev/null and b/Templates/BaseGame/game/data/splash.png differ diff --git a/Templates/BaseGame/game/data/torque.png b/Templates/BaseGame/game/data/torque.png new file mode 100644 index 000000000..1023f2bb6 Binary files /dev/null and b/Templates/BaseGame/game/data/torque.png differ diff --git a/Templates/BaseGame/game/data/ui/UI.cs b/Templates/BaseGame/game/data/ui/UI.cs new file mode 100644 index 000000000..323fda930 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/UI.cs @@ -0,0 +1,63 @@ + +// The general flow of a gane - server's creation, loading and hosting clients, and then destruction is as follows: + +// First, a client will always create a server in the event that they want to host a single player +// game. Torque3D treats even single player connections as a soft multiplayer game, with some stuff +// in the networking short-circuited to sidestep around lag and packet transmission times. + +// initServer() is called, loading the default server scripts. +// After that, if this is a dedicated server session, initDedicated() is called, otherwise initClient is called +// to prep a playable client session. + +// When a local game is started - a listen server - via calling StartGame() a server is created and then the client is +// connected to it via createAndConnectToLocalServer(). + +function UI::create( %this ) +{ + if ($Server::Dedicated) + return; + + // Use our prefs to configure our Canvas/Window + configureCanvas(); + + //Load UI stuff + //we need to load this because some of the menu profiles use the sounds here + exec("./scripts/datablocks/guiSounds.cs"); + + //Profiles + exec("./scripts/profiles.cs"); + + //Now gui files + exec("./scripts/guis/mainMenu.gui"); + exec("./scripts/guis/chooseLevelDlg.gui"); + exec("./scripts/guis/joinServerMenu.gui"); + exec("./scripts/guis/loadingGui.gui"); + exec("./scripts/guis/optionsMenu.gui"); + exec("./scripts/guis/pauseMenu.gui"); + exec("./scripts/guis/remapDlg.gui"); + exec("./scripts/guis/remapConfirmDlg.gui"); + + exec("./scripts/guis/profiler.gui"); + exec("./scripts/guis/netGraphGui.gui"); + + //Load gui companion scripts + exec("./scripts/chooseLevelDlg.cs"); + exec("./scripts/optionsList.cs"); + exec("./scripts/optionsMenu.cs"); + exec("./scripts/graphicsMenu.cs"); + exec("./scripts/controlsMenu.cs"); + exec("./scripts/chooseLevelDlg.cs"); + exec("./scripts/mainMenu.cs"); + exec("./scripts/joinServerMenu.cs"); + exec("./scripts/pauseMenu.cs"); + exec("./scripts/messageBoxes.cs"); + + %dbList = new ArrayObject(LevelFilesList); + + Canvas.pushDialog(MainMenuGui); +} + +function Game::destroy( %this ) +{ + +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/ui/UI.module b/Templates/BaseGame/game/data/ui/UI.module new file mode 100644 index 000000000..e22117d39 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/UI.module @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/Templates/BaseGame/game/data/ui/art/ScreenBrightness_Dark.png b/Templates/BaseGame/game/data/ui/art/ScreenBrightness_Dark.png new file mode 100644 index 000000000..85cde0bbc Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/ScreenBrightness_Dark.png differ diff --git a/Templates/BaseGame/game/data/ui/art/ScreenBrightness_Light.png b/Templates/BaseGame/game/data/ui/art/ScreenBrightness_Light.png new file mode 100644 index 000000000..6c16b7e44 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/ScreenBrightness_Light.png differ diff --git a/Templates/BaseGame/game/data/ui/art/Torque-3D-logo-shortcut.png b/Templates/BaseGame/game/data/ui/art/Torque-3D-logo-shortcut.png new file mode 100644 index 000000000..d993d4893 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/Torque-3D-logo-shortcut.png differ diff --git a/Templates/BaseGame/game/data/ui/art/Torque-3D-logo-w.png b/Templates/BaseGame/game/data/ui/art/Torque-3D-logo-w.png new file mode 100644 index 000000000..ec197dda3 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/Torque-3D-logo-w.png differ diff --git a/Templates/BaseGame/game/data/ui/art/Torque-3D-logo.png b/Templates/BaseGame/game/data/ui/art/Torque-3D-logo.png new file mode 100644 index 000000000..e31d42a68 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/Torque-3D-logo.png differ diff --git a/Templates/BaseGame/game/data/ui/art/Torque-3D-logo_alt.png b/Templates/BaseGame/game/data/ui/art/Torque-3D-logo_alt.png new file mode 100644 index 000000000..3836f1e7f Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/Torque-3D-logo_alt.png differ diff --git a/Templates/BaseGame/game/data/ui/art/background-dark.png b/Templates/BaseGame/game/data/ui/art/background-dark.png new file mode 100644 index 000000000..fedbcfc93 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/background-dark.png differ diff --git a/Templates/BaseGame/game/data/ui/art/background.png b/Templates/BaseGame/game/data/ui/art/background.png new file mode 100644 index 000000000..9444659f3 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/background.png differ diff --git a/Templates/BaseGame/game/data/ui/art/buttontab.png b/Templates/BaseGame/game/data/ui/art/buttontab.png new file mode 100644 index 000000000..047b88645 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/buttontab.png differ diff --git a/Templates/BaseGame/game/data/ui/art/chatHudBorderArray.png b/Templates/BaseGame/game/data/ui/art/chatHudBorderArray.png new file mode 100644 index 000000000..1aebdb2d8 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/chatHudBorderArray.png differ diff --git a/Templates/BaseGame/game/data/ui/art/checkbox.png b/Templates/BaseGame/game/data/ui/art/checkbox.png new file mode 100644 index 000000000..46e0ac959 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/checkbox.png differ diff --git a/Templates/BaseGame/game/data/ui/art/clear-btn_d.png b/Templates/BaseGame/game/data/ui/art/clear-btn_d.png new file mode 100644 index 000000000..229c71e8b Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/clear-btn_d.png differ diff --git a/Templates/BaseGame/game/data/ui/art/clear-btn_h.png b/Templates/BaseGame/game/data/ui/art/clear-btn_h.png new file mode 100644 index 000000000..5e67cb13b Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/clear-btn_h.png differ diff --git a/Templates/BaseGame/game/data/ui/art/clear-btn_n.png b/Templates/BaseGame/game/data/ui/art/clear-btn_n.png new file mode 100644 index 000000000..ecb13a8d6 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/clear-btn_n.png differ diff --git a/Templates/BaseGame/game/data/ui/art/collapse-toolbar_d.png b/Templates/BaseGame/game/data/ui/art/collapse-toolbar_d.png new file mode 100644 index 000000000..984a63853 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/collapse-toolbar_d.png differ diff --git a/Templates/BaseGame/game/data/ui/art/collapse-toolbar_h.png b/Templates/BaseGame/game/data/ui/art/collapse-toolbar_h.png new file mode 100644 index 000000000..7e3de8387 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/collapse-toolbar_h.png differ diff --git a/Templates/BaseGame/game/data/ui/art/collapse-toolbar_n.png b/Templates/BaseGame/game/data/ui/art/collapse-toolbar_n.png new file mode 100644 index 000000000..b36de3ae0 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/collapse-toolbar_n.png differ diff --git a/Templates/BaseGame/game/data/ui/art/defaultCursor.png b/Templates/BaseGame/game/data/ui/art/defaultCursor.png new file mode 100644 index 000000000..ee03cd483 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/defaultCursor.png differ diff --git a/Templates/BaseGame/game/data/ui/art/dropDown.png b/Templates/BaseGame/game/data/ui/art/dropDown.png new file mode 100644 index 000000000..9b7414acc Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/dropDown.png differ diff --git a/Templates/BaseGame/game/data/ui/art/dropdown-button-arrow.png b/Templates/BaseGame/game/data/ui/art/dropdown-button-arrow.png new file mode 100644 index 000000000..8c420ab85 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/dropdown-button-arrow.png differ diff --git a/Templates/BaseGame/game/data/ui/art/dropdown-textEdit.png b/Templates/BaseGame/game/data/ui/art/dropdown-textEdit.png new file mode 100644 index 000000000..3966efbb5 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/dropdown-textEdit.png differ diff --git a/Templates/BaseGame/game/data/ui/art/dropslider_d.png b/Templates/BaseGame/game/data/ui/art/dropslider_d.png new file mode 100644 index 000000000..0c65347aa Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/dropslider_d.png differ diff --git a/Templates/BaseGame/game/data/ui/art/dropslider_h.png b/Templates/BaseGame/game/data/ui/art/dropslider_h.png new file mode 100644 index 000000000..bd2cb89d8 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/dropslider_h.png differ diff --git a/Templates/BaseGame/game/data/ui/art/dropslider_n.png b/Templates/BaseGame/game/data/ui/art/dropslider_n.png new file mode 100644 index 000000000..a4577f9ea Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/dropslider_n.png differ diff --git a/Templates/BaseGame/game/data/ui/art/expand-toolbar_d.png b/Templates/BaseGame/game/data/ui/art/expand-toolbar_d.png new file mode 100644 index 000000000..462929e95 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/expand-toolbar_d.png differ diff --git a/Templates/BaseGame/game/data/ui/art/expand-toolbar_h.png b/Templates/BaseGame/game/data/ui/art/expand-toolbar_h.png new file mode 100644 index 000000000..c33bcad69 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/expand-toolbar_h.png differ diff --git a/Templates/BaseGame/game/data/ui/art/expand-toolbar_n.png b/Templates/BaseGame/game/data/ui/art/expand-toolbar_n.png new file mode 100644 index 000000000..0af2f1bd1 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/expand-toolbar_n.png differ diff --git a/Templates/BaseGame/game/data/ui/art/folder.png b/Templates/BaseGame/game/data/ui/art/folder.png new file mode 100644 index 000000000..571a904d0 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/folder.png differ diff --git a/Templates/BaseGame/game/data/ui/art/group-border.png b/Templates/BaseGame/game/data/ui/art/group-border.png new file mode 100644 index 000000000..61234ae1f Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/group-border.png differ diff --git a/Templates/BaseGame/game/data/ui/art/hudfill.png b/Templates/BaseGame/game/data/ui/art/hudfill.png new file mode 100644 index 000000000..57d72468b Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/hudfill.png differ diff --git a/Templates/BaseGame/game/data/ui/art/inactive-overlay.png b/Templates/BaseGame/game/data/ui/art/inactive-overlay.png new file mode 100644 index 000000000..feab83209 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/inactive-overlay.png differ diff --git a/Templates/BaseGame/game/data/ui/art/lagIcon.png b/Templates/BaseGame/game/data/ui/art/lagIcon.png new file mode 100644 index 000000000..cf158dd65 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/lagIcon.png differ diff --git a/Templates/BaseGame/game/data/ui/art/loadingbar.png b/Templates/BaseGame/game/data/ui/art/loadingbar.png new file mode 100644 index 000000000..34f594403 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/loadingbar.png differ diff --git a/Templates/BaseGame/game/data/ui/art/macCursor.png b/Templates/BaseGame/game/data/ui/art/macCursor.png new file mode 100644 index 000000000..22c444970 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/macCursor.png differ diff --git a/Templates/BaseGame/game/data/ui/art/menu-button.png b/Templates/BaseGame/game/data/ui/art/menu-button.png new file mode 100644 index 000000000..9964e0e69 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/menu-button.png differ diff --git a/Templates/BaseGame/game/data/ui/art/menu.png b/Templates/BaseGame/game/data/ui/art/menu.png new file mode 100644 index 000000000..2b7a33f58 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/menu.png differ diff --git a/Templates/BaseGame/game/data/ui/art/menuSlider.png b/Templates/BaseGame/game/data/ui/art/menuSlider.png new file mode 100644 index 000000000..92fee1e9c Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/menuSlider.png differ diff --git a/Templates/BaseGame/game/data/ui/art/new_d.png b/Templates/BaseGame/game/data/ui/art/new_d.png new file mode 100644 index 000000000..bdfc9400d Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/new_d.png differ diff --git a/Templates/BaseGame/game/data/ui/art/new_h.png b/Templates/BaseGame/game/data/ui/art/new_h.png new file mode 100644 index 000000000..1f9b722c1 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/new_h.png differ diff --git a/Templates/BaseGame/game/data/ui/art/new_n.png b/Templates/BaseGame/game/data/ui/art/new_n.png new file mode 100644 index 000000000..06531327d Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/new_n.png differ diff --git a/Templates/BaseGame/game/data/ui/art/next-button_d.png b/Templates/BaseGame/game/data/ui/art/next-button_d.png new file mode 100644 index 000000000..76c3ec0ff Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/next-button_d.png differ diff --git a/Templates/BaseGame/game/data/ui/art/next-button_h.png b/Templates/BaseGame/game/data/ui/art/next-button_h.png new file mode 100644 index 000000000..f52f5fb42 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/next-button_h.png differ diff --git a/Templates/BaseGame/game/data/ui/art/next-button_n.png b/Templates/BaseGame/game/data/ui/art/next-button_n.png new file mode 100644 index 000000000..203133732 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/next-button_n.png differ diff --git a/Templates/BaseGame/game/data/ui/art/no-preview.png b/Templates/BaseGame/game/data/ui/art/no-preview.png new file mode 100644 index 000000000..fccdc858b Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/no-preview.png differ diff --git a/Templates/BaseGame/game/data/ui/art/numericslider.png b/Templates/BaseGame/game/data/ui/art/numericslider.png new file mode 100644 index 000000000..6a97d60c8 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/numericslider.png differ diff --git a/Templates/BaseGame/game/data/ui/art/previous-button_d.png b/Templates/BaseGame/game/data/ui/art/previous-button_d.png new file mode 100644 index 000000000..688b30345 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/previous-button_d.png differ diff --git a/Templates/BaseGame/game/data/ui/art/previous-button_h.png b/Templates/BaseGame/game/data/ui/art/previous-button_h.png new file mode 100644 index 000000000..26cf0e8c6 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/previous-button_h.png differ diff --git a/Templates/BaseGame/game/data/ui/art/previous-button_n.png b/Templates/BaseGame/game/data/ui/art/previous-button_n.png new file mode 100644 index 000000000..c0b9f4662 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/previous-button_n.png differ diff --git a/Templates/BaseGame/game/data/ui/art/radioButton.png b/Templates/BaseGame/game/data/ui/art/radioButton.png new file mode 100644 index 000000000..d5ecc9853 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/radioButton.png differ diff --git a/Templates/BaseGame/game/data/ui/art/scrollBar.png b/Templates/BaseGame/game/data/ui/art/scrollBar.png new file mode 100644 index 000000000..e8c34dc85 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/scrollBar.png differ diff --git a/Templates/BaseGame/game/data/ui/art/selector-button-blank.png b/Templates/BaseGame/game/data/ui/art/selector-button-blank.png new file mode 100644 index 000000000..e965b3af6 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/selector-button-blank.png differ diff --git a/Templates/BaseGame/game/data/ui/art/selector-button-dark.png b/Templates/BaseGame/game/data/ui/art/selector-button-dark.png new file mode 100644 index 000000000..84ee7e6f3 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/selector-button-dark.png differ diff --git a/Templates/BaseGame/game/data/ui/art/selector-button-highlight-only.png b/Templates/BaseGame/game/data/ui/art/selector-button-highlight-only.png new file mode 100644 index 000000000..77e01fc74 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/selector-button-highlight-only.png differ diff --git a/Templates/BaseGame/game/data/ui/art/selector-button.png b/Templates/BaseGame/game/data/ui/art/selector-button.png new file mode 100644 index 000000000..cd0780068 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/selector-button.png differ diff --git a/Templates/BaseGame/game/data/ui/art/separator-h.png b/Templates/BaseGame/game/data/ui/art/separator-h.png new file mode 100644 index 000000000..339c0fbe0 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/separator-h.png differ diff --git a/Templates/BaseGame/game/data/ui/art/separator-v.png b/Templates/BaseGame/game/data/ui/art/separator-v.png new file mode 100644 index 000000000..6a0f87361 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/separator-v.png differ diff --git a/Templates/BaseGame/game/data/ui/art/slider-w-box.png b/Templates/BaseGame/game/data/ui/art/slider-w-box.png new file mode 100644 index 000000000..d9ef04961 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/slider-w-box.png differ diff --git a/Templates/BaseGame/game/data/ui/art/slider.png b/Templates/BaseGame/game/data/ui/art/slider.png new file mode 100644 index 000000000..92fee1e9c Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/slider.png differ diff --git a/Templates/BaseGame/game/data/ui/art/tab-border.png b/Templates/BaseGame/game/data/ui/art/tab-border.png new file mode 100644 index 000000000..6703924d4 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/tab-border.png differ diff --git a/Templates/BaseGame/game/data/ui/art/tab.png b/Templates/BaseGame/game/data/ui/art/tab.png new file mode 100644 index 000000000..ecd81daf7 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/tab.png differ diff --git a/Templates/BaseGame/game/data/ui/art/textEdit.png b/Templates/BaseGame/game/data/ui/art/textEdit.png new file mode 100644 index 000000000..5a65fac3c Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/textEdit.png differ diff --git a/Templates/BaseGame/game/data/ui/art/textEditSliderBox.png b/Templates/BaseGame/game/data/ui/art/textEditSliderBox.png new file mode 100644 index 000000000..57a0c49d3 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/textEditSliderBox.png differ diff --git a/Templates/BaseGame/game/data/ui/art/window.png b/Templates/BaseGame/game/data/ui/art/window.png new file mode 100644 index 000000000..d9e8006e4 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/window.png differ diff --git a/Templates/BaseGame/game/data/ui/scripts/chooseLevelDlg.cs b/Templates/BaseGame/game/data/ui/scripts/chooseLevelDlg.cs new file mode 100644 index 000000000..9dccc2481 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/chooseLevelDlg.cs @@ -0,0 +1,301 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//---------------------------------------- +function ChooseLevelDlg::onWake( %this ) +{ + CL_levelList.clear(); + ChooseLevelWindow->SmallPreviews.clear(); + + %count = LevelFilesList.count(); + for ( %i=0; %i < %count; %i++ ) + { + %file = LevelFilesList.getKey( %i ); + if ( !isFile(%file @ ".mis") && !isFile(%file) ) + continue; + + // Skip our new level/mission if we arent choosing a level + // to launch in the editor. + if ( !%this.launchInEditor ) + { + %fileName = fileName(%file); + if (strstr(%fileName, "newMission.mis") > -1 || strstr(%fileName, "newLevel.mis") > -1) + continue; + } + + %this.addMissionFile( %file ); + } + + // Also add the new level mission as defined in the world editor settings + // if we are choosing a level to launch in the editor. + if ( %this.launchInEditor ) + { + %file = EditorSettings.value( "WorldEditor/newLevelFile" ); + if ( %file !$= "" ) + %this.addMissionFile( %file ); + } + + // Sort our list + CL_levelList.sort(0); + + // Set the first row as the selected row + CL_levelList.setSelectedRow(0); + + for (%i = 0; %i < CL_levelList.rowCount(); %i++) + { + %preview = new GuiButtonCtrl() { + profile = "GuiMenuButtonProfile"; + internalName = "SmallPreview" @ %i; + Extent = "368 35"; + text = getField(CL_levelList.getRowText(%i), 0); + command = "ChooseLevelWindow.previewSelected(ChooseLevelWindow->SmallPreviews->SmallPreview" @ %i @ ");"; + buttonType = "RadioButton"; + }; + + ChooseLevelWindow->SmallPreviews.add(%preview); + + %rowText = CL_levelList.getRowText(%i); + + // Set the level index + %preview.levelIndex = %i; + + // Get the name + %name = getField(CL_levelList.getRowText(%i), 0); + + %preview.levelName = %name; + + %file = getField(CL_levelList.getRowText(%i), 1); + + // Find the preview image + %levelPreview = getField(CL_levelList.getRowText(%i), 3); + + // Test against all of the different image formats + // This should probably be moved into an engine function + if (isFile(%levelPreview @ ".png") || + isFile(%levelPreview @ ".jpg") || + isFile(%levelPreview @ ".bmp") || + isFile(%levelPreview @ ".gif") || + isFile(%levelPreview @ ".jng") || + isFile(%levelPreview @ ".mng") || + isFile(%levelPreview @ ".tga")) + { + %preview.bitmap = %levelPreview; + } + + // Get the description + %desc = getField(CL_levelList.getRowText(%i), 2); + + %preview.levelDesc = %desc; + } + + ChooseLevelWindow->SmallPreviews.firstVisible = -1; + ChooseLevelWindow->SmallPreviews.lastVisible = -1; + + if (ChooseLevelWindow->SmallPreviews.getCount() > 0) + { + ChooseLevelWindow->SmallPreviews.firstVisible = 0; + + if (ChooseLevelWindow->SmallPreviews.getCount() < 6) + ChooseLevelWindow->SmallPreviews.lastVisible = ChooseLevelWindow->SmallPreviews.getCount() - 1; + else + ChooseLevelWindow->SmallPreviews.lastVisible = 4; + } + + if (ChooseLevelWindow->SmallPreviews.getCount() > 0) + ChooseLevelWindow.previewSelected(ChooseLevelWindow->SmallPreviews.getObject(0)); + + // If we have 5 or less previews then hide our next/previous buttons + // and resize to fill their positions + if (ChooseLevelWindow->SmallPreviews.getCount() < 6) + { + ChooseLevelWindow->PreviousSmallPreviews.setVisible(false); + ChooseLevelWindow->NextSmallPreviews.setVisible(false); + + %previewPos = ChooseLevelWindow->SmallPreviews.getPosition(); + %previousPos = ChooseLevelWindow->PreviousSmallPreviews.getPosition(); + + %previewPosX = getWord(%previousPos, 0); + %previewPosY = getWord(%previewPos, 1); + + ChooseLevelWindow->SmallPreviews.setPosition(%previewPosX, %previewPosY); + + ChooseLevelWindow->SmallPreviews.colSpacing = 10;//((getWord(NextSmallPreviews.getPosition(), 0)+11)-getWord(PreviousSmallPreviews.getPosition(), 0))/4; + ChooseLevelWindow->SmallPreviews.refresh(); + } + + /*if (ChooseLevelWindow->SmallPreviews.getCount() <= 1) + { + // Hide the small previews + ChooseLevelWindow->SmallPreviews.setVisible(false); + + // Shrink the ChooseLevelWindow so that we don't have a large blank space + %extentX = getWord(ChooseLevelWindow.getExtent(), 0); + %extentY = getWord(ChooseLevelWindow->SmallPreviews.getPosition(), 1); + + ChooseLevelWIndow.setExtent(%extentX, %extentY); + } + else + { + // Make sure the small previews are visible + ChooseLevelWindow->SmallPreviews.setVisible(true); + + %extentX = getWord(ChooseLevelWindow.getExtent(), 0); + + %extentY = getWord(ChooseLevelWindow->SmallPreviews.getPosition(), 1); + %extentY = %extentY + getWord(ChooseLevelWindow->SmallPreviews.getExtent(), 1); + %extentY = %extentY + 9; + + //ChooseLevelWIndow.setExtent(%extentX, %extentY); + //}*/ +} + +function ChooseLevelDlg::addMissionFile( %this, %file ) +{ + %levelName = fileBase(%file); + %levelDesc = "A Torque level"; + + %LevelInfoObject = getLevelInfo(%file); + + if (%LevelInfoObject != 0) + { + if(%LevelInfoObject.levelName !$= "") + %levelName = %LevelInfoObject.levelName; + else if(%LevelInfoObject.name !$= "") + %levelName = %LevelInfoObject.name; + + if (%LevelInfoObject.desc0 !$= "") + %levelDesc = %LevelInfoObject.desc0; + + if (%LevelInfoObject.preview !$= "") + %levelPreview = %LevelInfoObject.preview; + + %LevelInfoObject.delete(); + } + + CL_levelList.addRow( CL_levelList.rowCount(), %levelName TAB %file TAB %levelDesc TAB %levelPreview ); +} + +function ChooseLevelDlg::onSleep( %this ) +{ + // This is set from the outside, only stays true for a single wake/sleep + // cycle. + %this.launchInEditor = false; +} + +function ChooseLevelWindow::previewSelected(%this, %preview) +{ + // Set the selected level + if (isObject(%preview) && %preview.levelIndex !$= "") + CL_levelList.setSelectedRow(%preview.levelIndex); + else + CL_levelList.setSelectedRow(-1); + + // Set the large preview image + if (isObject(%preview) && %preview.bitmap !$= "") + %this->CurrentPreview.setBitmap(%preview.bitmap); + else + %this->CurrentPreview.setBitmap("data/ui/art/no-preview"); + + // Set the current level name + if (isObject(%preview) && %preview.levelName !$= "") + %this->LevelName.setText(%preview.levelName); + else + %this->LevelName.setText("Level"); + + // Set the current level description + if (isObject(%preview) && %preview.levelDesc !$= "") + %this->LevelDescription.setText(%preview.levelDesc); + else + %this->LevelDescription.setText("A Torque Level"); +} + +function ChooseLevelWindow::previousPreviews(%this) +{ + %prevHiddenIdx = %this->SmallPreviews.firstVisible - 1; + + if (%prevHiddenIdx < 0) + return; + + %lastVisibleIdx = %this->SmallPreviews.lastVisible; + + if (%lastVisibleIdx >= %this->SmallPreviews.getCount()) + return; + + %prevHiddenObj = %this->SmallPreviews.getObject(%prevHiddenIdx); + %lastVisibleObj = %this->SmallPreviews.getObject(%lastVisibleIdx); + + if (isObject(%prevHiddenObj) && isObject(%lastVisibleObj)) + { + %this->SmallPreviews.firstVisible--; + %this->SmallPreviews.lastVisible--; + + %prevHiddenObj.setVisible(true); + %lastVisibleObj.setVisible(false); + } +} + +function ChooseLevelWindow::nextPreviews(%this) +{ + %firstVisibleIdx = %this->SmallPreviews.firstVisible; + + if (%firstVisibleIdx < 0) + return; + + %firstHiddenIdx = %this->SmallPreviews.lastVisible + 1; + + if (%firstHiddenIdx >= %this->SmallPreviews.getCount()) + return; + + %firstVisibleObj = %this->SmallPreviews.getObject(%firstVisibleIdx); + %firstHiddenObj = %this->SmallPreviews.getObject(%firstHiddenIdx); + + if (isObject(%firstVisibleObj) && isObject(%firstHiddenObj)) + { + %this->SmallPreviews.firstVisible++; + %this->SmallPreviews.lastVisible++; + + %firstVisibleObj.setVisible(false); + %firstHiddenObj.setVisible(true); + } +} + +// Do this onMouseUp not via Command which occurs onMouseDown so we do +// not have a lingering mouseUp event lingering in the ether. +function ChooseLevelDlgGoBtn::onMouseUp( %this ) +{ + // So we can't fire the button when loading is in progress. + if ( isObject( ServerGroup ) ) + return; + + // Launch the chosen level with the editor open? + if ( ChooseLevelDlg.launchInEditor ) + { + activatePackage( "BootEditor" ); + ChooseLevelDlg.launchInEditor = false; + StartGame("", "SinglePlayer"); + } + else + { + StartGame(); + } +} + diff --git a/Templates/BaseGame/game/data/ui/scripts/controlsMenu.cs b/Templates/BaseGame/game/data/ui/scripts/controlsMenu.cs new file mode 100644 index 000000000..f9718e647 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/controlsMenu.cs @@ -0,0 +1,417 @@ +// ============================================================================= +// KEYBINDS MENU +// ============================================================================= +$RemapCount = 0; +$RemapName[$RemapCount] = "Forward"; +$RemapCmd[$RemapCount] = "moveforward"; +$RemapGroup[$RemapCount] = "Movement"; +$RemapCount++; +$RemapName[$RemapCount] = "Backward"; +$RemapCmd[$RemapCount] = "movebackward"; +$RemapGroup[$RemapCount] = "Movement"; +$RemapCount++; +$RemapName[$RemapCount] = "Strafe Left"; +$RemapCmd[$RemapCount] = "moveleft"; +$RemapGroup[$RemapCount] = "Movement"; +$RemapCount++; +$RemapName[$RemapCount] = "Strafe Right"; +$RemapCmd[$RemapCount] = "moveright"; +$RemapGroup[$RemapCount] = "Movement"; +$RemapCount++; +$RemapName[$RemapCount] = "Jump"; +$RemapCmd[$RemapCount] = "jump"; +$RemapGroup[$RemapCount] = "Movement"; +$RemapCount++; + +$RemapName[$RemapCount] = "Fire Weapon"; +$RemapCmd[$RemapCount] = "mouseFire"; +$RemapGroup[$RemapCount] = "Combat"; +$RemapCount++; +$RemapName[$RemapCount] = "Adjust Zoom"; +$RemapCmd[$RemapCount] = "setZoomFov"; +$RemapGroup[$RemapCount] = "Combat"; +$RemapCount++; +$RemapName[$RemapCount] = "Toggle Zoom"; +$RemapCmd[$RemapCount] = "toggleZoom"; +$RemapGroup[$RemapCount] = "Combat"; +$RemapCount++; + +$RemapName[$RemapCount] = "Free Look"; +$RemapCmd[$RemapCount] = "toggleFreeLook"; +$RemapGroup[$RemapCount] = "Miscellaneous"; +$RemapCount++; +$RemapName[$RemapCount] = "Switch 1st/3rd"; +$RemapCmd[$RemapCount] = "toggleFirstPerson"; +$RemapGroup[$RemapCount] = "Miscellaneous"; +$RemapCount++; +$RemapName[$RemapCount] = "Toggle Camera"; +$RemapCmd[$RemapCount] = "toggleCamera"; +$RemapGroup[$RemapCount] = "Miscellaneous"; +$RemapCount++; + +function ControlsMenu::onWake(%this) +{ + ControlSetList.clear(); + ControlSetList.add( "Movement", "Movement" ); + ControlSetList.add( "Combat", "Combat" ); + ControlSetList.add( "Miscellaneous", "Miscellaneous" ); + + ControlSetList.setSelected( "Movement", false ); + + ControlsMenuOptionsArray.clear(); + ControlsMenu.loadGroupKeybinds("Movement"); + ControlsMenuOptionsArray.refresh(); +} + +function ControlSetList::onSelect( %this, %id, %text ) +{ + ControlsMenuOptionsArray.clear(); + + if(%text $= "Movement") + ControlsMenu.loadGroupKeybinds("Movement"); + else if(%text $= "Combat") + ControlsMenu.loadGroupKeybinds("Combat"); + else if(%text $= "Miscellaneous") + ControlsMenu.loadGroupKeybinds("Miscellaneous"); + + ControlsMenuOptionsArray.refresh(); +} + +function ControlsMenuOKButton::onClick(%this) +{ + // write out the control config into the keybinds.cs file + %prefPath = getPrefpath(); + moveMap.save( %prefPath @ "/keybinds.cs" ); + + OptionsMenu.backOut(); +} + +function ControlsMenuDefaultsButton::onClick(%this) +{ + //For this to work with module-style, we have to figure that somewhere, we'll set where our default keybind script is at. + //This can be hardcoded in your actual project. + exec($KeybindPath); + ControlsMenu.reload(); +} + +function ControlsMenu::loadGroupKeybinds(%this, %keybindGroup) +{ + %optionIndex = 0; + for(%i=0; %i < $RemapCount; %i++) + { + //find and add all the keybinds for the particular group we're looking at + if($RemapGroup[%i] $= %keybindGroup) + { + %temp = %this.getKeybindString(%i); + + %option = %this.addKeybindOption(); + %option-->nameText.setText($RemapName[%i]); + %option-->rebindButton.setText(%temp); + %option-->rebindButton.keybindIndex = %i; + %option-->rebindButton.optionIndex = %optionIndex; + %optionIndex++; + } + } +} + +function ControlsMenu::addKeybindOption(%this) +{ + %tamlReader = new Taml(); + + %graphicsOption = %tamlReader.read("data/ui/scripts/guis/controlsMenuSetting.taml"); + + ControlsMenuOptionsArray.add(%graphicsOption); + + return %graphicsOption; +} + +function ControlsMenu::getKeybindString(%this, %index ) +{ + %name = $RemapName[%index]; + %cmd = $RemapCmd[%index]; + + %temp = moveMap.getBinding( %cmd ); + if ( %temp $= "" ) + return %name TAB ""; + + %mapString = ""; + + %count = getFieldCount( %temp ); + for ( %i = 0; %i < %count; %i += 2 ) + { + %device = getField( %temp, %i + 0 ); + %object = getField( %temp, %i + 1 ); + + %displayName = %this.getMapDisplayName( %device, %object ); + + if(%displayName !$= "") + { + %tmpMapString = %this.getMapDisplayName( %device, %object ); + + if(%mapString $= "") + { + %mapString = %tmpMapString; + } + else + { + if ( %tmpMapString !$= "") + { + %mapString = %mapString @ ", " @ %tmpMapString; + } + } + } + } + + return %mapString; +} + +function ControlsMenu::redoMapping( %device, %action, %cmd, %oldIndex, %newIndex ) +{ + //%actionMap.bind( %device, %action, $RemapCmd[%newIndex] ); + moveMap.bind( %device, %action, %cmd ); + + %remapList = %this-->OptRemapList; + %remapList.setRowById( %oldIndex, buildFullMapString( %oldIndex ) ); + %remapList.setRowById( %newIndex, buildFullMapString( %newIndex ) ); +} + +function ControlsMenu::getMapDisplayName( %this, %device, %action ) +{ + if ( %device $= "keyboard" ) + return( %action ); + else if ( strstr( %device, "mouse" ) != -1 ) + { + // Substitute "mouse" for "button" in the action string: + %pos = strstr( %action, "button" ); + if ( %pos != -1 ) + { + %mods = getSubStr( %action, 0, %pos ); + %object = getSubStr( %action, %pos, 1000 ); + %instance = getSubStr( %object, strlen( "button" ), 1000 ); + return( %mods @ "mouse" @ ( %instance + 1 ) ); + } + else + error( "Mouse input object other than button passed to getDisplayMapName!" ); + } + else if ( strstr( %device, "joystick" ) != -1 ) + { + // Substitute "joystick" for "button" in the action string: + %pos = strstr( %action, "button" ); + if ( %pos != -1 ) + { + %mods = getSubStr( %action, 0, %pos ); + %object = getSubStr( %action, %pos, 1000 ); + %instance = getSubStr( %object, strlen( "button" ), 1000 ); + return( %mods @ "joystick" @ ( %instance + 1 ) ); + } + else + { + %pos = strstr( %action, "pov" ); + if ( %pos != -1 ) + { + %wordCount = getWordCount( %action ); + %mods = %wordCount > 1 ? getWords( %action, 0, %wordCount - 2 ) @ " " : ""; + %object = getWord( %action, %wordCount - 1 ); + switch$ ( %object ) + { + case "upov": %object = "POV1 up"; + case "dpov": %object = "POV1 down"; + case "lpov": %object = "POV1 left"; + case "rpov": %object = "POV1 right"; + case "upov2": %object = "POV2 up"; + case "dpov2": %object = "POV2 down"; + case "lpov2": %object = "POV2 left"; + case "rpov2": %object = "POV2 right"; + default: %object = ""; + } + return( %mods @ %object ); + } + else + error( "Unsupported Joystick input object passed to getDisplayMapName!" ); + } + } + + return( "" ); +} + +function ControlsMenu::buildFullMapString( %this, %index ) +{ + %name = $RemapName[%index]; + %cmd = $RemapCmd[%index]; + + %temp = moveMap.getBinding( %cmd ); + if ( %temp $= "" ) + return %name TAB ""; + + %mapString = ""; + + %count = getFieldCount( %temp ); + for ( %i = 0; %i < %count; %i += 2 ) + { + if ( %mapString !$= "" ) + %mapString = %mapString @ ", "; + + %device = getField( %temp, %i + 0 ); + %object = getField( %temp, %i + 1 ); + %mapString = %mapString @ %this.getMapDisplayName( %device, %object ); + } + + return %name TAB %mapString; +} + +function ControlsMenu::fillRemapList( %this ) +{ + %remapList = %this-->OptRemapList; + + %remapList.clear(); + for ( %i = 0; %i < $RemapCount; %i++ ) + %remapList.addRow( %i, %this.buildFullMapString( %i ) ); +} + +function ControlsMenu::doRemap( %this ) +{ + %remapList = %this-->OptRemapList; + + %selId = %remapList.getSelectedId(); + %name = $RemapName[%selId]; + + RemapDlg-->OptRemapText.setValue( "Re-bind \"" @ %name @ "\" to..." ); + OptRemapInputCtrl.index = %selId; + Canvas.pushDialog( RemapDlg ); +} + +function ControlsMenuRebindButton::onClick(%this) +{ + %name = $RemapName[%this.keybindIndex]; + RemapDlg-->OptRemapText.setValue( "Re-bind \"" @ %name @ "\" to..." ); + + OptRemapInputCtrl.index = %this.keybindIndex; + OptRemapInputCtrl.optionIndex = %this.optionIndex; + Canvas.pushDialog( RemapDlg ); +} + +function OptRemapInputCtrl::onInputEvent( %this, %device, %action ) +{ + //error( "** onInputEvent called - device = " @ %device @ ", action = " @ %action @ " **" ); + Canvas.popDialog( RemapDlg ); + + // Test for the reserved keystrokes: + if ( %device $= "keyboard" ) + { + // Cancel... + if ( %action $= "escape" ) + { + // Do nothing... + return; + } + } + + %cmd = $RemapCmd[%this.index]; + %name = $RemapName[%this.index]; + + // Grab the friendly display name for this action + // which we'll use when prompting the user below. + %mapName = ControlsMenu.getMapDisplayName( %device, %action ); + + // Get the current command this action is mapped to. + %prevMap = moveMap.getCommand( %device, %action ); + + // If nothing was mapped to the previous command + // mapping then it's easy... just bind it. + if ( %prevMap $= "" ) + { + ControlsMenu.unbindExtraActions( %cmd, 1 ); + moveMap.bind( %device, %action, %cmd ); + + //ControlsMenu.reload(); + %newCommands = getField(ControlsMenu.buildFullMapString( %this.index ), 1); + ControlsMenuOptionsArray.getObject(%this.optionIndex)-->rebindButton.setText(%newCommands); + return; + } + + // If the previous command is the same as the + // current then they hit the same input as what + // was already assigned. + if ( %prevMap $= %cmd ) + { + ControlsMenu.unbindExtraActions( %cmd, 0 ); + moveMap.bind( %device, %action, %cmd ); + + //ControlsMenu.reload(); + %newCommands = getField(ControlsMenu.buildFullMapString( %this.index ), 1); + ControlsMenuOptionsArray.getObject(%this.optionIndex)-->rebindButton.setText(%newCommands); + return; + } + + // Look for the index of the previous mapping. + %prevMapIndex = ControlsMenu.findRemapCmdIndex( %prevMap ); + + // If we get a negative index then the previous + // mapping was to an item that isn't included in + // the mapping list... so we cannot unmap it. + if ( %prevMapIndex == -1 ) + { + MessageBoxOK( "Remap Failed", "\"" @ %mapName @ "\" is already bound to a non-remappable command!" ); + return; + } + + // Setup the forced remapping callback command. + %callback = "redoMapping(" @ %device @ ", \"" @ %action @ "\", \"" @ + %cmd @ "\", " @ %prevMapIndex @ ", " @ %this.index @ ");"; + + // Warn that we're about to remove the old mapping and + // replace it with another. + %prevCmdName = $RemapName[%prevMapIndex]; + Canvas.pushDialog( RemapConfirmDlg ); + + RemapConfirmationText.setText("\"" @ %mapName @ "\" is already bound to \"" + @ %prevCmdName @ "\"! Do you wish to replace this mapping?"); + RemapConfirmationYesButton.command = "ControlsMenu.redoMapping(" @ %device @ ", \"" @ %action @ "\", \"" @ + %cmd @ "\", " @ %prevMapIndex @ ", " @ %this.index @ "); Canvas.popDialog();"; + RemapConfirmationNoButton.command = "Canvas.popDialog();"; + + /*MessageBoxYesNo( "Warning", + "\"" @ %mapName @ "\" is already bound to \"" + @ %prevCmdName @ "\"!\nDo you wish to replace this mapping?", + %callback, "" );*/ +} + +function ControlsMenu::findRemapCmdIndex( %this, %command ) +{ + for ( %i = 0; %i < $RemapCount; %i++ ) + { + if ( %command $= $RemapCmd[%i] ) + return( %i ); + } + return( -1 ); +} + +/// This unbinds actions beyond %count associated to the +/// particular moveMap %commmand. +function ControlsMenu::unbindExtraActions( %this, %command, %count ) +{ + %temp = moveMap.getBinding( %command ); + if ( %temp $= "" ) + return; + + %count = getFieldCount( %temp ) - ( %count * 2 ); + for ( %i = 0; %i < %count; %i += 2 ) + { + %device = getField( %temp, %i + 0 ); + %action = getField( %temp, %i + 1 ); + + moveMap.unbind( %device, %action ); + } +} + +function ControlsMenu::redoMapping( %this, %device, %action, %cmd, %oldIndex, %newIndex ) +{ + //%actionMap.bind( %device, %action, $RemapCmd[%newIndex] ); + moveMap.bind( %device, %action, %cmd ); + + %remapList = %this-->OptRemapList; + %remapList.setRowById( %oldIndex, %this.buildFullMapString( %oldIndex ) ); + %remapList.setRowById( %newIndex, %this.buildFullMapString( %newIndex ) ); + + %this.changeSettingsPage(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/ui/scripts/datablocks/guiSounds.cs b/Templates/BaseGame/game/data/ui/scripts/datablocks/guiSounds.cs new file mode 100644 index 000000000..0e8534eec --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/datablocks/guiSounds.cs @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +singleton SFXProfile(menuButtonPressed) +{ + preload = true; + description = AudioGui; + fileName = "data/ui/sound/buttonClick"; +}; + +singleton SFXProfile(menuButtonHover) +{ + preload = true; + description = AudioGui; + fileName = "data/ui/sound/buttonHover"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/data/ui/scripts/graphicsMenu.cs b/Templates/BaseGame/game/data/ui/scripts/graphicsMenu.cs new file mode 100644 index 000000000..7189d11c2 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/graphicsMenu.cs @@ -0,0 +1,567 @@ +// ============================================================================= +// GRAPHICS MENU +// ============================================================================= +//Mesh and Textures +// +function GraphicsMenu::onWake(%this) +{ + DisplaySettingsMenu.hidden = false; + GeneralGraphicsSettingsMenu.hidden = true; + + %this.refresh(); +} + +function GraphicsMenu::refresh(%this) +{ + // + // Display Menu + GraphicsMenuFullScreen.setStateOn( Canvas.isFullScreen() ); + GraphicsMenuVSync.setStateOn( !$pref::Video::disableVerticalSync ); + + %this.initResMenu(); + %resSelId = GraphicsMenuResolution.findText( _makePrettyResString( $pref::Video::mode ) ); + if( %resSelId != -1 ) + GraphicsMenuResolution.setSelected( %resSelId ); + + GraphicsMenuDriver.clear(); + + %buffer = getDisplayDeviceList(); + %count = getFieldCount( %buffer ); + for(%i = 0; %i < %count; %i++) + GraphicsMenuDriver.add(getField(%buffer, %i), %i); + + %selId = GraphicsMenuDriver.findText( getDisplayDeviceInformation() ); + if ( %selId == -1 ) + GraphicsMenuDriver.setFirstSelected(); + else + GraphicsMenuDriver.setSelected( %selId ); + // + + // + // General Graphics menu + GraphicsMenuShadowQlty.init(ShadowQualityList); + GraphicsMenuSoftShadow.init(SoftShadowList); + + GraphicsMenuModelDtl.init(MeshQualityGroup); + GraphicsMenuTextureDtl.init(TextureQualityGroup); + GraphicsMenuTerrainDtl.init(TerrainQualityGroup); + GraphicsMenuDecalLife.init(DecalLifetimeGroup); + GraphicsMenuGroundClutter.init(GroundCoverDensityGroup); + + GraphicsMenuMaterialQlty.init(ShaderQualityGroup); + + // Setup the anisotropic filtering menu. + %ansioCtrl = GraphicsMenuAniso; + %ansioCtrl.clear(); + %ansioCtrl.add( "16X", 16 ); + %ansioCtrl.add( "8X", 8 ); + %ansioCtrl.add( "4X", 4 ); + %ansioCtrl.add( "Off", 0 ); + %ansioCtrl.setSelected( $pref::Video::defaultAnisotropy, false ); + + // set up the Refresh Rate menu. + %refreshMenu = GraphicsMenuRefreshRate; + %refreshMenu.clear(); + // %refreshMenu.add("Auto", 60); + %refreshMenu.add("60", 60); + %refreshMenu.add("75", 75); + %refreshMenu.setSelected( $pref::Video::RefreshRate ); + + // Populate the Anti-aliasing popup. + %aaMenu = GraphicsMenuAA; + %aaMenu.clear(); + %aaMenu.Add( "4x", 4 ); + %aaMenu.Add( "2x", 2 ); + %aaMenu.Add( "1x", 1 ); + %aaMenu.Add( "Off", 0 ); + %aaMenu.setSelected( $pref::Video::AA ); + + //Parallax + GraphicsMenuParallax.setStateOn(!$pref::Video::disableParallaxMapping); + + //water reflections + GraphicsMenuWaterRefl.setStateOn(!$pref::Water::disableTrueReflections); + + GraphicsMenuParallax.setStateOn(!$pref::Video::disableParallaxMapping); + + GraphicsMenuAO.setStateOn($pref::PostFX::EnableSSAO); + GraphicsMenuHDR.setStateOn($pref::PostFX::EnableHDR); + GraphicsMenuDOF.setStateOn($pref::PostFX::EnableDOF); + GraphicsMenuVignette.setStateOn($pref::PostFX::EnableVignette); + GraphicsMenuLightRay.setStateOn($pref::PostFX::EnableLightRays); +} + +function GraphicsMenuOKButton::onClick(%this) +{ + //save the settings and then back out + GraphicsMenu.apply(); + OptionsMenu.backOut(); +} + +function GraphicsMenu::initResMenu( %this ) +{ + // Clear out previous values + %resMenu = GraphicsMenuResolution; + %resMenu.clear(); + + // If we are in a browser then we can't change our resolution through + // the options dialog + if (getWebDeployment()) + { + %count = 0; + %currRes = getWords(Canvas.getVideoMode(), $WORD::RES_X, $WORD::RES_Y); + %resMenu.add(%currRes, %count); + %count++; + + return; + } + + // Loop through all and add all valid resolutions + %count = 0; + %resCount = Canvas.getModeCount(); + for (%i = 0; %i < %resCount; %i++) + { + %testResString = Canvas.getMode( %i ); + %testRes = _makePrettyResString( %testResString ); + + // Only add to list if it isn't there already. + if (%resMenu.findText(%testRes) == -1) + { + %resMenu.add(%testRes, %i); + %count++; + } + } + + %resMenu.sort(); +} + +function GraphicsQualityPopup::init( %this, %qualityGroup ) +{ + assert( isObject( %this ) ); + assert( isObject( %qualityGroup ) ); + + %this.qualityGroup = %qualityGroup; + + // Clear the existing content first. + %this.clear(); + + // Fill it. + %select = -1; + for ( %i=0; %i < %qualityGroup.getCount(); %i++ ) + { + %level = %qualityGroup.getObject( %i ); + if ( %level.isCurrent() ) + %select = %i; + + %this.add( %level.displayName, %i ); + } + + // Setup a default selection. + if ( %select == -1 ) + %this.setText( "Custom" ); + else + %this.setSelected( %select ); +} + +function GraphicsQualityPopup::apply( %this ) +{ + %levelName = %this.getText(); + %this.qualityGroup.applySetting(%levelName); +} +// +function GraphicsMenu::Autodetect(%this) +{ + $pref::Video::autoDetect = false; + + %shaderVer = getPixelShaderVersion(); + %intel = ( strstr( strupr( getDisplayDeviceInformation() ), "INTEL" ) != -1 ) ? true : false; + %videoMem = GFXCardProfilerAPI::getVideoMemoryMB(); + + return %this.Autodetect_Apply( %shaderVer, %intel, %videoMem ); +} + +function GraphicsMenu::Autodetect_Apply(%this, %shaderVer, %intel, %videoMem ) +{ + if ( %shaderVer < 2.0 ) + { + return "Your video card does not meet the minimum requirment of shader model 2.0."; + } + + if ( %shaderVer < 3.0 || %intel ) + { + // Allow specular and normals for 2.0a and 2.0b + if ( %shaderVer > 2.0 ) + { + MeshQualityGroup.applySetting("Lowest"); + TextureQualityGroup.applySetting("Lowest"); + GroundCoverDensityGroup.applySetting("Lowest"); + DecalLifetimeGroup.applySetting("None"); + TerrainQualityGroup.applySetting("Lowest"); + ShaderQualityGroup.applySetting("High"); + + ShadowQualityList.applySetting("None"); + + SoftShadowList.applySetting("Off"); + + $pref::Shadows::useShadowCaching = true; + + $pref::Water::disableTrueReflections = true; + $pref::Video::disableParallaxMapping = true; + $pref::PostFX::EnableSSAO = false; + $pref::PostFX::EnableHDR = false; + $pref::PostFX::EnableDOF = false; + $pref::PostFX::EnableLightRays = false; + $pref::PostFX::EnableVignette = false; + + $pref::Video::AA = 0; + $pref::Video::disableVerticalSync = 0; + } + else + { + MeshQualityGroup.applySetting("Lowest"); + TextureQualityGroup.applySetting("Lowest"); + GroundCoverDensityGroup.applySetting("Lowest"); + DecalLifetimeGroup.applySetting("None"); + TerrainQualityGroup.applySetting("Lowest"); + ShaderQualityGroup.applySetting("Low"); + + ShadowQualityList.applySetting("None"); + + SoftShadowList.applySetting("Off"); + + $pref::Shadows::useShadowCaching = true; + + $pref::Water::disableTrueReflections = true; + $pref::Video::disableParallaxMapping = true; + $pref::PostFX::EnableSSAO = false; + $pref::PostFX::EnableHDR = false; + $pref::PostFX::EnableDOF = false; + $pref::PostFX::EnableLightRays = false; + $pref::PostFX::EnableVignette = false; + + $pref::Video::AA = 0; + $pref::Video::disableVerticalSync = 0; + } + } + else + { + if ( %videoMem > 1000 ) + { + MeshQualityGroup.applySetting("High"); + TextureQualityGroup.applySetting("High"); + GroundCoverDensityGroup.applySetting("High"); + DecalLifetimeGroup.applySetting("High"); + TerrainQualityGroup.applySetting("High"); + ShaderQualityGroup.applySetting("High"); + + ShadowQualityList.applySetting("High"); + + SoftShadowList.applySetting("High"); + + //Should this default to on in ultra settings? + $pref::Shadows::useShadowCaching = true; + + $pref::Water::disableTrueReflections = false; + $pref::Video::disableParallaxMapping = false; + $pref::PostFX::EnableSSAO = true; + $pref::PostFX::EnableHDR = true; + $pref::PostFX::EnableDOF = true; + $pref::PostFX::EnableLightRays = true; + $pref::PostFX::EnableVignette = true; + + $pref::Video::AA = 4; + $pref::Video::disableVerticalSync = 16; + } + else if ( %videoMem > 400 || %videoMem == 0 ) + { + MeshQualityGroup.applySetting("Medium"); + TextureQualityGroup.applySetting("Medium"); + GroundCoverDensityGroup.applySetting("Medium"); + DecalLifetimeGroup.applySetting("Medium"); + TerrainQualityGroup.applySetting("Medium"); + ShaderQualityGroup.applySetting("High"); + + ShadowQualityList.applySetting("Medium"); + + SoftShadowList.applySetting("Low"); + + $pref::Shadows::useShadowCaching = true; + + $pref::Water::disableTrueReflections = false; + $pref::Video::disableParallaxMapping = true; + $pref::PostFX::EnableSSAO = false; + $pref::PostFX::EnableHDR = true; + $pref::PostFX::EnableDOF = true; + $pref::PostFX::EnableLightRays = true; + $pref::PostFX::EnableVignette = true; + + $pref::Video::AA = 4; + $pref::Video::disableVerticalSync = 4; + + if ( %videoMem == 0 ) + return "Torque was unable to detect available video memory. Applying 'Medium' quality."; + } + else + { + MeshQualityGroup.applySetting("Low"); + TextureQualityGroup.applySetting("Low"); + GroundCoverDensityGroup.applySetting("Low"); + DecalLifetimeGroup.applySetting("Low"); + TerrainQualityGroup.applySetting("Low"); + ShaderQualityGroup.applySetting("Low"); + + ShadowQualityList.applySetting("None"); + + SoftShadowList.applySetting("Off"); + + $pref::Shadows::useShadowCaching = true; + + $pref::Water::disableTrueReflections = false; + $pref::Video::disableParallaxMapping = true; + $pref::PostFX::EnableSSAO = false; + $pref::PostFX::EnableHDR = false; + $pref::PostFX::EnableDOF = false; + $pref::PostFX::EnableLightRays = false; + $pref::PostFX::EnableVignette = false; + + $pref::Video::AA = 0; + $pref::Video::disableVerticalSync = 0; + } + } + + %this.refresh(); + + %this.apply(); + + //force postFX updates + PostFXManager.settingsEffectSetEnabled("SSAO", $pref::PostFX::EnableSSAO); + PostFXManager.settingsEffectSetEnabled("HDR", $pref::PostFX::EnableHDR); + PostFXManager.settingsEffectSetEnabled("DOF", $pref::PostFX::EnableDOF); + PostFXManager.settingsEffectSetEnabled("LightRays", $pref::PostFX::EnableLightRays); + PostFXManager.settingsEffectSetEnabled("Vignette", $pref::PostFX::EnableVignette); + + return "Graphics quality settings have been auto detected."; +} + +function _makePrettyResString( %resString ) +{ + %width = getWord( %resString, $WORD::RES_X ); + %height = getWord( %resString, $WORD::RES_Y ); + + %aspect = %width / %height; + %aspect = mRound( %aspect * 100 ) * 0.01; + + switch$( %aspect ) + { + case "1.33": + %aspect = "4:3"; + case "1.78": + %aspect = "16:9"; + default: + %aspect = ""; + } + + %outRes = %width @ " x " @ %height; + if ( %aspect !$= "" ) + %outRes = %outRes @ " (" @ %aspect @ ")"; + + return %outRes; +} + +// +function GraphicsMenuSetting::init( %this ) +{ + assert( isObject( %this ) ); + assert( isObject( %this.qualitySettingGroup ) ); + + // Fill it. + %select = -1; + %selectedName = ""; + for ( %i=0; %i < %this.qualitySettingGroup.getCount(); %i++ ) + { + %level = %this.qualitySettingGroup.getObject( %i ); + + %levelName = %level.displayName; + if ( %level.isCurrent() ) + { + %select = %i; + %selectedName = %level.displayName; + } + } + + // Setup a default selection. + if ( %select == -1 ) + { + %this-->SettingText.setText( "Custom" ); + %this.selectedLevel = %this.qualitySettingGroup.getCount(); + } + else + { + %this-->SettingText.setText(%selectedName); + %this.selectedLevel = %select; + } +} + +function GraphicsQualityLevel::isCurrent( %this ) +{ + // Test each pref to see if the current value + // equals our stored value. + + for ( %i=0; %i < %this.count(); %i++ ) + { + %pref = %this.getKey( %i ); + %value = %this.getValue( %i ); + + if ( getVariable( %pref ) !$= %value ) + return false; + } + + return true; +} + +function GraphicsQualityLevel::apply( %this ) +{ + for ( %i=0; %i < %this.count(); %i++ ) + { + %pref = %this.getKey( %i ); + %value = %this.getValue( %i ); + setVariable( %pref, %value ); + } + + // If we have an overloaded onApply method then + // call it now to finalize the changes. + if ( %this.isMethod( "onApply" ) ) + %this.onApply(); + else + { + %group = %this.getGroup(); + if ( isObject( %group ) && %group.isMethod( "onApply" ) ) + %group.onApply( %this ); + } +} + +function GraphicsOptionsMenuGroup::applySetting(%this, %settingName) +{ + for(%i=0; %i < %this.getCount(); %i++) + { + %setting = %this.getObject(%i); + if(%setting.displayName $= %settingName) + { + for ( %s=0; %s < %setting.count(); %s++ ) + { + %pref = %setting.getKey( %s ); + %value = %setting.getValue( %s ); + setVariable( %pref, %value ); + } + } + } +} + +function GraphicsMenu::apply(%this) +{ + %newAdapter = GraphicsMenuDriver.getText(); + %numAdapters = GFXInit::getAdapterCount(); + %newDevice = $pref::Video::displayDevice; + + for( %i = 0; %i < %numAdapters; %i ++ ) + { + if( GFXInit::getAdapterName( %i ) $= %newAdapter ) + { + %newDevice = GFXInit::getAdapterType( %i ); + break; + } + } + + // Change the device. + if ( %newDevice !$= $pref::Video::displayDevice ) + { + if ( %testNeedApply ) + return true; + + $pref::Video::displayDevice = %newDevice; + if( %newAdapter !$= getDisplayDeviceInformation() ) + MessageBoxOK( "Change requires restart", "Please restart the game for a display device change to take effect." ); + } + + GraphicsMenuShadowQlty.apply(); + GraphicsMenuSoftShadow.apply(); + + GraphicsMenuModelDtl.apply(); + GraphicsMenuTextureDtl.apply(); + GraphicsMenuTerrainDtl.apply(); + GraphicsMenuDecalLife.apply(); + GraphicsMenuGroundClutter.apply(); + + GraphicsMenuMaterialQlty.apply(); + + //Update Textures + reloadTextures(); + + //Update lighting + // Set the light manager. This should do nothing + // if its already set or if its not compatible. + setLightManager( $pref::lightManager ); + + PostFXManager.settingsEffectSetEnabled("SSAO", $pref::PostFX::EnableSSAO); + PostFXManager.settingsEffectSetEnabled("HDR", $pref::PostFX::EnableHDR); + PostFXManager.settingsEffectSetEnabled("DOF", $pref::PostFX::EnableDOF); + PostFXManager.settingsEffectSetEnabled("LightRays", $pref::PostFX::EnableLightRays); + PostFXManager.settingsEffectSetEnabled("Vignette", $pref::PostFX::EnableVignette); + + $pref::Video::disableParallaxMapping = !GraphicsMenuParallax.isStateOn(); + + //water reflections + $pref::Water::disableTrueReflections = !GraphicsMenuWaterRefl.isStateOn(); + + //Update the display settings now + $pref::Video::Resolution = getWords( Canvas.getMode( GraphicsMenuResolution.getSelected() ), $WORD::RES_X, $WORD::RES_Y ); + %newBpp = 32; // ... its not 1997 anymore. + $pref::Video::FullScreen = GraphicsMenuFullScreen.isStateOn() ? "true" : "false"; + $pref::Video::RefreshRate = GraphicsMenuRefreshRate.getSelected(); + $pref::Video::disableVerticalSync = !GraphicsMenuVSync.isStateOn(); + $pref::Video::AA = GraphicsMenuAA.getSelected(); + + if ( %newFullScreen $= "false" ) + { + // If we're in windowed mode switch the fullscreen check + // if the resolution is bigger than the desktop. + %deskRes = getDesktopResolution(); + %deskResX = getWord(%deskRes, $WORD::RES_X); + %deskResY = getWord(%deskRes, $WORD::RES_Y); + if ( getWord( %newRes, $WORD::RES_X ) > %deskResX || + getWord( %newRes, $WORD::RES_Y ) > %deskResY ) + { + $pref::Video::FullScreen = "true"; + GraphicsMenuFullScreen.setStateOn( true ); + } + } + + // Build the final mode string. + %newMode = $pref::Video::Resolution SPC $pref::Video::FullScreen SPC %newBpp SPC $pref::Video::RefreshRate SPC $pref::Video::AA; + + // Change the video mode. + if ( %newMode !$= $pref::Video::mode || + %newVsync != $pref::Video::disableVerticalSync ) + { + if ( %testNeedApply ) + return true; + + $pref::Video::mode = %newMode; + $pref::Video::disableVerticalSync = %newVsync; + configureCanvas(); + } + + // Check the anisotropic filtering. + %level = GraphicsMenuAniso.getSelected(); + if ( %level != $pref::Video::defaultAnisotropy ) + { + if ( %testNeedApply ) + return true; + + $pref::Video::defaultAnisotropy = %level; + } + + echo("Exporting client prefs"); + %prefPath = getPrefpath(); + export("$pref::*", %prefPath @ "/clientPrefs.cs", false); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/RecordingsDlg.gui b/Templates/BaseGame/game/data/ui/scripts/guis/RecordingsDlg.gui new file mode 100644 index 000000000..0e863fff5 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/RecordingsDlg.gui @@ -0,0 +1,230 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(recordingsDlg) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + helpTag = "0"; + + new GuiWindowCtrl() { + text = "Demo Recordings"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(recordingsDlg);"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "247 215"; + extent = "530 338"; + minExtent = "48 92"; + horizSizing = "center"; + vertSizing = "center"; + profile = "GuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "23 60"; + extent = "484 237"; + minExtent = "32 32"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextListCtrl(RecordingsDlgList) { + columns = "0"; + fitParentWidth = "1"; + clipColumnText = "0"; + position = "1 1"; + extent = "469 32"; + minExtent = "8 20"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextArrayProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl(DR_CancelBtn) { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "396 306"; + extent = "110 20"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "top"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(recordingsDlg);"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(DR_StartDemoBtn) { + text = "Play"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "25 305"; + extent = "110 20"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "top"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "StartSelectedDemo();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "During gameplay press the following keys:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "23 30"; + extent = "206 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Start = F3"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "253 32"; + extent = "50 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Stop = F4"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "320 32"; + extent = "49 13"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(DR_DelDemoBtn) { + text = "Delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "210 305"; + extent = "110 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "deleteDemoRecord();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/chooseLevelDlg.gui b/Templates/BaseGame/game/data/ui/scripts/guis/chooseLevelDlg.gui new file mode 100644 index 000000000..d6dec3e48 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/chooseLevelDlg.gui @@ -0,0 +1,287 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ChooseLevelDlg) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + Enabled = "1"; + launchInEditor = "0"; + returnGui = "MainMenuGui"; + + new GuiControl(ChooseLevelWindow) { + position = "80 36"; + extent = "770 616"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "./art/no-preview"; + wrap = "0"; + position = "369 31"; + extent = "400 300"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "CurrentPreview"; + canSave = "1"; + canSaveDynamicFields = "1"; + Enabled = "1"; + }; + new GuiTextCtrl() { + text = "Empty Room"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "370 335"; + extent = "90 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "levelName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Description:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "370 354"; + extent = "91 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + position = "370 380"; + extent = "165 28"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMLWhiteTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "LevelDescription"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "./art/previous-button"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "2 -1"; + extent = "368 33"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "0"; + active = "1"; + command = "ChooseLevelWindow.previousPreviews();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "PreviousSmallPreviews"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + Enabled = "1"; + wrap = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "./art/next-button"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "-3 549"; + extent = "374 33"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "0"; + active = "1"; + command = "ChooseLevelWindow.nextPreviews();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "NextSmallPreviews"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + Enabled = "1"; + wrap = "0"; + }; + new GuiTextListCtrl(CL_levelList) { + columns = "0"; + fitParentWidth = "1"; + clipColumnText = "0"; + position = "-7 1"; + extent = "80 30"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextArrayProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiDynamicCtrlArrayControl() { + colCount = "1"; + colSize = "368"; + rowCount = "14"; + rowSize = "35"; + rowSpacing = "0"; + colSpacing = "10"; + frozen = "0"; + autoCellSize = "1"; + fillRowFirst = "0"; + dynamicSize = "0"; + padding = "0 0 0 0"; + position = "2 33"; + extent = "368 516"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "SmallPreviews"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl() { + text = "Empty"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "0 0"; + extent = "368 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "ChooseLevelWindow.previewSelected(ChooseLevelWindow->SmallPreviews->SmallPreview0);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "SmallPreview0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl(ChooseLevelDlgGoBtn) { + text = "Start Level"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "371 583"; + extent = "399 33"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(ChooseLevelDlgBackBtn) { + text = "Return to Menu"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 583"; + extent = "371 33"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(ChooseLevelDlg);\n\nif(isObject(ChooseLevelDlg.returnGui) && ChooseLevelDlg.returnGui.isMethod(\"onReturnTo\")) ChooseLevelDlg.returnGui.onReturnTo();"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/controlsMenuSetting.taml b/Templates/BaseGame/game/data/ui/scripts/guis/controlsMenuSetting.taml new file mode 100644 index 000000000..f0da59eed --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/controlsMenuSetting.taml @@ -0,0 +1,102 @@ + + + + + + + diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/graphicsMenuSettingsCtrl.taml b/Templates/BaseGame/game/data/ui/scripts/guis/graphicsMenuSettingsCtrl.taml new file mode 100644 index 000000000..b5beaf713 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/graphicsMenuSettingsCtrl.taml @@ -0,0 +1,159 @@ + + + + + + + + + + diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/graphicsMenuSettingsSlider.taml b/Templates/BaseGame/game/data/ui/scripts/guis/graphicsMenuSettingsSlider.taml new file mode 100644 index 000000000..4bbc1c982 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/graphicsMenuSettingsSlider.taml @@ -0,0 +1,140 @@ + + + + + + + + + diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/joinServerMenu.gui b/Templates/BaseGame/game/data/ui/scripts/guis/joinServerMenu.gui new file mode 100644 index 000000000..96545c438 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/joinServerMenu.gui @@ -0,0 +1,455 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(JoinServerMenu) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiControl(JoinServerWindow) { + position = "80 36"; + extent = "800 616"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl(JS_status) { + text = "No servers found."; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "277 31"; + extent = "148 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "10 80"; + extent = "780 461"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextListCtrl(JS_serverList) { + columns = "0 200 270 335 400"; + fitParentWidth = "1"; + clipColumnText = "0"; + position = "1 1"; + extent = "762 8"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextArrayProfile"; + visible = "1"; + active = "1"; + altCommand = "JoinServerDlg.join();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "116 31"; + extent = "144 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Player::Name"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Player Name:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 31"; + extent = "98 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Players"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "269 59"; + extent = "36 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMLWhiteTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Version"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "335 59"; + extent = "38 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMLWhiteTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Game"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "412 59"; + extent = "28 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMLWhiteTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Ping"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "212 59"; + extent = "20 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMLWhiteTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Server Name"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 59"; + extent = "63 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMLWhiteTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiControl(JS_queryStatus) { + position = "10 541"; + extent = "778 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiProgressCtrl(JS_statusBar) { + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "84 0"; + extent = "695 35"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiProgressProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(JS_cancelQuery) { + text = "Cancel!"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 0"; + extent = "84 35"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "JoinServerDlg.cancel();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(JS_statusText) { + text = "Querying master server"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "84 0"; + extent = "695 35"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl(JoinServerBackBtn) { + text = "Return to Menu"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 583"; + extent = "160 33"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(JoinServerMenu);\n\nif(isObject(JoinServerMenu.returnGui) && JoinServerMenu.returnGui.isMethod(\"onReturnTo\")) JoinServerMenu.returnGui.onReturnTo();"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(JoinServerQryLanBtn) { + text = "Query Lan"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "160 583"; + extent = "160 33"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "JoinServerMenu.queryLan();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(JoinServerQryInternetBtn) { + text = "Query Internet"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "320 583"; + extent = "160 33"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "JoinServerMenu.query();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(JoinServerRefreshBtn) { + text = "Refresh Server"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "480 583"; + extent = "160 33"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "JoinServerMenu.refresh();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(JoinServerJoinBtn) { + text = "Join Server"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "640 583"; + extent = "160 33"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "0"; + command = "JoinServerMenu.join();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/loadingGui.gui b/Templates/BaseGame/game/data/ui/scripts/guis/loadingGui.gui new file mode 100644 index 000000000..d51d9d94c --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/loadingGui.gui @@ -0,0 +1,102 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiChunkedBitmapCtrl(LoadingGui) { + bitmap = "data/ui/art/background-dark.png"; + useVariable = "0"; + tile = "0"; + position = "0 0"; + extent = "1600 838"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + Enabled = "1"; + + new GuiControl() { + position = "391 429"; + extent = "497 166"; + minExtent = "8 8"; + horizSizing = "center"; + vertSizing = "center"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "disconnect();\nCanvas.setContent(MainMenuGui);"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl(LoadingLogo) { + bitmap = "data/ui/art/Torque-3D-logo.png"; + wrap = "0"; + position = "27 6"; + extent = "443 139"; + minExtent = "8 2"; + horizSizing = "center"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiProgressBitmapCtrl(LoadingProgress) { + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "17 126"; + extent = "464 24"; + minExtent = "8 2"; + horizSizing = "center"; + vertSizing = "bottom"; + profile = "GuiProgressBitmapProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(LoadingProgressTxt) { + text = "LOADING DATABLOCKS"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "28 144"; + extent = "440 20"; + minExtent = "8 8"; + horizSizing = "center"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/mainMenu.gui b/Templates/BaseGame/game/data/ui/scripts/guis/mainMenu.gui new file mode 100644 index 000000000..a757274ed --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/mainMenu.gui @@ -0,0 +1,194 @@ +exec( "tools/gui/profiles.ed.cs" ); + +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiChunkedBitmapCtrl(MainMenuGui) { + bitmap = "data/ui/art/background-dark.png"; + useVariable = "0"; + tile = "0"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + Enabled = "1"; + isDecoy = "0"; + + new GuiBitmapButtonCtrl(MainMenuAppLogo) { + bitmap = "data/ui/art/Torque-3D-logo-shortcut.png"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "368 30"; + extent = "443 139"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "gotoWebPage(\"forums.torque3d.org\");"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "1"; + + }; + new GuiControl(MainMenuButtonContainer) { + position = "67 321"; + extent = "442 381"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "center"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiDynamicCtrlArrayControl() { + colCount = "1"; + colSize = "442"; + rowCount = "9"; + rowSize = "40"; + rowSpacing = "0"; + colSpacing = "0"; + frozen = "0"; + autoCellSize = "1"; + fillRowFirst = "0"; + dynamicSize = "0"; + padding = "0 0 0 0"; + position = "0 0"; + extent = "442 381"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl() { + text = "Singleplayer"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 0"; + extent = "442 40"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiBlankMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "MainMenuGui.openSinglePlayerMenu();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Create Server"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 40"; + extent = "442 40"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiBlankMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "MainMenuGui.openMultiPlayerMenu();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Join Server"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 80"; + extent = "442 40"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiBlankMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.pushDialog(JoinServerMenu);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Options"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 120"; + extent = "442 40"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiBlankMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "MainMenuGui.openOptionsMenu();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Exit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "0 160"; + extent = "442 40"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiBlankMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "quit();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "ExitButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/messageBoxOK.ed.gui b/Templates/BaseGame/game/data/ui/scripts/guis/messageBoxOK.ed.gui new file mode 100644 index 000000000..52e119ea6 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/messageBoxOK.ed.gui @@ -0,0 +1,60 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxOKDlg) { + profile = "GuiOverlayProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiWindowCtrl(MBOKFrame) { + profile = "GuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "170 175"; + extent = "300 107"; + minExtent = "48 95"; + visible = "1"; + helpTag = "0"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = ""; + + new GuiMLTextCtrl(MBOKText) { + profile = "GuiMLTextProfile"; + horizSizing = "center"; + vertSizing = "bottom"; + position = "9 35"; + extent = "281 24"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "111 75"; + extent = "80 24"; + minExtent = "8 8"; + visible = "1"; + command = "MessageCallback(MessageBoxOKDlg,MessageBoxOKDlg.callback);"; + accelerator = "return"; + helpTag = "0"; + text = "Ok"; + simpleStyle = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/messageBoxYesNo.gui b/Templates/BaseGame/game/data/ui/scripts/guis/messageBoxYesNo.gui new file mode 100644 index 000000000..b58aa170b --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/messageBoxYesNo.gui @@ -0,0 +1,126 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxYesNoDlg) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiOverlayProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + helpTag = "0"; + + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "168 352"; + extent = "700 64"; + minExtent = "8 2"; + horizSizing = "center"; + vertSizing = "center"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiChunkedBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + useVariable = "0"; + tile = "0"; + position = "0 0"; + extent = "700 64"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "MessageCallback(MessageBoxYesNoDlg,MessageBoxYesNoDlg.noCallback);"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(MBYesNoText) { + text = "Re-bind \"\" to..."; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "177 8"; + extent = "384 20"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Yes"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "270 36"; + extent = "80 22"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "top"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "MessageCallback(MessageBoxYesNoDlg,MessageBoxYesNoDlg.yesCallback);"; + accelerator = "return"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "No"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "367 36"; + extent = "80 22"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "top"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "MessageCallback(MessageBoxYesNoDlg,MessageBoxYesNoDlg.noCallback);"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/netGraphGui.gui b/Templates/BaseGame/game/data/ui/scripts/guis/netGraphGui.gui new file mode 100644 index 000000000..b034a447e --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/netGraphGui.gui @@ -0,0 +1,557 @@ +function execNetGraphGuiGUI() +{ + if ( isObject( NetGraphGui ) ) + NetGraphGui.delete(); + + if ( isObject( NetGraphProfile ) ) + NetGraphProfile.delete(); + + if ( isObject( NetGraphGhostsActiveProfile ) ) + NetGraphGhostsActiveProfile.delete(); + + if ( isObject( NetGraphGhostUpdatesProfile ) ) + NetGraphGhostUpdatesProfile.delete(); + + if ( isObject( NetGraphBitsSentProfile ) ) + NetGraphBitsSentProfile.delete(); + + if ( isObject( NetGraphBitsReceivedProfile ) ) + NetGraphBitsReceivedProfile.delete(); + + if ( isObject( NetGraphLatencyProfile ) ) + NetGraphLatencyProfile.delete(); + + if ( isObject( NetGraphPacketLossProfile ) ) + NetGraphPacketLossProfile.delete(); + + exec( "./NetGraphGui.gui" ); +} + +// Profiles +new GuiControlProfile (NetGraphProfile) +{ + modal = false; + opaque = false; + canKeyFocus = false; +}; + +new GuiControlProfile (NetGraphKeyContainerProfile) +{ + border = true; + opaque = true; + fillColor = "100 100 100 200"; +}; +new GuiControlProfile (NetGraphGhostsActiveProfile) +{ + border = false; + fontColor = "255 255 255"; +}; +new GuiControlProfile (NetGraphGhostUpdatesProfile) +{ + border = false; + fontColor = "255 0 0"; +}; +new GuiControlProfile (NetGraphBitsSentProfile) +{ + border = false; + fontColor = "0 255 0"; +}; +new GuiControlProfile (NetGraphBitsReceivedProfile) +{ + border = false; + fontColor = "0 0 255"; +}; +new GuiControlProfile (NetGraphLatencyProfile) +{ + border = false; + fontColor = "0 255 255"; +}; +new GuiControlProfile (NetGraphPacketLossProfile) +{ + border = false; + fontColor = "0 0 0"; +}; + +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(NetGraphGui) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "NetGraphProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + noCursor = "1"; + + new GuiGraphCtrl(NetGraph) { + centerY = "1"; + plotColor[0] = "1 1 1 1"; + plotColor[1] = "1 0 0 1"; + plotColor[2] = "0 1 0 1"; + plotColor[3] = "0 0 1 1"; + plotColor[4] = "0 1 1 1"; + plotColor[5] = "0 0 0 1"; + plotType[0] = "PolyLine"; + plotType[1] = "PolyLine"; + plotType[2] = "PolyLine"; + plotType[3] = "PolyLine"; + plotType[4] = "PolyLine"; + plotType[5] = "PolyLine"; + plotInterval[0] = "0"; + plotInterval[1] = "0"; + plotInterval[2] = "0"; + plotInterval[3] = "0"; + plotInterval[4] = "0"; + plotInterval[5] = "0"; + position = "816 5"; + extent = "200 200"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "NetGraphKeyContainerProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + position = "816 205"; + extent = "200 104"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "NetGraphKeyContainerProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl(GhostsActive) { + text = "Ghosts Active"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "100 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "NetGraphGhostsActiveProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(GhostUpdates) { + text = "Ghost Updates"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "100 0"; + extent = "100 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "NetGraphGhostUpdatesProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(BitsSent) { + text = "Bytes Sent"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 18"; + extent = "100 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "NetGraphBitsSentProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(BitsReceived) { + text = "Bytes Received"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "100 18"; + extent = "100 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "NetGraphBitsReceivedProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(Latency) { + text = "Latency"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 36"; + extent = "100 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "NetGraphLatencyProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(PacketLoss) { + text = "Packet Loss"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "100 36"; + extent = "59 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "NetGraphPacketLossProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Network Simulation:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 52"; + extent = "97 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "NetGraphPacketLossProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Simulated Latency:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 68"; + extent = "91 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "NetGraphPacketLossProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "ms"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "179 68"; + extent = "20 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "NetGraphPacketLossProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(NetGraphSimLatency) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "112 67"; + extent = "64 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Simulated Packet Loss:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 83"; + extent = "111 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "NetGraphPacketLossProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "%"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "179 84"; + extent = "20 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "NetGraphPacketLossProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(NetGraphSimPacket) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "112 85"; + extent = "64 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + command = "if(NetGraphSimLatency.text $= \"\" || NetGraphSimLatency.text < 0)\n{\n NetGraphSimLatency.text = 0;\n}\n\nif(NetGraphSimPacket.text $= \"\" || NetGraphSimPacket.text < 0)\n{\n NetGraphSimLatency.text = 0;\n}\nelse if(NetGraphSimPacket.text > 100)\n{\n NetGraphSimPacket.text = 100;\n}\n\nnetSimulateLag( NetGraphSimLatency.text, NetGraphSimPacket.text );"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +// Functions +function toggleNetGraph() +{ + if(!$NetGraph::isInitialized) + { + NetGraph::updateStats(); + $NetGraph::isInitialized = true; + } + + if(!Canvas.isMember(NetGraphGui)) + { + Canvas.add(NetGraphGui); + } + else + { + Canvas.remove(NetGraphGui); + netSimulateLag( 0, 0 ); + } +} + +function NetGraph::updateStats() +{ + $NetGraphThread = NetGraph.schedule(32, "updateStats"); + + if(!$Stats::netGhostUpdates) + return; + + if(isobject(NetGraph)) + { + if(isobject(ServerConnection)) + NetGraph.addDatum(0,ServerConnection.getGhostsActive()); + GhostsActive.setText("Ghosts Active: " @ ServerConnection.getGhostsActive()); + NetGraph.addDatum(1,$Stats::netGhostUpdates); + GhostUpdates.setText("Ghost Updates: " @ $Stats::netGhostUpdates); + NetGraph.addDatum(2,$Stats::netBitsSent); + BitsSent.setText("Bytes Sent: " @ $Stats::netBitsSent); + NetGraph.addDatum(3,$Stats::netBitsReceived); + BitsReceived.setText("Bytes Received: " @ $Stats::netBitsReceived); + NetGraph.matchScale(2,3); + NetGraph.addDatum(4,ServerConnection.getPing()); + Latency.setText("Latency: " @ ServerConnection.getPing()); + NetGraph.addDatum(5,ServerConnection.getPacketLoss()); + PacketLoss.setText("Packet Loss: " @ ServerConnection.getPacketLoss()); + } +} + +function NetGraph::toggleKey() +{ + if(!GhostsActive.visible) + { + GhostsActive.visible = 1; + GhostUpdates.visible = 1; + BitsSent.visible = 1; + BitsReceived.visible = 1; + Latency.visible = 1; + PacketLoss.visible = 1; + } + else + { + GhostsActive.visible = 0; + GhostUpdates.visible = 0; + BitsSent.visible = 0; + BitsReceived.visible = 0; + Latency.visible = 0; + PacketLoss.visible = 0; + } +} + +function NetGraphSimLatency::onReturn(%this) +{ + NetGraph.updateNetworkSimulation(); +} + +function NetGraphSimPacket::onReturn(%this) +{ + NetGraph.updateNetworkSimulation(); +} + +function NetGraph::updateNetworkSimulation(%this) +{ + %latency = NetGraphSimLatency.getText(); + + if(%latency $= "" || %latency < 0) + { + NetGraphSimLatency.text = 0; + %latency = 0; + } + + %packetLoss = NetGraphSimPacket.getText(); + + if(%packetLoss $= "" || %packetLoss < 0) + { + NetGraphSimLatency.text = 0; + %packetLoss = 0; + } + else if(%packetLoss > 100) + { + NetGraphSimPacket.text = 100; + %packetLoss = 100; + } + + netSimulateLag( %latency, %packetLoss ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/optionsDlg.gui b/Templates/BaseGame/game/data/ui/scripts/guis/optionsDlg.gui new file mode 100644 index 000000000..fcff1cb95 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/optionsDlg.gui @@ -0,0 +1,1417 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(OptionsDlg) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiOverlayProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + fixedAspectRatio = "0"; + + new GuiWindowCtrl() { + text = "Options"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(optionsDlg);"; + edgeSnap = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "323 232"; + extent = "377 303"; + minExtent = "8 8"; + horizSizing = "center"; + vertSizing = "center"; + profile = "GuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl() { + text = "Done"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "306 271"; + extent = "60 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(optionsDlg);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapBorderCtrl() { + position = "9 55"; + extent = "358 210"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBorderProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "OptControlsPane"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 24"; + extent = "347 152"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextListCtrl() { + columns = "0 160"; + fitParentWidth = "1"; + clipColumnText = "0"; + position = "1 1"; + extent = "329 780"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + altCommand = "OptionsDlg.doRemap();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "OptRemapList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTextCtrl() { + text = "Control Name"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 6"; + extent = "64 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Control Binding"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "165 6"; + extent = "72 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + new GuiSliderCtrl(OptMouseSensitivity) { + range = "0.02 2"; + ticks = "10"; + value = "0.75"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "105 182"; + Extent = "244 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "OptMouseSetSensitivity(OptMouseSensitivity.value);"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Mouse Sensitivity:"; + maxLength = "255"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "15 182"; + Extent = "85 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + position = "9 55"; + extent = "358 210"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBorderProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "OptAudioPane"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + position = "149 10"; + extent = "190 14"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMLTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptAudioInfo"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Audio Provider:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "16 16"; + extent = "75 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(OptAudioProviderList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Null"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "101 15"; + extent = "240 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Audio Device:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "23 48"; + extent = "75 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(OptAudioDeviceList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "SFX Null Device"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "101 47"; + extent = "240 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + position = "18 84"; + extent = "325 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Master Volume"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "72 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0 1"; + ticks = "0"; + snap = "0"; + value = "0.8"; + position = "85 1"; + extent = "240 14"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + altCommand = "OptAudioUpdateMasterVolume( $thisControl.value );"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptAudioVolumeMaster"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "9 115"; + extent = "334 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Interface Volume"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "82 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0 1"; + ticks = "0"; + snap = "0"; + value = "1"; + position = "94 2"; + extent = "240 13"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + altCommand = "OptAudioUpdateChannelVolume(AudioGui, $thisControl.value);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptAudioVolumeShell"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "18 146"; + extent = "325 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Effects Volume"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "74 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0 1"; + ticks = "0"; + snap = "0"; + value = "1"; + position = "85 2"; + extent = "240 13"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + altCommand = "OptAudioUpdateChannelVolume(AudioEffect, $thisControl.value);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptAudioVolumeSim"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "23 177"; + extent = "320 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSliderCtrl() { + range = "0 1"; + ticks = "0"; + snap = "0"; + value = "1"; + position = "80 2"; + extent = "240 13"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + altCommand = "OptAudioUpdateChannelVolume(AudioMusic, $thisControl.value);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptAudioVolumeMusic"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Music Volume"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "67 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiBitmapBorderCtrl() { + position = "9 55"; + extent = "358 210"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "OptGraphicsPane"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Display Driver:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 8"; + extent = "70 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Resolution:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 35"; + extent = "53 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + text = "Fullscreen"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "11 62"; + extent = "85 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptGraphicsFullscreenToggle"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(OptGraphicsDriverMenu) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "ATI Radeon HD 5700 Series (D3D9)"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "88 8"; + extent = "258 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "1024 x 768 (4:3)"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "67 35"; + extent = "127 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptGraphicsResolutionMenu"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Refresh:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "207 35"; + extent = "45 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "60"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "252 35"; + extent = "49 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptRefreshSelectMenu"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Mesh Quality:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "21 91"; + extent = "62 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Low"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "90 91"; + extent = "78 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptMeshQualityPopup"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Low"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "90 118"; + extent = "78 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptTextureQualityPopup"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Texture Quality:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 118"; + extent = "77 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Low"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "90 143"; + extent = "78 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptLightingQualityPopup"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Lighting Quality:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 143"; + extent = "73 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Effect Quality:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "191 91"; + extent = "73 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "263 91"; + extent = "78 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptEffectQualityPopup"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Shader Quality:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "186 118"; + extent = "77 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Low"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "263 118"; + extent = "78 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptShaderQualityPopup"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Particle Quality:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "186 156"; + extent = "73 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "263 156"; + extent = "78 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "0"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptParticleQualityPopup"; + class = "GraphicsQualityPopup"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Anisotropic Filtering:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "22 167"; + extent = "105 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Off"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "123 167"; + extent = "45 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptAnisotropicPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + text = "Vertical Sync"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "92 62"; + extent = "85 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptGraphicsVSyncToggle"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Auto Detect Quality"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "205 152"; + extent = "110 27"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._autoDetectQuality();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "263 62"; + extent = "78 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "OptionsDlg._updateApplyState();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptAAQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Anti-aliasing"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "191 62"; + extent = "73 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + position = "0 190"; + extent = "352 15"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "GammaSliderContainer"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSliderCtrl() { + range = "0.001 2.2"; + ticks = "0"; + snap = "0"; + value = "1"; + position = "76 -1"; + extent = "268 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Video::Gamma"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Gamma:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "22 -4"; + extent = "105 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiControl() { + position = "9 55"; + extent = "357 208"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiWindowProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "OptNetworkPane"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Graphics"; + groupNum = "-1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "9 33"; + extent = "117 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonTabProfile"; + visible = "1"; + active = "1"; + command = "optionsDlg.setPane(Graphics);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "OptGraphicsButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Audio"; + groupNum = "-1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "126 33"; + extent = "117 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonTabProfile"; + visible = "1"; + active = "1"; + command = "optionsDlg.setPane(Audio);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Controls"; + groupNum = "-1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "243 33"; + extent = "117 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonTabProfile"; + visible = "1"; + active = "1"; + command = "optionsDlg.setPane(Controls);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Apply"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "241 271"; + extent = "60 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "0"; + command = "optionsDlg.applyGraphics();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "apply"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/optionsMenu.gui b/Templates/BaseGame/game/data/ui/scripts/guis/optionsMenu.gui new file mode 100644 index 000000000..860850cb3 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/optionsMenu.gui @@ -0,0 +1,5194 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(OptionsMenu) { + position = "0 0"; + extent = "1280 720"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + returnGui = "MainMenuGui"; + tamlReader = "17544"; + tile = "0"; + useVariable = "0"; + + new GuiChunkedBitmapCtrl(OptionsMenuBG) { + useVariable = "0"; + tile = "0"; + position = "278 -645"; + extent = "1440 900"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextCtrl(OptionsMenuHeader) { + text = "Controls"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "59 63"; + extent = "129 43"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + position = "51 118"; + extent = "700 518"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl(OptionsMain) { + position = "1 1"; + extent = "700 320"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "center"; + profile = "GuiDefaultProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl(ControlsSettingsMenuButton) { + text = "Controls Settings"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 0"; + extent = "700 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(GraphicsSettingsMenuButton) { + text = "Graphics Settings"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 35"; + extent = "700 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(AudioSettingsMenuButton) { + text = "Audio Settings"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 105"; + extent = "700 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(ScreenBrSettingsMenuButton) { + text = "Screen Brightness"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 140"; + extent = "700 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(OptionsOKButton) { + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 285"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(OptionsMenu);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "OptionsMenuOKButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(OptionsCancelButton) { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "233 285"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "OptionsMenuCancelButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(OptionsDefaultButton) { + text = "Defaults"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "466 285"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "OptionsMenuDefaultsButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl(GraphicsMenu) { + position = "1 -1"; + extent = "700 519"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl() { + text = "Display"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 0"; + extent = "175 25"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "DisplaySettingsMenu.hidden = false;\nGeneralGraphicsSettingsMenu.hidden = true;"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "General"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "175 0"; + extent = "175 25"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "DisplaySettingsMenu.hidden = true;\nGeneralGraphicsSettingsMenu.hidden = false;"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiContainer(DisplaySettingsMenu) { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 25"; + extent = "700 450"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "700 450"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + position = "0 0"; + extent = "450 80"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { + position = "0 0"; + extent = "450 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "450 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Graphics Driver"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "450 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 20"; + extent = "450 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Driver"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GraphicsMenuDriver) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "NVIDIA GeForce GTX 950 (D3D9)"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 0"; + extent = "275 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiControl() { + position = "0 72"; + extent = "450 220"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { + position = "0 0"; + extent = "450 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "450 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Display Settings"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "450 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 20"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Resolution"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GraphicsMenuResolution) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "1280 x 720 (16:9)"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 40"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Full Screen"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(GraphicsMenuFullScreen) { + text = "Button"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "250 0"; + extent = "20 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 60"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Refresh Rate"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GraphicsMenuRefreshRate) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "60"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 80"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "VSync"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(GraphicsMenuVSync) { + text = "Button"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "250 0"; + extent = "20 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 120"; + extent = "450 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Field of View"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "65 90"; + ticks = "25"; + snap = "1"; + value = "90"; + position = "190 0"; + extent = "209 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Player::defaultFov"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "90"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "410 0"; + extent = "40 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Player::defaultFov"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 160"; + extent = "450 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Gamma"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "2 2.5"; + ticks = "0"; + snap = "0"; + value = "2"; + position = "190 0"; + extent = "261 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Video::Gamma"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 180"; + extent = "450 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Brightness"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "-0.5 0.5"; + ticks = "0"; + snap = "0"; + value = "0"; + position = "190 0"; + extent = "261 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Video::Brightness"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 200"; + extent = "450 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Contrast"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0.5 1.5"; + ticks = "0"; + snap = "0"; + value = "1"; + position = "190 0"; + extent = "261 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Video::Contrast"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiContainer(GeneralGraphicsSettingsMenu) { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 25"; + extent = "700 450"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "700 450"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "700 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "700 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(GraphisMenuPageText) { + text = "Overall Quality"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 0"; + extent = "116 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GraphicsMenuOverallQlty) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "142 0"; + extent = "548 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 25"; + extent = "350 80"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { + position = "0 0"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Lighting"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "350 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 20"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Shadow Quality"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GraphicsMenuShadowQlty) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "High"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 40"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Shadow Caching"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(GraphicsMenuShadowCache) { + text = "Button"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "250 0"; + extent = "20 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Shadows::useShadowCaching"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 60"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Soft Shadows"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GraphicsMenuSoftShadow) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "High"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiControl() { + position = "0 140"; + extent = "350 120"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { + position = "0 0"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Models and Textures"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "350 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 20"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Model Detail"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GraphicsMenuModelDtl) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "High"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 40"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Texture Detail"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GraphicsMenuTextureDtl) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "High"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 60"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Terrain Detail"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GraphicsMenuTerrainDtl) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "High"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 80"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Decal Lifetime"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GraphicsMenuDecalLife) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "High"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 100"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Ground Clutter Density"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GraphicsMenuGroundClutter) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "High"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiControl() { + position = "350 25"; + extent = "350 220"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { + position = "0 0"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Effects"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "350 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 20"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Material Quality"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GraphicsMenuMaterialQlty) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "High"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "GraphicsQualityPopup"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 40"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "High Dynamic Range"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(GraphicsMenuHDR) { + text = "Button"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "250 0"; + extent = "20 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + variable = "$pref::PostFX::EnableHDR"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 60"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Parallax"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(GraphicsMenuParallax) { + text = "Button"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "250 0"; + extent = "20 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 80"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + variable = "$pref::PostFX::EnableSSAO"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Ambient Occlusion"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(GraphicsMenuAO) { + text = "Button"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "250 0"; + extent = "20 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + variable = "$pref::PostFX::EnableSSAO"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 100"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Light Rays"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(GraphicsMenuLightRay) { + text = "Button"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "250 0"; + extent = "20 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + variable = "$pref::PostFX::EnableLightRays"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 120"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Depth of Field"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(GraphicsMenuDOF) { + text = "Button"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "250 0"; + extent = "20 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + variable = "$pref::PostFX::EnableDOF"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 160"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Water Reflections"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(GraphicsMenuWaterRefl) { + text = "Button"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "250 0"; + extent = "20 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 140"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Vignetting"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(GraphicsMenuVignette) { + text = "Button"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "250 0"; + extent = "20 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + variable = "$pref::PostFX::EnableVignette"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 180"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Anti Aliasing"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GraphicsMenuAA) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "4x"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 200"; + extent = "350 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Anisotropic Filtering"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GraphicsMenuAniso) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "16X"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiButtonCtrl() { + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 484"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "GraphicsMenuOKButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "233 484"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "OptionsMenuCancelButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Defaults"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "466 484"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "GraphicsMenu.Autodetect();\nGraphicsMenu.loadSettings();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl(ScreenBrightnessMenu) { + position = "1 1"; + extent = "700 519"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "center"; + profile = "GuiDefaultProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiChunkedBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + useVariable = "0"; + tile = "0"; + position = "0 0"; + extent = "700 450"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/ScreenBrightness_Dark.png"; + wrap = "0"; + position = "0 100"; + extent = "350 200"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl() { + bitmap = "data/ui/art/ScreenBrightness_Light.png"; + wrap = "0"; + position = "350 100"; + extent = "350 200"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Adjust the brightness until only the right side image is visible."; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 400"; + extent = "700 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 484"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "OptionsMenuOKButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "233 484"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "OptionsMenuCancelButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(BrightnessMenuDefaultsButton) { + text = "Defaults"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "466 484"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "OptionsMenuDefaultsButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiChunkedBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + useVariable = "0"; + tile = "0"; + position = "0 450"; + extent = "700 34"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiTextCtrl() { + text = "Screen Brightness"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "350 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl(BrightnessMenuSlider) { + range = "0.001 2.2"; + ticks = "9"; + snap = "1"; + value = "1.1005"; + position = "350 9"; + extent = "340 68"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Video::Gamma"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiControl(ControlsMenu) { + position = "1 1"; + extent = "700 519"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "center"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl() { + text = "Keyboard"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 0"; + extent = "175 25"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "KeyboardControlPanel.hidden = false;\nMouseControlPanel.hidden = true;"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Mouse"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "175 0"; + extent = "175 25"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "KeyboardControlPanel.hidden = true;\nMouseControlPanel.hidden = false;"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Gamepad"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "350 0"; + extent = "175 25"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "0"; + active = "1"; + command = "DisplaySettingsMenu.hidden = true;\nGeneralGraphicsSettingsMenu.hidden = false;"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiControl(KeyboardControlPanel) { + position = "0 25"; + extent = "700 460"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "700 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "700 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Control Set"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 0"; + extent = "116 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(ControlSetList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Movement"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "142 0"; + extent = "548 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer(ControlsSettingsMenu) { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 20"; + extent = "700 440"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "700 440"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiDynamicCtrlArrayControl(ControlsMenuOptionsArray) { + colCount = "1"; + colSize = "700"; + rowCount = "5"; + rowSize = "35"; + rowSpacing = "0"; + colSpacing = "0"; + frozen = "0"; + autoCellSize = "1"; + fillRowFirst = "1"; + dynamicSize = "0"; + padding = "0 0 0 0"; + position = "1 1"; + extent = "685 440"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiContainer(MouseControlPanel) { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 25"; + extent = "700 460"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "700 460"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + position = "0 0"; + extent = "490 202"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { + position = "0 20"; + extent = "490 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Invert Vertical"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "215 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ControlMenuInvertMouse) { + text = "Button"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "258 0"; + extent = "20 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Input::invertVerticalMouse"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 40"; + extent = "490 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Vertical Sensitivity"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "215 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0.1 1"; + ticks = "8"; + snap = "1"; + value = "1"; + position = "215 0"; + extent = "220 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Input::VertMouseSensitivity"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "1"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "440 0"; + extent = "50 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Input::VertMouseSensitivity"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 60"; + extent = "490 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Horizontal Sensitivity"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "215 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0.1 1"; + ticks = "8"; + snap = "1"; + value = "1"; + position = "215 0"; + extent = "220 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Input::HorzMouseSensitivity"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "1"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "440 0"; + extent = "50 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Input::HorzMouseSensitivity"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 80"; + extent = "490 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Zoom Vertical Sensitivity"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "215 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0.1 1"; + ticks = "8"; + snap = "1"; + value = "0.3"; + position = "215 0"; + extent = "220 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Input::ZoomVertMouseSensitivity"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "0.3"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "440 0"; + extent = "50 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Input::ZoomVertMouseSensitivity"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 100"; + extent = "490 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Zoom Horizontal Sensitivity"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "215 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0.1 1"; + ticks = "8"; + snap = "1"; + value = "0.3"; + position = "215 0"; + extent = "220 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Input::ZoomHorzMouseSensitivity"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "0.3"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "440 0"; + extent = "50 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Input::ZoomHorzMouseSensitivity"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiButtonCtrl() { + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 484"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "ControlsMenuOKButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "233 484"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "OptionsMenuCancelButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Defaults"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "466 484"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "ControlsMenuDefaultsButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl(AudioMenu) { + position = "1 1"; + extent = "700 519"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "center"; + profile = "GuiDefaultProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "700 450"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "700 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "700 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(AudioMenuPageText) { + text = "Audio"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "700 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer(AudioSettingsMenu) { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 40"; + extent = "700 442"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiDynamicCtrlArrayControl(AudioMenuOptionsArray) { + colCount = "1"; + colSize = "700"; + rowCount = "6"; + rowSize = "35"; + rowSpacing = "0"; + colSpacing = "0"; + frozen = "0"; + autoCellSize = "1"; + fillRowFirst = "1"; + dynamicSize = "0"; + padding = "0 0 0 0"; + position = "0 0"; + extent = "700 444"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "700 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "GraphicsMenuSetting"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "450 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "450 0"; + extent = "250 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "35 0"; + extent = "180 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "XAudio"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "35 0"; + extent = "180 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "SettingText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = ">"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "215 0"; + extent = "35 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "OptionsMenuForwardSetting"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "<"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 0"; + extent = "35 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "OptionsMenuBackSetting"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTextCtrl() { + text = "Sound Provider"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "450 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "nameText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 35"; + extent = "700 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "GraphicsMenuSetting"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "450 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "450 0"; + extent = "250 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "35 0"; + extent = "180 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Speakers (High Definition Audio Device)"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "35 0"; + extent = "180 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "SettingText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = ">"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "215 0"; + extent = "35 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "OptionsMenuForwardSetting"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "<"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 0"; + extent = "35 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "OptionsMenuBackSetting"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTextCtrl() { + text = "Sound Device"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "450 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "nameText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 70"; + extent = "700 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "450 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "450 0"; + extent = "250 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "250 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0.1 1"; + ticks = "8"; + snap = "1"; + value = "0.8"; + position = "0 0"; + extent = "200 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::SFX::masterVolume"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "slider"; + class = "OptionsMenuSlider"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "8"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "200 0"; + extent = "50 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "valueText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTextCtrl() { + text = "Master Audio Volume"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "450 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "nameText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 105"; + extent = "700 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "450 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "450 0"; + extent = "250 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "250 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0.1 1"; + ticks = "8"; + snap = "1"; + value = "0.1"; + position = "0 0"; + extent = "200 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::SFX::channelVolume[1]"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "slider"; + class = "OptionsMenuSlider"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "10"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "200 0"; + extent = "50 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "valueText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTextCtrl() { + text = "Gui Volume"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "450 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "nameText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 140"; + extent = "700 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "450 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "450 0"; + extent = "250 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "250 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0.1 1"; + ticks = "8"; + snap = "1"; + value = "0.1"; + position = "0 0"; + extent = "200 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::SFX::channelVolume[2]"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "slider"; + class = "OptionsMenuSlider"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "10"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "200 0"; + extent = "50 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "valueText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTextCtrl() { + text = "Effect Volume"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "450 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "nameText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 175"; + extent = "700 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "450 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "450 0"; + extent = "250 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + wrap = "0"; + position = "0 0"; + extent = "250 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0.1 1"; + ticks = "8"; + snap = "1"; + value = "0.1"; + position = "0 0"; + extent = "200 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::SFX::channelVolume[4]"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "slider"; + class = "OptionsMenuSlider"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "10"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "200 0"; + extent = "50 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "valueText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTextCtrl() { + text = "Music Volume"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "450 35"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "nameText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiControl() { + position = "0 40"; + extent = "450 140"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { + position = "0 0"; + extent = "450 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Sound Driver"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(AudioMenuSoundDriver) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "XAudio"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 0"; + extent = "265 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 20"; + extent = "450 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Sound Device"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(AudioMenuSoundDevice) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "Speakers (High Definition Audio Device)"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "175 0"; + extent = "265 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 60"; + extent = "450 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Master Audio Volume"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0.1 1"; + ticks = "8"; + snap = "1"; + value = "1"; + position = "190 0"; + extent = "209 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::SFX::masterVolume"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "1"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "410 0"; + extent = "40 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + variable = "$pref::SFX::masterVolume"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 80"; + extent = "450 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Gui Volume"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0.1 1"; + ticks = "8"; + snap = "1"; + value = "1"; + position = "190 0"; + extent = "209 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::SFX::channelVolume[1]"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "1"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "410 0"; + extent = "40 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + variable = "$pref::SFX::channelVolume[1]"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 100"; + extent = "450 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Effect Volume"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0.1 1"; + ticks = "8"; + snap = "1"; + value = "1"; + position = "190 0"; + extent = "209 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::SFX::channelVolume[2]"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "1"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "410 0"; + extent = "40 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + variable = "$pref::SFX::channelVolume[2]"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "0 120"; + extent = "450 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Music Volume"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "175 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0.1 1"; + ticks = "8"; + snap = "1"; + value = "1"; + position = "190 0"; + extent = "209 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::SFX::channelVolume[4]"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "1"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "410 0"; + extent = "40 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + variable = "$pref::SFX::channelVolume[4]"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiButtonCtrl() { + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 484"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "AudioMenuOKButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "233 484"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "OptionsMenuCancelButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(AudioMenuDefaultsButton) { + text = "Defaults"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "466 484"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "OptionsMenuDefaultsButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/pauseMenu.gui b/Templates/BaseGame/game/data/ui/scripts/guis/pauseMenu.gui new file mode 100644 index 000000000..5995cdf36 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/pauseMenu.gui @@ -0,0 +1,153 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(PauseMenu) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + tamlReader = "19772"; + tile = "0"; + useVariable = "0"; + + new GuiChunkedBitmapCtrl(PauseMenuBG) { + bitmap = "data/ui/art/hudfill"; + useVariable = "0"; + tile = "0"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiControl() { + position = "51 118"; + extent = "700 518"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl(PauseOptionsMain) { + position = "1 1"; + extent = "700 320"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "center"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl(PauseMenuExitButton) { + text = "Exit Game"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 0"; + extent = "700 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "escapeFromGame();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(PauseMenuOptionsButton) { + text = "Options"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 35"; + extent = "700 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "PauseMenu.openOptionsMenu();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(PauseMenuControlsButton) { + text = "Controls"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "0 70"; + extent = "700 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "PauseMenu.openControlsMenu();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(PauseMenuCancelButton) { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + position = "466 285"; + extent = "233 35"; + minExtent = "8 8"; + horizSizing = "relative"; + vertSizing = "bottom"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "OptionsMenuDefaultsButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + accelerator="escape"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/profiler.gui b/Templates/BaseGame/game/data/ui/scripts/guis/profiler.gui new file mode 100644 index 000000000..7c69006c2 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/profiler.gui @@ -0,0 +1,661 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ProfilerGui) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl(ppProfilerWindow) { + text = "Profiler Manager"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(ProfilerGui);"; + edgeSnap = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "306 216"; + extent = "415 199"; + minExtent = "8 8"; + horizSizing = "center"; + vertSizing = "center"; + profile = "GuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiCheckBoxCtrl(ppShowFps) { + text = "Show Fps"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "13 24"; + extent = "127 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable or Disable the Fps counter"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppShowGfx) { + text = "Show Gfx"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "13 40"; + extent = "127 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable or Disable the Gfx"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppShowShadow) { + text = "Show Shadow"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "13 56"; + extent = "127 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable or Disable the Shdow"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppShowNet) { + text = "Show Net"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "13 136"; + extent = "127 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable or Disable the Network activity"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppShowForest) { + text = "Show Forest"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "13 120"; + extent = "127 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable or Disable the Forest"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppShowGroundcover) { + text = "Show Groundcover"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "13 104"; + extent = "127 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable or Disable the Groundcover"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppShowTerrain) { + text = "Show Terrain"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "13 88"; + extent = "127 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable or Disable the Terrain"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(ppShowSfx) { + text = "Show Sfx"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "13 72"; + extent = "127 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Enable or Disable the Sfx"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(ppOptionsEnableDisable) { + text = "On/Off OSD"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "309 38"; + extent = "93 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "showMetrics(true);"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Apply the setting from the dialog box"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(ppOptionsUpdate) { + text = "Update"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "200 38"; + extent = "93 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "showMetrics(false);"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Update the profiler with the new parameters"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(ppOptionsDoProfiling) { + text = "DoProfiling"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "309 141"; + extent = "93 23"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "doProfileFromGui();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Does the profile for the ammount of time specified "; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(DurationLabel) { + text = "Duration[ms]"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "200 144"; + extent = "39 21"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextRightProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(Duration) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "1000"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "249 144"; + extent = "53 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +$MetricsParamArray[0] = "fps "; +$MetricsParamArray[1] = "shadow "; +$MetricsParamArray[2] = "gfx "; +$MetricsParamArray[3] = "sfx "; +$MetricsParamArray[4] = "terrain "; +$MetricsParamArray[5] = "groundcover "; +$MetricsParamArray[6] = "forest "; +$MetricsParamArray[7] = "net "; +$EnableProfiler = false; +$string = ""; //string used to collet the parameters for metrics function + +function showMetrics(%var) +{ + $string = ""; + if(ppShowFps.getValue()) + { + $string = $string @ $MetricsParamArray[0]; + } + if(ppShowShadow.getValue()) + { + $string = $string @ $MetricsParamArray[1]; + } + if(ppShowGfx.getValue()) + { + $string = $string @ $MetricsParamArray[2]; + } + if(ppShowSfx.getValue()) + { + $string = $string @ $MetricsParamArray[3]; + } + if(ppShowTerrain.getValue()) + { + $string = $string @ $MetricsParamArray[4]; + } + if(ppShowForest.getValue()) + { + $string = $string @ $MetricsParamArray[5]; + } + if(ppShowGroundcover.getValue()) + { + $string = $string @ $MetricsParamArray[6]; + } + if(ppShowNet.getValue()) + { + $string = $string @ $MetricsParamArray[7]; + } + + if(%var) + { + $EnableProfiler = !($EnableProfiler); + + if($EnableProfiler) + { + metrics($string); + } + else if((false == $EnableProfiler)) + { + metrics(); + } + } + else if($EnableProfiler) //will enter only when the enable/disable button was pressed + { + metrics($string); + } +} + +function showMetics(%var) +{ + if(%var) + { + metrics($string); + } + else if(true == $EnableProfiler) + { + $EnableProfiler = false; + metrics(); + } +} + +GlobalActionMap.bind(keyboard, "ctrl F2", showMetics); + +%guiContent = new GuiControl(FrameOverlayGui) { + profile = "GuiModelessDialogProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "True"; + modal = "false"; + helpTag = "0"; + noCursor = true; + new GuiConsoleTextCtrl(TextOverlayControl) { + profile = "GuiConsoleTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 5"; + extent = "130 18"; + minExtent = "4 4"; + visible = "True"; + setFirstResponder = "True"; + modal = "True"; + helpTag = "0"; + expression = "10"; + command = "Canvas.popDialog(FrameOverlayGui);"; + accelerator = "escape"; + }; +}; + +// Note: To implement your own metrics overlay +// just add a function with a name in the form +// XXXXMetricsCallback which can be enabled via +// metrics( XXXX ) + +function fpsMetricsCallback() +{ + return " | FPS |" @ + " " @ $fps::real @ + " max: " @ $fps::realMax @ + " min: " @ $fps::realMin @ + " mspf: " @ 1000 / $fps::real; +} + +function gfxMetricsCallback() +{ + return " | GFX |" @ + " PolyCount: " @ $GFXDeviceStatistics::polyCount @ + " DrawCalls: " @ $GFXDeviceStatistics::drawCalls @ + " RTChanges: " @ $GFXDeviceStatistics::renderTargetChanges; + +} + +function terrainMetricsCallback() +{ + return " | Terrain |" @ + " Cells: " @ $TerrainBlock::cellsRendered @ + " Override Cells: " @ $TerrainBlock::overrideCells @ + " DrawCalls: " @ $TerrainBlock::drawCalls; +} + +function netMetricsCallback() +{ + return " | Net |" @ + " BitsSent: " @ $Stats::netBitsSent @ + " BitsRcvd: " @ $Stats::netBitsReceived @ + " GhostUpd: " @ $Stats::netGhostUpdates; +} + +function groundCoverMetricsCallback() +{ + return " | GroundCover |" @ + " Cells: " @ $GroundCover::renderedCells @ + " Billboards: " @ $GroundCover::renderedBillboards @ + " Batches: " @ $GroundCover::renderedBatches @ + " Shapes: " @ $GroundCover::renderedShapes; +} + +function forestMetricsCallback() +{ + return " | Forest |" @ + " Cells: " @ $Forest::totalCells @ + " Cells Meshed: " @ $Forest::cellsRendered @ + " Cells Billboarded: " @ $Forest::cellsBatched @ + " Meshes: " @ $Forest::cellItemsRendered @ + " Billboards: " @ $Forest::cellItemsBatched; +} + +function sfxMetricsCallback() +{ + return " | SFX |" @ + " Sounds: " @ $SFX::numSounds @ + " Lists: " @ ( $SFX::numSources - $SFX::numSounds - $SFX::Device::fmodNumEventSource ) @ + " Events: " @ $SFX::fmodNumEventSources @ + " Playing: " @ $SFX::numPlaying @ + " Culled: " @ $SFX::numCulled @ + " Voices: " @ $SFX::numVoices @ + " Buffers: " @ $SFX::Device::numBuffers @ + " Memory: " @ ( $SFX::Device::numBufferBytes / 1024.0 / 1024.0 ) @ " MB" @ + " Time/S: " @ $SFX::sourceUpdateTime @ + " Time/P: " @ $SFX::parameterUpdateTime @ + " Time/A: " @ $SFX::ambientUpdateTime; +} + +function sfxSourcesMetricsCallback() +{ + return sfxDumpSourcesToString(); +} + +function sfxStatesMetricsCallback() +{ + return " | SFXStates |" @ sfxGetActiveStates(); +} + +function timeMetricsCallback() +{ + return " | Time |" @ + " Sim Time: " @ getSimTime() @ + " Mod: " @ getSimTime() % 32; +} + +function reflectMetricsCallback() +{ + return " | REFLECT |" @ + " Objects: " @ $Reflect::numObjects @ + " Visible: " @ $Reflect::numVisible @ + " Occluded: " @ $Reflect::numOccluded @ + " Updated: " @ $Reflect::numUpdated @ + " Elapsed: " @ $Reflect::elapsed NL + + " Allocated: " @ $Reflect::renderTargetsAllocated @ + " Pooled: " @ $Reflect::poolSize NL + + " " @ getWord( $Reflect::textureStats, 1 ) TAB + " " @ getWord( $Reflect::textureStats, 2 ) @ "MB" TAB + " " @ getWord( $Reflect::textureStats, 0 ); +} + +function decalMetricsCallback() +{ + return " | DECAL |" @ + " Batches: " @ $Decal::Batches @ + " Buffers: " @ $Decal::Buffers @ + " DecalsRendered: " @ $Decal::DecalsRendered; +} + +function renderMetricsCallback() +{ + return " | Render |" @ + " Mesh: " @ $RenderMetrics::RIT_Mesh @ + " MeshDL: " @ $RenderMetrics::RIT_MeshDynamicLighting @ + " Shadow: " @ $RenderMetrics::RIT_Shadow @ + " Sky: " @ $RenderMetrics::RIT_Sky @ + " Obj: " @ $RenderMetrics::RIT_Object @ + " ObjT: " @ $RenderMetrics::RIT_ObjectTranslucent @ + " Decal: " @ $RenderMetrics::RIT_Decal @ + " Water: " @ $RenderMetrics::RIT_Water @ + " Foliage: " @ $RenderMetrics::RIT_Foliage @ + " Trans: " @ $RenderMetris::RIT_Translucent @ + " Custom: " @ $RenderMetrics::RIT_Custom; +} + +function shadowMetricsCallback() +{ + return " | Shadow |" @ + " Active: " @ $ShadowStats::activeMaps @ + " Updated: " @ $ShadowStats::updatedMaps @ + " PolyCount: " @ $ShadowStats::polyCount @ + " DrawCalls: " @ $ShadowStats::drawCalls @ + " RTChanges: " @ $ShadowStats::rtChanges @ + " PoolTexCount: " @ $ShadowStats::poolTexCount @ + " PoolTexMB: " @ $ShadowStats::poolTexMemory @ "MB"; +} + +function basicShadowMetricsCallback() +{ + return " | Shadow |" @ + " Active: " @ $BasicLightManagerStats::activePlugins @ + " Updated: " @ $BasicLightManagerStats::shadowsUpdated @ + " Elapsed Ms: " @ $BasicLightManagerStats::elapsedUpdateMs; +} + +function lightMetricsCallback() +{ + return " | Deferred Lights |" @ + " Active: " @ $lightMetrics::activeLights @ + " Culled: " @ $lightMetrics::culledLights; +} + +function particleMetricsCallback() +{ + return " | Particles |" @ + " # Simulated " @ $particle::numSimulated; +} +function partMetricsCallback() +{ + return particleMetricsCallback(); +} + + +// alias +function audioMetricsCallback() +{ + return sfxMetricsCallback(); +} + +// alias +function videoMetricsCallback() +{ + return gfxMetricsCallback(); +} + +// Add a metrics HUD. %expr can be a vector of names where each element +// must have a corresponding 'MetricsCallback()' function defined +// that will be called on each update of the GUI control. The results +// of each function are stringed together. +// +// Example: metrics( "fps gfx" ); + +function metrics( %expr ) +{ + %metricsExpr = ""; + if( %expr !$= "" ) + { + for( %i = 0;; %i ++ ) + { + %name = getWord( %expr, %i ); + if( %name $= "" ) + break; + else + { + %cb = %name @ "MetricsCallback"; + if( !isFunction( %cb ) ) + error( "metrics - undefined callback: " @ %cb ); + else + { + %cb = %cb @ "()"; + if( %i > 0 ) + %metricsExpr = %metricsExpr @ " NL "; + %metricsExpr = %metricsExpr @ %cb; + } + } + } + + if( %metricsExpr !$= "" ) + %metricsExpr = %metricsExpr @ " @ \" \""; + } + + if( %metricsExpr !$= "" ) + { + $GameCanvas.pushDialog( FrameOverlayGui, 1000 ); + TextOverlayControl.setValue( %metricsExpr ); + } + else + $GameCanvas.popDialog(FrameOverlayGui); +} diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/remapConfirmDlg.gui b/Templates/BaseGame/game/data/ui/scripts/guis/remapConfirmDlg.gui new file mode 100644 index 000000000..e0489a9f8 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/remapConfirmDlg.gui @@ -0,0 +1,125 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(RemapConfirmDlg) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + helpTag = "0"; + + new GuiContainer(RemapConfirmationPanel) { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "168 352"; + extent = "700 64"; + minExtent = "8 2"; + horizSizing = "center"; + vertSizing = "center"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiChunkedBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + useVariable = "0"; + tile = "0"; + position = "0 0"; + extent = "700 64"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(RemapConfirmationText) { + text = "\"m\" is already bound to \"Forward\"!\nDo you wish to replace this mapping?"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 8"; + extent = "700 20"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + accelerator = "return"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(RemapConfirmationYesButton) { + text = "Yes"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "270 36"; + extent = "80 22"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "top"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "ControlsMenu.redoMapping(keyboard, \"m\", \"jump\", 0, 4); Canvas.popDialog();"; + accelerator = "return"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(RemapConfirmationNoButton) { + text = "No"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "367 36"; + extent = "80 22"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "top"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog();"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/ui/scripts/guis/remapDlg.gui b/Templates/BaseGame/game/data/ui/scripts/guis/remapDlg.gui new file mode 100644 index 000000000..a4dd8edac --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/guis/remapDlg.gui @@ -0,0 +1,122 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(RemapDlg) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + helpTag = "0"; + + new GuiContainer(RemapPanel) { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "162 352"; + extent = "700 64"; + minExtent = "8 2"; + horizSizing = "center"; + vertSizing = "center"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiInputCtrl(OptRemapInputCtrl) { + lockMouse = "0"; + position = "480 0"; + extent = "64 64"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiInputCtrlProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiChunkedBitmapCtrl() { + bitmap = "data/ui/art/hudfill.png"; + useVariable = "0"; + tile = "0"; + position = "0 0"; + extent = "700 64"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Press escape to cancel"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "247 34"; + extent = "242 20"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Re-bind \"\" to..."; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "177 8"; + extent = "384 20"; + minExtent = "8 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiMenuButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "OptRemapText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/ui/scripts/joinServerMenu.cs b/Templates/BaseGame/game/data/ui/scripts/joinServerMenu.cs new file mode 100644 index 000000000..5529ebaed --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/joinServerMenu.cs @@ -0,0 +1,143 @@ + +function JoinServerMenu::onWake() +{ + // Double check the status. Tried setting this the control + // inactive to start with, but that didn't seem to work. + JoinServerJoinBtn.setActive(JS_serverList.rowCount() > 0); +} + +//---------------------------------------- +function JoinServerMenu::query(%this) +{ + queryMasterServer( + 0, // Query flags + $Client::GameTypeQuery, // gameTypes + $Client::MissionTypeQuery, // missionType + 0, // minPlayers + 100, // maxPlayers + 0, // maxBots + 2, // regionMask + 0, // maxPing + 100, // minCPU + 0 // filterFlags + ); +} + +//---------------------------------------- +function JoinServerMenu::queryLan(%this) +{ + queryLANServers( + $pref::Net::Port, // lanPort for local queries + 0, // Query flags + $Client::GameTypeQuery, // gameTypes + $Client::MissionTypeQuery, // missionType + 0, // minPlayers + 100, // maxPlayers + 0, // maxBots + 2, // regionMask + 0, // maxPing + 100, // minCPU + 0 // filterFlags + ); +} + +//---------------------------------------- +function JoinServerMenu::cancel(%this) +{ + cancelServerQuery(); + JS_queryStatus.setVisible(false); +} + + +//---------------------------------------- +function JoinServerMenu::join(%this) +{ + cancelServerQuery(); + %index = JS_serverList.getSelectedId(); + + JoinGame(%index); +} + +//---------------------------------------- +function JoinServerMenu::refresh(%this) +{ + cancelServerQuery(); + %index= JS_serverList.getSelectedId(); + + // The server info index is stored in the row along with the + // rest of displayed info. + if( setServerInfo( %index ) ) + querySingleServer( $ServerInfo::Address, 0 ); +} + +//---------------------------------------- +function JoinServerMenu::refreshSelectedServer( %this ) +{ + querySingleServer( $JoinGameAddress, 0 ); +} + +//---------------------------------------- +function JoinServerMenu::exit(%this) +{ + cancelServerQuery(); + + Canvas.popDialog(JoinServerMenu); +} + +//---------------------------------------- +function JoinServerMenu::update(%this) +{ + // Copy the servers into the server list. + JS_queryStatus.setVisible(false); + JS_serverList.clear(); + %sc = getServerCount(); + for( %i = 0; %i < %sc; %i ++ ) { + setServerInfo(%i); + JS_serverList.addRow( %i, + $ServerInfo::Name TAB + $ServerInfo::Ping TAB + $ServerInfo::PlayerCount @ "/" @ $ServerInfo::MaxPlayers TAB + $ServerInfo::Version TAB + $ServerInfo::MissionName + ); + } + JS_serverList.sort(0); + JS_serverList.setSelectedRow(0); + JS_serverList.scrollVisible(0); + + JoinServerJoinBtn.setActive(JS_serverList.rowCount() > 0); +} + +//---------------------------------------- +function onServerQueryStatus(%status, %msg, %value) +{ + echo("ServerQuery: " SPC %status SPC %msg SPC %value); + // Update query status + // States: start, update, ping, query, done + // value = % (0-1) done for ping and query states + if (!JS_queryStatus.isVisible()) + JS_queryStatus.setVisible(true); + + switch$ (%status) { + case "start": + JoinServerJoinBtn.setActive(false); + JoinServerQryInternetBtn.setActive(false); + JS_statusText.setText(%msg); + JS_statusBar.setValue(0); + JS_serverList.clear(); + + case "ping": + JS_statusText.setText("Ping Servers"); + JS_statusBar.setValue(%value); + + case "query": + JS_statusText.setText("Query Servers"); + JS_statusBar.setValue(%value); + + case "done": + JoinServerQryInternetBtn.setActive(true); + JS_queryStatus.setVisible(false); + JS_status.setText(%msg); + JoinServerMenu.update(); + } +} diff --git a/Templates/BaseGame/game/data/ui/scripts/mainMenu.cs b/Templates/BaseGame/game/data/ui/scripts/mainMenu.cs new file mode 100644 index 000000000..3a3b22f61 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/mainMenu.cs @@ -0,0 +1,41 @@ +function MainMenuGui::onWake(%this) +{ + if (isFunction("getWebDeployment") && + getWebDeployment() && + isObject(%this-->ExitButton)) + %this-->ExitButton.setVisible(false); + + MainMenuButtonContainer.hidden = false; +} + +function MainMenuGui::openSinglePlayerMenu(%this) +{ + $pref::HostMultiPlayer=false; + Canvas.pushDialog(ChooseLevelDlg); + ChooseLevelDlg.returnGui = %this; + MainMenuButtonContainer.hidden = true; + MainMenuAppLogo.setBitmap("data/ui/art/Torque-3D-logo"); +} + +function MainMenuGui::openMultiPlayerMenu(%this) +{ + $pref::HostMultiPlayer=true; + Canvas.pushDialog(ChooseLevelDlg); + ChooseLevelDlg.returnGui = %this; + MainMenuButtonContainer.hidden = true; + MainMenuAppLogo.setBitmap("data/ui/art/Torque-3D-logo"); +} + +function MainMenuGui::openOptionsMenu(%this) +{ + Canvas.pushDialog(OptionsMenu); + OptionsMenu.returnGui = %this; + MainMenuButtonContainer.hidden = true; + MainMenuAppLogo.setBitmap("data/ui/art/Torque-3D-logo"); +} + +function MainMenuGui::onReturnTo(%this) +{ + MainMenuButtonContainer.hidden = false; + MainMenuAppLogo.setBitmap("data/ui/art/Torque-3D-logo-shortcut"); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/ui/scripts/messageBoxes.cs b/Templates/BaseGame/game/data/ui/scripts/messageBoxes.cs new file mode 100644 index 000000000..98a121db6 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/messageBoxes.cs @@ -0,0 +1,301 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +// Cleanup Dialog created by 'core' +if( isObject( MessagePopupDlg ) ) + MessagePopupDlg.delete(); +if( isObject( MessageBoxYesNoDlg ) ) + MessageBoxYesNoDlg.delete(); +if( isObject( MessageBoxYesNoCancelDlg ) ) + MessageBoxYesNoCancelDlg.delete(); +if( isObject( MessageBoxOKCancelDetailsDlg ) ) + MessageBoxOKCancelDetailsDlg.delete(); +if( isObject( MessageBoxOKCancelDlg ) ) + MessageBoxOKCancelDlg.delete(); +if( isObject( MessageBoxOKDlg ) ) + MessageBoxOKDlg.delete(); +if( isObject( IODropdownDlg ) ) + IODropdownDlg.delete(); + + +// Load Editor Dialogs +exec("./guis/messageBoxOk.ed.gui"); +exec("./guis/messageBoxYesNo.ed.gui"); + +// -------------------------------------------------------------------- +// Message Sound +// -------------------------------------------------------------------- +/*new SFXDescription(MessageBoxAudioDescription) +{ + volume = 1.0; + isLooping = false; + is3D = false; + channel = $GuiAudioType; +}; + +new SFXProfile(messageBoxBeep) +{ + filename = "./messageBoxSound"; + description = MessageBoxAudioDescription; + preload = true; +};*/ + + + + +//--------------------------------------------------------------------------------------------- +// messageCallback +// Calls a callback passed to a message box. +//--------------------------------------------------------------------------------------------- +function messageCallback(%dlg, %callback) +{ + Canvas.popDialog(%dlg); + eval(%callback); +} + +//The # in the function passed replaced with the output +//of the preset menu. +function IOCallback(%dlg, %callback) +{ + %id = IODropdownMenu.getSelected(); + %text = IODropdownMenu.getTextById(%id); + %callback = strreplace(%callback, "#", %text); + eval(%callback); + + Canvas.popDialog(%dlg); +} + +//--------------------------------------------------------------------------------------------- +// MBSetText +// Sets the text of a message box and resizes it to accomodate the new string. +//--------------------------------------------------------------------------------------------- +function MBSetText(%text, %frame, %msg) +{ + // Get the extent of the text box. + %ext = %text.getExtent(); + // Set the text in the center of the text box. + %text.setText("" @ %msg); + // Force the textbox to resize itself vertically. + %text.forceReflow(); + // Grab the new extent of the text box. + %newExtent = %text.getExtent(); + + // Get the vertical change in extent. + %deltaY = getWord(%newExtent, 1) - getWord(%ext, 1); + + // Resize the window housing the text box. + %windowPos = %frame.getPosition(); + %windowExt = %frame.getExtent(); + %frame.resize(getWord(%windowPos, 0), getWord(%windowPos, 1) - (%deltaY / 2), + getWord(%windowExt, 0), getWord(%windowExt, 1) + %deltaY); + + %frame.canMove = "0"; + //%frame.canClose = "0"; + %frame.resizeWidth = "0"; + %frame.resizeHeight = "0"; + %frame.canMinimize = "0"; + %frame.canMaximize = "0"; + + //sfxPlayOnce( messageBoxBeep ); +} + +//--------------------------------------------------------------------------------------------- +// Various message box display functions. Each one takes a window title, a message, and a +// callback for each button. +//--------------------------------------------------------------------------------------------- + +function MessageBoxOK(%title, %message, %callback) +{ + MBOKFrame.text = %title; + Canvas.pushDialog(MessageBoxOKDlg); + MBSetText(MBOKText, MBOKFrame, %message); + MessageBoxOKDlg.callback = %callback; +} + +function MessageBoxOKDlg::onSleep( %this ) +{ + %this.callback = ""; +} + +function MessageBoxOKCancel(%title, %message, %callback, %cancelCallback) +{ + MBOKCancelFrame.text = %title; + Canvas.pushDialog(MessageBoxOKCancelDlg); + MBSetText(MBOKCancelText, MBOKCancelFrame, %message); + MessageBoxOKCancelDlg.callback = %callback; + MessageBoxOKCancelDlg.cancelCallback = %cancelCallback; +} + +function MessageBoxOKCancelDlg::onSleep( %this ) +{ + %this.callback = ""; +} + +function MessageBoxOKCancelDetails(%title, %message, %details, %callback, %cancelCallback) +{ + if(%details $= "") + { + MBOKCancelDetailsButton.setVisible(false); + } + + MBOKCancelDetailsScroll.setVisible(false); + + MBOKCancelDetailsFrame.setText( %title ); + + Canvas.pushDialog(MessageBoxOKCancelDetailsDlg); + MBSetText(MBOKCancelDetailsText, MBOKCancelDetailsFrame, %message); + MBOKCancelDetailsInfoText.setText(%details); + + %textExtent = MBOKCancelDetailsText.getExtent(); + %textExtentY = getWord(%textExtent, 1); + %textPos = MBOKCancelDetailsText.getPosition(); + %textPosY = getWord(%textPos, 1); + + %extentY = %textPosY + %textExtentY + 65; + + MBOKCancelDetailsInfoText.setExtent(285, 128); + + MBOKCancelDetailsFrame.setExtent(300, %extentY); + + MessageBoxOKCancelDetailsDlg.callback = %callback; + MessageBoxOKCancelDetailsDlg.cancelCallback = %cancelCallback; + + MBOKCancelDetailsFrame.defaultExtent = MBOKCancelDetailsFrame.getExtent(); +} + +function MBOKCancelDetailsToggleInfoFrame() +{ + if(!MBOKCancelDetailsScroll.isVisible()) + { + MBOKCancelDetailsScroll.setVisible(true); + MBOKCancelDetailsText.forceReflow(); + %textExtent = MBOKCancelDetailsText.getExtent(); + %textExtentY = getWord(%textExtent, 1); + %textPos = MBOKCancelDetailsText.getPosition(); + %textPosY = getWord(%textPos, 1); + + %verticalStretch = %textExtentY; + + if((%verticalStretch > 260) || (%verticalStretch < 0)) + %verticalStretch = 260; + + %extent = MBOKCancelDetailsFrame.defaultExtent; + %height = getWord(%extent, 1); + + %posY = %textPosY + %textExtentY + 10; + %posX = getWord(MBOKCancelDetailsScroll.getPosition(), 0); + MBOKCancelDetailsScroll.setPosition(%posX, %posY); + MBOKCancelDetailsScroll.setExtent(getWord(MBOKCancelDetailsScroll.getExtent(), 0), %verticalStretch); + MBOKCancelDetailsFrame.setExtent(300, %height + %verticalStretch + 10); + } else + { + %extent = MBOKCancelDetailsFrame.defaultExtent; + %width = getWord(%extent, 0); + %height = getWord(%extent, 1); + MBOKCancelDetailsFrame.setExtent(%width, %height); + MBOKCancelDetailsScroll.setVisible(false); + } +} + +function MessageBoxOKCancelDetailsDlg::onSleep( %this ) +{ + %this.callback = ""; +} + +function MessageBoxYesNo(%title, %message, %yesCallback, %noCallback) +{ + MBYesNoFrame.text = %title; + Canvas.pushDialog(MessageBoxYesNoDlg); + MBSetText(MBYesNoText, MBYesNoFrame, %message); + MessageBoxYesNoDlg.yesCallBack = %yesCallback; + MessageBoxYesNoDlg.noCallback = %noCallBack; +} + +function MessageBoxYesNoCancel(%title, %message, %yesCallback, %noCallback, %cancelCallback) +{ + MBYesNoCancelFrame.text = %title; + MessageBoxYesNoDlg.profile = "GuiOverlayProfile"; + Canvas.pushDialog(MessageBoxYesNoCancelDlg); + MBSetText(MBYesNoCancelText, MBYesNoCancelFrame, %message); + MessageBoxYesNoCancelDlg.yesCallBack = %yesCallback; + MessageBoxYesNoCancelDlg.noCallback = %noCallBack; + MessageBoxYesNoCancelDlg.cancelCallback = %cancelCallback; +} + +function MessageBoxYesNoDlg::onSleep( %this ) +{ + %this.yesCallback = ""; + %this.noCallback = ""; +} + +//--------------------------------------------------------------------------------------------- +// MessagePopup +// Displays a message box with no buttons. Disappears after %delay milliseconds. +//--------------------------------------------------------------------------------------------- +function MessagePopup(%title, %message, %delay) +{ + // Currently two lines max. + MessagePopFrame.setText(%title); + Canvas.pushDialog(MessagePopupDlg); + MBSetText(MessagePopText, MessagePopFrame, %message); + if (%delay !$= "") + schedule(%delay, 0, CloseMessagePopup); +} + +//--------------------------------------------------------------------------------------------- +// IODropdown +// By passing in a simgroup or simset, the user will be able to choose a child of that group +// through a guiPopupMenuCtrl +//--------------------------------------------------------------------------------------------- + +function IODropdown(%title, %message, %simgroup, %callback, %cancelCallback) +{ + IODropdownFrame.text = %title; + Canvas.pushDialog(IODropdownDlg); + MBSetText(IODropdownText, IODropdownFrame, %message); + + if(isObject(%simgroup)) + { + for(%i = 0; %i < %simgroup.getCount(); %i++) + IODropdownMenu.add(%simgroup.getObject(%i).getName()); + + } + + IODropdownMenu.sort(); + IODropdownMenu.setFirstSelected(0); + + IODropdownDlg.callback = %callback; + IODropdownDlg.cancelCallback = %cancelCallback; +} + +function IODropdownDlg::onSleep( %this ) +{ + %this.callback = ""; + %this.cancelCallback = ""; + IODropdownMenu.clear(); +} + +function CloseMessagePopup() +{ + Canvas.popDialog(MessagePopupDlg); +} diff --git a/Templates/BaseGame/game/data/ui/scripts/optionsList.cs b/Templates/BaseGame/game/data/ui/scripts/optionsList.cs new file mode 100644 index 000000000..ad1da0759 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/optionsList.cs @@ -0,0 +1,437 @@ +new SimGroup( MeshQualityGroup ) +{ + class = "GraphicsOptionsMenuGroup"; + + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "High"; + + key["$pref::TS::detailAdjust"] = 1.5; + key["$pref::TS::skipRenderDLs"] = 0; + }; + new ArrayObject( ) + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Medium"; + + key["$pref::TS::detailAdjust"] = 1.0; + key["$pref::TS::skipRenderDLs"] = 0; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Low"; + + key["$pref::TS::detailAdjust"] = 0.75; + key["$pref::TS::skipRenderDLs"] = 0; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Lowest"; + + key["$pref::TS::detailAdjust"] = 0.5; + key["$pref::TS::skipRenderDLs"] = 1; + }; +}; + +new SimGroup( TextureQualityGroup ) +{ + class = "GraphicsOptionsMenuGroup"; + + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "High"; + + key["$pref::Video::textureReductionLevel"] = 0; + key["$pref::Reflect::refractTexScale"] = 1.25; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Medium"; + + key["$pref::Video::textureReductionLevel"] = 0; + key["$pref::Reflect::refractTexScale"] = 1; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Low"; + + key["$pref::Video::textureReductionLevel"] = 1; + key["$pref::Reflect::refractTexScale"] = 0.75; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Lowest"; + + key["$pref::Video::textureReductionLevel"] = 2; + key["$pref::Reflect::refractTexScale"] = 0.5; + }; +}; + +new SimGroup( GroundCoverDensityGroup ) +{ + class = "GraphicsOptionsMenuGroup"; + + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "High"; + + key["$pref::GroundCover::densityScale"] = 1.0; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Medium"; + + key["$pref::GroundCover::densityScale"] = 0.75; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Low"; + + key["$pref::GroundCover::densityScale"] = 0.5; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Lowest"; + + key["$pref::GroundCover::densityScale"] = 0.25; + }; +}; + +new SimGroup( DecalLifetimeGroup ) +{ + class = "GraphicsOptionsMenuGroup"; + + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "High"; + + key["$pref::decalMgr::enabled"] = true; + key["$pref::Decals::lifeTimeScale"] = 1; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Medium"; + + key["$pref::decalMgr::enabled"] = true; + key["$pref::Decals::lifeTimeScale"] = 0.5; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Low"; + + key["$pref::decalMgr::enabled"] = true; + key["$pref::Decals::lifeTimeScale"] = 0.25; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "None"; + + key["$pref::decalMgr::enabled"] = false; + }; +}; + +new SimGroup( TerrainQualityGroup ) +{ + class = "GraphicsOptionsMenuGroup"; + + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "High"; + + key["$pref::Terrain::lodScale"] = 0.75; + key["$pref::Terrain::detailScale"] = 1.5; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Medium"; + + key["$pref::Terrain::lodScale"] = 1.0; + key["$pref::Terrain::detailScale"] = 1.0; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Low"; + + key["$pref::Terrain::lodScale"] = 1.5; + key["$pref::Terrain::detailScale"] = 0.75; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Lowest"; + + key["$pref::Terrain::lodScale"] = 2.0; + key["$pref::Terrain::detailScale"] = 0.5; + }; +}; + +//Shadows and Lighting +new SimGroup( ShadowQualityList ) +{ + class = "GraphicsOptionsMenuGroup"; + + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "High"; + + key["$pref::lightManager"] = "Advanced Lighting"; + key["$pref::Shadows::disable"] = false; + key["$pref::Shadows::textureScalar"] = 1.0; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Medium"; + + key["$pref::lightManager"] = "Advanced Lighting"; + key["$pref::Shadows::disable"] = false; + key["$pref::Shadows::textureScalar"] = 0.5; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Low"; + + key["$pref::lightManager"] = "Advanced Lighting"; + key["$pref::Shadows::disable"] = false; + key["$pref::Shadows::textureScalar"] = 0.25; + + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "None"; + + key["$pref::lightManager"] = "Advanced Lighting"; + key["$pref::Shadows::disable"] = true; + key["$pref::Shadows::textureScalar"] = 0.5; + }; +}; + +new SimGroup( ShadowDistanceList ) +{ + class = "GraphicsOptionsMenuGroup"; + + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Highest"; + + key["$pref::Shadows::drawDistance"] = 2; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "High"; + + key["$pref::Shadows::drawDistance"] = 1.5; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Medium"; + + key["$pref::Shadows::drawDistance"] = 1; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Low"; + + key["$pref::Shadows::drawDistance"] = 0.5; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Lowest"; + + key["$pref::Shadows::drawDistance"] = 0.25; + }; +}; + +new SimGroup( SoftShadowList ) +{ + class = "GraphicsOptionsMenuGroup"; + + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "High"; + + key["$pref::Shadows::filterMode"] = "SoftShadowHighQuality"; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Low"; + + key["$pref::Shadows::filterMode"] = "SoftShadow"; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Off"; + + key["$pref::Shadows::filterMode"] = "None"; + }; +}; + +new SimGroup( LightDistanceList ) +{ + class = "GraphicsOptionsMenuGroup"; + + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Highest"; + + key["$pref::Lights::drawDistance"] = 2; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "High"; + + key["$pref::Lights::drawDistance"] = 1.5; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Medium"; + + key["$pref::Lights::drawDistance"] = 1; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Low"; + + key["$pref::Lights::drawDistance"] = 0.5; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Lowest"; + + key["$pref::Lights::drawDistance"] = 0.25; + }; +}; + +new SimGroup( ShaderQualityGroup ) +{ + class = "GraphicsOptionsMenuGroup"; + + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "High"; + + key["$pref::Video::disablePixSpecular"] = false; + key["$pref::Video::disableNormalmapping"] = false; + }; + new ArrayObject() + { + class = "GraphicsQualityLevel"; + caseSensitive = true; + + displayName = "Low"; + + key["$pref::Video::disablePixSpecular"] = true; + key["$pref::Video::disableNormalmapping"] = true; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/data/ui/scripts/optionsMenu.cs b/Templates/BaseGame/game/data/ui/scripts/optionsMenu.cs new file mode 100644 index 000000000..40807691c --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/optionsMenu.cs @@ -0,0 +1,473 @@ +//options settings + +//Screen and Display menu +//Renderer Mode +//Screen resolution +//Windowed/fullscreen(borderless?) +//VSync + +//Screen brightness +//screen brightness +//screen gamma + +//Lighting Menu +//Shadow Distance(Distance shadows are drawn to. Also affects shadowmap slices) +//Shadow Quality(Resolution of shadows rendered, setting to none disables dynamic shadows) +//Soft Shadows(Whether shadow softening is used) +//Shadow caching(If the lights enable it, shadow caching is activated) +//Light Draw Distance(How far away lights are still drawn. Doesn't impact vector lights like the sun) + +//Mesh and Textures Menu +//Draw distance(Overall draw distance) -slider +//Object draw distance(Draw distance from small/unimportant objects) -slider +//Mesh quality +//Texture quality +//Foliage draw distance +//Terrain Quality +//Decal Quality + +//Effects Menu +//Parallax +//HDR +//Light shafts +//Motion Blur +//Depth of Field +//SSAO +//AA(ModelXAmount)[defualt is FXAA] +//Anisotropic filtering + +//Keybinds + +//Camera +//horizontal mouse sensitivity +//vert mouse sensitivity +//invert vertical +//zoom mouse sensitivities(both horz/vert) +//headbob +//FOV + +function OptionsMenu::onWake(%this) +{ + OptionsMain.hidden = false; + ControlsMenu.hidden = true; + GraphicsMenu.hidden = true; + AudioMenu.hidden = true; + CameraMenu.hidden = true; + ScreenBrightnessMenu.hidden = true; + + OptionsOKButton.hidden = false; + OptionsCancelButton.hidden = false; + OptionsDefaultsButton.hidden = false; +} + +function OptionsMenuOKButton::onClick(%this) +{ + //save the settings and then back out + + OptionsMenu.backOut(); +} + +function OptionsMenuCancelButton::onClick(%this) +{ + //we don't save, so go straight to backing out of the menu + OptionsMenu.backOut(); +} + +function OptionsMenuDefaultsButton::onClick(%this) +{ + //we don't save, so go straight to backing out of the menu + OptionsMenu.backOut(); +} + +function ControlsSettingsMenuButton::onClick(%this) +{ + OptionsMain.hidden = true; + ControlsMenu.hidden = false; + + KeyboardControlPanel.hidden = false; + MouseControlPanel.hidden = true; + + ControlsMenu.reload(); +} + +function GraphicsSettingsMenuButton::onClick(%this) +{ + OptionsMain.hidden = true; + GraphicsMenu.hidden = false; +} + +function CameraSettingsMenuButton::onClick(%this) +{ + OptionsMain.hidden = true; + CameraMenu.hidden = false; + + CameraMenu.loadSettings(); +} + +function AudioSettingsMenuButton::onClick(%this) +{ + OptionsMain.hidden = true; + AudioMenu.hidden = false; + AudioMenu.loadSettings(); +} + +function ScreenBrSettingsMenuButton::onClick(%this) +{ + OptionsMain.hidden = true; + ScreenBrightnessMenu.hidden = false; +} + +function OptionsMenu::backOut(%this) +{ + //save the settings and then back out + if(OptionsMain.hidden == false) + { + //we're not in a specific menu, so we're actually exiting + Canvas.popDialog(OptionsMenu); + + if(isObject(OptionsMenu.returnGui) && OptionsMenu.returnGui.isMethod("onReturnTo")) + OptionsMenu.returnGui.onReturnTo(); + } + else + { + OptionsMain.hidden = false; + ControlsMenu.hidden = true; + GraphicsMenu.hidden = true; + CameraMenu.hidden = true; + AudioMenu.hidden = true; + ScreenBrightnessMenu.hidden = true; + } +} + +function OptionsMenu::addSettingOption(%this, %arrayTarget) +{ + %graphicsOption = OptionsMenu.tamlReader.read("data/ui/scripts/guis/graphicsMenuSettingsCtrl.taml"); + + %arrayTarget.add(%graphicsOption); + + return %graphicsOption; +} + +function OptionsMenu::addSliderOption(%this, %arrayTarget, %range, %ticks, %variable, %value, %class) +{ + %graphicsOption = OptionsMenu.tamlReader.read("data/ui/scripts/guis/graphicsMenuSettingsSlider.taml"); + + %arrayTarget.add(%graphicsOption); + + if(%range !$= "") + { + %graphicsOption-->slider.range = %range; + } + + if(%ticks !$= "") + { + %graphicsOption-->slider.ticks = %ticks; + } + + if(%variable !$= "") + { + %graphicsOption-->slider.variable = %variable; + } + + if(%value !$= "") + { + %graphicsOption-->slider.setValue(%value); + } + + if(%class !$= "") + { + %graphicsOption-->slider.className = %class; + } + else + %graphicsOption-->slider.className = OptionsMenuSlider; + + %graphicsOption-->slider.snap = true; + + %graphicsOption-->slider.onValueSet(); + + return %graphicsOption; +} + +function OptionsMenuSlider::onMouseDragged(%this) +{ + %this.onValueSet(); +} + +function OptionsMenuSlider::onValueSet(%this) +{ + %this.getParent().getParent()-->valueText.setText(mRound(%this.value * 10)); +} + +function FOVOptionSlider::onMouseDragged(%this) +{ + %this.onValueSet(); +} + +function FOVOptionSlider::onValueSet(%this) +{ + %this.getParent().getParent()-->valueText.setText(mRound(%this.value)); +} + +/// Returns true if the current quality settings equal +/// this graphics quality level. +function OptionsMenuSettingLevel::isCurrent( %this ) +{ + // Test each pref to see if the current value + // equals our stored value. + + for ( %i=0; %i < %this.count(); %i++ ) + { + %pref = %this.getKey( %i ); + %value = %this.getValue( %i ); + + %prefVarValue = getVariable( %pref ); + if ( getVariable( %pref ) !$= %value ) + return false; + } + + return true; +} +// ============================================================================= +// CAMERA MENU +// ============================================================================= +function CameraMenu::onWake(%this) +{ + +} + +function CameraMenu::apply(%this) +{ + setFOV($pref::Player::defaultFov); +} + +function CameraMenu::loadSettings(%this) +{ + CameraMenuOptionsArray.clear(); + + %option = OptionsMenu.addSettingOption(CameraMenuOptionsArray); + %option-->nameText.setText("Invert Vertical"); + %option.qualitySettingGroup = InvertVerticalMouse; + %option.init(); + + %option = OptionsMenu.addSliderOption(CameraMenuOptionsArray, "0.1 1", 8, "$pref::Input::VertMouseSensitivity", $pref::Input::VertMouseSensitivity); + %option-->nameText.setText("Vertical Sensitivity"); + + %option = OptionsMenu.addSliderOption(CameraMenuOptionsArray, "0.1 1", 8, "$pref::Input::HorzMouseSensitivity", $pref::Input::HorzMouseSensitivity); + %option-->nameText.setText("Horizontal Sensitivity"); + + %option = OptionsMenu.addSliderOption(CameraMenuOptionsArray, "0.1 1", 8, "$pref::Input::ZoomVertMouseSensitivity", $pref::Input::ZoomVertMouseSensitivity); + %option-->nameText.setText("Zoom Vertical Sensitivity"); + + %option = OptionsMenu.addSliderOption(CameraMenuOptionsArray, "0.1 1", 8, "$pref::Input::ZoomHorzMouseSensitivity", $pref::Input::ZoomHorzMouseSensitivity); + %option-->nameText.setText("Zoom Horizontal Sensitivity"); + + %option = OptionsMenu.addSliderOption(CameraMenuOptionsArray, "65 90", 25, "$pref::Player::defaultFov", $pref::Player::defaultFov, FOVOptionSlider); + %option-->nameText.setText("Field of View"); + + CameraMenuOptionsArray.refresh(); +} + +function CameraMenuOKButton::onClick(%this) +{ + //save the settings and then back out + CameraMenu.apply(); + OptionsMenu.backOut(); +} + +function CameraMenuDefaultsButton::onClick(%this) +{ + +} +// ============================================================================= +// AUDIO MENU +// ============================================================================= +$AudioTestHandle = 0; +// Description to use for playing the volume test sound. This isn't +// played with the description of the channel that has its volume changed +// because we know nothing about the playback state of the channel. If it +// is paused or stopped, the test sound would not play then. +$AudioTestDescription = new SFXDescription() +{ + sourceGroup = AudioChannelMaster; +}; + +function AudioMenu::loadSettings(%this) +{ + // Audio + //OptAudioHardwareToggle.setStateOn($pref::SFX::useHardware); + //OptAudioHardwareToggle.setActive( true ); + + %this-->OptAudioVolumeMaster.setValue( $pref::SFX::masterVolume ); + %this-->OptAudioVolumeShell.setValue( $pref::SFX::channelVolume[ $GuiAudioType] ); + %this-->OptAudioVolumeSim.setValue( $pref::SFX::channelVolume[ $SimAudioType ] ); + %this-->OptAudioVolumeMusic.setValue( $pref::SFX::channelVolume[ $MusicAudioType ] ); + + AudioMenuSoundDriver.clear(); + %buffer = sfxGetAvailableDevices(); + %count = getRecordCount( %buffer ); + for(%i = 0; %i < %count; %i++) + { + %record = getRecord(%buffer, %i); + %provider = getField(%record, 0); + + if ( AudioMenuSoundDriver.findText( %provider ) == -1 ) + AudioMenuSoundDriver.add( %provider, %i ); + } + + AudioMenuSoundDriver.sort(); + + %selId = AudioMenuSoundDriver.findText($pref::SFX::provider); + if ( %selId == -1 ) + AudioMenuSoundDriver.setFirstSelected(); + else + AudioMenuSoundDriver.setSelected( %selId ); +} + +function AudioMenu::loadDevices(%this) +{ + if(!isObject(SoundDeviceGroup)) + { + new SimGroup( SoundDeviceGroup ); + } + else + { + SoundDeviceGroup.clear(); + } + + %buffer = sfxGetAvailableDevices(); + %count = getRecordCount( %buffer ); + for (%i = 0; %i < %count; %i++) + { + %record = getRecord(%buffer, %i); + %provider = getField(%record, 0); + %device = getField(%record, 1); + + if($pref::SFX::provider !$= %provider) + continue; + + %setting = new ArrayObject() + { + class = "OptionsMenuSettingLevel"; + caseSensitive = true; + + displayName = %device; + + key["$pref::SFX::Device"] = %device; + }; + + SoundDeviceGroup.add(%setting); + } +} + +function AudioMenu::apply(%this) +{ + sfxSetMasterVolume( $pref::SFX::masterVolume ); + + sfxSetChannelVolume( $GuiAudioType, $pref::SFX::channelVolume[ $GuiAudioType ] ); + sfxSetChannelVolume( $SimAudioType, $pref::SFX::channelVolume[ $SimAudioType ] ); + sfxSetChannelVolume( $MusicAudioType, $pref::SFX::channelVolume[ $MusicAudioType ] ); + + if ( !sfxCreateDevice( $pref::SFX::provider, + $pref::SFX::device, + $pref::SFX::useHardware, + -1 ) ) + error( "Unable to create SFX device: " @ $pref::SFX::provider + SPC $pref::SFX::device + SPC $pref::SFX::useHardware ); + + if( !isObject( $AudioTestHandle ) ) + { + sfxPlay(menuButtonPressed); + } +} + +function AudioMenuOKButton::onClick(%this) +{ + //save the settings and then back out + AudioMenu.apply(); + OptionsMenu.backOut(); +} + +function AudioMenuDefaultsButton::onClick(%this) +{ + sfxInit(); + AudioMenu.loadSettings(); +} + +function OptAudioUpdateMasterVolume( %volume ) +{ + if( %volume == $pref::SFX::masterVolume ) + return; + + sfxSetMasterVolume( %volume ); + $pref::SFX::masterVolume = %volume; + + if( !isObject( $AudioTestHandle ) ) + $AudioTestHandle = sfxPlayOnce( AudioChannel, "art/sound/ui/volumeTest.wav" ); +} + +function OptAudioUpdateChannelVolume( %description, %volume ) +{ + %channel = sfxGroupToOldChannel( %description.sourceGroup ); + + if( %volume == $pref::SFX::channelVolume[ %channel ] ) + return; + + sfxSetChannelVolume( %channel, %volume ); + $pref::SFX::channelVolume[ %channel ] = %volume; + + if( !isObject( $AudioTestHandle ) ) + { + $AudioTestDescription.volume = %volume; + $AudioTestHandle = sfxPlayOnce( $AudioTestDescription, "art/sound/ui/volumeTest.wav" ); + } +} + +function AudioMenuSoundDriver::onSelect( %this, %id, %text ) +{ + // Skip empty provider selections. + if ( %text $= "" ) + return; + + $pref::SFX::provider = %text; + AudioMenuSoundDevice.clear(); + + %buffer = sfxGetAvailableDevices(); + %count = getRecordCount( %buffer ); + for(%i = 0; %i < %count; %i++) + { + %record = getRecord(%buffer, %i); + %provider = getField(%record, 0); + %device = getField(%record, 1); + + if (%provider !$= %text) + continue; + + if ( AudioMenuSoundDevice.findText( %device ) == -1 ) + AudioMenuSoundDevice.add( %device, %i ); + } + + // Find the previous selected device. + %selId = AudioMenuSoundDevice.findText($pref::SFX::device); + if ( %selId == -1 ) + AudioMenuSoundDevice.setFirstSelected(); + else + AudioMenuSoundDevice.setSelected( %selId ); +} + +function AudioMenuSoundDevice::onSelect( %this, %id, %text ) +{ + // Skip empty selections. + if ( %text $= "" ) + return; + + $pref::SFX::device = %text; + + if ( !sfxCreateDevice( $pref::SFX::provider, + $pref::SFX::device, + $pref::SFX::useHardware, + -1 ) ) + error( "Unable to create SFX device: " @ $pref::SFX::provider + SPC $pref::SFX::device + SPC $pref::SFX::useHardware ); +} diff --git a/Templates/BaseGame/game/data/ui/scripts/pauseMenu.cs b/Templates/BaseGame/game/data/ui/scripts/pauseMenu.cs new file mode 100644 index 000000000..b23b423f0 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/pauseMenu.cs @@ -0,0 +1,30 @@ +function PauseMenu::onWake(%this) +{ + $timescale = 0; +} + +function PauseMenu::onSleep(%this) +{ + $timescale = 1; +} + +function PauseMenu::openOptionsMenu(%this) +{ + Canvas.pushDialog(OptionsMenu); + OptionsMenu.returnGui = %this; + PauseOptionsMain.hidden = true; +} + +function PauseMenu::openControlsMenu(%this) +{ + Canvas.pushDialog(OptionsMenu); + OptionsMenu.returnGui = %this; + PauseOptionsMain.hidden = true; + OptionsMain.hidden = true; + ControlsMenu.hidden = false; +} + +function PauseMenu::onReturnTo(%this) +{ + PauseOptionsMain.hidden = false; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/data/ui/scripts/profiles.cs b/Templates/BaseGame/game/data/ui/scripts/profiles.cs new file mode 100644 index 000000000..5e6303fb0 --- /dev/null +++ b/Templates/BaseGame/game/data/ui/scripts/profiles.cs @@ -0,0 +1,429 @@ +if( !isObject( GuiMenuButtonProfile ) ) +new GuiControlProfile( GuiMenuButtonProfile ) +{ + opaque = true; + border = false; + fontSize = 18; + fontType = "Arial Bold"; + fontColor = "240 240 240"; + fontColorHL = "0 0 0"; + fontColorNA = "125 125 125"; + //fontColorSEL ="0 0 0"; + fixedExtent = false; + justify = "center"; + canKeyFocus = false; + bitmap = "data/ui/art/menu-button"; + hasBitmapArray = false; + soundButtonDown = menuButtonPressed; + soundButtonOver = menuButtonHover; + category = "Core"; +}; + +if( !isObject( GuiHighlightMenuButtonProfile ) ) +new GuiControlProfile( GuiHighlightMenuButtonProfile ) +{ + opaque = true; + border = false; + fontSize = 18; + fontType = "Arial Bold"; + fontColor = "240 240 240"; + fontColorHL = "0 0 0"; + fontColorNA = "125 125 125"; + //fontColorSEL ="0 0 0"; + fixedExtent = false; + justify = "center"; + canKeyFocus = false; + bitmap = "data/ui/art/selector-button-highlight-only"; + hasBitmapArray = false; + category = "Core"; +}; + +if( !isObject( GuiBlankMenuButtonProfile ) ) +new GuiControlProfile( GuiBlankMenuButtonProfile ) +{ + opaque = true; + border = false; + fontSize = 18; + fontType = "Arial Bold"; + fontColor = "200 200 200"; + fontColorHL = "255 255 255"; + fontColorNA = "200 200 200"; + //fontColorSEL ="0 0 0"; + fixedExtent = false; + justify = "center"; + canKeyFocus = false; + bitmap = "data/ui/art/selector-button-blank"; + hasBitmapArray = false; + soundButtonDown = menuButtonPressed; + soundButtonOver = menuButtonHover; + category = "Core"; +}; + +if( !isObject( GuiMenuTextProfile ) ) +new GuiControlProfile( GuiMenuTextProfile ) +{ + opaque = true; + border = false; + fontSize = 18; + fontType = "Arial Bold"; + fontColor = "240 240 240"; + fontColorHL = "0 0 0"; + fontColorNA = "125 125 125"; + fixedExtent = false; + justify = "center"; + category = "Core"; +}; + +if( !isObject( GuiSolidDefaultProfile ) ) +new GuiControlProfile (GuiSolidDefaultProfile) +{ + opaque = true; + border = true; + category = "Core"; +}; + +if( !isObject( GuiTransparentProfile ) ) +new GuiControlProfile (GuiTransparentProfile) +{ + opaque = false; + border = false; + category = "Core"; +}; + +if( !isObject( GuiGroupBorderProfile ) ) +new GuiControlProfile( GuiGroupBorderProfile ) +{ + border = false; + opaque = false; + hasBitmapArray = true; + bitmap = "data/ui/art/group-border"; + category = "Core"; +}; + +if( !isObject( GuiTabBorderProfile ) ) +new GuiControlProfile( GuiTabBorderProfile ) +{ + border = false; + opaque = false; + hasBitmapArray = true; + bitmap = "data/ui/art/tab-border"; + category = "Core"; +}; + +if( !isObject( GuiModelessDialogProfile ) ) +new GuiControlProfile( GuiModelessDialogProfile ) +{ + modal = false; + category = "Core"; +}; + +if( !isObject( GuiFrameSetProfile ) ) +new GuiControlProfile (GuiFrameSetProfile) +{ + fillcolor = "255 255 255"; + borderColor = "246 245 244"; + border = 1; + opaque = true; + border = true; + category = "Core"; +}; + +if( !isObject( GuiInputCtrlProfile ) ) +new GuiControlProfile( GuiInputCtrlProfile ) +{ + tab = true; + canKeyFocus = true; + category = "Core"; +}; + +if( !isObject( GuiTextProfile ) ) +new GuiControlProfile (GuiTextProfile) +{ + justify = "left"; + fontColor = "20 20 20"; + category = "Core"; +}; + +if( !isObject( GuiTextRightProfile ) ) +new GuiControlProfile (GuiTextRightProfile : GuiTextProfile) +{ + justify = "right"; + category = "Core"; +}; + +if( !isObject( GuiAutoSizeTextProfile ) ) +new GuiControlProfile (GuiAutoSizeTextProfile) +{ + fontColor = "0 0 0"; + autoSizeWidth = true; + autoSizeHeight = true; + category = "Core"; +}; + +if( !isObject( GuiMediumTextProfile ) ) +new GuiControlProfile( GuiMediumTextProfile : GuiTextProfile ) +{ + fontSize = 24; + category = "Core"; +}; + +if( !isObject( GuiBigTextProfile ) ) +new GuiControlProfile( GuiBigTextProfile : GuiTextProfile ) +{ + fontSize = 36; + category = "Core"; +}; + +if( !isObject( GuiMLTextProfile ) ) +new GuiControlProfile( GuiMLTextProfile ) +{ + fontColorLink = "100 100 100"; + fontColorLinkHL = "255 255 255"; + autoSizeWidth = true; + autoSizeHeight = true; + border = false; + category = "Core"; +}; + +if( !isObject( GuiMLWhiteTextProfile ) ) +new GuiControlProfile( GuiMLWhiteTextProfile ) +{ + fontColor = "220 220 220"; + fontColorHL = "255 255 255"; + autoSizeWidth = true; + autoSizeHeight = true; + border = false; + category = "Core"; +}; + +if( !isObject( GuiTextArrayProfile ) ) +new GuiControlProfile( GuiTextArrayProfile : GuiTextProfile ) +{ + fontColor = "250 250 250"; + fontColorHL = " 0 0 0"; + fontColorSEL = "0 0 0"; + fillColor ="50 50 50"; + fillColorHL = "125 125 125"; + fillColorSEL = "180 180 180"; + border = false; + category = "Core"; +}; + +// ---------------------------------------------------------------------------- +// TODO: Revisit Popupmenu +// ---------------------------------------------------------------------------- + +if( !isObject( GuiPopupMenuItemBorder ) ) +new GuiControlProfile( GuiPopupMenuItemBorder : GuiButtonProfile ) +{ + opaque = true; + border = true; + fontColor = "0 0 0"; + fontColorHL = "0 0 0"; + fontColorNA = "255 255 255"; + fixedExtent = false; + justify = "center"; + canKeyFocus = false; + bitmap = "data/ui/art/button"; + category = "Core"; +}; + +if( !isObject( GuiPopUpMenuDefault ) ) +new GuiControlProfile( GuiPopUpMenuDefault : GuiDefaultProfile ) +{ + opaque = true; + mouseOverSelected = true; + textOffset = "3 3"; + border = 0; + borderThickness = 0; + fixedExtent = true; + bitmap = "data/ui/art/scrollBar"; + hasBitmapArray = true; + profileForChildren = GuiPopupMenuItemBorder; + fillColor = "242 241 240 ";//"255 255 255";//100 + fillColorHL = "228 228 235 ";//"204 203 202"; + fillColorSEL = "98 100 137 ";//"204 203 202"; + // font color is black + fontColorHL = "0 0 0 ";//"0 0 0"; + fontColorSEL = "255 255 255";//"0 0 0"; + borderColor = "100 100 100"; + category = "Core"; +}; + +if( !isObject( GuiPopUpMenuProfile ) ) +new GuiControlProfile( GuiPopUpMenuProfile : GuiPopUpMenuDefault ) +{ + textOffset = "6 4"; + bitmap = "data/ui/art/dropDown"; + hasBitmapArray = true; + border = 1; + profileForChildren = GuiPopUpMenuDefault; + category = "Core"; +}; + +if( !isObject( GuiTabBookProfile ) ) +new GuiControlProfile( GuiTabBookProfile ) +{ + fillColorHL = "100 100 100"; + fillColorNA = "150 150 150"; + fontColor = "30 30 30"; + fontColorHL = "0 0 0"; + fontColorNA = "50 50 50"; + fontType = "Arial"; + fontSize = 14; + justify = "center"; + bitmap = "data/ui/art/tab"; + tabWidth = 64; + tabHeight = 24; + tabPosition = "Top"; + tabRotation = "Horizontal"; + textOffset = "0 -3"; + tab = true; + cankeyfocus = true; + category = "Core"; +}; + +if( !isObject( GuiTabPageProfile ) ) +new GuiControlProfile( GuiTabPageProfile : GuiDefaultProfile ) +{ + fontType = "Arial"; + fontSize = 10; + justify = "center"; + bitmap = "data/ui/art/tab"; + opaque = false; + fillColor = "240 239 238"; + category = "Core"; +}; + +if( !isObject( GuiConsoleProfile ) ) +new GuiControlProfile( GuiConsoleProfile ) +{ + fontType = ($platform $= "macos") ? "Monaco" : "Lucida Console"; + fontSize = ($platform $= "macos") ? 13 : 12; + fontColor = "255 255 255"; + fontColorHL = "0 255 255"; + fontColorNA = "255 0 0"; + fontColors[6] = "100 100 100"; + fontColors[7] = "100 100 0"; + fontColors[8] = "0 0 100"; + fontColors[9] = "0 100 0"; + category = "Core"; +}; + +if( !isObject( GuiConsoleTextProfile ) ) +new GuiControlProfile( GuiConsoleTextProfile ) +{ + fontColor = "0 0 0"; + autoSizeWidth = true; + autoSizeHeight = true; + textOffset = "2 2"; + opaque = true; + fillColor = "255 255 255"; + border = true; + borderThickness = 1; + borderColor = "0 0 0"; + category = "Core"; +}; + +$ConsoleDefaultFillColor = "0 0 0 175"; + +if( !isObject( ConsoleScrollProfile ) ) +new GuiControlProfile( ConsoleScrollProfile : GuiScrollProfile ) +{ + opaque = true; + fillColor = $ConsoleDefaultFillColor; + border = 1; + //borderThickness = 0; + borderColor = "0 0 0"; + category = "Core"; +}; + +if( !isObject( ConsoleTextEditProfile ) ) +new GuiControlProfile( ConsoleTextEditProfile : GuiTextEditProfile ) +{ + fillColor = "242 241 240 255"; + fillColorHL = "255 255 255"; + category = "Core"; +}; + +//----------------------------------------------------------------------------- +// Center and bottom print +//----------------------------------------------------------------------------- + +if( !isObject( CenterPrintProfile ) ) +new GuiControlProfile ( CenterPrintProfile ) +{ + opaque = false; + fillColor = "128 128 128"; + fontColor = "0 255 0"; + border = true; + borderColor = "0 255 0"; + category = "Core"; +}; + +if( !isObject( CenterPrintTextProfile ) ) +new GuiControlProfile ( CenterPrintTextProfile ) +{ + opaque = false; + fontType = "Arial"; + fontSize = 12; + fontColor = "0 255 0"; + category = "Core"; +}; + +// ---------------------------------------------------------------------------- +// Radio button control +// ---------------------------------------------------------------------------- + +if( !isObject( GuiRadioProfile ) ) +new GuiControlProfile( GuiRadioProfile ) +{ + fontSize = 14; + fillColor = "232 232 232"; + fontColor = "20 20 20"; + fontColorHL = "80 80 80"; + fixedExtent = true; + bitmap = "data/ui/art/radioButton"; + hasBitmapArray = true; + category = "Core"; +}; + +// --------------------------------------------------------------------------- +// Slider control +// --------------------------------------------------------------------------- +if( !isObject( GuiSliderProfile ) ) +new GuiControlProfile( GuiSliderProfile ) +{ + bitmap = "data/ui/art/slider"; + category = "Core"; +}; + +// +// Scroll Profile +// +if(!isObject(GuiMenuScrollProfile)) +new GuiControlProfile(GuiMenuScrollProfile) +{ + opaque = true; + fillcolor = "50 50 50"; + fontColor = "200 200 200"; + fontColorHL = "250 250 250"; + border = true; + bitmap = "data/ui/art/scrollBar"; + hasBitmapArray = true; + category = "Core"; +}; + +// Scroll +if(!isObject(GuiMenuScrollProfile)) +new GuiControlProfile(GuiMenuScrollProfile) +{ + opaque = true; + fillcolor = "128 128 128"; + fontColor = "0 0 0"; + fontColorHL = "150 150 150"; + border = true; + bitmap = "./images/scrollBar"; + hasBitmapArray = true; + category = "Core"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/data/ui/sound/buttonClick.wav b/Templates/BaseGame/game/data/ui/sound/buttonClick.wav new file mode 100644 index 000000000..ec55432ee Binary files /dev/null and b/Templates/BaseGame/game/data/ui/sound/buttonClick.wav differ diff --git a/Templates/BaseGame/game/data/ui/sound/buttonHover.wav b/Templates/BaseGame/game/data/ui/sound/buttonHover.wav new file mode 100644 index 000000000..e7276cde4 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/sound/buttonHover.wav differ diff --git a/Templates/BaseGame/game/main.cs.in b/Templates/BaseGame/game/main.cs.in new file mode 100644 index 000000000..760e45b02 --- /dev/null +++ b/Templates/BaseGame/game/main.cs.in @@ -0,0 +1,93 @@ +$Core::windowIcon = "data/icon.png"; +$Core::splashWindowImage = "data/splash.png"; + +// Display a splash window immediately to improve app responsiveness before +// engine is initialized and main window created. +displaySplashWindow($Core::splashWindowImage); + +// Console does something. +setLogMode(6); + +// Disable script trace. +trace(false); + +// Set the name of our application +$appName = "@TORQUE_APP_NAME@"; + +//----------------------------------------------------------------------------- +// Load up scripts to initialise subsystems. +exec("core/main.cs"); + +// Parse the command line arguments +echo("\n--------- Parsing Arguments ---------"); +parseArgs(); + +// The canvas needs to be initialized before any gui scripts are run since +// some of the controls assume that the canvas exists at load time. +createCanvas($appName); + +//----------------------------------------------------------------------------- +// Load console. +exec("core/console/main.cs"); + +// Init the physics plugin. +physicsInit(); + +sfxStartup(); + +// Set up networking. +setNetPort(0); + +// Start processing file change events. +startFileChangeNotifications(); + +// If we have editors, initialize them here as well +if(isFile("tools/main.cs") && !$isDedicated) + exec("tools/main.cs"); + +ModuleDatabase.setModuleExtension("module"); +ModuleDatabase.scanModules( "data", false ); +ModuleDatabase.LoadGroup( "Game" ); + +if( !$isDedicated ) +{ + // Start rendering and stuff. + initRenderManager(); + initLightingSystems("Advanced Lighting"); + + //load prefs + %prefPath = getPrefpath(); + if ( isFile( %prefPath @ "/clientPrefs.cs" ) ) + exec( %prefPath @ "/clientPrefs.cs" ); + else + exec("data/defaults.cs"); + + configureCanvas(); + + //Autodetect settings if it's our first time + if($pref::Video::autoDetect) + GraphicsMenu.Autodetect(); + + closeSplashWindow(); + + // As we know at this point that the initial load is complete, + // we can hide any splash screen we have, and show the canvas. + // This keeps things looking nice, instead of having a blank window + Canvas.showWindow(); +} +else +{ + closeSplashWindow(); +} + +echo("Engine initialized..."); + +//----------------------------------------------------------------------------- +// Called when the engine is shutting down. +function onExit() +{ + // Stop file change events. + stopFileChangeNotifications(); + + ModuleDatabase.UnloadExplicit( "Game" ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/runTests.cs b/Templates/BaseGame/game/runTests.cs new file mode 100644 index 000000000..b6d903ff0 --- /dev/null +++ b/Templates/BaseGame/game/runTests.cs @@ -0,0 +1,5 @@ +setLogMode(2); +$Con::LogBufferEnabled = false; +$Testing::CheckMemoryLeaks = false; +runAllUnitTests("-*.Stress*"); +quit(); diff --git a/Templates/BaseGame/game/tools/base/canvas/baseCanvas.ed.cs b/Templates/BaseGame/game/tools/base/canvas/baseCanvas.ed.cs new file mode 100644 index 000000000..4689d0ae5 --- /dev/null +++ b/Templates/BaseGame/game/tools/base/canvas/baseCanvas.ed.cs @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +function BaseEditorCanvas::onAdd( %this ) +{ + %this.createMenuBar(); + + %panel = new GuiPanel() { internalName = "DocumentContainer"; }; + %this.setContent( %panel ); + + %xOffset = 20; + %yOffset = 20; + + for( %i =0; %i<10; %i++ ) + { + %window = new GuiWindowCtrl() + { + extent = "200 100"; + position = %xOffset SPC %yOffset; + }; + %panel.add( %window ); + + %xOffset += 30; + %yOffset += 30; + + } +} + +function BaseEditorCanvas::onRemove( %this ) +{ + %this.destroyMenuBar(); +} + +function testBaseEditor() +{ + %baseEd = new GuiCanvas() { class="BaseEditorCanvas"; }; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/base/main.cs b/Templates/BaseGame/game/tools/base/main.cs new file mode 100644 index 000000000..eab511eb6 --- /dev/null +++ b/Templates/BaseGame/game/tools/base/main.cs @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function initializeBase() +{ + echo(" % - Initializing Base Editor"); + + // Load Custom Editors + loadDirectory( expandFilename( "./canvas" ) ); + loadDirectory( expandFilename( "./menuBar" ) ); + loadDirectory( expandFilename( "./utils" ) ); +} + +function destroyBase() +{ +} diff --git a/Templates/BaseGame/game/tools/base/menuBar/baseMenu.ed.cs b/Templates/BaseGame/game/tools/base/menuBar/baseMenu.ed.cs new file mode 100644 index 000000000..f53606518 --- /dev/null +++ b/Templates/BaseGame/game/tools/base/menuBar/baseMenu.ed.cs @@ -0,0 +1,81 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// onAdd creates the base menu's and document controller +function BaseEditorCanvas::createMenuBar( %this ) +{ + if(isObject(%this.menuBar)) + return; + + // Menu bar + %this.menuBar = new MenuBar() + { + dynamicItemInsertPos = 3; + + // File Menu + new PopupMenu() + { + superClass = "MenuBuilder"; + class = "BaseEditorFileMenu"; + internalName = "FileMenu"; + + barTitle = "File"; + + item[0] = "New..." TAB "Ctrl N" TAB "[this].onNew();"; + item[1] = "Open..." TAB "Ctrl O" TAB "[this].onOpen();"; + item[2] = "-"; + item[3] = "Save" TAB "Ctrl S" TAB "[this].onSave();"; + item[4] = "Save As" TAB "Ctrl-Alt S" TAB "[this].onSaveAs();"; + item[5] = "Save All" TAB "Ctrl-Shift S" TAB "[this].onSaveAll();"; + item[6] = "-"; + item[7] = "Import..." TAB "Ctrl-Shift I" TAB "[this].onImport();"; + item[8] = "Export..." TAB "Ctrl-Shift E" TAB "[this].onExport();"; + item[9] = "-"; + item[10] = "Revert" TAB "Ctrl R" TAB "[this].onRevert();"; + item[11] = "-"; + item[12] = "Close" TAB "Ctrl W" TAB "[this].onClose();"; + }; + }; +} + +function BaseEditorCanvas::destroyMenuBar( %this ) +{ + if( isObject( %this.menuBar ) ) + %this.menuBar.delete(); +} + +function BaseEditorCanvas::onCreateMenu(%this) +{ + if( !isObject( %this.menuBar ) ) + %this.createMenuBar(); + + %this.menuBar.attachToCanvas( %this, 0 ); +} + +function BaseEditorCanvas::onDestroyMenu(%this) +{ + if( isObject( %this.menuBar ) ) + { + %this.destroyMenuBar(); + %this.menuBar.removeFromCanvas( %this ); + } +} diff --git a/Templates/BaseGame/game/tools/base/menuBar/fileMenu.ed.cs b/Templates/BaseGame/game/tools/base/menuBar/fileMenu.ed.cs new file mode 100644 index 000000000..1ab685e4a --- /dev/null +++ b/Templates/BaseGame/game/tools/base/menuBar/fileMenu.ed.cs @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// +// +// +function BaseEditorFileMenu::onNew( %this ) +{ +} +function BaseEditorFileMenu::onOpen( %this ) +{ +} +function BaseEditorFileMenu::onSave( %this ) +{ +} +function BaseEditorFileMenu::onSaveAs( %this ) +{ +} +function BaseEditorFileMenu::onSaveAll( %this ) +{ +} +function BaseEditorFileMenu::onRevert( %this ) +{ +} +function BaseEditorFileMenu::onClose( %this ) +{ +} +function BaseEditorFileMenu::onImport( %this ) +{ +} +function BaseEditorFileMenu::onExport( %this ) +{ +} diff --git a/Templates/BaseGame/game/tools/base/menuBar/menuBuilder.ed.cs b/Templates/BaseGame/game/tools/base/menuBar/menuBuilder.ed.cs new file mode 100644 index 000000000..11d66b2ed --- /dev/null +++ b/Templates/BaseGame/game/tools/base/menuBar/menuBuilder.ed.cs @@ -0,0 +1,248 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Menu Builder Helper Class +//----------------------------------------------------------------------------- +/// @class MenuBuilder +/// @brief Create Dynamic Context and MenuBar Menus +/// +/// +/// Summary : The MenuBuilder script class exists merely as a helper for creating +/// popup menu's for use in torque editors. It is setup as a single +/// object with dynamic fields starting with item[0]..[n] that describe +/// how to create the menu in question. An example is below. +/// +/// isPopup : isPopup is a persistent field on PopupMenu console class which +/// when specified to true will allow you to perform .showPopup(x,y) +/// commands which allow popupmenu's to be used/reused as menubar menus +/// as well as context menus. +/// +/// barPosition : barPosition indicates which index on the menu bar (0 = leftmost) +/// to place this menu if it is attached. Use the attachToMenuBar() command +/// to attach a menu. +/// +/// barName : barName specifies the visible name of a menu item that is attached +/// to the global menubar. +/// +/// canvas : The GuiCanvas object the menu should be attached to. This defaults to +/// the global Canvas object if unspecified. +/// +/// Remarks : If you wish to use a menu as a context popup menu, isPopup must be +/// specified as true at the creation time of the menu. +/// +/// +/// @li @b item[n] (String) TAB (String) TAB (String) : A Menu Item Definition. +/// @code item[0] = "Open File..." TAB "Ctrl O" TAB "Something::OpenFile"; @endcode +/// +/// @li @b isPopup (bool) : If Specified the menu will be considered a popup menu and should be used via .showPopup() +/// @code isPopup = true; @endcode +/// +/// +/// Example : Creating a @b MenuBar Menu +/// @code +/// %%editMenu = new PopupMenu() +/// { +/// barPosition = 3; +/// barName = "View"; +/// superClass = "MenuBuilder"; +/// item[0] = "Undo" TAB "Ctrl Z" TAB "levelBuilderUndo(1);"; +/// item[1] = "Redo" TAB "Ctrl Y" TAB "levelBuilderRedo(1);"; +/// item[2] = "-"; +/// }; +/// +/// %%editMenu.attachToMenuBar( 1, "Edit" ); +/// +/// @endcode +/// +/// +/// Example : Creating a @b Context (Popup) Menu +/// @code +/// %%contextMenu = new PopupMenu() +/// { +/// superClass = MenuBuilder; +/// isPopup = true; +/// item[0] = "My Super Cool Item" TAB "Ctrl 2" TAB "echo(\"Clicked Super Cool Item\");"; +/// item[1] = "-"; +/// }; +/// +/// %%contextMenu.showPopup(); +/// @endcode +/// +/// +/// Example : Modifying a Menu +/// @code +/// %%editMenu = new PopupMenu() +/// { +/// item[0] = "Foo" TAB "Ctrl F" TAB "echo(\"clicked Foo\")"; +/// item[1] = "-"; +/// }; +/// %%editMenu.addItem( 2, "Bar" TAB "Ctrl B" TAB "echo(\"clicked Bar\")" ); +/// %%editMenu.removeItem( 0 ); +/// %%editMenu.addItem( 0, "Modified Foo" TAB "Ctrl F" TAB "echo(\"clicked modified Foo\")" ); +/// @endcode +/// +/// +/// @see PopupMenu +/// +//----------------------------------------------------------------------------- + +// Adds one item to the menu. +// if %item is skipped or "", we will use %item[#], which was set when the menu was created. +// if %item is provided, then we update %item[#]. +function MenuBuilder::addItem(%this, %pos, %item) +{ + if(%item $= "") + %item = %this.item[%pos]; + + if(%item !$= %this.item[%pos]) + %this.item[%pos] = %item; + + %name = getField(%item, 0); + %accel = getField(%item, 1); + %cmd = getField(%item, 2); + + // We replace the [this] token with our object ID + %cmd = strreplace( %cmd, "[this]", %this ); + %this.item[%pos] = setField( %item, 2, %cmd ); + + if(isObject(%accel)) + { + // If %accel is an object, we want to add a sub menu + %this.insertSubmenu(%pos, %name, %accel); + } + else + { + %this.insertItem(%pos, %name !$= "-" ? %name : "", %accel, %cmd); + } +} + +function MenuBuilder::appendItem(%this, %item) +{ + %this.addItem(%this.getItemCount(), %item); +} + +function MenuBuilder::onAdd(%this) +{ + if(! isObject(%this.canvas)) + %this.canvas = Canvas; + + for(%i = 0;%this.item[%i] !$= "";%i++) + { + %this.addItem(%i); + } +} + +function MenuBuilder::onRemove(%this) +{ + %this.removeFromMenuBar(); +} + +////////////////////////////////////////////////////////////////////////// + +function MenuBuilder::onSelectItem(%this, %id, %text) +{ + %cmd = getField(%this.item[%id], 2); + if(%cmd !$= "") + { + eval( %cmd ); + return true; + } + return false; +} + +/// Sets a new name on an existing menu item. +function MenuBuilder::setItemName( %this, %id, %name ) +{ + %item = %this.item[%id]; + %accel = getField(%item, 1); + %this.setItem( %id, %name, %accel ); +} + +/// Sets a new command on an existing menu item. +function MenuBuilder::setItemCommand( %this, %id, %command ) +{ + %this.item[%id] = setField( %this.item[%id], 2, %command ); +} + +/// (SimID this) +/// Wraps the attachToMenuBar call so that it does not require knowledge of +/// barName or barIndex to be removed/attached. This makes the individual +/// MenuBuilder items very easy to add and remove dynamically from a bar. +/// +function MenuBuilder::attachToMenuBar( %this ) +{ + if( %this.barName $= "" ) + { + error("MenuBuilder::attachToMenuBar - Menu property 'barName' not specified."); + return false; + } + + if( %this.barPosition < 0 ) + { + error("MenuBuilder::attachToMenuBar - Menu " SPC %this.barName SPC "property 'barPosition' is invalid, must be zero or greater."); + return false; + } + + Parent::attachToMenuBar( %this, %this.canvas, %this.barPosition, %this.barName ); +} + +////////////////////////////////////////////////////////////////////////// + +// Callbacks from PopupMenu. These callbacks are now passed on to submenus +// in C++, which was previously not the case. Thus, no longer anything to +// do in these. I am keeping the callbacks in case they are needed later. + +function MenuBuilder::onAttachToMenuBar(%this, %canvas, %pos, %title) +{ +} + +function MenuBuilder::onRemoveFromMenuBar(%this, %canvas) +{ +} + +////////////////////////////////////////////////////////////////////////// + +/// Method called to setup default state for the menu. Expected to be overriden +/// on an individual menu basis. See the mission editor for an example. +function MenuBuilder::setupDefaultState(%this) +{ + for(%i = 0;%this.item[%i] !$= "";%i++) + { + %name = getField(%this.item[%i], 0); + %accel = getField(%this.item[%i], 1); + %cmd = getField(%this.item[%i], 2); + + // Pass on to sub menus + if(isObject(%accel)) + %accel.setupDefaultState(); + } +} + +/// Method called to easily enable or disable all items in a menu. +function MenuBuilder::enableAllItems(%this, %enable) +{ + for(%i = 0; %this.item[%i] !$= ""; %i++) + { + %this.enableItem(%i, %enable); + } +} diff --git a/Templates/BaseGame/game/tools/base/utils/inspector.ed.cs b/Templates/BaseGame/game/tools/base/utils/inspector.ed.cs new file mode 100644 index 000000000..f7c27ecf0 --- /dev/null +++ b/Templates/BaseGame/game/tools/base/utils/inspector.ed.cs @@ -0,0 +1,289 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Functionality that allows all editor inspectors to share certain functionality. + + + +//--------------------------------------------------------------------------------------------- + +function EditorInspectorBase::onAdd( %this ) +{ + if( !isObject( EditorInspectorBaseDatablockFieldPopup ) ) + new PopupMenu( EditorInspectorBaseDatablockFieldPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Edit Datablock" TAB "" TAB "DatablockEditorPlugin.openDatablock( %this.inspectorField.getData() );"; + Item[ 1 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.inspectorField.getData() );"; + item[ 2 ] = "Inspect Object" TAB "" TAB "inspectObject( %this.inspectorField.getData() );"; + item[ 3 ] = "-"; + item[ 4 ] = "Copy Value" TAB "" TAB "setClipboard( %this.inspectorField.getData() );"; + item[ 5 ] = "Paste Value" TAB "" TAB "%this.inspectorField.apply( getClipboard() );"; + item[ 6 ] = "Reset to Default" TAB "" TAB "%this.inspectorField.reset();"; + + inspectorField = -1; + }; + + if( !isObject( EditorInspectorBaseFieldPopup ) ) + new PopupMenu( EditorInspectorBaseFieldPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Inspect Object" TAB "" TAB "inspectObject( %this.inspectorField.getData() );"; + Item[ 1 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.inspectorField.getData() );"; + item[ 2 ] = "-"; + item[ 3 ] = "Copy Value" TAB "" TAB "setClipboard( %this.inspectorField.getData() );"; + item[ 4 ] = "Paste Value" TAB "" TAB "%this.inspectorField.apply( getClipboard() );"; + item[ 5 ] = "Reset to Default" TAB "" TAB "%this.inspectorField.reset();"; + + inspectorField = -1; + }; + + if( !isObject( EditorInspectorBaseFileFieldPopup ) ) + new PopupMenu( EditorInspectorBaseFileFieldPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Open File" TAB "" TAB "openFile( %this.filePath );"; + item[ 1 ] = "Open Folder" TAB "" TAB "openFolder( %this.folderPath );"; + item[ 2 ] = "-"; + item[ 3 ] = "Copy Value" TAB "" TAB "setClipboard( %this.inspectorField.getData() );"; + item[ 4 ] = "Paste Value" TAB "" TAB "%this.inspectorField.apply( getClipboard() );"; + item[ 5 ] = "Reset to Default" TAB "" TAB "%this.inspectorField.reset();"; + + inspectorField = -1; + folderPath = ""; + filePath = ""; + }; + + if( !isObject( EditorInspectorBaseShapeFieldPopup ) ) + new PopupMenu( EditorInspectorBaseShapeFieldPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Edit Shape" TAB "" TAB "ShapeEditorPlugin.openShape( %this.inspectorField.getData() );"; + item[ 1 ] = "-"; + item[ 2 ] = "Open File" TAB "" TAB "openFile( %this.filePath );"; + item[ 3 ] = "Open Folder" TAB "" TAB "openFolder( %this.folderPath );"; + item[ 4 ] = "-"; + item[ 5 ] = "Copy Value" TAB "" TAB "setClipboard( %this.inspectorField.getData() );"; + item[ 6 ] = "Paste Value" TAB "" TAB "%this.inspectorField.apply( getClipboard() );"; + item[ 7 ] = "Reset to Default" TAB "" TAB "%this.inspectorField.reset();"; + + inspectorField = -1; + folderPath = ""; + filePath = ""; + }; + + if( !isObject( EditorInspectorBaseProfileFieldPopup ) ) + new PopupMenu( EditorInspectorBaseProfileFieldPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Edit Profile" TAB "" TAB "if( !GuiEditorIsActive() ) toggleGuiEditor( true ); GuiEditor.editProfile( %this.inspectorField.getData() );"; + item[ 1 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.inspectorField.getData() );"; + item[ 2 ] = "Inspect Object" TAB "" TAB "inspectObject( %this.inspectorField.getData() );"; + item[ 3 ] = "-"; + item[ 4 ] = "Copy Value" TAB "" TAB "setClipboard( %this.inspectorField.getData() );"; + item[ 5 ] = "Paste Value" TAB "" TAB "%this.inspectorField.apply( getClipboard() );"; + item[ 6 ] = "Reset to Default" TAB "" TAB "%this.inspectorField.reset();"; + + inspectorField = -1; + folderPath = ""; + filePath = ""; + }; +} + +//--------------------------------------------------------------------------------------------- + +function EditorInspectorBase::onFieldRightClick( %this, %field ) +{ + %obj = %this.getInspectObject(); + %fieldValue = %field.getData(); + + %inspectIndex = -1; + %openFileIndex = -1; + %openFolderIndex = -1; + + // Find out if this is a TypeFilename field referring to a shape file. + + %isShapeFilenameField = false; + if( %field.getInspectedFieldName() $= "shapeName" ) + { + %isShapeFilenameField = + %obj.isMemberOfClass( "PhysicsShape" ) || + %obj.isMemberOfClass( "TSStatic" ); + } + else if( %field.getInspectedFieldName() $= "shapeFile" ) + { + %isShapeFilenameField = + %obj.isMemberOfClass( "ShapeBaseData" ) || + %obj.isMemberOfClass( "ShapeBaseImageData" ) || + %obj.isMemberOfClass( "ForestItemData" ) || + %obj.isMemberOfClass( "WheeledVehicleTire" ) || + %obj.isMemberOfClass( "fxShapeReplicator" ) || + %obj.isMemberOfClass( "RenderShapeExample" ) || + %obj.isMemberOfClass( "DebrisData" ); + } + + // Select the popup. + + if( %isShapeFilenameField ) + { + %popup = EditorInspectorBaseShapeFieldPopup; + + %openFileIndex = 2; + %openFolderIndex = 3; + } + else if( EditorInspectorBase::isFileTypeField( %field ) ) + { + %popup = EditorInspectorBaseFileFieldPopup; + %openFileIndex = 0; + %openFolderIndex = 1; + } + else + { + switch$( %field.getClassName() ) + { + case "GuiInspectorCustomField": + if( %field.getInspectedFieldName() !$= "parentGroup" ) + return; + + case "GuiInspectorTypeGuiProfile": + + %popup = EditorInspectorBaseProfileFieldPopup; + + %popup.enableItem( 0, isObject( %fieldValue ) ); + %inspectIndex = 2; + %jumpToIndex = 1; + + case "GuiInspectorDatablockField" or + "GuiInspectorTypeSFXDescriptionName" or + "GuiInspectorTypeSFXEnvironmentName" or + "GuiInspectorTypeSFXTrackName" or + "GuiInspectorTypeSFXAmbienceName" or + "GuiInspectorTypeSFXSourceName": + + %popup = EditorInspectorBaseDatablockFieldPopup; + %popup.enableItem( 0, isObject( %fieldValue ) ); + %inspectIndex = 2; + %jumpToIndex = 1; + + default: + + %popup = EditorInspectorBaseFieldPopup; + %inspectIndex = 0; + %jumpToIndex = 1; + } + } + + if( %inspectIndex != -1 ) + { + %isObject = false; + if( EditorInspectorBase::isObjectTypeField( %field ) ) + %isObject = isObject( %fieldValue ); + + %popup.enableItem( %inspectIndex, %isObject ); + %popup.enableItem( %jumpToIndex, %isObject ); + } + + if( %openFileIndex != -1 || %openFolderIndex != -1 ) + { + %fullPath = EditorInspectorBase::getFullFilePath( %field ); + %popup.filePath = %fullPath; + %popup.folderPath = filePath( %fullPath ); + + if( %openFileIndex != -1 ) + %popup.enableItem( 0, isFile( %fullPath ) ); + + if( %openFolderIndex != -1 ) + %popup.enableItem( 1, isDirectory( %popup.folderPath ) ); + } + + %popup.inspectorField = %field; + %popup.showPopup( Canvas ); +} + +//--------------------------------------------------------------------------------------------- + +function EditorInspectorBase::isObjectTypeField( %field ) +{ + // Inspector field types that refer to objects. + + switch$( %field.getClassName() ) + { + case "GuiInspectorDatablockField" or + "GuiInspectorTypeSFXDescriptionName" or + "GuiInspectorTypeSFXEnvironmentName" or + "GuiInspectorTypeSFXTrackName" or + "GuiInspectorTypeSFXAmbienceName" or + "GuiInspectorTypeSFXSourceName" or + "GuiInspectorTypeGuiProfile": + return true; + } + + // Other console types that refer to objects. + + switch$( %field.getInspectedFieldType() ) + { + case "TypeSimObject" or + "TypeSimObjectName" or + "TypeMaterialName" or + "TypeCubemapName" or + "TypeGuiProfile": + return true; + } + + return false; +} + +//--------------------------------------------------------------------------------------------- + +function EditorInspectorBase::isFileTypeField( %field ) +{ + return %field.isMemberOfClass( "GuiInspectorTypeFileName" ); +} + +//--------------------------------------------------------------------------------------------- + +function EditorInspectorBase::getFullFilePath( %field ) +{ + %fileName = %field.getData(); + %inspector = %field.getInspector(); + %object = %inspector.getInspectObject(); + + if( %object.isMemberOfClass( "Material" ) ) + { + // Image filenames in materials are relative to the material's file. + + %objectPath = filePath( makeFullPath( %object.getFilename(), getMainDotCsDir() ) ); + return makeFullPath( %fileName, %objectPath ); + } + else + return makeFullPath( %fileName, getMainDotCsDir() ); +} diff --git a/Templates/BaseGame/game/tools/base/utils/objectNameValidation.ed.cs b/Templates/BaseGame/game/tools/base/utils/objectNameValidation.ed.cs new file mode 100644 index 000000000..ba74d0d36 --- /dev/null +++ b/Templates/BaseGame/game/tools/base/utils/objectNameValidation.ed.cs @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +function Editor::validateObjectName( %name, %mustHaveName ) +{ + if( %mustHaveName && %name $= "" ) + { + MessageBoxOK( "Missing Object Name", "No name given for object. Please enter a valid object name." ); + return false; + } + if( !isValidObjectName( %name ) ) + { + MessageBoxOK( "Invalid Object Name", "'" @ %name @ "' is not a valid object name." NL + "" NL + "Please choose a name that begins with a letter or underscore and is otherwise comprised " @ + "exclusively of letters, digits, and/or underscores." + ); + return false; + } + if( isObject( %name ) ) + { + %filename = %name.getFilename(); + if ( %filename $= "" ) + %filename = "an unknown file"; + + MessageBoxOK( "Invalid Object Name", "Object names must be unique, and there is an " @ + "existing " @ %name.getClassName() @ " object with the name '" @ %name @ "' (defined " @ + "in " @ %filename @ "). Please choose another name." ); + return false; + } + if( isClass( %name ) ) + { + MessageBoxOK( "Invalid Object Name", "'" @ %name @ "' is the name of an existing TorqueScript " @ + "class. Please choose another name." ); + return false; + } + + return true; +} diff --git a/Templates/BaseGame/game/tools/base/utils/swatchButtons.ed.cs b/Templates/BaseGame/game/tools/base/utils/swatchButtons.ed.cs new file mode 100644 index 000000000..b26cffcd8 --- /dev/null +++ b/Templates/BaseGame/game/tools/base/utils/swatchButtons.ed.cs @@ -0,0 +1,99 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Common functionality for GuiSwatchButtonCtrls. +// +// Note that for the mouse-event related functionality, "useMouseEvents" must be set +// to true. + + +//--------------------------------------------------------------------------------------------- + +function GuiSwatchButtonCtrl::onMouseDragged( %this ) +{ + %payload = new GuiSwatchButtonCtrl(); + %payload.assignFieldsFrom( %this ); + %payload.position = "0 0 "; + %payload.dragSourceControl = %this; + + %xOffset = getWord( %payload.extent, 0 ) / 2; + %yOffset = getWord( %payload.extent, 1 ) / 2; + %cursorpos = Canvas.getCursorPos(); + %xPos = getWord( %cursorpos, 0 ) - %xOffset; + %yPos = getWord( %cursorpos, 1 ) - %yOffset; + + // Create the drag control. + + %ctrl = new GuiDragAndDropControl() + { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiSolidDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = %xPos SPC %yPos; + extent = %payload.extent; + MinExtent = "4 4"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + deleteOnMouseUp = true; + class = "GuiDragAndDropControlType_ColorSwatch"; + }; + + %ctrl.add( %payload ); + + // Start drag. + + Canvas.getContent().add( %ctrl ); + %ctrl.startDragging( %xOffset, %yOffset ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiSwatchButtonCtrl::onControlDropped( %this, %payload, %position ) +{ + if( !%payload.parentGroup.isInNamespaceHierarchy( "GuiDragAndDropControlType_ColorSwatch" ) ) + return; + + // If dropped on same button whence we came from, + // do nothing. + + if( %payload.dragSourceControl == %this ) + return; + + // If a swatch button control is dropped onto this control, + // copy it's color. + + if( %payload.isMemberOfClass( "GuiSwatchButtonCtrl" ) ) + { + // If the swatch button is part of a color-type inspector field, + // remember the inspector field so we can later set the color + // through it. + + if( %this.parentGroup.isMemberOfClass( "GuiInspectorTypeColorI" ) ) + %this.parentGroup.apply( ColorFloatToInt( %payload.color ) ); + else if( %this.parentGroup.isMemberOfClass( "GuiInspectorTypeColorF" ) ) + %this.parentGroup.apply( %payload.color ); + else + %this.setColor( %payload.color ); + } +} diff --git a/Templates/BaseGame/game/tools/base/utils/treeViewFilterCtrls.ed.cs b/Templates/BaseGame/game/tools/base/utils/treeViewFilterCtrls.ed.cs new file mode 100644 index 000000000..a3e055bc6 --- /dev/null +++ b/Templates/BaseGame/game/tools/base/utils/treeViewFilterCtrls.ed.cs @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Common functions for filter text and clear button controls on tree views. +// The GuiTextEditCtrl having the filter text must have "treeView" dynamic field +// that has the ID of the associated GuiTreeViewCtrl. +// The button ctrl used to clear the text field must have a "textCtrl" dynamic field +// that has the ID of the associated filter GuiTextEditCtrl. + + +//--------------------------------------------------------------------------------------------- + +function GuiTreeViewFilterText::onWake( %this ) +{ + %filter = %this.treeView.getFilterText(); + if( %filter $= "" ) + %this.setText( "\c2Filter..." ); + else + %this.setText( %filter ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiTreeViewFilterText::onGainFirstResponder( %this ) +{ + %this.selectAllText(); +} + +//--------------------------------------------------------------------------------------------- + +// When Enter is pressed in the filter text control, pass along the text of the control +// as the treeview's filter. +function GuiTreeViewFilterText::onReturn( %this ) +{ + %text = %this.getText(); + if( %text $= "" ) + %this.reset(); + else + %this.treeView.setFilterText( %text ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiTreeViewFilterText::reset( %this ) +{ + %this.setText( "\c2Filter..." ); + %this.treeView.clearFilterText(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiTreeViewFilterClearButton::onClick( %this ) +{ + %this.textCtrl.reset(); +} diff --git a/Templates/BaseGame/game/tools/base/utils/undoActions.ed.cs b/Templates/BaseGame/game/tools/base/utils/undoActions.ed.cs new file mode 100644 index 000000000..3de6c2f1b --- /dev/null +++ b/Templates/BaseGame/game/tools/base/utils/undoActions.ed.cs @@ -0,0 +1,93 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Undo actions that are useful in multiple editors. + + +//============================================================================================= +// Undo reparenting. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function UndoActionReparentObjects::create( %treeView ) +{ + pushInstantGroup(); + %action = new UndoScriptAction() + { + class = "UndoActionReparentObjects"; + numObjects = 0; + treeView = %treeView; + }; + popInstantGroup(); + + return %action; +} + +//--------------------------------------------------------------------------------------------- + +function UndoActionReparentObjects::add( %this, %object, %oldParent, %newParent ) +{ + %index = %this.numObjects; + + %this.objects[ %index ] = %object; + %this.oldParents[ %index ] = %oldParent; + %this.newParents[ %index ] = %newParent; + + %this.numObjects = %this.numObjects + 1; +} + +//--------------------------------------------------------------------------------------------- + +function UndoActionReparentObjects::undo( %this ) +{ + %numObjects = %this.numObjects; + for( %i = 0; %i < %numObjects; %i ++ ) + { + %obj = %this.objects[ %i ]; + %group = %this.oldParents[ %i ]; + + if( isObject( %obj ) && isObject( %group ) ) + %obj.parentGroup = %group; + } + + if( isObject( %this.treeView ) ) + %this.treeView.update(); +} + +//--------------------------------------------------------------------------------------------- + +function UndoActionReparentObjects::redo( %this ) +{ + %numObjects = %this.numObjects; + for( %i = 0; %i < %numObjects; %i ++ ) + { + %obj = %this.objects[ %i ]; + %group = %this.newParents[ %i ]; + + if( isObject( %obj ) && isObject( %group ) ) + %obj.parentGroup = %group; + } + + if( isObject( %this.treeView ) ) + %this.treeView.update(); +} diff --git a/Templates/BaseGame/game/tools/classIcons/BasicClouds.png b/Templates/BaseGame/game/tools/classIcons/BasicClouds.png new file mode 100644 index 000000000..f5c863f29 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/BasicClouds.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/Camera.png b/Templates/BaseGame/game/tools/classIcons/Camera.png new file mode 100644 index 000000000..0722c8515 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/Camera.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/CameraBookmark.png b/Templates/BaseGame/game/tools/classIcons/CameraBookmark.png new file mode 100644 index 000000000..0722c8515 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/CameraBookmark.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/CloudLayer.png b/Templates/BaseGame/game/tools/classIcons/CloudLayer.png new file mode 100644 index 000000000..0cde23bc0 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/CloudLayer.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/ConvexShape.png b/Templates/BaseGame/game/tools/classIcons/ConvexShape.png new file mode 100644 index 000000000..bc9c749d4 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/ConvexShape.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/CreatorTree.png b/Templates/BaseGame/game/tools/classIcons/CreatorTree.png new file mode 100644 index 000000000..f916c304e Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/CreatorTree.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/DecalRoad.png b/Templates/BaseGame/game/tools/classIcons/DecalRoad.png new file mode 100644 index 000000000..cbe8aab12 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/DecalRoad.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/Forest.png b/Templates/BaseGame/game/tools/classIcons/Forest.png new file mode 100644 index 000000000..014caf957 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/Forest.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/ForestBrush.png b/Templates/BaseGame/game/tools/classIcons/ForestBrush.png new file mode 100644 index 000000000..af9ab2520 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/ForestBrush.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/ForestBrushElement.png b/Templates/BaseGame/game/tools/classIcons/ForestBrushElement.png new file mode 100644 index 000000000..0fc969d30 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/ForestBrushElement.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GameTSCtrl.png b/Templates/BaseGame/game/tools/classIcons/GameTSCtrl.png new file mode 100644 index 000000000..f1801ffe0 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GameTSCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GroundCover.png b/Templates/BaseGame/game/tools/classIcons/GroundCover.png new file mode 100644 index 000000000..6d3ebecd3 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GroundCover.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GroundPlane.png b/Templates/BaseGame/game/tools/classIcons/GroundPlane.png new file mode 100644 index 000000000..96815a58f Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GroundPlane.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiAutoScrollCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiAutoScrollCtrl.png new file mode 100644 index 000000000..b8219f575 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiAutoScrollCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiBitmapBorderCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiBitmapBorderCtrl.png new file mode 100644 index 000000000..b6d8e52ac Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiBitmapBorderCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiBitmapButtonCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiBitmapButtonCtrl.png new file mode 100644 index 000000000..76cb12598 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiBitmapButtonCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiBitmapButtonTextCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiBitmapButtonTextCtrl.png new file mode 100644 index 000000000..eeee4adcf Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiBitmapButtonTextCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiBitmapCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiBitmapCtrl.png new file mode 100644 index 000000000..6f511189f Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiBitmapCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiBorderButtonCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiBorderButtonCtrl.png new file mode 100644 index 000000000..25044777f Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiBorderButtonCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiButtonCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiButtonCtrl.png new file mode 100644 index 000000000..cc15e745f Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiButtonCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiCheckBoxCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiCheckBoxCtrl.png new file mode 100644 index 000000000..8e608ba2d Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiCheckBoxCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiColorPickerCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiColorPickerCtrl.png new file mode 100644 index 000000000..cd9c6ca32 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiColorPickerCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiContainer.png b/Templates/BaseGame/game/tools/classIcons/GuiContainer.png new file mode 100644 index 000000000..e4838a4b4 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiContainer.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiControl.png b/Templates/BaseGame/game/tools/classIcons/GuiControl.png new file mode 100644 index 000000000..633934138 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiControl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiControlArrayControl.png b/Templates/BaseGame/game/tools/classIcons/GuiControlArrayControl.png new file mode 100644 index 000000000..f7340fae4 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiControlArrayControl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiCrossHairHud.png b/Templates/BaseGame/game/tools/classIcons/GuiCrossHairHud.png new file mode 100644 index 000000000..65b06404a Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiCrossHairHud.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiDecoyCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiDecoyCtrl.png new file mode 100644 index 000000000..a092c1ee2 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiDecoyCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiDragAndDropControl.png b/Templates/BaseGame/game/tools/classIcons/GuiDragAndDropControl.png new file mode 100644 index 000000000..d55dd70f7 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiDragAndDropControl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiDynamicCtrlArrayControl.png b/Templates/BaseGame/game/tools/classIcons/GuiDynamicCtrlArrayControl.png new file mode 100644 index 000000000..a356634e8 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiDynamicCtrlArrayControl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiFadeinBitmapCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiFadeinBitmapCtrl.png new file mode 100644 index 000000000..60463c219 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiFadeinBitmapCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiFileTreeCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiFileTreeCtrl.png new file mode 100644 index 000000000..f916c304e Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiFileTreeCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiFilterCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiFilterCtrl.png new file mode 100644 index 000000000..b0ddc8a78 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiFilterCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiFormCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiFormCtrl.png new file mode 100644 index 000000000..6717fa7ac Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiFormCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiFrameSetCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiFrameSetCtrl.png new file mode 100644 index 000000000..633934138 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiFrameSetCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiGradientSwatchCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiGradientSwatchCtrl.png new file mode 100644 index 000000000..0b7d7c58b Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiGradientSwatchCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiGraphCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiGraphCtrl.png new file mode 100644 index 000000000..18dfdd8d5 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiGraphCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiHealthBarHud.png b/Templates/BaseGame/game/tools/classIcons/GuiHealthBarHud.png new file mode 100644 index 000000000..f661a431a Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiHealthBarHud.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiIconButtonCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiIconButtonCtrl.png new file mode 100644 index 000000000..752de83a4 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiIconButtonCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiListBoxCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiListBoxCtrl.png new file mode 100644 index 000000000..d6e5e064d Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiListBoxCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiMLTextCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiMLTextCtrl.png new file mode 100644 index 000000000..acb4ea577 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiMLTextCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiMLTextEditCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiMLTextEditCtrl.png new file mode 100644 index 000000000..0e1dea166 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiMLTextEditCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiMenuBar.png b/Templates/BaseGame/game/tools/classIcons/GuiMenuBar.png new file mode 100644 index 000000000..ef40a9834 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiMenuBar.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiObjectView.png b/Templates/BaseGame/game/tools/classIcons/GuiObjectView.png new file mode 100644 index 000000000..e6b832c9a Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiObjectView.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiPanel.png b/Templates/BaseGame/game/tools/classIcons/GuiPanel.png new file mode 100644 index 000000000..ea571796b Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiPanel.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiPopUpMenuCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiPopUpMenuCtrl.png new file mode 100644 index 000000000..c5ef727a2 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiPopUpMenuCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiPopUpMenuCtrlEx.png b/Templates/BaseGame/game/tools/classIcons/GuiPopUpMenuCtrlEx.png new file mode 100644 index 000000000..18a4aaf59 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiPopUpMenuCtrlEx.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiProgressBitmapCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiProgressBitmapCtrl.png new file mode 100644 index 000000000..a6be7a2ed Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiProgressBitmapCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiProgressCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiProgressCtrl.png new file mode 100644 index 000000000..5c07e2345 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiProgressCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiRadioCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiRadioCtrl.png new file mode 100644 index 000000000..062f90af2 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiRadioCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiRectHandles.png b/Templates/BaseGame/game/tools/classIcons/GuiRectHandles.png new file mode 100644 index 000000000..11e5a06a9 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiRectHandles.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiRolloutCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiRolloutCtrl.png new file mode 100644 index 000000000..ed922abdb Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiRolloutCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiScrollCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiScrollCtrl.png new file mode 100644 index 000000000..64e9fe1bc Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiScrollCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiSplitContainer.png b/Templates/BaseGame/game/tools/classIcons/GuiSplitContainer.png new file mode 100644 index 000000000..752127aaf Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiSplitContainer.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiStackControl.png b/Templates/BaseGame/game/tools/classIcons/GuiStackControl.png new file mode 100644 index 000000000..b8d34ffa3 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiStackControl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiSwatchButtonCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiSwatchButtonCtrl.png new file mode 100644 index 000000000..0b7d7c58b Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiSwatchButtonCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiTabBookCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiTabBookCtrl.png new file mode 100644 index 000000000..41e09bd65 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiTabBookCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiTabPageCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiTabPageCtrl.png new file mode 100644 index 000000000..ac58cc276 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiTabPageCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiTextCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiTextCtrl.png new file mode 100644 index 000000000..b185f092d Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiTextCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiTextEditCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiTextEditCtrl.png new file mode 100644 index 000000000..114a30e5f Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiTextEditCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiTextEditSliderCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiTextEditSliderCtrl.png new file mode 100644 index 000000000..27844cf39 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiTextEditSliderCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiTextListCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiTextListCtrl.png new file mode 100644 index 000000000..5369870c0 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiTextListCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiTheoraCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiTheoraCtrl.png new file mode 100644 index 000000000..2cf955565 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiTheoraCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiTreeViewCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiTreeViewCtrl.png new file mode 100644 index 000000000..f916c304e Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiTreeViewCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiWindowCollapseCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiWindowCollapseCtrl.png new file mode 100644 index 000000000..09e99cdd1 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiWindowCollapseCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/GuiWindowCtrl.png b/Templates/BaseGame/game/tools/classIcons/GuiWindowCtrl.png new file mode 100644 index 000000000..09e99cdd1 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/GuiWindowCtrl.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/Item.png b/Templates/BaseGame/game/tools/classIcons/Item.png new file mode 100644 index 000000000..94c6222dc Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/Item.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/LevelInfo.png b/Templates/BaseGame/game/tools/classIcons/LevelInfo.png new file mode 100644 index 000000000..d7d757686 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/LevelInfo.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/Lightning.png b/Templates/BaseGame/game/tools/classIcons/Lightning.png new file mode 100644 index 000000000..baedee38d Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/Lightning.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/Marker.png b/Templates/BaseGame/game/tools/classIcons/Marker.png new file mode 100644 index 000000000..a93b82252 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/Marker.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/MeshRoad.png b/Templates/BaseGame/game/tools/classIcons/MeshRoad.png new file mode 100644 index 000000000..8f33e23f4 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/MeshRoad.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/MissionArea.png b/Templates/BaseGame/game/tools/classIcons/MissionArea.png new file mode 100644 index 000000000..91bb1e219 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/MissionArea.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/NavMesh.png b/Templates/BaseGame/game/tools/classIcons/NavMesh.png new file mode 100644 index 000000000..056d3c3ac Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/NavMesh.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/NavPath.png b/Templates/BaseGame/game/tools/classIcons/NavPath.png new file mode 100644 index 000000000..35b8372ae Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/NavPath.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/ParticleEmitter.png b/Templates/BaseGame/game/tools/classIcons/ParticleEmitter.png new file mode 100644 index 000000000..e5489fc70 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/ParticleEmitter.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/ParticleEmitterNode.png b/Templates/BaseGame/game/tools/classIcons/ParticleEmitterNode.png new file mode 100644 index 000000000..351e4bd72 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/ParticleEmitterNode.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/Path.png b/Templates/BaseGame/game/tools/classIcons/Path.png new file mode 100644 index 000000000..945102557 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/Path.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/PhysicalZone.png b/Templates/BaseGame/game/tools/classIcons/PhysicalZone.png new file mode 100644 index 000000000..023cb7dd0 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/PhysicalZone.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/Player.png b/Templates/BaseGame/game/tools/classIcons/Player.png new file mode 100644 index 000000000..480dfce70 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/Player.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/PointLight.png b/Templates/BaseGame/game/tools/classIcons/PointLight.png new file mode 100644 index 000000000..bd47c6187 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/PointLight.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/Portal.png b/Templates/BaseGame/game/tools/classIcons/Portal.png new file mode 100644 index 000000000..0dec3b0a5 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/Portal.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/Precipitation.png b/Templates/BaseGame/game/tools/classIcons/Precipitation.png new file mode 100644 index 000000000..8e2cc784c Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/Precipitation.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/Prefab.png b/Templates/BaseGame/game/tools/classIcons/Prefab.png new file mode 100644 index 000000000..6786bda75 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/Prefab.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/PxCloth.png b/Templates/BaseGame/game/tools/classIcons/PxCloth.png new file mode 100644 index 000000000..5fa4a9ba4 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/PxCloth.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/River.png b/Templates/BaseGame/game/tools/classIcons/River.png new file mode 100644 index 000000000..87d6d0d2d Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/River.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/SFXEmitter.png b/Templates/BaseGame/game/tools/classIcons/SFXEmitter.png new file mode 100644 index 000000000..92f165e99 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/SFXEmitter.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/ScatterSky.png b/Templates/BaseGame/game/tools/classIcons/ScatterSky.png new file mode 100644 index 000000000..52257b0bc Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/ScatterSky.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/SceneObject.png b/Templates/BaseGame/game/tools/classIcons/SceneObject.png new file mode 100644 index 000000000..59079e3d7 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/SceneObject.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/SimDataBlock.png b/Templates/BaseGame/game/tools/classIcons/SimDataBlock.png new file mode 100644 index 000000000..63655e1cb Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/SimDataBlock.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/SimObject.png b/Templates/BaseGame/game/tools/classIcons/SimObject.png new file mode 100644 index 000000000..5c143982f Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/SimObject.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/SimSet.png b/Templates/BaseGame/game/tools/classIcons/SimSet.png new file mode 100644 index 000000000..571a904d0 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/SimSet.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/SkyBox.png b/Templates/BaseGame/game/tools/classIcons/SkyBox.png new file mode 100644 index 000000000..cfe50f6c4 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/SkyBox.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/SpawnSphere.png b/Templates/BaseGame/game/tools/classIcons/SpawnSphere.png new file mode 100644 index 000000000..df46d9df5 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/SpawnSphere.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/SpotLight.png b/Templates/BaseGame/game/tools/classIcons/SpotLight.png new file mode 100644 index 000000000..c63369559 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/SpotLight.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/Sun.png b/Templates/BaseGame/game/tools/classIcons/Sun.png new file mode 100644 index 000000000..097526cac Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/Sun.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/TSForestItemData.png b/Templates/BaseGame/game/tools/classIcons/TSForestItemData.png new file mode 100644 index 000000000..183c7e532 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/TSForestItemData.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/TSStatic.png b/Templates/BaseGame/game/tools/classIcons/TSStatic.png new file mode 100644 index 000000000..e0b7e7f94 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/TSStatic.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/TerrainBlock.png b/Templates/BaseGame/game/tools/classIcons/TerrainBlock.png new file mode 100644 index 000000000..db58bb863 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/TerrainBlock.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/TimeOfDay.png b/Templates/BaseGame/game/tools/classIcons/TimeOfDay.png new file mode 100644 index 000000000..e210a22da Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/TimeOfDay.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/Trigger.png b/Templates/BaseGame/game/tools/classIcons/Trigger.png new file mode 100644 index 000000000..c9f12040b Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/Trigger.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/VolumetricFog.png b/Templates/BaseGame/game/tools/classIcons/VolumetricFog.png new file mode 100644 index 000000000..5dc516cb5 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/VolumetricFog.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/WaterBlock.png b/Templates/BaseGame/game/tools/classIcons/WaterBlock.png new file mode 100644 index 000000000..6b396fff5 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/WaterBlock.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/WaterPlane.png b/Templates/BaseGame/game/tools/classIcons/WaterPlane.png new file mode 100644 index 000000000..a2d28f854 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/WaterPlane.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/Zone.png b/Templates/BaseGame/game/tools/classIcons/Zone.png new file mode 100644 index 000000000..117e48ad0 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/Zone.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/cameraSpawn.png b/Templates/BaseGame/game/tools/classIcons/cameraSpawn.png new file mode 100644 index 000000000..8a060a651 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/cameraSpawn.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/decal.png b/Templates/BaseGame/game/tools/classIcons/decal.png new file mode 100644 index 000000000..ba792f986 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/decal.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/decalNode.png b/Templates/BaseGame/game/tools/classIcons/decalNode.png new file mode 100644 index 000000000..f6684f185 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/decalNode.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/default.png b/Templates/BaseGame/game/tools/classIcons/default.png new file mode 100644 index 000000000..0519b5220 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/default.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/fxFoliageReplicator.png b/Templates/BaseGame/game/tools/classIcons/fxFoliageReplicator.png new file mode 100644 index 000000000..4dac38fc0 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/fxFoliageReplicator.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/fxShapeReplicator.png b/Templates/BaseGame/game/tools/classIcons/fxShapeReplicator.png new file mode 100644 index 000000000..94d1c4b30 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/fxShapeReplicator.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/interiorInstance.png b/Templates/BaseGame/game/tools/classIcons/interiorInstance.png new file mode 100644 index 000000000..7c699f858 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/interiorInstance.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/particleEffecterObject.png b/Templates/BaseGame/game/tools/classIcons/particleEffecterObject.png new file mode 100644 index 000000000..255a5a8a8 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/particleEffecterObject.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/particleEmitterObject.png b/Templates/BaseGame/game/tools/classIcons/particleEmitterObject.png new file mode 100644 index 000000000..e5489fc70 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/particleEmitterObject.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/particleSimulation.png b/Templates/BaseGame/game/tools/classIcons/particleSimulation.png new file mode 100644 index 000000000..95bcfef6b Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/particleSimulation.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/pathMarker.png b/Templates/BaseGame/game/tools/classIcons/pathMarker.png new file mode 100644 index 000000000..a93b82252 Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/pathMarker.png differ diff --git a/Templates/BaseGame/game/tools/classIcons/volumeLight.png b/Templates/BaseGame/game/tools/classIcons/volumeLight.png new file mode 100644 index 000000000..114a7f2ab Binary files /dev/null and b/Templates/BaseGame/game/tools/classIcons/volumeLight.png differ diff --git a/Templates/BaseGame/game/tools/componentEditor/gui/superToolTipDlg.ed.gui b/Templates/BaseGame/game/tools/componentEditor/gui/superToolTipDlg.ed.gui new file mode 100644 index 000000000..ef506941a --- /dev/null +++ b/Templates/BaseGame/game/tools/componentEditor/gui/superToolTipDlg.ed.gui @@ -0,0 +1,45 @@ +%guiContent = new GuiControl(SuperTooltipDlg) { + canSaveDynamicFields = "0"; + Profile = "GuiTransparentProfileModeless"; + class = "SuperTooltip"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "640 480"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiControl(SuperTooltipWindow) { + canSaveDynamicFields = "0"; + Profile = "EditorTextEditBoldModeless"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "216 160"; + Extent = "221 134"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + internalName = "tooltipWindow"; + + new GuiMLTextCtrl(SuperTooltipMLText) { + canSaveDynamicFields = "0"; + Profile = "EditorMLTextProfileModeless"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 5"; + Extent = "210 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + internalName = "tooltipMLText"; + }; + }; +}; + diff --git a/Templates/BaseGame/game/tools/componentEditor/main.cs b/Templates/BaseGame/game/tools/componentEditor/main.cs new file mode 100644 index 000000000..56d74830a --- /dev/null +++ b/Templates/BaseGame/game/tools/componentEditor/main.cs @@ -0,0 +1,28 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//Scripts +exec("./scripts/componentEditor.ed.cs"); +exec("./scripts/superToolTipDlg.ed.cs"); + +//gui +exec("./gui/superToolTipDlg.ed.gui"); diff --git a/Templates/BaseGame/game/tools/componentEditor/scripts/componentEditor.ed.cs b/Templates/BaseGame/game/tools/componentEditor/scripts/componentEditor.ed.cs new file mode 100644 index 000000000..9a9ce33d6 --- /dev/null +++ b/Templates/BaseGame/game/tools/componentEditor/scripts/componentEditor.ed.cs @@ -0,0 +1,233 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function GuiInspectorEntityGroup::CreateContent(%this) +{ +} + +function GuiInspectorEntityGroup::InspectObject( %this, %targetObject ) +{ + %this.stack.clear(); + %this.stack.addGuiControl(%this.createAddComponentList()); +} + +function GuiInspectorEntityGroup::createAddComponentList(%this) +{ + %extent = %this.getExtent(); + + %container = new GuiControl() + { + Profile = "EditorContainerProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = %extent.x SPC "25"; + }; + + %componentList = new GuiPopUpMenuCtrlEx(QuickEditComponentList) + { + Profile = "GuiPopupMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "28 4"; + Extent = (%extent.x - 28) SPC "18"; + hovertime = "100"; + tooltip = "The component to add to the object"; + tooltipProfile = "EditorToolTipProfile"; + }; + + %addButton = new GuiIconButtonCtrl() { + class = AddComponentQuickEditButton; + Profile = "EditorButton"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "2 0"; + Extent = "24 24"; + buttonMargin = "4 4"; + iconLocation = "Left"; + sizeIconToButton = "0"; + iconBitmap = "tools/gui/images/iconAdd.png"; + hovertime = "100"; + tooltip = "Add the selected component to the object"; + tooltipProfile = "EditorToolTipProfile"; + componentList = %componentList; + }; + + %componentList.refresh(); + + %container.add(%componentList); + %container.add(%addButton); + + if(!isObject("componentTooltipTheme")) + { + %theme = createsupertooltiptheme("componentTooltipTheme"); + %theme.addstyle("headerstyle", ""); + %theme.addstyle("headertwostyle", ""); + %theme.addstyle("basictextstyle", ""); + %theme.setdefaultstyle("title", "headerstyle"); + %theme.setdefaultstyle("paramtitle", "headertwostyle"); + %theme.setdefaultstyle("param", "basictextstyle"); + %theme.setspacing(3, 0); + } + + return %container; +} + +function QuickEditComponentList::refresh(%this) +{ + %this.clear(); + + //find all ComponentAssets + %assetQuery = new AssetQuery(); + if(!AssetDatabase.findAssetType(%assetQuery, "ComponentAsset")) + return; //if we didn't find ANY, just exit + + // Find all the types. + %count = %assetQuery.getCount(); + + %categories = ""; + for (%i = 0; %i < %count; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + %componentAsset = AssetDatabase.acquireAsset(%assetId); + %componentType = %componentAsset.componentType; + if (!isInList(%componentType, %categories)) + %categories = %categories TAB %componentType; + } + + %categories = trim(%categories); + + %index = 0; + %categoryCount = getFieldCount(%categories); + for (%i = 0; %i < %categoryCount; %i++) + { + %category = getField(%categories, %i); + %this.addCategory(%category); + + for (%j = 0; %j < %count; %j++) + { + %assetId = %assetQuery.getAsset(%j); + + %componentAsset = AssetDatabase.acquireAsset(%assetId); + %componentType = %componentAsset.componentType; + %friendlyName = %componentAsset.friendlyName; + + if (%componentType $= %category) + { + //TODO: Haven't worked out getting categories to look distinct + //from entries in the drop-down so for now just indent them for the visual distinction + %spacedName = " " @ %friendlyName; + %this.add(%spacedName, %index); + %this.component[%index] = %componentAsset; + %index++; + } + } + } +} + +function QuickEditComponentList::onHotTrackItem( %this, %itemID ) +{ + %componentObj = %this.component[%itemID]; + if( isObject( %componentObj ) && %this.componentDesc != %componentObj ) + { + SuperTooltipDlg.init("componentTooltipTheme"); + SuperTooltipDlg.setTitle(%componentObj.friendlyName); + SuperTooltipDlg.addParam("", %componentObj.description @ "\n"); + + %fieldCount = %componentObj.getComponentFieldCount(); + for (%i = 0; %i < %fieldCount; %i++) + { + %name = getField(%componentObj.getComponentField(%i), 0); + + SuperTooltipDlg.addParam(%name, %description @ "\n"); + } + %position = %this.getGlobalPosition(); + SuperTooltipDlg.processTooltip( %position,0,1 ); + %this.opened = true; + %this.componentDesc = %componentObj; + } + else if( !isObject( %componentObj ) ) + { + if( %this.opened == true ) + SuperTooltipDlg.hide(); + %this.componentDesc = ""; + } +} + +function QuickEditComponentList::setProperty(%this, %object) +{ + %this.objectToAdd = %object; +} + +function QuickEditComponentList::onSelect(%this) +{ + if( %this.opened == true ) + SuperTooltipDlg.hide(); + + %this.componentToAdd = %this.component[%this.getSelected()]; +} + +function QuickEditComponentList::onCancel( %this ) +{ + if( %this.opened == true ) + SuperTooltipDlg.hide(); +} + +function AddComponentQuickEditButton::onClick(%this) +{ + %component = %this.componentList.componentToAdd; + + %componentName = %this.componentList.componentToAdd.componentName; + %componentClass = %this.componentList.componentToAdd.componentClass; + + %command = "$ComponentEditor::newComponent = new" SPC %componentClass SPC "(){ class = \"" + @ %componentName @ "\"; };"; + + eval(%command); + + %instance = $ComponentEditor::newComponent; + %undo = new UndoScriptAction() + { + actionName = "Added Component"; + class = UndoAddComponent; + object = %this.componentList.objectToAdd; + component = %instance; + }; + + %undo.addToManager(LevelBuilderUndoManager); + + %instance.owner = Inspector.getInspectObject(0); + %instance.owner.add(%instance); + + Inspector.schedule( 50, "refresh" ); + EWorldEditor.isDirty = true; +} + +function addComponent(%obj, %instance) +{ + echo("Adding the component!"); + %obj.addComponent(%instance); + Inspector.schedule( 50, "refresh" ); + EWorldEditor.isDirty = true; +} + diff --git a/Templates/BaseGame/game/tools/componentEditor/scripts/superToolTipDlg.ed.cs b/Templates/BaseGame/game/tools/componentEditor/scripts/superToolTipDlg.ed.cs new file mode 100644 index 000000000..7f25bd5e6 --- /dev/null +++ b/Templates/BaseGame/game/tools/componentEditor/scripts/superToolTipDlg.ed.cs @@ -0,0 +1,155 @@ +function createSuperTooltipTheme(%name) +{ + %theme = new ScriptObject() + { + class = SuperTooltipTheme; + }; + + %theme.setName(%name); + + return %theme; +} + +function SuperTooltipTheme::addStyle(%this, %name, %style) +{ + %this.styles[%name] = %style; +} + +function SuperTooltipTheme::setDefaultStyle(%this, %type, %default) +{ + %this.defaultStyles[%type] = %default; +} + +function SuperTooltipTheme::setSpacing(%this, %verticalSpace, %horizontalSpace) +{ + %this.verticalSpace = %verticalSpace; + %this.horizontalSpace = %horizontalSpace; +} + +function SuperTooltipTheme::getStyle(%this, %name) +{ + return %this.styles[%name]; +} + +function SuperTooltip::init(%this, %theme) +{ + %this.clearTooltip(); + + if(isObject(%theme)) + %this.setTheme(%theme); +} + +function SuperTooltip::clearTooltip(%this) +{ + if(%this.paramCount > 0) + { + for(%i=0;%i<%this.paramCount;%i++) + %this.param[%i] = ""; + } + + %this.title = ""; + %this.paramCount = 0; +} + +function SuperTooltip::processTooltip(%this, %globalPos, %verticalAlign, %horizontalAlign) +{ + if (%verticalAlign $= "") + %verticalAlign = 1; + if (%horizontalAlign $= "") + %horizontalAlign = 0; + + %tooltipWindow = %this.findObjectByInternalName("tooltipWindow"); + + if(isObject(%tooltipWindow)) + %tooltipMLText = %tooltipWindow.findObjectByInternalName("tooltipMLText"); + else + return false; + + if(!isObject(%tooltipMLText)) + return false; + + %verticalSpace = %this.theme.verticalSpace; + %horizontalSpace = %this.theme.horizontalSpace; + + if (%verticalAlign == 1) + %verticalSpace = -%verticalSpace; + if (%horizontalAlign == 1) + %horizontalSpace = -%horizontalSpace; + + %text = %this.getFormatedText(); + %tooltipMLText.setText(%text); + + canvas.pushDialog(%this); + + %tooltipMLText.forceReflow(); + %MLExtent = %tooltipMLText.extent; + %MLHeight = getWord(%MLExtent, 1); + + %tooltipExtent = %tooltipWindow.extent; + %tooltipWidth = getWord(%tooltipExtent, 0); + %tooltipHeight = %MLHeight; + %tooltipWindow.extent = %tooltipWidth SPC %tooltipHeight; + + %globalPosX = getWord(%globalPos, 0); + %globalPosY = getWord(%globalPos, 1); + + %tooltipPosX = %globalPosX - (%horizontalAlign * %tooltipWidth) + %horizontalSpace; + %tooltipPosY = %globalPosY - (%verticalAlign * %tooltipHeight) + %verticalSpace; + + %tooltipWindow.setPosition(%tooltipPosX, %tooltipPosY); + + return true; +} + +function SuperTooltip::hide(%this) +{ + canvas.popDialog(%this); + + %this.clearTooltip(); +} + +function SuperTooltip::setTheme(%this, %theme) +{ + %this.theme = %theme; +} + +function SuperTooltip::setTitle(%this, %title, %style) +{ + if(%style !$= "") + %themeStyle = %this.theme.styles[%style]; + else + %themeStyle = %this.theme.getStyle(%this.theme.defaultStyles[Title]); + + %this.title = %themeStyle @ %title; +} + +function SuperTooltip::addParam(%this, %title, %text, %paramTitleStyle, %paramStyle) +{ + if(%paramTitleStyle !$= "") + %themeTitleStyle = %this.theme.styles[%paramTitleStyle]; + else + %themeTitleStyle = %this.theme.getStyle(%this.theme.defaultStyles[ParamTitle]); + + if(%paramStyle !$= "") + %themeStyle = %this.theme.styles[%paramStyle]; + else + %themeStyle = %this.theme.getStyle(%this.theme.defaultStyles[Param]); + + if (%title $= "") + %this.param[%this.paramCount] = %themeStyle @ %text @ "\n"; + else + %this.param[%this.paramCount] = %themeTitleStyle @ %title @ ": " @ %themeStyle @ %text @ "\n"; + %this.paramCount++; +} + +function SuperTooltip::getFormatedText(%this) +{ + %text = %this.title @ "\n\n"; + + for(%i=0;%i<%this.paramCount;%i++) + { + %text = %text @ %this.param[%i]; + } + + return %text; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/convexEditor/convexEditor.cs b/Templates/BaseGame/game/tools/convexEditor/convexEditor.cs new file mode 100644 index 000000000..859667bc1 --- /dev/null +++ b/Templates/BaseGame/game/tools/convexEditor/convexEditor.cs @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( ConvexEditorProfile ) +{ + canKeyFocus = true; + opaque = true; + fillColor = "192 192 192 192"; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiDisabledTextEditProfile) +{ + opaque = false; + border = 0; + bitmap = "./textEdit"; + borderColor = "255 255 255 200"; + fontColor = "0 0 0"; + fontColorHL = "255 255 255"; + fontColorNA = "128 128 128"; + textOffset = "4 2"; + autoSizeWidth = false; + autoSizeHeight = false; + tab = false; + canKeyFocus = false; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiSimpleBorderProfile) +{ + opaque = false; + border = 1; + category = "Editor"; +}; diff --git a/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.cs b/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.cs new file mode 100644 index 000000000..1cda5416c --- /dev/null +++ b/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.cs @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function ConvexEditorGui::onWake( %this ) +{ +} + +function ConvexEditorGui::onSleep( %this ) +{ +} + +function ConvexEditorGui::createConvexBox( %this ) +{ + %obj = genericCreateObject( "ConvexShape" ); + %this.handleDeselect(); + %this.selectConvex( %obj ); + %this.dropSelectionAtScreenCenter(); +} + +function ConvexEditorGui::onSelectionChanged( %this, %shape, %face ) +{ + //echo( "onSelectionChanged: " @ %shape SPC %face ); + + ConvexEditorSplitFaceBtn.setActive( false ); + ConvexEditorSplitFaceBtn.ToolTip = "Split selected face [Disabled]" NL "Use Ctrl + Rotate instead for more control"; + ConvexEditorDeleteFaceBtn.setActive( false ); + ConvexEditorDeleteFaceBtn.ToolTip = "Delete selection [Disabled] (Delete)"; + + if ( !isObject( %shape ) ) + return; + + ConvexEditorDeleteFaceBtn.setActive( true ); + + if ( %face == -1 ) + ConvexEditorDeleteFaceBtn.ToolTip = "Delete selected ConvexShape (Delete)"; + else + { + ConvexEditorDeleteFaceBtn.ToolTip = "Delete selected Face (Delete)"; + + ConvexEditorSplitFaceBtn.ToolTip = "Split selected face" NL "Use Ctrl + Rotate instead for more control"; + ConvexEditorSplitFaceBtn.setActive( true ); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.gui b/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.gui new file mode 100644 index 000000000..1849a91c5 --- /dev/null +++ b/Templates/BaseGame/game/tools/convexEditor/convexEditorGui.gui @@ -0,0 +1,440 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiConvexEditorCtrl(ConvexEditorGui) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ConvexEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + DefaultWidth = "10"; + HoverSplineColor = "0 255 0 255"; + SelectedSplineColor = "255 0 255 255"; + HoverNodeColor = "255 255 255 255"; + + new GuiWindowCollapseCtrl(ConvexEditorTreeWindow) { + internalName = ""; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 167"; + MinExtent = "210 100"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EditorGui.setEditor( WorldEditorInspectorPlugin );"; + EdgeSnap = "1"; + text = "ConvexShapes"; + + new GuiContainer(){ + profile = "ToolsGuiDefaultProfile"; + Position = "5 25"; + Extent = "200 120"; + Docking = "Client"; + Margin = "3 1 3 3 "; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "200 118"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl(ConvexTreeView) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "193 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "1"; + internalNamesOnly = "0"; + }; + }; + }; + }; + new GuiWindowCollapseCtrl(ConvexEditorOptionsWindow) { + internalName = "Window"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(ConvexEditorTreeWindow.extent, 1) - 2; + Extent = "210 530"; + MinExtent = "210 298"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EditorGui.setEditor( WorldEditorPlugin );"; + EdgeSnap = "1"; + text = "Properties"; + + new GuiContainer(){ //Node Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 24"; + Extent = "202 85"; + Docking = "Top"; + Margin = "3 3 3 3"; + + new GuiTextCtrl(){ + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "86 18"; + text = "Node Properties"; + }; + + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 21"; + Extent = "46 18"; + text = "Position"; + }; + new GuiTextEditCtrl(){ + internalName = "position"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 21"; + Extent = "141 18"; + text = ""; + AltCommand = "ConvexEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 42"; + Extent = "46 18"; + text = "Rotation"; + }; + new GuiTextEditCtrl(){ + internalName = "rotation"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 42"; + Extent = "141 18"; + text = ""; + AltCommand = "ConvexEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 63"; + Extent = "46 18"; + text = "Width"; + }; + new GuiTextEditCtrl(){ + internalName = "width"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "57 63"; + Extent = "52 18"; + text = ""; + AltCommand = "ConvexEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "110 63"; + Extent = "32 18"; + text = "Depth"; + }; + new GuiTextEditCtrl(){ + internalName = "depth"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "146 63"; + Extent = "52 18"; + text = ""; + AltCommand = "ConvexEditorGui.editNodeDetails();"; + }; + }; + new GuiContainer(){ //Conve Road Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 112"; + Extent = "202 31"; + Docking = "Top"; + Margin = "0 0 3 3"; + + new GuiTextCtrl(){ + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "121 18"; + text = "ConvexShape Properties"; + }; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 129"; + Extent = "202 357"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "-14 41 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(ConvexInspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + name = "ConvexInspector"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "179 16"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + }; + }; + new GuiMLTextCtrl(ConvexFieldInfoControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "1 485"; + Extent = "202 42"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; + new GuiWindowCollapseCtrl(ConvexEditorTipsWindow) { + CollapseGroup = "-1"; + CollapseGroupNum = "-1"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Tips"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowCollapseProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + position = "6 483"; + Extent = "136 246"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Docking = "Client"; + Margin = "3 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 24"; + Extent = "128 218"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextListCtrl() { + columns = "0"; + fitParentWidth = "1"; + clipColumnText = "0"; + isContainer = "1"; + Profile = "ToolsGuiTextListProfile"; + HorizSizing = "width"; + VertSizing = "top"; + position = "1 1"; + Extent = "126 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "TextList"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/convexEditor/convexEditorSettingsTab.ed.gui b/Templates/BaseGame/game/tools/convexEditor/convexEditorSettingsTab.ed.gui new file mode 100644 index 000000000..3cd3a1ebd --- /dev/null +++ b/Templates/BaseGame/game/tools/convexEditor/convexEditorSettingsTab.ed.gui @@ -0,0 +1,180 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ConvexEditorSettingsTab,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(EConvexEditorSettingsPage) { + fitBook = "1"; + text = "Convex Editor"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Defaults"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Material:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "ConvexEditorPlugin.readSettings();"; + editorSettingsValue = "ConvexEditor/MaterialName"; + editorSettingsWrite = "ConvexEditorPlugin.writeSettings();"; + }; + }; + }; + }; + }; + }; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/convexEditor/convexEditorToolbar.ed.gui b/Templates/BaseGame/game/tools/convexEditor/convexEditorToolbar.ed.gui new file mode 100644 index 000000000..575907d81 --- /dev/null +++ b/Templates/BaseGame/game/tools/convexEditor/convexEditorToolbar.ed.gui @@ -0,0 +1,121 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(convexEditorToolbar, EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = ""; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "305 0"; + Extent = "550" SPC getWord(EditorGuiToolbar.extent, 1); + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + canMove = "0"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + EdgeSnap = "0"; + text =""; + + new GuiContainer() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "menubarProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 32"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "15 7"; + extent = "86 16"; + minExtent = "8 8"; + visible = "1"; + text = "Sketch Tool"; + maxLength = "255"; + helpTag = "0"; + }; + new GuiBitmapCtrl() { + Profile = "ToolsGuiDefaultProfile"; + position = "94 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + new GuiBitmapButtonCtrl(ConvexEditorCreateBoxBtn) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "100 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ConvexEditorGui.createConvexBox();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Create ConvexShape Box" NL "Use Alt + Click-Drag instead of this for more control of starting placement."; + hovertime = "1000"; + bitmap = "tools/convexEditor/images/convex-editor-btn"; + text = ""; + groupNum = "-1"; + buttonType = "pushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ConvexEditorSplitFaceBtn) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "134 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ConvexEditorGui.splitSelectedFace();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Split selected face" NL "Use Ctrl + Rotate instead for more control."; + hovertime = "1000"; + bitmap = "tools/convexEditor/images/split-face-btn"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ConvexEditorDeleteFaceBtn) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "166 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ConvexEditorGui.handleDelete();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Delete selected face" NL "(Delete)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/delete-btn"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; +}; diff --git a/Templates/BaseGame/game/tools/convexEditor/images/512_orange.png b/Templates/BaseGame/game/tools/convexEditor/images/512_orange.png new file mode 100644 index 000000000..43c4953e8 Binary files /dev/null and b/Templates/BaseGame/game/tools/convexEditor/images/512_orange.png differ diff --git a/Templates/BaseGame/game/tools/convexEditor/images/convex-editor-btn_d.png b/Templates/BaseGame/game/tools/convexEditor/images/convex-editor-btn_d.png new file mode 100644 index 000000000..2ea137fca Binary files /dev/null and b/Templates/BaseGame/game/tools/convexEditor/images/convex-editor-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/convexEditor/images/convex-editor-btn_h.png b/Templates/BaseGame/game/tools/convexEditor/images/convex-editor-btn_h.png new file mode 100644 index 000000000..956fae3d8 Binary files /dev/null and b/Templates/BaseGame/game/tools/convexEditor/images/convex-editor-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/convexEditor/images/convex-editor-btn_n.png b/Templates/BaseGame/game/tools/convexEditor/images/convex-editor-btn_n.png new file mode 100644 index 000000000..cdb2a4b6d Binary files /dev/null and b/Templates/BaseGame/game/tools/convexEditor/images/convex-editor-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/convexEditor/images/materials.cs b/Templates/BaseGame/game/tools/convexEditor/images/materials.cs new file mode 100644 index 000000000..945a824f6 --- /dev/null +++ b/Templates/BaseGame/game/tools/convexEditor/images/materials.cs @@ -0,0 +1,5 @@ +singleton Material(DefaultConvexShapeMat) +{ + mapTo = "unmapped_mat"; + diffuseMap[0] = "./512_orange.png"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/convexEditor/images/split-face-btn_d.png b/Templates/BaseGame/game/tools/convexEditor/images/split-face-btn_d.png new file mode 100644 index 000000000..8d0ff5114 Binary files /dev/null and b/Templates/BaseGame/game/tools/convexEditor/images/split-face-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/convexEditor/images/split-face-btn_h.png b/Templates/BaseGame/game/tools/convexEditor/images/split-face-btn_h.png new file mode 100644 index 000000000..c2d84b49d Binary files /dev/null and b/Templates/BaseGame/game/tools/convexEditor/images/split-face-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/convexEditor/images/split-face-btn_i.png b/Templates/BaseGame/game/tools/convexEditor/images/split-face-btn_i.png new file mode 100644 index 000000000..c8719cc7d Binary files /dev/null and b/Templates/BaseGame/game/tools/convexEditor/images/split-face-btn_i.png differ diff --git a/Templates/BaseGame/game/tools/convexEditor/images/split-face-btn_n.png b/Templates/BaseGame/game/tools/convexEditor/images/split-face-btn_n.png new file mode 100644 index 000000000..100952571 Binary files /dev/null and b/Templates/BaseGame/game/tools/convexEditor/images/split-face-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/convexEditor/main.cs b/Templates/BaseGame/game/tools/convexEditor/main.cs new file mode 100644 index 000000000..bdc06687c --- /dev/null +++ b/Templates/BaseGame/game/tools/convexEditor/main.cs @@ -0,0 +1,220 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function initializeConvexEditor() +{ + echo(" % - Initializing Sketch Tool"); + + exec( "./convexEditor.cs" ); + exec( "./convexEditorGui.gui" ); + exec( "./convexEditorToolbar.ed.gui" ); + exec( "./convexEditorGui.cs" ); + + ConvexEditorGui.setVisible( false ); + ConvexEditorOptionsWindow.setVisible( false ); + ConvexEditorTreeWindow.setVisible( false ); + ConvexEditorToolbar.setVisible( false ); + + EditorGui.add( ConvexEditorGui ); + EditorGui.add( ConvexEditorOptionsWindow ); + EditorGui.add( ConvexEditorTreeWindow ); + EditorGui.add( ConvexEditorToolbar ); + + new ScriptObject( ConvexEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = ConvexEditorGui; + }; + + // Note that we use the WorldEditor's Toolbar. + + %map = new ActionMap(); + %map.bindCmd( keyboard, "1", "ConvexEditorNoneModeBtn.performClick();", "" ); // Select + %map.bindCmd( keyboard, "2", "ConvexEditorMoveModeBtn.performClick();", "" ); // Move + %map.bindCmd( keyboard, "3", "ConvexEditorRotateModeBtn.performClick();", "" );// Rotate + %map.bindCmd( keyboard, "4", "ConvexEditorScaleModeBtn.performClick();", "" ); // Scale + ConvexEditorPlugin.map = %map; + + ConvexEditorPlugin.initSettings(); +} + +function ConvexEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Sketch Tool", "", ConvexEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Sketch Tool (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "ConvexEditorPlugin", "ConvexEditorPalette", expandFilename("tools/convexEditor/images/convex-editor-btn"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( ConvexEditorOptionsWindow, ConvexEditorTreeWindow); + + // Allocate our special menu. + // It will be added/removed when this editor is activated/deactivated. + + if ( !isObject( ConvexActionsMenu ) ) + { + singleton PopupMenu( ConvexActionsMenu ) + { + superClass = "MenuBuilder"; + + barTitle = "Sketch"; + + Item[0] = "Hollow Selected Shape" TAB "" TAB "ConvexEditorGui.hollowSelection();"; + item[1] = "Recenter Selected Shape" TAB "" TAB "ConvexEditorGui.recenterSelection();"; + }; + } + + %this.popupMenu = ConvexActionsMenu; + + exec( "./convexEditorSettingsTab.ed.gui" ); + ESettingsWindow.addTabPage( EConvexEditorSettingsPage ); +} + +function ConvexEditorPlugin::onActivated( %this ) +{ + %this.readSettings(); + + EditorGui.bringToFront( ConvexEditorGui ); + ConvexEditorGui.setVisible( true ); + ConvexEditorToolbar.setVisible( true ); + ConvexEditorGui.makeFirstResponder( true ); + %this.map.push(); + + // Set the status bar here until all tool have been hooked up + EditorGuiStatusBar.setInfo( "Sketch Tool." ); + EditorGuiStatusBar.setSelection( "" ); + + // Add our menu. + EditorGui.menuBar.insert( ConvexActionsMenu, EditorGui.menuBar.dynamicItemInsertPos ); + + // Sync the pallete button state with the gizmo mode. + %mode = GlobalGizmoProfile.mode; + switch$ (%mode) + { + case "None": + ConvexEditorNoneModeBtn.performClick(); + case "Move": + ConvexEditorMoveModeBtn.performClick(); + case "Rotate": + ConvexEditorRotateModeBtn.performClick(); + case "Scale": + ConvexEditorScaleModeBtn.performClick(); + } + + Parent::onActivated( %this ); +} + +function ConvexEditorPlugin::onDeactivated( %this ) +{ + %this.writeSettings(); + + ConvexEditorGui.setVisible( false ); + ConvexEditorOptionsWindow.setVisible( false ); + ConvexEditorTreeWindow.setVisible( false ); + ConvexEditorToolbar.setVisible( false ); + %this.map.pop(); + + // Remove our menu. + EditorGui.menuBar.remove( ConvexActionsMenu ); + + Parent::onDeactivated( %this ); +} + +function ConvexEditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %hasSelection = false; + + if ( ConvexEditorGui.hasSelection() ) + %hasSelection = true; + + %editMenu.enableItem( 3, false ); // Cut + %editMenu.enableItem( 4, false ); // Copy + %editMenu.enableItem( 5, false ); // Paste + %editMenu.enableItem( 6, %hasSelection ); // Delete + %editMenu.enableItem( 8, %hasSelection ); // Deselect +} + +function ConvexEditorPlugin::handleDelete( %this ) +{ + ConvexEditorGui.handleDelete(); +} + +function ConvexEditorPlugin::handleDeselect( %this ) +{ + ConvexEditorGui.handleDeselect(); +} + +function ConvexEditorPlugin::handleCut( %this ) +{ + //WorldEditorInspectorPlugin.handleCut(); +} + +function ConvexEditorPlugin::handleCopy( %this ) +{ + //WorldEditorInspectorPlugin.handleCopy(); +} + +function ConvexEditorPlugin::handlePaste( %this ) +{ + //WorldEditorInspectorPlugin.handlePaste(); +} + +function ConvexEditorPlugin::isDirty( %this ) +{ + return ConvexEditorGui.isDirty; +} + +function ConvexEditorPlugin::onSaveMission( %this, %missionFile ) +{ + if( ConvexEditorGui.isDirty ) + { + MissionGroup.save( %missionFile ); + ConvexEditorGui.isDirty = false; + } +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +function ConvexEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup( "ConvexEditor", true ); + EditorSettings.setDefaultValue( "MaterialName", "DefaultConvexShapeMat" ); + EditorSettings.endGroup(); +} + +function ConvexEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup( "ConvexEditor", true ); + ConvexEditorGui.materialName = EditorSettings.value("MaterialName"); + EditorSettings.endGroup(); +} + +function ConvexEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "ConvexEditor", true ); + EditorSettings.setValue( "MaterialName", ConvexEditorGui.materialName ); + EditorSettings.endGroup(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/datablockEditor/DatablockEditorCreatePrompt.ed.gui b/Templates/BaseGame/game/tools/datablockEditor/DatablockEditorCreatePrompt.ed.gui new file mode 100644 index 000000000..d55bcc45c --- /dev/null +++ b/Templates/BaseGame/game/tools/datablockEditor/DatablockEditorCreatePrompt.ed.gui @@ -0,0 +1,224 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(DatablockEditorCreatePrompt,EditorGuiGroup) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl() { + text = "Create New Datablock"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "0"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "canvas.popDialog(DatablockEditorCreatePrompt);"; + edgeSnap = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "389 252"; + extent = "207 167"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Your new datablock must have a name"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "7 26"; + extent = "190 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "Name"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "7 45"; + extent = "191 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "CreateDatablockName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Create"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "7 137"; + extent = "122 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "DatablockEditorPlugin.createPromptNameCheck();"; + accelerator = "return"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "135 137"; + extent = "63 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "canvas.popDialog(DatablockEditorCreatePrompt);"; + accelerator = "escape"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Copy values from"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "7 66"; + extent = "100 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "7 87"; + extent = "191 19"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "CopySourceDropdown"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Client-Side Datablock"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "7 105"; + extent = "140 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "ClientSideCheckBox"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/datablockEditor/DatablockEditorInspectorWindow.ed.gui b/Templates/BaseGame/game/tools/datablockEditor/DatablockEditorInspectorWindow.ed.gui new file mode 100644 index 000000000..b8dce9bd2 --- /dev/null +++ b/Templates/BaseGame/game/tools/datablockEditor/DatablockEditorInspectorWindow.ed.gui @@ -0,0 +1,211 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiWindowCollapseCtrl(DatablockEditorInspectorWindow) { + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "DatablockEditorInspectorWindow.setVisible(false);"; + EdgeSnap = "1"; + text = "Datablock"; + Margin = "8 8 8 8"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(DatablockEditorTreeWindow.extent, 1) - 2; + Extent = "210 373"; + MinExtent = "210 140"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "DatablockEditorInspectorWindow"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + Docking = "Client"; + Margin = "22 41 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "4 41"; + Extent = "202 287"; + MinExtent = "64 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 287"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiInspector(DatablockEditorInspector) { + dividerMargin = "5"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + ChangeChildSizeToFit = "1"; + ChangeChildPosition = "1"; + isContainer = "1"; + Profile = "GuiInspectorProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "190 8"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + superClass = "EditorInspectorBase"; + }; + }; + }; + new GuiMLTextCtrl(DatablockFieldInfoControl) { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + position = "1 328"; + Extent = "205 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "4 23"; + Extent = "159 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "DatablockFile"; + canSaveDynamicFields = "0"; + active = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/save-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "167 23"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DatablockEditorPlugin.save();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Save Datablock (ALT S)"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/save-as"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "187 23"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DatablockEditorPlugin.showSaveNewFileDialog();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Save Datablock to a New File"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + internalName = "saveAsButton"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/datablockEditor/DatablockEditorTreeWindow.ed.gui b/Templates/BaseGame/game/tools/datablockEditor/DatablockEditorTreeWindow.ed.gui new file mode 100644 index 000000000..49a819840 --- /dev/null +++ b/Templates/BaseGame/game/tools/datablockEditor/DatablockEditorTreeWindow.ed.gui @@ -0,0 +1,311 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiWindowCollapseCtrl(DatablockEditorTreeWindow) { + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "DatablockInspectorTreeWindow.setVisible(false);"; + EdgeSnap = "1"; + text = "Datablock Library"; + Margin = "8 8 8 8"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 324"; + MinExtent = "210 140"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "DatablockEditorTreeWindow"; + canSaveDynamicFields = "0"; + + new GuiTabBookCtrl(DatablockEditorTreeTabBook) { + TabPosition = "Top"; + TabMargin = "0"; + MinTabWidth = "64"; + Docking = "Client"; + Margin = "3 2 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "4 25"; + Extent = "202 294"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "DatablockEditorTree"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl() { + text = "Existing"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiEditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "202 276"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextEditCtrl( DatablockEditorTreeFilter ) { + position = "2 4"; + extent = "180 18"; + profile = "GuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + class = "GuiTreeViewFilterText"; + treeView = DatablockEditorTree; + }; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "185 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + class = "GuiTreeViewFilterClearButton"; + textCtrl = DatablockEditorTreeFilter; + }; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 25"; + Extent = "202 251"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(DatablockEditorTree) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "0"; + MouseDragging = "0"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + ClearAllOnSingleSelection = "1"; + showRoot = "1"; + internalNamesOnly = "0"; + objectNamesOnly = "0"; + compareToObjectID = "0"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "198 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiTabPageCtrl(DatablockEditorCreator) { + text = "New"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiEditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "202 276"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "DatablockEditorCreator"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 276"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(DatablockEditorTypeTree) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "0"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "0"; + DragToItemAllowed = "0"; + ClearAllOnSingleSelection = "1"; + showRoot = "1"; + internalNamesOnly = "0"; + objectNamesOnly = "0"; + compareToObjectID = "1"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "196 260"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + altCommand = "DatablockEditorPlugin.createDatablock();"; + }; + }; + }; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "190 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DatablockEditorPlugin.deleteDatablock();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Delete Datablock"; + hovertime = "1000"; + internalName = "deleteSelection"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/new"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "192 25"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + Command = "DatablockEditorPlugin.createDatablock();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Create New Datablock"; + hovertime = "1000"; + internalName = "CreateSelection"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/datablockEditor/datablockEditor.cs b/Templates/BaseGame/game/tools/datablockEditor/datablockEditor.cs new file mode 100644 index 000000000..8eb47e085 --- /dev/null +++ b/Templates/BaseGame/game/tools/datablockEditor/datablockEditor.cs @@ -0,0 +1,885 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Main code for the Datablock Editor plugin. + + +$DATABLOCK_EDITOR_DEFAULT_FILENAME = "art/datablocks/managedDatablocks.cs"; + +//============================================================================================= +// Initialization. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::init( %this ) +{ + if( !DatablockEditorTree.getItemCount() ) + %this.populateTrees(); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Datablock Editor", "", DatablockEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Datablock Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "DatablockEditorPlugin", "DatablockEditorPalette", expandFilename("tools/worldEditor/images/toolbar/datablock-editor"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::Attach( DatablockEditorInspectorWindow, DatablockEditorTreeWindow); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::onActivated( %this ) +{ + EditorGui-->WorldEditorToolbar.setVisible(false); + EditorGui.bringToFront( DatablockEditorPlugin ); + + DatablockEditorTreeWindow.setVisible( true ); + DatablockEditorInspectorWindow.setVisible( true ); + DatablockEditorInspectorWindow.makeFirstResponder( true ); + + %this.map.push(); + + // Set the status bar here until all tool have been hooked up + EditorGuiStatusBar.setInfo( "Datablock editor." ); + + %numSelected = %this.getNumSelectedDatablocks(); + if( !%numSelected ) + EditorGuiStatusBar.setSelection( "" ); + else + EditorGuiStatusBar.setSelection( %numSelected @ " datablocks selected" ); + + %this.init(); + DatablockEditorPlugin.readSettings(); + + if( EWorldEditor.getSelectionSize() == 1 ) + %this.onObjectSelected( EWorldEditor.getSelectedObject( 0 ) ); + + Parent::onActivated( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::onDeactivated( %this ) +{ + DatablockEditorPlugin.writeSettings(); + + DatablockEditorInspectorWindow.setVisible( false ); + DatablockEditorTreeWindow.setVisible( false ); + %this.map.pop(); + + Parent::onDeactivated(%this); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::onExitMission( %this ) +{ + DatablockEditorTree.clear(); + DatablockEditorInspector.inspect( "" ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::openDatablock( %this, %datablock ) +{ + EditorGui.setEditor( DatablockEditorPlugin ); + %this.selectDatablock( %datablock ); + DatablockEditorTreeTabBook.selectedPage = 0; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::setEditorFunction( %this ) +{ + return true; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::onObjectSelected( %this, %object ) +{ + // Select datablock of object if this is a GameBase object. + + if( %object.isMemberOfClass( "GameBase" ) ) + %this.selectDatablock( %object.getDatablock() ); + else if( %object.isMemberOfClass( "SFXEmitter" ) && isObject( %object.track ) ) + %this.selectDatablock( %object.track ); + else if( %object.isMemberOfClass( "LightBase" ) && isObject( %object.animationType ) ) + %this.selectDatablock( %object.animationType ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::populateTrees(%this) +{ + // Populate datablock tree. + + if( %this.excludeClientOnlyDatablocks ) + %set = DataBlockGroup; + else + %set = DataBlockSet; + + DatablockEditorTree.clear(); + + foreach( %datablock in %set ) + { + %unlistedFound = false; + %id = %datablock.getId(); + + foreach( %obj in UnlistedDatablocks ) + if( %obj.getId() == %id ) + { + %unlistedFound = true; + break; + } + + if( %unlistedFound ) + continue; + + %this.addExistingItem( %datablock, true ); + } + + DatablockEditorTree.sort( 0, true, false, false ); + + // Populate datablock type tree. + + %classList = enumerateConsoleClasses( "SimDatablock" ); + DatablockEditorTypeTree.clear(); + + foreach$( %datablockClass in %classList ) + { + if( !%this.isExcludedDatablockType( %datablockClass ) + && DatablockEditorTypeTree.findItemByName( %datablockClass ) == 0 ) + DatablockEditorTypeTree.insertItem( 0, %datablockClass ); + } + + DatablockEditorTypeTree.sort( 0, false, false, false ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::addExistingItem( %this, %datablock, %dontSort ) +{ + %tree = DatablockEditorTree; + + // Look up class at root level. Create if needed. + + %class = %datablock.getClassName(); + %parentID = %tree.findItemByName( %class ); + if( %parentID == 0 ) + %parentID = %tree.insertItem( 0, %class ); + + // If the datablock is already there, don't + // do anything. + + if( %tree.findItemByValue( %datablock.getId() ) ) + return; + + // It doesn't exist so add it. + + %name = %datablock.getName(); + if( %this.PM.isDirty( %datablock ) ) + %name = %name @ " *"; + + %id = DatablockEditorTree.insertItem( %parentID, %name, %datablock.getId() ); + if( !%dontSort ) + DatablockEditorTree.sort( %parentID, false, false, false ); + + return %id; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::isExcludedDatablockType( %this, %className ) +{ + switch$( %className ) + { + case "SimDatablock": + return true; + case "SFXTrack": // Abstract. + return true; + case "SFXFMODEvent": // Internally created. + return true; + case "SFXFMODEventGroup": // Internally created. + return true; + } + return false; +} + +//============================================================================================= +// Settings. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup("DatablockEditor", true); + + EditorSettings.setDefaultValue("libraryTab", "0"); + + EditorSettings.endGroup(); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup("DatablockEditor", true); + + DatablockEditorTreeTabBook.selectPage( EditorSettings.value( "libraryTab" ) ); + %db = EditorSettings.value( "selectedDatablock" ); + if( isObject( %db ) && %db.isMemberOfClass( "SimDatablock" ) ) + %this.selectDatablock( %db ); + + EditorSettings.endGroup(); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "DatablockEditor", true ); + + EditorSettings.setValue( "libraryTab", DatablockEditorTreeTabBook.getSelectedPage() ); + if( %this.getNumSelectedDatablocks() > 0 ) + EditorSettings.setValue( "selectedDatablock", %this.getSelectedDatablock().getName() ); + + EditorSettings.endGroup(); +} + +//============================================================================================= +// Persistence. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +/// Return true if there is any datablock with unsaved changes. +function DatablockEditorPlugin::isDirty( %this ) +{ + return %this.PM.hasDirty(); +} + +//--------------------------------------------------------------------------------------------- + +/// Return true if any of the currently selected datablocks has unsaved changes. +function DatablockEditorPlugin::selectedDatablockIsDirty( %this ) +{ + %tree = DatablockEditorTree; + + %count = %tree.getSelectedItemsCount(); + %selected = %tree.getSelectedItemList(); + + foreach$( %id in %selected ) + { + %db = %tree.getItemValue( %id ); + if( %this.PM.isDirty( %db ) ) + return true; + } + + return false; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::syncDirtyState( %this ) +{ + %tree = DatablockEditorTree; + + %count = %tree.getSelectedItemsCount(); + %selected = %tree.getSelectedItemList(); + %haveDirty = false; + + foreach$( %id in %selected ) + { + %db = %tree.getItemValue( %id ); + if( %this.PM.isDirty( %db ) ) + { + %this.flagDatablockAsDirty( %db, true ); + %haveDirty = true; + } + else + %this.flagInspectorAsDirty( %db, false ); + } + + %this.flagInspectorAsDirty( %haveDirty ); +} + +//--------------------------------------------------------------------------------------------- + +/// +function DatablockEditorPlugin::flagInspectorAsDirty( %this, %dirty ) +{ + if( %dirty ) + DatablockEditorInspectorWindow.text = "Datablock *"; + else + DatablockEditorInspectorWindow.text = "Datablock"; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::flagDatablockAsDirty(%this, %datablock, %dirty ) +{ + %tree = DatablockEditorTree; + + %id = %tree.findItemByValue( %datablock.getId() ); + if( %id == 0 ) + return; + + // Tag the item caption and sync the persistence manager. + + if( %dirty ) + { + DatablockEditorTree.editItem( %id, %datablock.getName() @ " *", %datablock.getId() ); + %this.PM.setDirty( %datablock ); + } + else + { + DatablockEditorTree.editItem( %id, %datablock.getName(), %datablock.getId() ); + %this.PM.removeDirty( %datablock ); + } + + // Sync the inspector dirty state. + + %this.flagInspectorAsDirty( %this.PM.hasDirty() ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::showSaveNewFileDialog(%this) +{ + %currentFile = %this.getSelectedDatablock().getFilename(); + getSaveFilename( "TorqueScript Files|*.cs|All Files|*.*", %this @ ".saveNewFileFinish", %currentFile, false ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::saveNewFileFinish( %this, %newFileName ) +{ + // Clear the first responder to capture any inspector changes + %ctrl = canvas.getFirstResponder(); + if( isObject(%ctrl) ) + %ctrl.clearFirstResponder(); + + %tree = DatablockEditorTree; + %count = %tree.getSelectedItemsCount(); + %selected = %tree.getSelectedItemList(); + + foreach$( %id in %selected ) + { + %db = %tree.getItemValue( %id ); + %db = %this.getSelectedDatablock(); + + // Remove from current file. + + %oldFileName = %db.getFileName(); + if( %oldFileName !$= "" ) + %this.PM.removeObjectFromFile( %db, %oldFileName ); + + // Save to new file. + + %this.PM.setDirty( %db, %newFileName ); + if( %this.PM.saveDirtyObject( %db ) ) + { + // Clear dirty state. + + %this.flagDatablockAsDirty( %db, false ); + } + } + + DatablockEditorInspectorWindow-->DatablockFile.setText( %newFileName ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::save( %this ) +{ + // Clear the first responder to capture any inspector changes + %ctrl = canvas.getFirstResponder(); + if( isObject(%ctrl) ) + %ctrl.clearFirstResponder(); + + %tree = DatablockEditorTree; + %count = %tree.getSelectedItemsCount(); + %selected = %tree.getSelectedItemList(); + + for( %i = 0; %i < %count; %i ++ ) + { + %id = getWord( %selected, %i ); + %db = %tree.getItemValue( %id ); + + if( %this.PM.isDirty( %db ) ) + { + %this.PM.saveDirtyObject( %db ); + %this.flagDatablockAsDirty( %db, false ); + } + } +} + +//============================================================================================= +// Selection. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::getNumSelectedDatablocks( %this ) +{ + return DatablockEditorTree.getSelectedItemsCount(); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::getSelectedDatablock( %this, %index ) +{ + %tree = DatablockEditorTree; + if( !%tree.getSelectedItemsCount() ) + return 0; + + if( !%index ) + %id = %tree.getSelectedItem(); + else + %id = getWord( %tree.getSelectedItemList(), %index ); + + return %tree.getItemValue( %id ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::resetSelectedDatablock( %this ) +{ + DatablockEditorTree.clearSelection(); + DatablockEditorInspector.inspect(0); + DatablockEditorInspectorWindow-->DatablockFile.setText(""); + + EditorGuiStatusBar.setSelection( "" ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::selectDatablockCheck( %this, %datablock ) +{ + if( %this.selectedDatablockIsDirty() ) + %this.showSaveDialog( %datablock ); + else + %this.selectDatablock( %datablock ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::selectDatablock( %this, %datablock, %add, %dontSyncTree ) +{ + if( %add ) + DatablockEditorInspector.addInspect( %datablock ); + else + DatablockEditorInspector.inspect( %datablock ); + + if( !%dontSyncTree ) + { + %id = DatablockEditorTree.findItemByValue( %datablock.getId() ); + + if( !%add ) + DatablockEditorTree.clearSelection(); + + DatablockEditorTree.selectItem( %id, true ); + DatablockEditorTree.scrollVisible( %id ); + } + + %this.syncDirtyState(); + + // Update the filename text field. + + %numSelected = %this.getNumSelectedDatablocks(); + %fileNameField = DatablockEditorInspectorWindow-->DatablockFile; + + if( %numSelected == 1 ) + { + %fileName = %datablock.getFilename(); + if( %fileName !$= "" ) + %fileNameField.setText( %fileName ); + else + %fileNameField.setText( $DATABLOCK_EDITOR_DEFAULT_FILENAME ); + } + else + { + %fileNameField.setText( "" ); + } + + EditorGuiStatusBar.setSelection( %this.getNumSelectedDatablocks() @ " Datablocks Selected" ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::unselectDatablock( %this, %datablock, %dontSyncTree ) +{ + DatablockEditorInspector.removeInspect( %datablock ); + + if( !%dontSyncTree ) + { + %id = DatablockEditorTree.findItemByValue( %datablock.getId() ); + DatablockEditorTree.selectItem( %id, false ); + } + + %this.syncDirtyState(); + + // If we have exactly one selected datablock remaining, re-enable + // the save-as button. + + %numSelected = %this.getNumSelectedDatablocks(); + if( %numSelected == 1 ) + { + DatablockEditorInspectorWindow-->saveAsButton.setActive( true ); + + %fileNameField = DatablockEditorInspectorWindow-->DatablockFile; + %fileNameField.setText( %this.getSelectedDatablock().getFilename() ); + %fileNameField.setActive( true ); + } + + EditorGuiStatusBar.setSelection( %this.getNumSelectedDatablocks() @ " Datablocks Selected" ); +} + +//============================================================================================= +// Creation and Deletion. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::deleteDatablock( %this ) +{ + %tree = DatablockEditorTree; + + // If we have more than single datablock selected, + // turn our undos into a compound undo. + + %numSelected = %tree.getSelectedItemsCount(); + if( %numSelected > 1 ) + Editor.getUndoManager().pushCompound( "Delete Multiple Datablocks" ); + + for( %i = 0; %i < %numSelected; %i ++ ) + { + %id = %tree.getSelectedItem( %i ); + %db = %tree.getItemValue( %id ); + + %fileName = %db.getFileName(); + + // Remove the datablock from the tree. + + DatablockEditorTree.removeItem( %id ); + + // Create undo. + + %action = %this.createUndo( ActionDeleteDatablock, "Delete Datablock" ); + %action.db = %db; + %action.dbName = %db.getName(); + %action.fname = %fileName; + + %this.submitUndo( %action ); + + // Kill the datablock in the file. + + if( %fileName !$= "" ) + %this.PM.removeObjectFromFile( %db ); + + UnlistedDatablocks.add( %db ); + + // Show some confirmation. + + if( %numSelected == 1 ) + MessageBoxOk( "Datablock Deleted", "The datablock (" @ %db.getName() @ ") has been removed from " @ + "it's file (" @ %db.getFilename() @ ") and upon restart will cease to exist" ); + } + + // Close compound, if we were deleting multiple datablocks. + + if( %numSelected > 1 ) + Editor.getUndoManager().popCompound(); + + // Show confirmation for multiple datablocks. + + if( %numSelected > 1 ) + MessageBoxOk( "Datablocks Deleted", "The datablocks have been deleted and upon restart will cease to exist." ); + + // Clear selection. + + DatablockEditorPlugin.resetSelectedDatablock(); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::createDatablock(%this) +{ + %class = DatablockEditorTypeTree.getItemText(DatablockEditorTypeTree.getSelectedItem()); + if( %class !$= "" ) + { + // Need to prompt for a name. + + DatablockEditorCreatePrompt-->CreateDatablockName.setText("Name"); + DatablockEditorCreatePrompt-->CreateDatablockName.selectAllText(); + + // Populate the copy source dropdown. + + %list = DatablockEditorCreatePrompt-->CopySourceDropdown; + %list.clear(); + %list.add( "", 0 ); + + %set = DataBlockSet; + %count = %set.getCount(); + for( %i = 0; %i < %count; %i ++ ) + { + %datablock = %set.getObject( %i ); + %datablockClass = %datablock.getClassName(); + + if( !isMemberOfClass( %datablockClass, %class ) ) + continue; + + %list.add( %datablock.getName(), %i + 1 ); + } + + // Set up state of client-side checkbox. + + %clientSideCheckBox = DatablockEditorCreatePrompt-->ClientSideCheckBox; + %canBeClientSide = DatablockEditorPlugin::canBeClientSideDatablock( %class ); + %clientSideCheckBox.setStateOn( %canBeClientSide ); + %clientSideCheckBox.setActive( %canBeClientSide ); + + // Show the dialog. + + canvas.pushDialog( DatablockEditorCreatePrompt, 0, true ); + } +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::createPromptNameCheck(%this) +{ + %name = DatablockEditorCreatePrompt-->CreateDatablockName.getText(); + if( !Editor::validateObjectName( %name, true ) ) + return; + + // Fetch the copy source and clear the list. + + %copySource = DatablockEditorCreatePrompt-->copySourceDropdown.getText(); + DatablockEditorCreatePrompt-->copySourceDropdown.clear(); + + // Remove the dialog and create the datablock. + + canvas.popDialog( DatablockEditorCreatePrompt ); + %this.createDatablockFinish( %name, %copySource ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::createDatablockFinish( %this, %name, %copySource ) +{ + %class = DatablockEditorTypeTree.getItemText(DatablockEditorTypeTree.getSelectedItem()); + if( %class !$= "" ) + { + %action = %this.createUndo( ActionCreateDatablock, "Create New Datablock" ); + + if( DatablockEditorCreatePrompt-->ClientSideCheckBox.isStateOn() ) + %dbType = "singleton "; + else + %dbType = "datablock "; + + if( %copySource !$= "" ) + %eval = %dbType @ %class @ "(" @ %name @ " : " @ %copySource @ ") { canSaveDynamicFields = \"1\"; };"; + else + %eval = %dbType @ %class @ "(" @ %name @ ") { canSaveDynamicFields = \"1\"; };"; + + %res = eval( %eval ); + + %action.db = %name.getId(); + %action.dbName = %name; + %action.fname = $DATABLOCK_EDITOR_DEFAULT_FILENAME; + + %this.submitUndo( %action ); + + %action.redo(); + } +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::canBeClientSideDatablock( %className ) +{ + switch$( %className ) + { + case "SFXProfile" or + "SFXPlayList" or + "SFXAmbience" or + "SFXEnvironment" or + "SFXState" or + "SFXDescription" or + "SFXFMODProject": + return true; + + default: + return false; + } +} + +//============================================================================================= +// Events. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + // Same work to do as for the regular WorldEditor Inspector. + Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ); + + DatablockEditorPlugin.flagDatablockAsDirty( %object, true ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + DatablockFieldInfoControl.setText( "" @ %fieldName @ " (" @ %fieldTypeStr @ ") " NL "" @ %fieldDoc ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorInspector::onBeginCompoundEdit( %this ) +{ + Editor.getUndoManager().pushCompound( "Multiple Field Edit" ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorInspector::onEndCompoundEdit( %this, %discard ) +{ + Editor.getUndoManager().popCompound( %discard ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorInspector::onClear( %this ) +{ + DatablockFieldInfoControl.setText( "" ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTree::onDeleteSelection( %this ) +{ + %this.undoDeleteList = ""; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTree::onDeleteObject( %this, %object ) +{ + // Append it to our list. + %this.undoDeleteList = %this.undoDeleteList TAB %object; + + // We're gonna delete this ourselves in the + // completion callback. + return true; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTree::onObjectDeleteCompleted( %this ) +{ + //MEDeleteUndoAction::submit( %this.undoDeleteList ); + + // Let the world editor know to + // clear its selection. + //EWorldEditor.clearSelection(); + //EWorldEditor.isDirty = true; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTree::onClearSelected(%this) +{ + DatablockEditorInspector.inspect( 0 ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTree::onAddSelection( %this, %id ) +{ + %obj = %this.getItemValue( %id ); + + if( !isObject( %obj ) ) + %this.selectItem( %id, false ); + else + DatablockEditorPlugin.selectDatablock( %obj, true, true ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTree::onRemoveSelection( %this, %id ) +{ + %obj = %this.getItemValue( %id ); + if( isObject( %obj ) ) + DatablockEditorPlugin.unselectDatablock( %obj, true ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTree::onRightMouseUp( %this, %id, %mousePos ) +{ + %datablock = %this.getItemValue( %id ); + if( !isObject( %datablock ) ) + return; + + if( !isObject( DatablockEditorTreePopup ) ) + new PopupMenu( DatablockEditorTreePopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Delete" TAB "" TAB "DatablockEditorPlugin.selectDatablock( %this.datablockObject ); DatablockEditorPlugin.deleteDatablock( %this.datablockObject );"; + item[ 1 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.datablockObject );"; + + datablockObject = ""; + }; + + DatablockEditorTreePopup.datablockObject = %datablock; + DatablockEditorTreePopup.showPopup( Canvas ); +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorTreeTabBook::onTabSelected(%this, %text, %id) +{ + switch(%id) + { + case 0: + DatablockEditorTreeWindow-->DeleteSelection.visible = true; + DatablockEditorTreeWindow-->CreateSelection.visible = false; + + case 1: + DatablockEditorTreeWindow-->DeleteSelection.visible = false; + DatablockEditorTreeWindow-->CreateSelection.visible = true; + } +} diff --git a/Templates/BaseGame/game/tools/datablockEditor/datablockEditorUndo.cs b/Templates/BaseGame/game/tools/datablockEditor/datablockEditorUndo.cs new file mode 100644 index 000000000..f9a8d30b4 --- /dev/null +++ b/Templates/BaseGame/game/tools/datablockEditor/datablockEditorUndo.cs @@ -0,0 +1,159 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::createUndo( %this, %class, %desc ) +{ + pushInstantGroup(); + %action = new UndoScriptAction() + { + class = %class; + superClass = BaseDatablockEdAction; + actionName = %desc; + editor = DatablockEditorPlugin; + treeview = DatablockEditorTree; + inspector = DatablockEditorInspector; + }; + popInstantGroup(); + return %action; +} + +//--------------------------------------------------------------------------------------------- + +function DatablockEditorPlugin::submitUndo( %this, %action ) +{ + %action.addToManager( Editor.getUndoManager() ); +} + +//============================================================================================= +// BaseDatablockEdAction. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function BaseDatablockEdAction::redo( %this ) +{ +} + +//--------------------------------------------------------------------------------------------- + +function BaseDatablockEdAction::undo( %this ) +{ +} + +//============================================================================================= +// ActionCreateDatablock. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionCreateDatablock::redo( %this ) +{ + %db = %this.db; + + %db.name = %this.dbName; + + %this.editor.PM.setDirty( %db, %this.fname ); + %this.editor.addExistingItem( %db ); + %this.editor.selectDatablock( %db ); + %this.editor.flagInspectorAsDirty( true ); + + UnlistedDatablocks.remove( %id ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionCreateDatablock::undo( %this ) +{ + %db = %this.db; + + %itemId = %this.treeview.findItemByName( %db.name ); + if( !%itemId ) + %itemId = %this.treeview.findItemByName( %db.name @ " *" ); + + %this.treeview.removeItem( %itemId ); + %this.editor.resetSelectedDatablock(); + %this.editor.PM.removeDirty( %db ); + + %this.dbName = %db.name; + %db.name = ""; + + UnlistedDatablocks.add( %this.db ); +} + +//============================================================================================= +// ActionDeleteDatablock. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionDeleteDatablock::redo( %this ) +{ + %db = %this.db; + + %itemId = %this.treeview.findItemByName( %db.name ); + if( !%itemId ) + %itemId = %this.treeview.findItemByName( %db.name @ " *" ); + + // Remove from tree and file. + + %this.treeview.removeItem( %db ); + %this.editor.resetSelectedDatablock(); + if( %db.getFileName() !$= "" ) + %this.editor.PM.removeObjectFromFile( %db ); + + // Unassign name. + + %this.dbName = %db.name; + %db.name = ""; + + // Add to unlisted. + + UnlistedDatablocks.add( %db ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionDeleteDatablock::undo( %this ) +{ + %db = %this.db; + + // Restore name. + + %db.name = %this.dbName; + + // Add to tree and select. + + %this.editor.addExistingItem( %db, true ); + %this.editor.selectDatablock( %db ); + + // Mark as dirty. + + %this.editor.PM.setDirty( %db, %this.fname ); + %this.editor.syncDirtyState(); + + // Remove from unlisted. + + UnlistedDatablocks.remove( %id ); +} diff --git a/Templates/BaseGame/game/tools/datablockEditor/main.cs b/Templates/BaseGame/game/tools/datablockEditor/main.cs new file mode 100644 index 000000000..e7626a8b3 --- /dev/null +++ b/Templates/BaseGame/game/tools/datablockEditor/main.cs @@ -0,0 +1,66 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------------------------- + +function initializeDatablockEditor() +{ + echo( " - Initializing Datablock Editor" ); + + exec("./datablockEditor.cs"); + exec("./datablockEditorUndo.cs"); + exec("./DatablockEditorTreeWindow.ed.gui"); + exec("./DatablockEditorInspectorWindow.ed.gui"); + exec("./DatablockEditorCreatePrompt.ed.gui"); + + // Add ourselves to EditorGui, where all the other tools reside + DatablockEditorInspectorWindow.setVisible( false ); + DatablockEditorTreeWindow.setVisible( false ); + + EditorGui.add( DatablockEditorInspectorWindow ); + EditorGui.add( DatablockEditorTreeWindow ); + + new ScriptObject( DatablockEditorPlugin ) + { + superClass = "WorldEditorPlugin"; + editorGui = EWorldEditor; + }; + + new SimSet( UnlistedDatablocks ); + + // create our persistence manager + DatablockEditorPlugin.PM = new PersistenceManager(); + + %map = new ActionMap(); + %map.bindCmd( keyboard, "backspace", "DatablockEditorPlugin.onDeleteKey();", "" ); + %map.bindCmd( keyboard, "delete", "DatablockEditorPlugin.onDeleteKey();", "" ); + DatablockEditorPlugin.map = %map; + + DatablockEditorPlugin.initSettings(); +} + +//--------------------------------------------------------------------------------------------- + +function destroyDatablockEditor() +{ +} diff --git a/Templates/BaseGame/game/tools/debugger/gui/breakConditionDlg.ed.gui b/Templates/BaseGame/game/tools/debugger/gui/breakConditionDlg.ed.gui new file mode 100644 index 000000000..d6355e58f --- /dev/null +++ b/Templates/BaseGame/game/tools/debugger/gui/breakConditionDlg.ed.gui @@ -0,0 +1,145 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(DebuggerBreakConditionDlg, EditorGuiGroup) { + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiWindowCtrl() { + profile = "ToolsGuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "220 146"; + extent = "200 188"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Set the break condition"; + resizeWidth = "True"; + resizeHeight = "True"; + canMove = "False"; + canClose = "False"; + canMinimize = "False"; + canMaximize = "False"; + minSize = "50 50"; + + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 28"; + extent = "121 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Enter the break condition:"; + }; + new GuiTextEditCtrl(BreakCondition) { + profile = "ToolsGuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 44"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + altCommand = "DbgBreakConditionSet();"; + helpTag = "0"; + historySize = "0"; + }; + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 68"; + extent = "57 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Pass Count:"; + }; + new GuiTextEditCtrl(BreakPassCount) { + profile = "ToolsGuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 84"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + historySize = "0"; + returnTab = "true"; + }; + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 108"; + extent = "27 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Clear:"; + }; + new GuiTextEditCtrl(BreakClear) { + profile = "ToolsGuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 124"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + historySize = "0"; + returnTab = "true"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "56 156"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgBreakConditionSet();"; + helpTag = "0"; + text = "Set"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "104 156"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.popDialog(DebuggerBreakConditionDlg);"; + helpTag = "0"; + text = "Cancel"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/debugger/gui/connectDlg.ed.gui b/Templates/BaseGame/game/tools/debugger/gui/connectDlg.ed.gui new file mode 100644 index 000000000..927312fed --- /dev/null +++ b/Templates/BaseGame/game/tools/debugger/gui/connectDlg.ed.gui @@ -0,0 +1,148 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(DebuggerConnectDlg, EditorGuiGroup) { + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiWindowCtrl() { + profile = "ToolsGuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "220 146"; + extent = "200 188"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Connect to server:"; + resizeWidth = "True"; + resizeHeight = "True"; + canMove = "False"; + canClose = "False"; + canMinimize = "False"; + canMaximize = "False"; + minSize = "50 50"; + + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 28"; + extent = "55 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "IP Address:"; + }; + new GuiTextEditCtrl(DebuggerConnectAddress) { + profile = "ToolsGuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 44"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + variable = "$pref::DBGConnectAddress"; + helpTag = "0"; + historySize = "0"; + returnTab = "true"; + }; + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 68"; + extent = "21 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Port:"; + }; + new GuiTextEditCtrl(DebuggerConnectPort) { + profile = "ToolsGuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 84"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + variable = "$pref::DBGConnectPort"; + helpTag = "0"; + historySize = "0"; + returnTab = "true"; + }; + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 108"; + extent = "52 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Password:"; + }; + new GuiTextEditCtrl(DebuggerConnectPassword) { + profile = "ToolsGuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 124"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + variable = "$pref::DBGConnectPassword"; + helpTag = "0"; + historySize = "0"; + returnTab = "true"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "56 156"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgConnect();"; + helpTag = "0"; + text = "Open"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "104 156"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.popDialog(DebuggerConnectDlg);"; + helpTag = "0"; + text = "Cancel"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/debugger/gui/debugger.ed.gui b/Templates/BaseGame/game/tools/debugger/gui/debugger.ed.gui new file mode 100644 index 000000000..616a8f0fb --- /dev/null +++ b/Templates/BaseGame/game/tools/debugger/gui/debugger.ed.gui @@ -0,0 +1,583 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(DebuggerGui, EditorGuiGroup) { + profile = "ToolsGuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "8 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.pushDialog(DebuggerConnectDlg, 80);"; + helpTag = "0"; + text = "Connect"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "72 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.pushDialog(OpenFileDialog, 80);"; + helpTag = "0"; + text = "File"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "72 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "dbgStepIn();"; + accelerator = "f7"; + helpTag = "0"; + text = "Step In"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "136 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "dbgStepOver();"; + accelerator = "f8"; + helpTag = "0"; + text = "Step Over"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "200 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "dbgStepOut();"; + accelerator = "f6"; + helpTag = "0"; + text = "Step Out"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "264 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "dbgContinue();"; + accelerator = "f9"; + helpTag = "0"; + text = "Run"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "328 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.pushDialog(DebuggerFindDlg, 80);"; + helpTag = "0"; + text = "Find"; + }; + new GuiTextCtrl(DebuggerCursorWatch) { + profile = "ToolsGuiTextProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "398 4"; + extent = "126 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = ""; + justify = "left"; + }; + new GuiTextCtrl(DebuggerStatus) { + profile = "ToolsGuiTextProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "532 4"; + extent = "100 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "NOT CONNECTED"; + justify = "right"; + }; + new GuiFrameSetCtrl(DebuggerRootFrame) { + profile = "GuiContentProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 24"; + extent = "640 456"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + columns = "0 486"; + rows = "0"; + borderWidth = "4"; + borderEnable = "dynamic"; + borderMovable = "dynamic"; + + new GuiFrameSetCtrl(DebuggerLeftFrame) { + profile = "GuiContentProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "482 456"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + columns = "0"; + rows = "0 350"; + borderWidth = "4"; + borderEnable = "dynamic"; + borderMovable = "dynamic"; + + new GuiControl() { + profile = "ToolsGuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "482 346"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "True"; + modal = "True"; + helpTag = "0"; + + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "8 4"; + extent = "47 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Open File:"; + }; + new GuiPopUpMenuCtrl(DebuggerFilePopup) { + profile = "ToolsGuiPopUpMenuProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "64 4"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "True"; + modal = "True"; + helpTag = "0"; + maxPopupHeight = "200"; + }; + new GuiScrollCtrl() { + profile = "ToolsGuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 24"; + extent = "482 321"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + willFirstRespond = "True"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "False"; + + new DbgFileView(DebuggerFileView) { + profile = "ToolsGuiTextArrayProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 -433"; + extent = "509 3904"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + }; + }; + }; + new GuiControl() { + profile = "ToolsGuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 350"; + extent = "482 106"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "8 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.pushDialog(DebuggerWatchDlg, 80);"; + helpTag = "0"; + text = "Add"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "72 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.pushDialog(DebuggerEditWatchDlg, 80);"; + helpTag = "0"; + text = "Edit"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "136 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgDeleteSelectedWatch();"; + helpTag = "0"; + text = "Delete"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "200 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DebuggerWatchView.clear();"; + helpTag = "0"; + text = "Clear"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "264 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgRefreshWatches();"; + helpTag = "0"; + text = "Refresh"; + }; + new GuiScrollCtrl() { + profile = "ToolsGuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 24"; + extent = "481 80"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + willFirstRespond = "True"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "False"; + + new GuiTextListCtrl(DebuggerWatchView) { + profile = "ToolsGuiTextListProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 8"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + enumerate = "False"; + resizeCell = "True"; + columns = "0 200"; + }; + }; + }; + }; + new GuiFrameSetCtrl(DebuggerRightFrame) { + profile = "GuiContentProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "486 0"; + extent = "154 456"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + columns = "0"; + rows = "0 150 350"; + borderWidth = "4"; + borderEnable = "dynamic"; + borderMovable = "dynamic"; + + new GuiScrollCtrl() { + profile = "ToolsGuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "154 146"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + willFirstRespond = "True"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "False"; + + new GuiTextListCtrl(DebuggerCallStack) { + profile = "ToolsGuiTextListProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 8"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + enumerate = "False"; + resizeCell = "True"; + columns = "-1 -1 0"; + }; + }; + new GuiControl() { + profile = "ToolsGuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 150"; + extent = "154 196"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.pushDialog(DebuggerBreakConditionDlg, 80);"; + helpTag = "0"; + text = "Condition"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "68 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgDeleteSelectedBreak();"; + helpTag = "0"; + text = "Delete"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "132 4"; + extent = "56 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DebuggerBreakPoints.clearBreaks();"; + helpTag = "0"; + text = "Clear"; + }; + new GuiScrollCtrl() { + profile = "ToolsGuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 24"; + extent = "153 171"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + willFirstRespond = "True"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "False"; + + new GuiTextListCtrl(DebuggerBreakPoints) { + profile = "ToolsGuiTextListProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "182 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + enumerate = "False"; + resizeCell = "True"; + columns = "16 56 156"; + }; + }; + }; + new GuiControl() { + profile = "ToolsGuiWindowProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 350"; + extent = "154 106"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiScrollCtrl() { + profile = "ToolsGuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "153 80"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + willFirstRespond = "True"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "False"; + + new GuiTextListCtrl(DebuggerConsoleView) { + profile = "ToolsGuiTextListProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "62 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + enumerate = "False"; + resizeCell = "True"; + columns = "0"; + }; + }; + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "15 83"; + extent = "9 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "%"; + }; + new GuiTextEditCtrl(DbgConsoleEntry) { + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "top"; + position = "29 83"; + extent = "120 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + altCommand = "DbgConsoleEntryReturn();"; + helpTag = "0"; + historySize = "32"; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/debugger/gui/editWatchDlg.ed.gui b/Templates/BaseGame/game/tools/debugger/gui/editWatchDlg.ed.gui new file mode 100644 index 000000000..d1d5ebe4e --- /dev/null +++ b/Templates/BaseGame/game/tools/debugger/gui/editWatchDlg.ed.gui @@ -0,0 +1,93 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(DebuggerEditWatchDlg, EditorGuiGroup) { + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiWindowCtrl() { + profile = "ToolsGuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "220 180"; + extent = "200 108"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Edit a Variable"; + resizeWidth = "True"; + resizeHeight = "True"; + canMove = "False"; + canClose = "False"; + canMinimize = "False"; + canMaximize = "False"; + minSize = "50 50"; + + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 28"; + extent = "99 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Enter the new value:"; + }; + new GuiTextEditCtrl(EditWatchDialogValue) { + profile = "ToolsGuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 44"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + altCommand = "DbgWatchDialogEdit();"; + helpTag = "0"; + historySize = "0"; + fontHL = "14 253 Arial"; + font = "14 244 Arial"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "56 80"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgWatchDialogEdit();"; + helpTag = "0"; + text = "Edit"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "104 80"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.popDialog(DebuggerEditWatchDlg);"; + helpTag = "0"; + text = "Cancel"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/debugger/gui/findDlg.ed.gui b/Templates/BaseGame/game/tools/debugger/gui/findDlg.ed.gui new file mode 100644 index 000000000..5a74273d5 --- /dev/null +++ b/Templates/BaseGame/game/tools/debugger/gui/findDlg.ed.gui @@ -0,0 +1,93 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(DebuggerFindDlg, EditorGuiGroup) { + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiWindowCtrl() { + profile = "ToolsGuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "220 180"; + extent = "200 108"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "File Search"; + resizeWidth = "True"; + resizeHeight = "True"; + canMove = "False"; + canClose = "False"; + canMinimize = "False"; + canMaximize = "False"; + minSize = "50 50"; + + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 28"; + extent = "99 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Search for:"; + }; + new GuiTextEditCtrl(DebuggerFindStringText) { + profile = "ToolsGuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 44"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + altCommand = "DbgFileViewFind();"; + helpTag = "0"; + historySize = "0"; + fontHL = "14 253 Arial"; + font = "14 244 Arial"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "56 80"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgFileViewFind();"; + helpTag = "0"; + text = "Find"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "104 80"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.popDialog(DebuggerFindDlg);"; + helpTag = "0"; + text = "Cancel"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/debugger/gui/watchDlg.ed.gui b/Templates/BaseGame/game/tools/debugger/gui/watchDlg.ed.gui new file mode 100644 index 000000000..898563807 --- /dev/null +++ b/Templates/BaseGame/game/tools/debugger/gui/watchDlg.ed.gui @@ -0,0 +1,92 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(DebuggerWatchDlg, EditorGuiGroup) { + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + + new GuiWindowCtrl() { + profile = "ToolsGuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "220 180"; + extent = "200 108"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Add a Watch Expression:"; + resizeWidth = "True"; + resizeHeight = "True"; + canMove = "False"; + canClose = "False"; + canMinimize = "False"; + canMaximize = "False"; + minSize = "50 50"; + opaque = "true"; + + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 28"; + extent = "88 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + helpTag = "0"; + text = "Enter the Variable:"; + }; + new GuiTextEditCtrl(WatchDialogExpression) { + profile = "ToolsGuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 44"; + extent = "160 18"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + altCommand = "DbgWatchDialogAdd();"; + helpTag = "0"; + historySize = "0"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "56 80"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "DbgWatchDialogAdd();"; + helpTag = "0"; + text = "Add"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "104 80"; + extent = "40 16"; + minExtent = "8 8"; + visible = "True"; + setFirstResponder = "False"; + modal = "True"; + command = "Canvas.popDialog(DebuggerWatchDlg);"; + helpTag = "0"; + text = "Cancel"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/debugger/main.cs b/Templates/BaseGame/game/tools/debugger/main.cs new file mode 100644 index 000000000..f51222665 --- /dev/null +++ b/Templates/BaseGame/game/tools/debugger/main.cs @@ -0,0 +1,68 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//--------------------------------------------------------------------------------------------- +// TCP Debugger +// To use the debugger, first call "dbgSetParameters(port, password);" from one instance of +// your game. Then, in another instance (either on the same system, or a different one) call +// "startDebugger();". Then use the gui to connect to the first instance with the port and +// password you first passed to dbgSetParameters. +//--------------------------------------------------------------------------------------------- + +function initializeDebugger() +{ + echo(" % - Initializing Debugger"); + + // Load the scripts. + exec("./scripts/debugger.ed.cs"); + + // And the guis. + exec("./gui/breakConditionDlg.ed.gui"); + exec("./gui/connectDlg.ed.gui"); + exec("./gui/editWatchDlg.ed.gui"); + exec("./gui/findDlg.ed.gui"); + exec("./gui/debugger.ed.gui"); + exec("./gui/watchDlg.ed.gui"); +} + +function destroyDebugger() +{ + if (isObject(TCPDebugger)) + TCPDebugger.delete(); +} + +function startDebugger() +{ + // Clean up first. + destroyDebugger(); + + // Create a TCP object named TCPDebugger. + new TCPObject(TCPDebugger); + + // Used to get unique IDs for breakpoints and watch expressions. + $DbgBreakId = 0; + $DbgWatchSeq = 1; + + // Set up the GUI. + DebuggerConsoleView.setActive(false); + $GameCanvas.pushDialog(DebuggerGui); +} diff --git a/Templates/BaseGame/game/tools/debugger/scripts/debugger.ed.cs b/Templates/BaseGame/game/tools/debugger/scripts/debugger.ed.cs new file mode 100644 index 000000000..408de29eb --- /dev/null +++ b/Templates/BaseGame/game/tools/debugger/scripts/debugger.ed.cs @@ -0,0 +1,508 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//--------------------------------------------------------------------------------------------- +// onLine is invoked whenever the TCP object receives a line from the server. Treat the first +// word as a "command" and dispatch to an appropriate handler. +//--------------------------------------------------------------------------------------------- +function TCPDebugger::onLine(%this, %line) +{ + echo("Got line=>" @ %line); + %cmd = firstWord(%line); + %rest = restWords(%line); + + if (%cmd $= "PASS") { + %this.handlePass(%rest); + } + else if(%cmd $= "COUT") { + %this.handleLineOut(%rest); + } + else if(%cmd $= "FILELISTOUT") { + %this.handleFileList(%rest); + } + else if(%cmd $= "BREAKLISTOUT") { + %this.handleBreakList(%rest); + } + else if(%cmd $= "BREAK") { + %this.handleBreak(%rest); + } + else if(%cmd $= "RUNNING") { + %this.handleRunning(); + } + else if(%cmd $= "EVALOUT") { + %this.handleEvalOut(%rest); + } + else { + %this.handleError(%line); + } +} + +// Handler for PASS response. +function TCPDebugger::handlePass(%this, %message) +{ + if (%message $= "WrongPass") { + DebuggerConsoleView.print("Disconnected - wrong password."); + %this.disconnect(); + } + else if(%message $= "Connected.") { + DebuggerConsoleView.print("Connected."); + DebuggerStatus.setValue("CONNECTED"); + %this.send("FILELIST\r\n"); + } +} + +// Handler for COUT response. +function TCPDebugger::handleLineOut(%this, %line) +{ + DebuggerConsoleView.print(%line); +} + +// Handler for FILELISTOUT response. +function TCPDebugger::handleFileList(%this, %line) +{ + DebuggerFilePopup.clear(); + %word = 0; + while ((%file = getWord(%line, %word)) !$= "") { + %word++; + DebuggerFilePopup.add(%file, %word); + } +} + +// Handler for BREAKLISTOUT response. +function TCPDebugger::handleBreakList(%this, %line) +{ + %file = getWord(%line, 0); + if (%file != $DebuggerFile) { + return; + } + %pairs = getWord(%line, 1); + %curLine = 1; + DebuggerFileView.clearBreakPositions(); + + // Set the possible break positions. + for (%i = 0; %i < %pairs; %i++) { + %skip = getWord(%line, %i * 2 + 2); + %breaks = getWord(%line, %i * 2 + 3); + %curLine += %skip; + for (%j = 0; %j < %breaks; %j++) { + DebuggerFileView.setBreakPosition(%curLine); + %curLine++; + } + } + + // Now set the actual break points. + for (%i = 0; %i < DebuggerBreakPoints.rowCount(); %i++) { + %breakText = DebuggerBreakPoints.getRowText(%i); + %breakLine = getField(%breakText, 0); + %breakFile = getField(%breakText, 1); + if (%breakFile == $DebuggerFile) { + DebuggerFileView.setBreak(%breakLine); + } + } +} + +// Handler for BREAK response. +function TCPDebugger::handleBreak(%this, %line) +{ + DebuggerStatus.setValue("BREAK"); + + // Query all the watches. + for (%i = 0; %i < DebuggerWatchView.rowCount(); %i++) { + %id = DebuggerWatchView.getRowId(%i); + %row = DebuggerWatchView.getRowTextById(%id); + %expr = getField(%row, 0); + %this.send("EVAL " @ %id @ " 0 " @ %expr @ "\r\n"); + } + + // Update the call stack window. + DebuggerCallStack.clear(); + + %file = getWord(%line, 0); + %lineNumber = getWord(%line, 1); + %funcName = getWord(%line, 2); + + DbgOpenFile(%file, %lineNumber, true); + + %nextWord = 3; + %rowId = 0; + %id = 0; + while(1) { + DebuggerCallStack.setRowById(%id, %file @ "\t" @ %lineNumber @ "\t" @ %funcName); + %id++; + %file = getWord(%line, %nextWord); + %lineNumber = getWord(%line, %nextWord + 1); + %funcName = getWord(%line, %nextWord + 2); + %nextWord += 3; + if (%file $= "") { + break; + } + } +} + +// Handler for RUNNING response. +function TCPDebugger::handleRunning(%this) +{ + DebuggerFileView.setCurrentLine(-1, true); + DebuggerCallStack.clear(); + DebuggerStatus.setValue("RUNNING..."); +} + +// Handler for EVALOUT response. +function TCPDebugger::handleEvalOut(%this, %line) +{ + %id = firstWord(%line); + %value = restWords(%line); + + // See if it's the cursor watch, or from the watch window. + if (%id < 0) { + DebuggerCursorWatch.setText(DebuggerCursorWatch.expr SPC "=" SPC %value); + } + else { + %row = DebuggerWatchView.getRowTextById(%id); + if (%row $= "") { + return; + } + %expr = getField(%row, 0); + DebuggerWatchView.setRowById(%id, %expr @ "\t" @ %value); + } +} + +// Handler for unrecognized response. +function TCPDebugger::handleError(%this, %line) +{ + DebuggerConsoleView.print("ERROR - bogus message: " @ %line); +} + +// Print a line of response from the server. +function DebuggerConsoleView::print(%this, %line) +{ + %row = %this.addRow(0, %line); + %this.scrollVisible(%row); +} + +// When entry in file list selected, open the file. +function DebuggerFilePopup::onSelect(%this, %id, %text) +{ + DbgOpenFile(%text, 0, false); +} + +// When entry on call stack selected, open the file and go to the line. +function DebuggerCallStack::onAction(%this) +{ + %id = %this.getSelectedId(); + if (%id == -1) { + return; + } + %text = %this.getRowTextById(%id); + %file = getField(%text, 0); + %line = getField(%text, 1); + + DbgOpenFile(%file, %line, %id == 0); +} + +// Add a breakpoint at the selected spot, if it doesn't already exist. +function DebuggerBreakPoints::addBreak(%this, %file, %line, %clear, %passct, %expr) +{ + // columns 0 = line, 1 = file, 2 = expr + %textLine = %line @ "\t" @ %file @ "\t" @ %expr @ "\t" @ %passct @ "\t" @ %clear; + %selId = %this.getSelectedId(); + %selText = %this.getRowTextById(%selId); + if ((getField(%selText, 0) $= %line) && (getField(%selText, 1) $= %file)) { + %this.setRowById(%selId, %textLine); + } + else { + %this.addRow($DbgBreakId, %textLine); + $DbgBreakId++; + } +} + +// Remove the selected breakpoint. +function DebuggerBreakPoints::removeBreak(%this, %file, %line) +{ + for (%i = 0; %i < %this.rowCount(); %i++) { + %id = %this.getRowId(%i); + %text = %this.getRowTextById(%id); + if ((getField(%text, 0) $= %line) && (getField(%text, 1) $= %file)) { + %this.removeRowById(%id); + return; + } + } +} + +// Remove all breakpoints. +function DebuggerBreakPoints::clearBreaks(%this) +{ + while (%this.rowCount()) { + %id = %this.getRowId(0); + %text = %this.getRowTextById(%id); + %file = getField(%text, 1); + %line = getField(%text, 0); + DbgRemoveBreakPoint(%file, %line); + } +} + +// Go to file & line for the selected breakpoint. +function DebuggerBreakPoints::onAction(%this) +{ + %id = %this.getSelectedId(); + if (%id == -1) { + return; + } + %text = %this.getRowTextById(%id); + %line = getField(%text, 0); + %file = getField(%text, 1); + + DbgOpenFile(%file, %line, false); +} + +// Handle breakpoint removal executed from the file-view GUI. +function DebuggerFileView::onRemoveBreakPoint(%this, %line) +{ + %file = $DebuggerFile; + DbgRemoveBreakPoint(%file, %line); +} + +// Handle breakpoint addition executed from the file-view GUI. +function DebuggerFileView::onSetBreakPoint(%this, %line) +{ + %file = $DebuggerFile; + DbgSetBreakPoint(%file, %line, 0, 0, true); +} + +//--------------------------------------------------------------------------------------------- +// Various support functions. +//--------------------------------------------------------------------------------------------- + +// Add a watch expression. +function DbgWatchDialogAdd() +{ + %expr = WatchDialogExpression.getValue(); + if (%expr !$= "") { + DebuggerWatchView.setRowById($DbgWatchSeq, %expr @"\t(unknown)"); + TCPDebugger.send("EVAL " @ $DbgWatchSeq @ " 0 " @ %expr @ "\r\n"); + $DbgWatchSeq++; + } + Canvas.popDialog(DebuggerWatchDlg); +} + +// Edit a watch expression. +function DbgWatchDialogEdit() +{ + %newValue = EditWatchDialogValue.getValue(); + %id = DebuggerWatchView.getSelectedId(); + if (%id >= 0) { + %row = DebuggerWatchView.getRowTextById(%id); + %expr = getField(%row, 0); + if (%newValue $= "") { + %assignment = %expr @ " = \"\""; + } + else { + %assignment = %expr @ " = " @ %newValue; + } + TCPDebugger.send("EVAL " @ %id @ " 0 " @ %assignment @ "\r\n"); + } + Canvas.popDialog(DebuggerEditWatchDlg); +} + +// Set/change the singular "cursor watch" expression. +function DbgSetCursorWatch(%expr) +{ + DebuggerCursorWatch.expr = %expr; + if (DebuggerCursorWatch.expr $= "") { + DebuggerCursorWatch.setText(""); + } + else { + TCPDebugger.send("EVAL -1 0 " @ DebuggerCursorWatch.expr @ "\r\n"); + } +} + +// Connect to the server with the given addr/port/password. +function DbgConnect() +{ + %address = DebuggerConnectAddress.getValue(); + %port = DebuggerConnectPort.getValue(); + %password = DebuggerConnectPassword.getValue(); + + if ((%address !$= "" ) && (%port !$= "" ) && (%password !$= "" )) { + TCPDebugger.connect(%address @ ":" @ %port); + TCPDebugger.schedule(5000, send, %password @ "\r\n"); + TCPDebugger.password = %password; + } + + Canvas.popDialog(DebuggerConnectDlg); +} + +// Put a condition on a breakpoint. +function DbgBreakConditionSet() +{ + // Read the condition. + %condition = BreakCondition.getValue(); + %passct = BreakPassCount.getValue(); + %clear = BreakClear.getValue(); + if (%condition $= "") { + %condition = "true"; + } + if (%passct $= "") { + %passct = "0"; + } + if (%clear $= "") { + %clear = "false"; + } + + // Set the condition. + %id = DebuggerBreakPoints.getSelectedId(); + if (%id != -1) { + %bkp = DebuggerBreakPoints.getRowTextById(%id); + DbgSetBreakPoint(getField(%bkp, 1), getField(%bkp, 0), %clear, %passct, %condition); + } + + Canvas.popDialog(DebuggerBreakConditionDlg); +} + +// Open a file, go to the indicated line, and optionally select the line. +function DbgOpenFile(%file, %line, %selectLine) +{ + if (%file !$= "") { + // Open the file in the file view. + if (DebuggerFileView.open(%file)) { + // Go to the line. + DebuggerFileView.setCurrentLine(%line, %selectLine); + // Get the breakpoints for this file. + if (%file !$= $DebuggerFile) { + TCPDebugger.send("BREAKLIST " @ %file @ "\r\n"); + $DebuggerFile = %file; + } + } + } +} + +// Search in the fileview GUI. +function DbgFileViewFind() +{ + %searchString = DebuggerFindStringText.getValue(); + DebuggerFileView.findString(%searchString); + + Canvas.popDialog(DebuggerFindDlg); +} + +// Set a breakpoint, optionally with condition. +function DbgSetBreakPoint(%file, %line, %clear, %passct, %expr) +{ + if (!%clear) { + if (%file == $DebuggerFile) { + DebuggerFileView.setBreak(%line); + } + } + DebuggerBreakPoints.addBreak(%file, %line, %clear, %passct, %expr); + TCPDebugger.send("BRKSET " @ %file @ " " @ %line @ " " @ %clear @ " " @ %passct @ " " @ %expr @ "\r\n"); +} + +// Remove a breakpoint. +function DbgRemoveBreakPoint(%file, %line) +{ + if (%file == $DebuggerFile) { + DebuggerFileView.removeBreak(%line); + } + TCPDebugger.send("BRKCLR " @ %file @ " " @ %line @ "\r\n"); + DebuggerBreakPoints.removeBreak(%file, %line); +} + +// Remove whatever breakpoint is selected in the breakpoints GUI. +function DbgDeleteSelectedBreak() +{ + %selectedBreak = DebuggerBreakPoints.getSelectedId(); + %rowNum = DebuggerBreakPoints.getRowNumById(%selectedWatch); + if (%rowNum >= 0) { + %breakText = DebuggerBreakPoints.getRowText(%rowNum); + %breakLine = getField(%breakText, 0); + %breakFile = getField(%breakText, 1); + DbgRemoveBreakPoint(%breakFile, %breakLine); + } +} + +// Send an expression to the server for evaluation. +function DbgConsoleEntryReturn() +{ + %msg = DbgConsoleEntry.getValue(); + if (%msg !$= "") { + DebuggerConsoleView.print("%" @ %msg); + if (DebuggerStatus.getValue() $= "NOT CONNECTED") { + DebuggerConsoleView.print("*** Not connected."); + } + else if (DebuggerStatus.getValue() $= "BREAK") { + DebuggerConsoleView.print("*** Target is in BREAK mode."); + } + else { + TCPDebugger.send("CEVAL " @ %msg @ "\r\n"); + } + } + DbgConsoleEntry.setValue(""); +} + +// Print a line from the server. +function DbgConsolePrint(%status) +{ + DebuggerConsoleView.print(%status); +} + +// Delete the currently selected watch expression. +function DbgDeleteSelectedWatch() +{ + %selectedWatch = DebuggerWatchView.getSelectedId(); + %rowNum = DebuggerWatchView.getRowNumById(%selectedWatch); + DebuggerWatchView.removeRow(%rowNum); +} + +// Evaluate all the watch expressions. +function DbgRefreshWatches() +{ + for (%i = 0; %i < DebuggerWatchView.rowCount(); %i++) { + %id = DebuggerWatchView.getRowId(%i); + %row = DebuggerWatchView.getRowTextById(%id); + %expr = getField(%row, 0); + TCPDebugger.send("EVAL " @ %id @ " 0 " @ %expr @ "\r\n"); + } +} + +//--------------------------------------------------------------------------------------------- +// Incremental execution functions +// These just send commands to the server. +//--------------------------------------------------------------------------------------------- +function dbgStepIn() +{ + TCPDebugger.send("STEPIN\r\n"); +} + +function dbgStepOut() +{ + TCPDebugger.send("STEPOUT\r\n"); +} + +function dbgStepOver() +{ + TCPDebugger.send("STEPOVER\r\n"); +} + +function dbgContinue() +{ + TCPDebugger.send("CONTINUE\r\n"); +} diff --git a/Templates/BaseGame/game/tools/decalEditor/add-decal_d.png b/Templates/BaseGame/game/tools/decalEditor/add-decal_d.png new file mode 100644 index 000000000..5e45b78ce Binary files /dev/null and b/Templates/BaseGame/game/tools/decalEditor/add-decal_d.png differ diff --git a/Templates/BaseGame/game/tools/decalEditor/add-decal_h.png b/Templates/BaseGame/game/tools/decalEditor/add-decal_h.png new file mode 100644 index 000000000..4fd3f4e28 Binary files /dev/null and b/Templates/BaseGame/game/tools/decalEditor/add-decal_h.png differ diff --git a/Templates/BaseGame/game/tools/decalEditor/add-decal_n.png b/Templates/BaseGame/game/tools/decalEditor/add-decal_n.png new file mode 100644 index 000000000..7aa1ad2c9 Binary files /dev/null and b/Templates/BaseGame/game/tools/decalEditor/add-decal_n.png differ diff --git a/Templates/BaseGame/game/tools/decalEditor/decal-editor_d.png b/Templates/BaseGame/game/tools/decalEditor/decal-editor_d.png new file mode 100644 index 000000000..78fdcd6c3 Binary files /dev/null and b/Templates/BaseGame/game/tools/decalEditor/decal-editor_d.png differ diff --git a/Templates/BaseGame/game/tools/decalEditor/decal-editor_h.png b/Templates/BaseGame/game/tools/decalEditor/decal-editor_h.png new file mode 100644 index 000000000..f83cbe4a9 Binary files /dev/null and b/Templates/BaseGame/game/tools/decalEditor/decal-editor_h.png differ diff --git a/Templates/BaseGame/game/tools/decalEditor/decal-editor_n.png b/Templates/BaseGame/game/tools/decalEditor/decal-editor_n.png new file mode 100644 index 000000000..b94023007 Binary files /dev/null and b/Templates/BaseGame/game/tools/decalEditor/decal-editor_n.png differ diff --git a/Templates/BaseGame/game/tools/decalEditor/decalEditor.cs b/Templates/BaseGame/game/tools/decalEditor/decalEditor.cs new file mode 100644 index 000000000..b861d8694 --- /dev/null +++ b/Templates/BaseGame/game/tools/decalEditor/decalEditor.cs @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +/* +function doUtil() +{ + for ( %i = 0; %i < DecalDataSet.getCount(); %i++ ) + { + %obj = DecalDataSet.getObject(%i); + %obj.internalName = %obj.getName(); + DecalPMan.setDirty( %obj ); + } +} +*/ \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/decalEditor/decalEditorActions.cs b/Templates/BaseGame/game/tools/decalEditor/decalEditorActions.cs new file mode 100644 index 000000000..b65fb3000 --- /dev/null +++ b/Templates/BaseGame/game/tools/decalEditor/decalEditorActions.cs @@ -0,0 +1,122 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function DecalEditorGui::createAction(%this, %class, %desc) +{ + pushInstantGroup(); + %action = new UndoScriptAction() + { + class = %class; + superClass = BaseDecalEdAction; + actionName = %desc; + tree = DecalEditorTreeView; + }; + popInstantGroup(); + return %action; +} + +function DecalEditorGui::doAction(%this, %action) +{ + if (%action.doit()) + %action.addToManager(Editor.getUndoManager()); +} + +function BaseDecalEdAction::redo(%this) +{ + // Default redo action is the same as the doit action + %this.doit(); +} + +function BaseDecalEdAction::undo(%this) +{ +} + +//------------------------------------------------------------------------------ +// Edit node +function DecalEditorGui::doEditNodeDetails(%this, %instanceId, %transformData, %gizmo) +{ + %action = %this.createAction(ActionEditNodeDetails, "Edit Decal Transform"); + %action.instanceId = %instanceId; + %action.newTransformData = %transformData; + + if( %gizmo ) + %action.oldTransformData = %this.gizmoDetails; + else + %action.oldTransformData = %this.getDecalTransform(%instanceId); + + %this.doAction(%action); +} + +function ActionEditNodeDetails::doit(%this) +{ + %count = getWordCount(%this.newTransformData); + if(%this.instanceId !$= "" && %count == 7) + { + DecalEditorGui.editDecalDetails( %this.instanceId, %this.newTransformData ); + DecalEditorGui.syncNodeDetails(); + DecalEditorGui.selectDecal( %this.instanceId ); + return true; + } + return false; +} + +function ActionEditNodeDetails::undo(%this) +{ + %count = getWordCount(%this.oldTransformData); + if(%this.instanceId !$= "" && %count == 7) + { + DecalEditorGui.editDecalDetails( %this.instanceId, %this.oldTransformData ); + DecalEditorGui.syncNodeDetails(); + DecalEditorGui.selectDecal( %this.instanceId ); + } +} + +//------------------------------------------------------------------------------ +// Delete Decal Datablocks + +// This functionality solely depends on the undo/redo datablock callbacks in +// source. + +function DecalEditorGui::redoDeleteDecalDatablock( %this, %datablock ) +{ + // Remove the object from file and place a filter + if( %datablock.getFilename() !$= "" ) + { + DecalPMan.removeDirty( %datablock ); + DecalPMan.removeObjectFromFile( %datablock ); + } + + DecalDataList.addFilteredItem( %datablock ); +} + +function DecalEditorGui::undoDeleteDecalDatablock( %this, %datablock ) +{ + // Replace the object in file and remove the filter + %filename = %datablock.getFilename(); + if( %datablock.getFilename() !$= "" ) + { + DecalPMan.setDirty( %datablock, %filename ); + DecalPMan.saveDirty(); + } + + DecalDataList.removeFilteredItem( %datablock ); +} diff --git a/Templates/BaseGame/game/tools/decalEditor/decalEditorGui.cs b/Templates/BaseGame/game/tools/decalEditor/decalEditorGui.cs new file mode 100644 index 000000000..3636b29a1 --- /dev/null +++ b/Templates/BaseGame/game/tools/decalEditor/decalEditorGui.cs @@ -0,0 +1,343 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function DecalEditorGui::onWake( %this ) +{ +} + +function DecalEditorGui::onSelectInstance( %this, %decalId, %lookupName ) +{ + if( DecalEditorGui.selDecalInstanceId == %decalId ) + return; + // Lets remember the new Id + DecalEditorGui.selDecalInstanceId = %decalId; + DecalEditorTreeView.clearSelection(); + + %name = %decalId SPC %lookupName; + %item = DecalEditorTreeView.findItemByName( %name ); + DecalEditorTreeView.selectItem( %item ); + DecalEditorGui.syncNodeDetails(); +} + +function DecalEditorGui::onCreateInstance( %this, %decalId, %lookupName ) +{ + // Lets remember the new Id + DecalEditorGui.selDecalInstanceId = %decalId; + + // Add the new instance to the node tree + DecalEditorTreeView.addNodeTree( %decalId, %lookupName ); + DecalEditorTreeView.clearSelection(); + + %name = %decalId SPC %lookupName; + %item = DecalEditorTreeView.findItemByName( %name ); + DecalEditorTreeView.selectItem( %item ); + DecalEditorGui.syncNodeDetails(); +} + +function DecalEditorGui::onDeleteInstance( %this, %decalId, %lookupName ) +{ + if( %decalId == DecalEditorGui.selDecalInstanceId ) + DecalEditorGui.selDecalInstanceId = -1; + + %id = DecalEditorTreeView.findItemByName( %decalId SPC %lookupName ); + DecalEditorTreeView.removeItem(%id); +} + +function DecalEditorGui::editNodeDetails( %this ) +{ + %decalId = DecalEditorGui.selDecalInstanceId; + if( %decalId == -1 ) + return; + + %nodeDetails = DecalEditorDetailContainer-->nodePosition.getText(); + %nodeDetails = %nodeDetails @ " " @ DecalEditorDetailContainer-->nodeTangent.getText(); + %nodeDetails = %nodeDetails @ " " @ DecalEditorDetailContainer-->nodeSize.getText(); + + if( getWordCount(%nodeDetails) == 7 ) + DecalEditorGui.doEditNodeDetails( %decalId, %nodeDetails, false ); + +} + +// Stores the information when the gizmo is first used +function DecalEditorGui::prepGizmoTransform( %this, %decalId, %nodeDetails ) +{ + DecalEditorGui.gizmoDetails = %nodeDetails; +} + +// Activated in onMouseUp while gizmo is dirty +function DecalEditorGui::completeGizmoTransform( %this, %decalId, %nodeDetails ) +{ + DecalEditorGui.doEditNodeDetails( %decalId, %nodeDetails, true ); +} + +function DecalEditorGui::onSleep( %this ) +{ +} + +function DecalEditorGui::syncNodeDetails( %this ) +{ + %decalId = DecalEditorGui.selDecalInstanceId; + if( %decalId == -1 ) + return; + + %lookupName = DecalEditorGui.getDecalLookupName( %decalId ); + DecalEditorGui.updateInstancePreview( %lookupName.material ); + + DecalEditorDetailContainer-->instanceId.setText(%decalId @ " " @ %lookupName); + %transformData = DecalEditorGui.getDecalTransform(%decalId); + DecalEditorDetailContainer-->nodePosition.setText(getWords(%transformData, 0, 2)); + DecalEditorDetailContainer-->nodeTangent.setText(getWords(%transformData, 3, 5)); + DecalEditorDetailContainer-->nodeSize.setText(getWord(%transformData, 6)); +} + +function DecalEditorGui::paletteSync( %this, %mode ) +{ + %evalShortcut = "ToolsPaletteArray-->" @ %mode @ ".setStateOn(1);"; + eval(%evalShortcut); +} + +function DecalDataList::onSelect( %this, %id, %text ) +{ + %obj = %this.getItemObject( %id ); + DecalEditorGui.currentDecalData = %obj; + + %itemNum = DecalDataList.getSelectedItem(); + if ( %itemNum == -1 ) + return; + + %data = DecalDataList.getItemObject( %itemNum ); + + // Update the materialEditorList + $Tools::materialEditorList = %data.getId(); + + //Canvas.pushDialog( DecalEditDlg ); + DecalInspector.inspect( %data ); + DecalEditorGui.updateDecalPreview( %data.material ); +} + +function RetargetDecalButton::onClick( %this ) +{ + %id = DecalDataList.getSelectedItem(); + %datablock = DecalDataList.getItemText(%id ); + + if( !isObject(%datablock) ) + { + MessageBoxOK("Error", "A valid Decal Template must be selected."); + return; + } + + // This is the first place IODropdown is used. The # in the function passed replaced with the output + // of the preset menu. + + IODropdown("Retarget Decal Instances", + "Retarget DecalInstances from " @ %datablock.getName() @ " over to....", + "decalDataSet", + "DecalEditorGui.retargetDecalDatablock(" @ %datablock.getName() @ ", #);", + ""); + DecalEditorGui.rebuildInstanceTree(); +} + +function NewDecalButton::onClick( %this ) +{ + %name = getUniqueName( "NewDecalData" ); + + %str = "datablock DecalData( " @ %name @ " ) { Material = \"WarningMaterial\"; };"; + eval( %str ); + + DecalPMan.setDirty( %name, $decalDataFile ); + + if ( strchr(LibraryTabControl.text, "*") $= "" ) + LibraryTabControl.text = LibraryTabControl.text @ "*"; + + DecalDataList.doMirror(); + %id = DecalDataList.findItemText( %name ); + DecalDataList.setSelected( %id, true ); + + Canvas.pushDialog( DecalEditDlg ); + DecalInspector.inspect( %name ); +} + +function DeleteDecalButton::onClick( %this ) +{ + + if( DecalEditorTabBook.getSelectedPage() == 0 ) // library + { + %id = DecalDataList.getSelectedItem(); + %datablock = DecalDataList.getItemText(%id ); + + MessageBoxYesNoCancel("Delete Decal Datablock?", + "Are you sure you want to delete

" @ %datablock @ "

Datablock deletion won't take affect until the engine is quit.", + "DecalEditorGui.deleteSelectedDecalDatablock();", + "", + "" ); + } + else // instances + { + DecalEditorGui.deleteSelectedDecal(); + } +} + +// Intended for gui use. The undo/redo functionality for deletion of datablocks +// will enable itself automatically after using this function. +function DecalEditorGui::deleteSelectedDecalDatablock() +{ + %id = DecalDataList.getSelectedItem(); + %datablock = DecalDataList.getItemText(%id ); + + DecalEditorGui.deleteDecalDatablock( %datablock ); + + if( %datablock.getFilename() !$= "" ) + { + DecalPMan.removeDirty( %datablock ); + DecalPMan.removeObjectFromFile( %datablock ); + } + + DecalDataList.addFilteredItem( %datablock ); +} + +function DecalEditorTabBook::onTabSelected( %this, %text, %idx ) +{ + if( %idx == 0) + { + DecalPreviewWindow.text = "Template Properties"; + DecalEditorLibraryProperties.setVisible(true); + DecalEditorTemplateProperties.setVisible(false); + RetargetDecalButton.setVisible( true ); + SaveDecalsButton.setVisible( true ); + NewDecalButton.setVisible( true ); + DeleteDecalButton.tabSelected = %idx; + } + else + { + DecalPreviewWindow.text = "Instance Properties"; + RetargetDecalButton.setVisible( false ); + NewDecalButton.setVisible( false ); + SaveDecalsButton.setVisible( false ); + DeleteDecalButton.tabSelected = %idx; + DecalEditorLibraryProperties.setVisible(false); + DecalEditorTemplateProperties.setVisible(true); + } +} + +function DecalEditorTreeView::onDefineIcons() +{ + %icons = "tools/gui/images/treeview/default:" @ + "tools/classIcons/decal:" @ + "tools/classIcons/decalNode:"; + + DecalEditorTreeView.buildIconTable( %icons ); +} + +function DecalEditorTreeView::onSelect(%this, %id) +{ + %instanceTag = getWord( DecalEditorTreeView.getItemText(%id), 1 ); + if( !isObject( %instanceTag ) ) + return; + + if( %instanceTag.getClassName() !$= "DecalData" ) + return; + + // Grab the id from the tree view + %decalId = getWord( DecalEditorTreeView.getItemText(%id), 0 ); + + if( DecalEditorGui.selDecalInstanceId == %decalId ) + return; + + // Set the curent decalinstances id + DecalEditorGui.selDecalInstanceId = %decalId; + + DecalEditorGui.selectDecal(%decalId); + DecalEditorGui.syncNodeDetails(%id); +} + +// Creating per node in the instance tree +function DecalEditorTreeView::addNodeTree(%this, %nodeName, %parentName) +{ + // If my template isnt there...put it there + if ( %this.findItemByName(%parentName) == 0 ) + { + %rootId = %this.findItemByName(""); + %this.insertItem( %rootId, %parentName, 0, "", 1, 1); + } + + %nodeName = %nodeName SPC %parentName; + %parentId = %this.findItemByName(%parentName); + %id = %this.insertItem(%parentId, %nodeName, 0, "", 2); +} + +function DecalInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + if( %fieldName $= "Material" ) + DecalEditorGui.updateDecalPreview( %newValue ); + + // Same work to do as for the regular WorldEditor Inspector. + Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ); + + if (%oldValue != %newValue || %oldValue !$= %newValue) + %this.setDirty(%object); +} + +function DecalInspector::setDirty( %this, %object ) +{ + DecalPMan.setDirty( %object ); + + if ( strchr(LibraryTabControl.text, "*") $= "" ) + LibraryTabControl.text = LibraryTabControl.text @ "*"; +} + +function DecalInspector::removeDirty() +{ + if ( strchr(LibraryTabControl.text, "*") !$= "" ) + LibraryTabControl.text = stripChars(LibraryTabControl.text, "*"); +} + +function DecalEditorGui::updateDecalPreview( %this, %material ) +{ + if( isObject( %material ) ) + DecalPreviewWindow-->decalPreview.setBitmap( MaterialEditorGui.searchForTexture( %material.getId(), %material.diffuseMap[0]) ); + else + DecalPreviewWindow-->decalPreview.setBitmap("tools/materialEditor/gui/unknownImage"); +} + +function DecalEditorGui::updateInstancePreview( %this, %material ) +{ + if( isObject( %material ) ) + DecalPreviewWindow-->instancePreview.setBitmap( MaterialEditorGui.searchForTexture( %material.getId(), %material.diffuseMap[0]) ); + else + DecalPreviewWindow-->instancePreview.setBitmap("tools/materialEditor/gui/unknownImage"); +} + +function DecalEditorGui::rebuildInstanceTree( %this ) +{ + // Initialize the instance tree when the tab is selected + DecalEditorTreeView.removeItem(0); + %rootId = DecalEditorTreeView.insertItem(0, "", 0, ""); + %count = DecalEditorGui.getDecalCount(); + for (%i = 0; %i < %count; %i++) + { + %name = DecalEditorGui.getDecalLookupName(%i); + if( %name $= "invalid" ) + continue; + + DecalEditorTreeView.addNodeTree(%i, %name); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/decalEditor/decalEditorGui.gui b/Templates/BaseGame/game/tools/decalEditor/decalEditorGui.gui new file mode 100644 index 000000000..919291d2c --- /dev/null +++ b/Templates/BaseGame/game/tools/decalEditor/decalEditorGui.gui @@ -0,0 +1,831 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiDecalEditorCtrl(DecalEditorGui) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "WorldEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "255 0 0 120"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + currentDecalID = "175"; + Docking = "None"; + + new GuiWindowCollapseCtrl(DecalEditorWindow) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 SPC getWord(EditorGuiToolbar.extent, 1) -1; + Extent = "210 600"; + MinExtent = "210 100"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "2 2 2 2"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EditorGui.setEditor( WorldEditorInspectorPlugin );"; + EdgeSnap = "1"; + text = "Decal Editor"; + + new GuiTabBookCtrl(DecalEditorTabBook) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 502"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "3 1 3 3"; + Docking = "client"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "0"; + MinTabWidth = "64"; + + new GuiTabPageCtrl(LibraryTabControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiEditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 483"; + Docking = "client"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "-1 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Library"; + maxLength = "1024"; + + new GuiContainer() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 483"; + Margin = "0 0 0 0"; + Docking = "client"; + MinExtent = "0 8"; + Profile = "GuiInspectorProfile"; + + new GuiBitmapBorderCtrl() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 483"; + MinExtent = "0 -500"; + Profile = "ToolsGuiTabBorderProfile"; + }; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 483"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiDefaultProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiListBoxCtrl(DecalDataList) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiListBoxProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "474 48"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + AllowMultipleSelections = "0"; + fitParentWidth = "0"; + mirrorSet = "DecalDataSet"; + }; + }; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + internalName = "instanceTab"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiEditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 483"; + Docking = "client"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "-1 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Instances"; + maxLength = "1024"; + + new GuiContainer() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 483"; + Margin = "0 0 0 0"; + Docking = "client"; + MinExtent = "0 8"; + Profile = "GuiInspectorProfile"; + + new GuiBitmapBorderCtrl() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 483"; + MinExtent = "0 -500"; + Profile = "ToolsGuiTabBorderProfile"; + }; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 483"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiTreeViewCtrl(DecalEditorTreeView) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "200 100"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "0"; + internalNamesOnly = "0"; + }; + }; + }; + }; + // Save Button + new GuiBitmapButtonCtrl(SaveDecalsButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "137 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "DecalPMan.saveDirty(); DecalInspector::removeDirty();"; + hovertime = "1000"; + groupNum = "-1"; + text =""; + tooltip = "Save All"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/save-icon"; + }; + + new GuiBitmapButtonCtrl(RetargetDecalButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "157 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Retarget missing decals to an existing decal datablock"; + bitmap = "tools/gui/images/retarget-btn"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(NewDecalButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "177 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Create New Decal Template"; + bitmap = "tools/gui/images/new"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(DeleteDecalButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "190 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = ""; + tooltip = "Delete Selected Decal Template"; + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + tabSelected = "0"; + }; + }; + + + new GuiWindowCollapseCtrl(DecalPreviewWindow) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 SPC getWord(EditorGuiToolbar.extent, 1) + getWord(DecalEditorWindow.extent, 1) - 2; + Extent = "210 335"; + MinExtent = "210 335"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "152 235"; + closeCommand = "EPainter.parentGroup.setVisible(false);"; + EdgeSnap = "1"; + text = "Decal Properties"; + + new GuiScrollCtrl(DecalEditorTemplateProperties){ + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + VertSizing = "bottom"; + HorizSizing = "width"; + Position = "4 24"; + Extent = "202 259"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + willFirstRespond = "1"; + Docking = "client"; + Margin = "3 1 3 3"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "189 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "208 0"; + Caption = "Decal Instance Preview"; + Margin = "0 0 0 -3"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "-1 0"; + Extent = "202 187"; + Docking = "none"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "instancePreview"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "height"; + Position = "0 0"; + Extent = "188 186"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + wrap = "0"; + bitmap= "tools/materialeditor/gui/unknownImage"; + }; + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "height"; + Position = "0 0"; + Extent = "188 186"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/terrainpainter/terrain-painter-border-large"; + wrap = "0"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "202 0"; + Caption = "Decal Instance Properties"; + Margin = "0 0 0 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(DecalEditorDetailContainer){ + Position = "0 202"; + Extent = "202 79"; + HorizSizing = "width"; + VertSizing = "bottom"; + isContainer = "1"; + + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "3 2"; + Extent = "47 16"; + text = "Instance"; + }; + new GuiTextCtrl(){ // instance Name + Profile = "ToolsGuiTextProfile"; + internalName = "instanceId"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "54 2"; + Extent = "128 18"; + text = ""; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "3 21"; + Extent = "47 16"; + text = "Translate"; + }; + new GuiTextEditCtrl(){ // instance translate + Profile = "ToolsGuiTextEditProfile"; + internalName = "nodePosition"; + HorizSizing = "width"; + VertSizing = "bottom"; + AltCommand = "DecalEditorGui.editNodeDetails();"; + Position = "54 20"; + Extent = "128 18"; + text = ""; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "3 41"; + Extent = "47 16"; + text = "Tangent"; + }; + new GuiTextEditCtrl(){ // instance rotation + Profile = "ToolsGuiTextEditProfile"; + internalName = "nodeTangent"; + HorizSizing = "width"; + VertSizing = "bottom"; + AltCommand = "DecalEditorGui.editNodeDetails();"; + Position = "54 40"; + Extent = "128 18"; + text = ""; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "3 61"; + Extent = "47 16"; + text = "Size"; + }; + new GuiTextEditCtrl(){ // instance scale + Profile = "ToolsGuiTextEditProfile"; + internalName = "nodeSize"; + HorizSizing = "width"; + VertSizing = "bottom"; + AltCommand = "DecalEditorGui.editNodeDetails();"; + Position = "54 60"; + Extent = "128 18"; + text = ""; + }; + }; + }; + }; + }; + }; + + new GuiScrollCtrl(DecalEditorLibraryProperties) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + VertSizing = "bottom"; + HorizSizing = "width"; + Position = "4 24"; + Extent = "202 259"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + willFirstRespond = "1"; + Docking = "client"; + Margin = "3 1 3 3"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "187 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "208 0"; + Caption = "Decal Template Preview"; + Margin = "0 0 0 -3"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "-1 0"; + Extent = "202 187"; + Docking = "none"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "decalPreview"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "height"; + Position = "0 0"; + Extent = "188 186"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + wrap = "0"; + bitmap= "tools/materialeditor/gui/unknownImage"; + }; + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "height"; + Position = "0 0"; + Extent = "188 186"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/terrainpainter/terrain-painter-border-large"; + wrap = "0"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "202 0"; + Caption = "Decal Template Properties"; + Margin = "0 0 0 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiInspector(DecalInspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "200 257"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + groupFilters = "+General,+SimBase,+Decal,+Rendering,+Texturing"; + + }; + }; + }; + }; + //---------------------------------- + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/decalEditor/main.cs b/Templates/BaseGame/game/tools/decalEditor/main.cs new file mode 100644 index 000000000..06dd96f81 --- /dev/null +++ b/Templates/BaseGame/game/tools/decalEditor/main.cs @@ -0,0 +1,199 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function initializeDecalEditor() +{ + echo(" % - Initializing Decal Editor"); + + $decalDataFile = "art/decals/managedDecalData.cs"; + + exec( "./decalEditor.cs" ); + exec( "./decalEditorGui.gui" ); + exec( "./decalEditorGui.cs" ); + exec( "./decalEditorActions.cs" ); + + // Add ourselves to EditorGui, where all the other tools reside + DecalEditorGui.setVisible( false ); + DecalPreviewWindow.setVisible( false ); + DecalEditorWindow.setVisible( false ); + EditorGui.add( DecalEditorGui ); + EditorGui.add( DecalEditorWindow ); + EditorGui.add( DecalPreviewWindow ); + DecalEditorTabBook.selectPage( 0 ); + + new ScriptObject( DecalEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = DecalEditorGui; + }; + + %map = new ActionMap(); + %map.bindCmd( keyboard, "5", "EDecalEditorAddDecalBtn.performClick();", "" ); + %map.bindCmd( keyboard, "1", "EDecalEditorSelectDecalBtn.performClick();", "" ); + %map.bindCmd( keyboard, "2", "EDecalEditorMoveDecalBtn.performClick();", "" ); + %map.bindCmd( keyboard, "3", "EDecalEditorRotateDecalBtn.performClick();", "" ); + %map.bindCmd( keyboard, "4", "EDecalEditorScaleDecalBtn.performClick();", "" ); + + DecalEditorPlugin.map = %map; + + new PersistenceManager( DecalPMan ); + +} + +function destroyDecalEditor() +{ +} + +// JCF: helper for during development +function reinitDecalEditor() +{ + exec( "./main.cs" ); + exec( "./decalEditor.cs" ); + exec( "./decalEditorGui.cs" ); +} + +function DecalEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Decal Editor", "", DecalEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Decal Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "DecalEditorPlugin", "DecalEditorPalette", expandFilename("tools/decalEditor/decal-editor"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( DecalPreviewWindow, DecalEditorWindow ); + + //set initial palette setting + %this.paletteSelection = "AddDecalMode"; +} + +function DecalEditorPlugin::onActivated( %this ) +{ + EditorGui.bringToFront( DecalEditorGui ); + DecalEditorGui.setVisible( true ); + DecalEditorGui.makeFirstResponder( true ); + DecalPreviewWindow.setVisible( true ); + DecalEditorWindow.setVisible( true ); + + %this.map.push(); + + //WORKAROUND: due to the gizmo mode being stored on its profile (which may be shared), + // we may end up with a mismatch between the editor mode and gizmo mode here. + // Reset mode explicitly here to work around this. + DecalEditorGui.setMode( DecalEditorGui.getMode() ); + + // Set the current palette selection + DecalEditorGui.paletteSync( %this.paletteSelection ); + + // Store this on a dynamic field + // in order to restore whatever setting + // the user had before. + %this.prevGizmoAlignment = GlobalGizmoProfile.alignment; + + // The DecalEditor always uses Object alignment. + GlobalGizmoProfile.alignment = "Object"; + + DecalEditorGui.rebuildInstanceTree(); + + // These could perhaps be the node details like the shape editor + //ShapeEdPropWindow.syncNodeDetails(-1); + + Parent::onActivated(%this); +} + +function DecalEditorPlugin::onDeactivated( %this ) +{ + DecalEditorGui.setVisible(false); + DecalPreviewWindow.setVisible( false ); + DecalEditorWindow.setVisible( false ); + + %this.map.pop(); + + // Remember last palette selection + %this.paletteSelection = DecalEditorGui.getMode(); + + // Restore the previous Gizmo + // alignment settings. + GlobalGizmoProfile.alignment = %this.prevGizmoAlignment; + + Parent::onDeactivated(%this); +} + +function DecalEditorPlugin::isDirty( %this ) +{ + %dirty = DecalPMan.hasDirty(); + + %dirty |= decalManagerDirty(); + + return %dirty; +} + +function DecalEditorPlugin::onSaveMission( %this, %file ) +{ + DecalPMan.saveDirty(); + decalManagerSave( %file @ ".decals" ); +} + +function DecalEditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %hasSelection = false; + + if ( DecalEditorGui.getSelectionCount() > 0 ) + %hasSelection = true; + + %editMenu.enableItem( 3, false ); // Cut + %editMenu.enableItem( 4, false ); // Copy + %editMenu.enableItem( 5, false ); // Paste + %editMenu.enableItem( 6, %hasSelection ); // Delete + %editMenu.enableItem( 8, false ); // Deselect + + // NOTE: If you want to implement Cut, Copy, Paste, or Deselect + // for this editor simply enable the menu items when it is appropriate + // and fill in the method stubs below. +} + +function DecalEditorPlugin::handleDelete( %this ) +{ + DecalEditorGui.deleteSelectedDecal(); +} + +function DecalEditorPlugin::handleDeselect( %this ) +{ +} + +function DecalEditorPlugin::handleCut( %this ) +{ +} + +function DecalEditorPlugin::handleCopy( %this ) +{ +} + +function DecalEditorPlugin::handlePaste( %this ) +{ +} + +function DecalEditorPlugin::handleEscape( %this ) +{ +} + diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/button.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/button.png new file mode 100644 index 000000000..e255cb911 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/button.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/button_left.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/button_left.png new file mode 100644 index 000000000..3f7238fbf Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/button_left.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/button_middle.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/button_middle.png new file mode 100644 index 000000000..263e4bcc2 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/button_middle.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/button_right.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/button_right.png new file mode 100644 index 000000000..40ff128f1 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/button_right.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/button_toolbar.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/button_toolbar.png new file mode 100644 index 000000000..3de3b1519 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/button_toolbar.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/dropDown.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/dropDown.png new file mode 100644 index 000000000..795b0e575 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/dropDown.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/form.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/form.png new file mode 100644 index 000000000..cc0d39841 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/form.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/formMenu.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/formMenu.png new file mode 100644 index 000000000..110adef3e Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/formMenu.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/iconAccept.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/iconAccept.png new file mode 100644 index 000000000..a24d6052d Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/iconAccept.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/iconCancel.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/iconCancel.png new file mode 100644 index 000000000..744df795a Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/iconCancel.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/iconInformation.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/iconInformation.png new file mode 100644 index 000000000..a7e472232 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/iconInformation.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/iconNext.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/iconNext.png new file mode 100644 index 000000000..42eb8363b Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/iconNext.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/iconPrevious.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/iconPrevious.png new file mode 100644 index 000000000..6f197a442 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/iconPrevious.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/iconRSSNews.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/iconRSSNews.png new file mode 100644 index 000000000..feee9c056 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/iconRSSNews.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/iconSave.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/iconSave.png new file mode 100644 index 000000000..50e70bd70 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/iconSave.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/panel_button.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/panel_button.png new file mode 100644 index 000000000..6b945688a Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/panel_button.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/panel_dark.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/panel_dark.png new file mode 100644 index 000000000..8ba559c7b Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/panel_dark.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/panel_light.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/panel_light.png new file mode 100644 index 000000000..87372edab Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/panel_light.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/panel_medium.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/panel_medium.png new file mode 100644 index 000000000..23e63ebe6 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/panel_medium.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout.png new file mode 100644 index 000000000..082051e86 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout_dark.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout_dark.png new file mode 100644 index 000000000..0af73e3b4 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout_dark.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout_plusminus_header.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout_plusminus_header.png new file mode 100644 index 000000000..899491473 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout_plusminus_header.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout_plusminus_transparent.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout_plusminus_transparent.png new file mode 100644 index 000000000..312e30455 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout_plusminus_transparent.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout_thin.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout_thin.png new file mode 100644 index 000000000..6c4903668 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout_thin.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout_thin_light.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout_thin_light.png new file mode 100644 index 000000000..37a86b845 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/rollout_thin_light.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/scroll.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/scroll.png new file mode 100644 index 000000000..252200f93 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/scroll.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/slider.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/slider.png new file mode 100644 index 000000000..d13b9372d Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/slider.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/background.jpg b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/background.jpg new file mode 100644 index 000000000..5fee24333 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/background.jpg differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/create.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/create.png new file mode 100644 index 000000000..c3f868412 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/create.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/create_d.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/create_d.png new file mode 100644 index 000000000..35156129c Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/create_d.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/create_h.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/create_h.png new file mode 100644 index 000000000..d8c0ccd5c Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/create_h.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/create_i.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/create_i.png new file mode 100644 index 000000000..5c21094d9 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/create_i.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/import.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/import.png new file mode 100644 index 000000000..b1f2448de Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/import.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/import_d.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/import_d.png new file mode 100644 index 000000000..4b30cd1b5 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/import_d.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/import_h.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/import_h.png new file mode 100644 index 000000000..a5396d101 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/import_h.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/import_i.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/import_i.png new file mode 100644 index 000000000..fae4e774a Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/import_i.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/navPanel.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/navPanel.png new file mode 100644 index 000000000..2d1493b59 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/navPanel.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/open.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/open.png new file mode 100644 index 000000000..1af53606b Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/open.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/open_d.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/open_d.png new file mode 100644 index 000000000..d83907bfd Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/open_d.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/open_h.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/open_h.png new file mode 100644 index 000000000..13938ae28 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/open_h.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/open_i.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/open_i.png new file mode 100644 index 000000000..1775c78e9 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/open_i.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/splash.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/splash.png new file mode 100644 index 000000000..b988c35c3 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/splash.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/topBarLeft.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/topBarLeft.png new file mode 100644 index 000000000..206b6b0c6 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/topBarLeft.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/topBarMiddle.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/topBarMiddle.png new file mode 100644 index 000000000..c5332c092 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/topBarMiddle.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/start/topBarRight.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/topBarRight.png new file mode 100644 index 000000000..4ea1bc2a5 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/start/topBarRight.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/tabBook.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/tabBook.png new file mode 100644 index 000000000..c931238ce Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/tabBook.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/textEdit.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/textEdit.png new file mode 100644 index 000000000..1b601b2d6 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/textEdit.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/toolWindow.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/toolWindow.png new file mode 100644 index 000000000..5b3b89188 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/toolWindow.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/toolbar.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/toolbar.png new file mode 100644 index 000000000..1a2dde5f2 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/toolbar.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/treeView.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/treeView.png new file mode 100644 index 000000000..ae42402f1 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/treeView.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/images/window.png b/Templates/BaseGame/game/tools/editorClasses/gui/images/window.png new file mode 100644 index 000000000..a6db64820 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/images/window.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/editor-menubar.png b/Templates/BaseGame/game/tools/editorClasses/gui/panels/editor-menubar.png new file mode 100644 index 000000000..247aabcea Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/panels/editor-menubar.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/icon-dropdownbar.png b/Templates/BaseGame/game/tools/editorClasses/gui/panels/icon-dropdownbar.png new file mode 100644 index 000000000..bbde0016d Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/panels/icon-dropdownbar.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/inspector-style-rollout-dark.png b/Templates/BaseGame/game/tools/editorClasses/gui/panels/inspector-style-rollout-dark.png new file mode 100644 index 000000000..e62442ed8 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/panels/inspector-style-rollout-dark.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/inspector-style-rollout-list.png b/Templates/BaseGame/game/tools/editorClasses/gui/panels/inspector-style-rollout-list.png new file mode 100644 index 000000000..c97c2af67 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/panels/inspector-style-rollout-list.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/inspector-style-rollout-noheader.png b/Templates/BaseGame/game/tools/editorClasses/gui/panels/inspector-style-rollout-noheader.png new file mode 100644 index 000000000..f78dd71f4 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/panels/inspector-style-rollout-noheader.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/inspector-style-rollout.png b/Templates/BaseGame/game/tools/editorClasses/gui/panels/inspector-style-rollout.png new file mode 100644 index 000000000..39d35e326 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/panels/inspector-style-rollout.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/inspector-style-rollout_inner.png b/Templates/BaseGame/game/tools/editorClasses/gui/panels/inspector-style-rollout_inner.png new file mode 100644 index 000000000..a472dff4f Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/panels/inspector-style-rollout_inner.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/menu-fullborder.png b/Templates/BaseGame/game/tools/editorClasses/gui/panels/menu-fullborder.png new file mode 100644 index 000000000..f85b7dc11 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/panels/menu-fullborder.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/menubar.png b/Templates/BaseGame/game/tools/editorClasses/gui/panels/menubar.png new file mode 100644 index 000000000..353451a27 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/panels/menubar.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel.png b/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel.png new file mode 100644 index 000000000..f1098d895 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanelProfiles.ed.cs b/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanelProfiles.ed.cs new file mode 100644 index 000000000..ca03e2b60 --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanelProfiles.ed.cs @@ -0,0 +1,111 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +singleton GuiControlProfile (NavPanelProfile) +{ + opaque = false; + border = -2; + category = "Editor"; +}; + + +singleton GuiControlProfile (NavPanel : NavPanelProfile) +{ + bitmap = "./navPanel"; + category = "Editor"; +}; + +singleton GuiControlProfile (NavPanelBlue : NavPanelProfile) +{ + bitmap = "./navPanel_blue"; + category = "Editor"; +}; + +singleton GuiControlProfile (NavPanelGreen : NavPanelProfile) +{ + bitmap = "./navPanel_green"; + category = "Editor"; +}; + +singleton GuiControlProfile (NavPanelRed : NavPanelProfile) +{ + bitmap = "./navPanel_red"; + category = "Editor"; +}; + +singleton GuiControlProfile (NavPanelWhite : NavPanelProfile) +{ + bitmap = "./navPanel_white"; + category = "Editor"; +}; + +singleton GuiControlProfile (NavPanelYellow : NavPanelProfile) +{ + bitmap = "./navPanel_yellow"; + category = "Editor"; +}; +singleton GuiControlProfile (menubarProfile : NavPanelProfile) +{ + bitmap = "./menubar"; + category = "Editor"; +}; +singleton GuiControlProfile (editorMenubarProfile : NavPanelProfile) +{ + bitmap = "./editor-menubar"; + category = "Editor"; +}; +singleton GuiControlProfile (editorMenu_wBorderProfile : NavPanelProfile) +{ + bitmap = "./menu-fullborder"; + category = "Editor"; +}; +singleton GuiControlProfile (inspectorStyleRolloutProfile : NavPanelProfile) +{ + bitmap = "./inspector-style-rollout"; + category = "Editor"; +}; +singleton GuiControlProfile (inspectorStyleRolloutListProfile : NavPanelProfile) +{ + bitmap = "./inspector-style-rollout-list"; + category = "Editor"; +}; +singleton GuiControlProfile (inspectorStyleRolloutDarkProfile : NavPanelProfile) +{ + bitmap = "./inspector-style-rollout-dark"; + category = "Editor"; +}; +singleton GuiControlProfile (inspectorStyleRolloutInnerProfile : NavPanelProfile) +{ + bitmap = "./inspector-style-rollout_inner"; + category = "Editor"; +}; +singleton GuiControlProfile (inspectorStyleRolloutNoHeaderProfile : NavPanelProfile) +{ + bitmap = "./inspector-style-rollout-noheader"; + category = "Editor"; +}; +singleton GuiControlProfile (IconDropdownProfile : NavPanelProfile) +{ + bitmap = "./icon-dropdownbar"; + category = "Editor"; +}; diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel_blue.png b/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel_blue.png new file mode 100644 index 000000000..435e607fa Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel_blue.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel_green.png b/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel_green.png new file mode 100644 index 000000000..30324742d Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel_green.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel_red.png b/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel_red.png new file mode 100644 index 000000000..5cf1b0968 Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel_red.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel_white.png b/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel_white.png new file mode 100644 index 000000000..bcbeac17a Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel_white.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel_yellow.png b/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel_yellow.png new file mode 100644 index 000000000..269d15abd Binary files /dev/null and b/Templates/BaseGame/game/tools/editorClasses/gui/panels/navPanel_yellow.png differ diff --git a/Templates/BaseGame/game/tools/editorClasses/main.cs b/Templates/BaseGame/game/tools/editorClasses/main.cs new file mode 100644 index 000000000..7ebad5d4c --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/main.cs @@ -0,0 +1,86 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function initializeEditorClasses() +{ + echo(" % - Initializing Tools Base"); + + + $EditorClassesGroup = "EditorClassesCleanup"; + if( !isObject( $EditorClassesGroup ) ) + new SimGroup( $EditorClassesGroup ); + + + //----------------------------------------------------------------------------- + // Load Editor Profiles + //----------------------------------------------------------------------------- + + exec("./scripts/fileLoader.ed.cs"); + + loadDirectory( expandFilename("./gui/panels") ); + + + //----------------------------------------------------------------------------- + // Setup Preferences Manager + //----------------------------------------------------------------------------- + + exec("./scripts/preferencesManager.ed.cs"); + initPreferencesManager(); + + //----------------------------------------------------------------------------- + // Load Form Managers + //----------------------------------------------------------------------------- + + exec("./scripts/guiFormLibraryManager.ed.cs"); + exec("./scripts/guiFormContentManager.ed.cs"); + exec("./scripts/guiFormReferenceManager.ed.cs"); + exec("./scripts/guiFormLayoutManager.ed.cs"); + exec("./scripts/guiFormMessageManager.ed.cs"); + exec("./scripts/expandos.ed.cs"); + exec("./scripts/utility.ed.cs"); + setupBaseExpandos(); + + // User Display + exec("./scripts/contextPopup.ed.cs"); + + // Project Support + exec("./scripts/projects/projectEvents.ed.cs"); + exec("./scripts/projects/projectInternalInterface.ed.cs"); + + // Input + exec("./scripts/input/inputEvents.ed.cs"); + exec("./scripts/input/dragDropEvents.ed.cs"); + exec("./scripts/input/applicationEvents.ed.cs"); + + // Form Class + exec("./scripts/guiFormClass.ed.cs"); + exec("./scripts/guiClasses/guiThumbnailPopup.ed.cs"); + exec("./scripts/guiClasses/guiThumbnail.ed.cs"); + exec("./scripts/RSSNews/RSSFeedScript.ed.cs"); + + loadDirectory( expandFilename("./scripts/core") ); + loadDirectory( expandFilename("./scripts/platform") ); +} + +function destroyEditorClasses() +{ +} diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/RSSNews/RSSFeedScript.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/RSSNews/RSSFeedScript.ed.cs new file mode 100644 index 000000000..b61109efb --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/RSSNews/RSSFeedScript.ed.cs @@ -0,0 +1,155 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// RSS ticker configuration: +$RSSFeed::serverName = "feeds.garagegames.com"; +$RSSFeed::serverPort = 80; +$RSSFeed::serverURL = "/product/tgea"; +$RSSFeed::userAgent = "TorqueGameEngineAdvances/1.1"; +$RSSFeed::maxNewHeadlines = 10; + +// Load up the helper objects +exec( "./RSSStructs.ed.cs" ); + +function RSSFeedObject::onConnected(%this) +{ + //echo("RSS Feed"); + //echo(" - Requesting RSS data at URL: " @ $RSSFeed::serverURL ); + + // Reset some useful state information. + $RSSFeed::lineCount = 0; + $RSSFeed::requestResults = ""; + + // Load the cache here... + $RSSFeed::rssCache = 0; + + // Request our RSS. + %this.send("GET " @ $RSSFeed::serverURL @ " HTTP/1.0\nHost: " @ $RSSFeed::serverName @ "\nUser-Agent: " @ $RSSFeed::userAgent @ "\n\r\n\r\n"); +} + +function RSSFeedObject::onLine(%this, %line) +{ + // Collate info. + $RSSFeed::lineCount++; + $RSSFeed::requestResults = $RSSFeed::requestResults @ %line; +} + +function RSSFeedObject::getTagContents(%this, %string, %tag, %startChar) +{ + // This function occasionally makes Torque hard crash. It doesn't + // seem to do it anymore but be careful! + + // Ok, get thing between <%tag> and after char # + // %startChar in the passed string. + + %startTag = "<" @ %tag @ ">"; + %endTag = ""; + + %startTagOffset = strpos(%string, %startTag, %startChar); + + // Compensate for presence of start tag. + %startOffset = %startTagOffset + strlen(%startTag); + + // Ok, now look for end tag. + %endTagOffset = strpos(%string, %endTag, %startOffset - 1); + + // If we didn't find it, bail. + if(%endTagOffset < 0) + return ""; + + // Evil hack - store last found item in a global. + %this.lastOffset = %endTagOffset; + + // And get & return the substring between the tags. + %result = getSubStr(%string, %startOffset, %endTagOffset - %startOffset); + + // Do a little mojo to deal with " and some other htmlentities. + %result = strreplace(%result, """, "\""); + %result = strreplace(%result, "&", "&"); + + return %result; +} + +function RSSFeedObject::onDisconnect(%this) +{ + // Create collection and load cache. + %ret = constructRSSHeadlineCollection(); + %ret.loadFromFile( "RSSCache.cs" ); + + // Ok, we have a full buffer now, hopefully. Let's process it. + //echo(" - Got " @ $RSSFeed::lineCount @ " lines."); + + // We want the feed title and the first three headlines + links. + + // Feed title - get the first occurence in the string. + %title = %this.getTagContents($RSSFeed::requestResults, "title", 0); + %titleLink = %this.getTagContents($RSSFeed::requestResults, "link", 0); + + //echo(" - Feed title: '" @ %title @ "'"); + //echo(" - Feed link: '" @ %titleLink @ "'"); + + %newItems = ""; + + // Ok, get the first headlines, if any... + for( %i = 0; %i < $RSSFeed::maxNewHeadlines; %i++ ) + { + %headline[%i] = %this.getTagContents($RSSFeed::requestResults, "title", %this.lastOffset); + %headlineLink[%i] = %this.getTagContents($RSSFeed::requestResults, "link", %this.lastOffset); + + // Skip the content - it's not going to do anything but confuse us. + %garbage = %this.getTagContents($RSSFeed::requestResults, "content:encoded", %this.lastOffset); + %isNew = %ret.addHeadline( constructRSSHeadline( %headline[%i], %headlineLink[%i] ) ); + + if( %isNew ) + { + %newItems = true; + //echo(" - Headline #" @ %i @ " : '" @ %headline[%i] @ "'"); + //echo(" - Headline Link #" @ %i @ " : '" @ %headlineLink[%i] @ "'"); + } + } + + if( %this._callback !$= "" ) + { + %params = %ret; + + if( %newItems ) + %params = %params @ ", \"" @ %newItems @ "\""; + + eval( %this._callback @ "(" @ %params @ ");" ); + } + + %ret.writeToFile( "RSSCache.cs", false ); +} + +function RSSUpdate::initialize( %callback ) +{ + new TCPObject(RSSFeedObject); + RSSFeedObject._callback = %callback; + + RSSFeedObject.connect( $RSSFeed::serverName @ ":" @ $RSSFeed::serverPort ); +} + +function RSSUpdate::destroy() +{ + if(isObject(RSSFeedObject)) + RSSFeedObject.delete(); +} diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/RSSNews/RSSStructs.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/RSSNews/RSSStructs.ed.cs new file mode 100644 index 000000000..dbb55af72 --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/RSSNews/RSSStructs.ed.cs @@ -0,0 +1,153 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// RSS Feed integration structures +// I apologize in advance if this RSS reader is too restrictive with regard +// to tags/enclosures. I may revisit it at some point to add support + +//------------------------------------------------------------------------------ +// RSS Headline Item +//------------------------------------------------------------------------------ +function constructRSSHeadline( %headline, %link ) +{ + %ret = new ScriptObject() + { + class = "RSSHeadline"; + _headline = %headline; + _link = %link; + }; + + return %ret; +} + +function RSSHeadline::getHeadline( %this ) +{ + return %this._headline; +} + +function RSSHeadline::getLink( %this ) +{ + return %this._link; +} + +function RSSHeadline::sameAs( %this, %headline ) +{ + return ( strcmp( %this.toString(), %headline.toString() ) == 0 ); +} + +function RSSHeadline::toString( %this ) +{ + return %this.getHeadline() @ " ( " @ %this.getLink() @ " ) "; +} + +//------------------------------------------------------------------------------ + +function constructRSSHeadlineCollection() +{ + %ret = new ScriptObject() + { + class = "RSSHeadlineCollection"; + }; + + // Create sim group for it + %ret._simGroup = new SimGroup(); + + return %ret; +} + +function RSSHeadlineCollection::getObject( %this, %index ) +{ + %ret = %this._simGroup.getObject( %index ); + + if( !isObject( %ret ) ) + { + warn( "No such index in headline collection." ); + return -1; + } + + return %ret; +} + +function RSSHeadlineCollection::getCount( %this ) +{ + return %this._simGroup.getCount(); +} + +function RSSHeadlineCollection::addHeadline( %this, %headline, %skipReorder ) +{ + for( %i = 0; %i < %this.getCount(); %i++ ) + { + %obj = %this.getObject( %i ); + + if( %obj.sameAs( %headline ) ) + { + //echo( "cache hit headline: " @ %headline.toString() ); + return false; + } + } + + %this._simGroup.add( %headline ); + + if( !%skipReorder ) + %this._simGroup.bringToFront( %headline ); + + //echo( "adding headline: " @ %headline.toString() ); + + return true; +} + +function RSSHeadlineCollection::writeToFile( %this, %file ) +{ + $rssHeadlineCollection::count = %this.getCount(); + + for( %i = 0; %i < %this.getCount(); %i++ ) + { + %hdl = %this.getObject( %i ); + $rssHeadlineCollection::headline[%i] = %hdl.getHeadline(); + $rssHeadlineCollection::link[%i] = %hdl.getLink(); + } + + export( "$rssHeadlineCollection::*", %file, false ); +} + +function RSSHeadlineCollection::loadFromFile( %this, %file ) +{ + %this._simGroup.clear(); + + $rssHeadlineCollection::count = 0; + + %file = getPrefsPath(%file); + if (isFile(%file) || isFile(%file @ ".dso")) + exec( %file ); + + for( %i = 0; %i < $rssHeadlineCollection::count; %i++ ) + { + //echo( "[LD: " @ %i @ "] Headline: " @ $rssHeadlineCollection::headline[%i] ); + //echo( "[LD: " @ %i @ "] Link: " @ $rssHeadlineCollection::link[%i] ); + + %hdl = constructRSSHeadline( $rssHeadlineCollection::headline[%i], + $rssHeadlineCollection::link[%i] ); + + // This does negate the cache check, but that is ok -pw + %this.addHeadline( %hdl, true ); + } +} diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/contextPopup.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/contextPopup.ed.cs new file mode 100644 index 000000000..a3e49daf7 --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/contextPopup.ed.cs @@ -0,0 +1,210 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +/// @class ContextPopup +/// @brief Create a Popup Dialog that closes itself when signaled by an event. +/// +/// ContextPopup is a support class that offers a simple way of displaying +/// reusable context sensitive GuiControl popups. These dialogs are created +/// and shown to the user when the <b>show</b> method is used. +/// +/// Once a Popup is shown it will be dismissed if it meets one of a few +/// criteria. +/// +/// 1. A user clicks anywhere outside the bounds of the GuiControl, specified by +/// the 'dialog' field on the object. +/// 2. Time Passes of (n)Milliseconds, specifed by the 'timeout' field on +/// the object. +/// +/// For example, if you wished to create a context dialog with a dialog you held in +/// a local variable named %myDialog you would create a new script object as such. +/// +/// +/// @code +/// %MyContextPopup = new ScriptObject() +/// { +/// class = ContextPopup; +/// superClass= MyCallbackNamespace; // Only Necessary when you want to perform logic pre/post showing +/// dialog = %%myDialog.getID(); +/// delay = 500; // Pop the Popup after 500 Milliseconds +/// }; +/// @endcode +/// +/// Now, if you wanted to show the dialog %%myDialog and have it dismissed when anything in the +/// background is clicked, simply call the following. +/// +/// +/// @code +/// %MyContextPopup.show( %positionX, %positionY ); +/// @endcode +/// +/// If you need to know more than show the dialog and hide it when clicked or time passes, ContextPopup +/// Provides callback methods that you may override for doing intermediate processing on a dialog +/// that is to be shown or is being hidden. For example, in the above script we created a Context Dialog Container +/// called @%myContextDialog with a superClass of <b>MyCallbackNamespace</b>. If we wanted to hide the cursor when +/// the dialog was shown, and show it when the dialog was hidden, we could implement the following functions. +/// +/// @code +/// function MyCallbackNamespace::onContextActivate( %%this ) +/// { +/// // Hide Cursor Here +/// } +/// function MyCallbackNamespace::onContextDeactivate( %%this ) +/// { +/// // Show Cursor Here +/// } +/// @endcode +/// +/// @field GuiControl Dialog The GuiControl dialog to be shown when the context dialog is activated + +function ContextDialogContainer::onAdd(%this) +{ + // Add to our cleanup group. + $EditorClassesGroup.add( %this ); + + %this.base = new GuiButtonBaseCtrl() + { + profile = ToolsGuiTransparentProfile; + class = ContextDialogWatcher; + parent = %this; + modal = true; + }; + + // Flag not active. + %this.isPushed = false; + + // Add to our cleanup group. + $EditorClassesGroup.add( %this.base ); + + return true; + +} + +function ContextDialogContainer::onRemove(%this) +{ + %this.Hide(); + + if( isObject( %this.base ) ) + %this.base.delete(); +} + + + +//----------------------------------------------------------------------------- +/// (SimID this, int positionX, int positionY) +/// Shows the GuiControl specified in the Dialog field at the coordinates passed +/// to this function. If no coordinates are passed to this function, the Dialog control +/// is shown using it's current position. +/// +/// @param this The ContextDialogContainer object +/// @param positionX The X Position in Global Screen Coordinates to display the dialog +/// @param positionY The Y Position in Global Screen Coordinates to display the dialog +/// @param delay Optional delay before this popup is hidden that overrides that specified at construction time +/// +//----------------------------------------------------------------------------- +function ContextDialogContainer::Show( %this, %positionX, %positionY, %delay ) +{ + if( %this.isPushed == true ) + return true; + + if( !isObject( %this.Dialog ) ) + return false; + + // Store old parent. + %this.oldParent = %this.dialog.getParent(); + + // Set new parent. + %this.base.add( %this.Dialog ); + + if( %positionX !$= "" && %positionY !$= "" ) + %this.Dialog.setPositionGlobal( %positionX, %positionY ); + + Canvas.pushDialog( %this.base, 99 ); + + // Setup Delay Schedule + if( isEventPending( %this.popSchedule ) ) + cancel( %this.popSchedule ); + if( %delay !$= "" ) + %this.popSchedule = %this.schedule( %delay, hide ); + else if( %this.Delay !$= "" ) + %this.popSchedule = %this.schedule( %this.Delay, hide ); + +} + +//----------------------------------------------------------------------------- +/// (SimID this) +/// Hides the GuiControl specified in the Dialog field if shown. This function +/// is provided merely for more flexibility in when your dialog is shown. If you +/// do not call this function, it will be called when the dialog is dismissed by +/// a background click. +/// +/// @param this The ContextDialogContainer object +/// +//----------------------------------------------------------------------------- +function ContextDialogContainer::Hide( %this ) +{ + if( %this.isPushed == true ) + Canvas.popDialog( %this.base ); + + // Restore Old Parent; + if( isObject( %this.Dialog ) && isObject( %this.oldParent ) ) + %this.oldParent.add( %this.Dialog ); +} + + + +// ContextDialogWatcher Class - JDD +// CDW is a namespace link for the context background button to catch +// event information and pass it back to the main class. +// +// onClick it will dismiss the parent +// onDialogPop it will cleanup and notify user of deactivation +// onDialogPush it will initialize state information and notify user of activation +function ContextDialogWatcher::onClick( %this ) +{ + if( isObject( %this.parent ) ) + %this.parent.hide(); +} + +function ContextDialogWatcher::onDialogPop( %this ) +{ + if( !isObject( %this.parent ) ) + return; + + %this.parent.isPushed = false; + + if( %this.parent.isMethod( "onContextDeactivate" ) ) + %this.parent.onContextDeactivate(); +} + +function ContextDialogWatcher::onDialogPush( %this ) +{ + if( !isObject( %this.parent ) ) + return; + + %this.parent.isPushed = true; + + if( %this.parent.isMethod( "onContextActivate" ) ) + %this.parent.onContextActivate(); + +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/core/zip/zipFile.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/core/zip/zipFile.ed.cs new file mode 100644 index 000000000..9cbaa66c6 --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/core/zip/zipFile.ed.cs @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function ZipObject::addPath( %this, %path, %pathInZip ) +{ + %beginPath = expandFilename( %path ); + %path = pathConcat(%path, "*"); + %file = findFirstFile( %path ); + + while(%file !$= "") + { + %zipRel = makeRelativePath( %file, %beginPath ); + %finalZip = pathConcat(%pathInZip, %zipRel); + + %this.addFile( %file, %finalZip ); + + %file = findNextFile(%path); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/expandos.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/expandos.ed.cs new file mode 100644 index 000000000..6d2804fe3 --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/expandos.ed.cs @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Called to setup the base expandos +function setupBaseExpandos() +{ + // FIXME TGEA doesnt currently have these due to the way it's built + return; + + setScriptPathExpando("tools", getExecutablePath() @ "/tools", true); + setScriptPathExpando("tool", getExecutablePath() , true); + setScriptPathExpando("toolResources", getExecutablePath() @ "/resources", true); + + setScriptPathExpando("core", getExecutablePath() @ "/core", true); + + // Remove the game expando so we can use this to reset expandos + removeScriptPathExpando("game"); +} diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/fileLoader.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/fileLoader.ed.cs new file mode 100644 index 000000000..19456af2c --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/fileLoader.ed.cs @@ -0,0 +1,108 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function loadDirectory(%path, %type, %dsoType) +{ + if( %type $= "" ) + %type = "ed.cs"; + if( %dsoType $= "" ) + %dsoType = "edso"; + + %cspath = %path @ "/*." @ %type; + + // Because in a shipping version there will be no .cs files, we can't just + // find all the cs files and exec them. + + // First we find all the scripts and compile them if there are any + // In the shipping version, this wont find anything. + if( !$Scripts::ignoreDSOs ) + { + %dsoReloc = compileDirectory(%cspath); + + // Finally we find all the dsos and exec them instead + + // If the DSOs are relocated by the engine (which will be the case when + // running the tools) then we need to look for the scripts again. + + if(! %dsoReloc) + %dsopath = %path @ "/*." @ %type @ "." @ %dsoType; + else + %dsopath = %cspath; + } + else + %dsopath = %cspath; + + //error("Execing Directory " @ %dsopath @ " ..."); + %file = findFirstFile(%dsopath); + + while(%file !$= "") + { + //error(" Found File: " @ %file); + + // As we cant exec() a .dso directly, we need to strip that part from the filename + %pos = strstr(%file, "." @ %dsoType); + if(%pos != -1) + %csfile = getSubStr(%file, 0, %pos); + else + %csfile = %file; + + exec(%csfile); + %file = findNextFile(%dsopath); + } +} + +function compileDirectory(%path, %dsoPath) +{ + %saveDSOPath = $Scripts::OverrideDSOPath; + $Scripts::OverrideDSOPath = %dsoPath; + + %dsoReloc = false; + + %file = findFirstFile(%path); + + //error("Compiling Directory " @ %path @ " ..."); + while(%file !$= "") + { + //error(" Found File: " @ %file @ " (" @ getDSOPath(%file) @ ")"); + if(filePath(%file) !$= filePath(getDSOPath(%file))) + %dsoReloc = true; + + compile(%file); + %file = findNextFile(%path); + } + + $Scripts::OverrideDSOPath = %saveDSOPath; + + return %dsoReloc; +} + +function listDirectory(%path) +{ + %file = findFirstFile(%path); + + echo("Listing Directory " @ %path @ " ..."); + while(%file !$= "") + { + echo(" " @ %file); + %file = findNextFile(%path); + } +} diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/guiClasses/guiThumbnail.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/guiClasses/guiThumbnail.ed.cs new file mode 100644 index 000000000..6f302a9dc --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/guiClasses/guiThumbnail.ed.cs @@ -0,0 +1,76 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// This file merely contains the base functionality for creating your own +// 'subclassed' script namkespaces that define the visual appearance of +// a thumbnail for a guiThumnailPopup list. +// +// All border creation and callback click functionality is also defined in +// this file and may be overriden in your namespaces provided that you +// properly invoke the Parent::onMethodName( %parameterList ) to all this +// base namespace to do it's dependent processing. + +//function GuiDefaultThumbnail::onAdd( %this ) +//{ + //// Nothing Here. +//} +// +//function GuiDefaultThumbnail::onRemove( %this ) +//{ + //// Nothing Here. +//} + +//----------------------------------------------------------------------------- +// Object Browser Item Default Behaviors +//----------------------------------------------------------------------------- +function GuiDefaultThumbnail::onClick( %this ) +{ + // Store data and hide the dialog. + if( isObject( %this.base ) ) + { + %this.base.item = %this; + %this.base.Hide(); + } +} + +function GuiDefaultThumbnail::onRightClick( %this ) +{ + // Nothing Here. +} + +function GuiDefaultThumbnail::onMouseLeave( %this ) +{ + // Nothing Here. +} + +function ObjectBrowserItem::onMouseEnter( %this ) +{ + // Nothing Here. +} + +function GuiDefaultThumbnail::onDoubleClick( %this ) +{ + // By Default if the base funcitonality is called + // in onClick, we will never get here. However, if + // you want to override this functionality, simply + // override onClick and don't call the parent. +} diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/guiClasses/guiThumbnailPopup.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/guiClasses/guiThumbnailPopup.ed.cs new file mode 100644 index 000000000..5098cf052 --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/guiClasses/guiThumbnailPopup.ed.cs @@ -0,0 +1,224 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// ContextDialogContainer Class - Example Use +//----------------------------------------------------------------------------- +// +//%MyContextDialog = new ScriptObject() +//{ +// class = ContextDialogContainer; +// superClass = GuiThumbnailPopup; +// dialog = %myContainedDialog.getID(); +// thumbType = "GuiThumbnailClass"; +// listType = "StaticSpriteThumbs"; +//}; +// %MyContextDialog.show( %positionX, %positionY ); +// %MyContextDialog.hide(); +// +// NOTES +// +// - thumbType describes a script namespace that will be linked to the creation +// of the actual thumbs in the list. This allows you to override their display +// - listType describes a script namespace that will be linked to the creation +// of the list and will have refresh and destroy called on it when you need +// to add objects to the list. to add an object, call %this.AddObject on you +// get a refresh call. +// +// +//function MyCallbackNamespace::onContextActivate( %this ) +//{ +// echo("Dialog has been pushed onto canvas, clicking outside of it will pop it!"); +//} +//function MyCallbackNamespace::onContextDeactivate( %this ) +//{ +// echo("Dialog has lost it's context and has thus been popped from the canvas!"); +//} +// +// +// Object Hierarchy +// [%scriptObject] ScriptObject (GuiThumbnailPopup) +// .superClass (ContextDialogContainer) +// (%scriptObject)->[%dialogCtrl] +// | GuiScrollCtrl [%scrollCtrl] (GuiThumbnailArray) +// | GuiDynamicCtrlArrayCtrl [%objectList] (GuiThumbnailCreator) +// .superClass ( listType ) +// .thumbType = %thumbType +// .base = %this +// +function GuiThumbnailPopup::CreateThumbPopup( %this, %parent, %thumbType, %label ) +{ + %base = new GuiWindowCtrl() + { + profile = "ToolsGuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "260 200"; + minExtent = "140 200"; + visible = "1"; + text = %label; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + }; + %scroll = new GuiScrollCtrl() + { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiScrollProfile"; + class = "GuiThumbnailArray"; + internalName = "thumbnailScroll"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "5 13"; + Extent = "250 178"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + hScrollBar = "alwaysOff"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "1"; + Margin = "6 2"; + thumbType = %thumbType; // Special Tag - Class of thumbObject + }; + %base.add(%scroll); + %objectList = new GuiDynamicCtrlArrayControl() + { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiScrollProfile"; + class = %this.listType; + superClass = "GuiThumbnailCreator"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "250 178"; + MinExtent = "64 64"; + canSave = "1"; + Visible = "1"; + internalName = "objectList"; + hovertime = "1000"; + colCount = "0"; + colSize = %this.thumbSizeX; + rowSize = %this.thumbSizeY; + rowSpacing = "2"; + colSpacing = "2"; + thumbType = %thumbType; // Special Tag - Class of thumbObject + base = %this; // Special Tag - Link to base class for hiding of dlg + }; + %scroll.add(%objectList); + %parent.add(%base); + + return %base; + +} + +function GuiThumbnailPopup::onAdd(%this) +{ + // Call parent. + if( !Parent::onAdd( %this ) ) + return false; + + if( %this.thumbType $= "" ) + %this.thumbType = "GuiDefaultThumbnail"; + + %this.Dialog = %this.createThumbPopup( %this.base, %this.thumbType, %this.label ); + + if( !isObject( %this.Dialog ) ) + { + warn("GuiThumbnailPopup::onAdd - Invalid Context Dialog Specified!"); + return false; + } +} + + + +function GuiThumbnailArray::onRemove(%this) +{ + %this.destroy(); +} + +function GuiThumbnailArray::onWake( %this ) +{ + // Find objectList + %objectList = %this.findObjectByInternalName("ObjectList"); + + if( !isObject( %objectList ) ) + return; + + %objectList.refreshList(); +} + +function GuiThumbnailArray::refreshList(%this) +{ + // Find objectList + %objectList = %this.findObjectByInternalName("ObjectList"); + + if( !isObject( %objectList ) ) + return; + + // Parent will clear + %objectList.destroy(); + +} + +function GuiThumbnailArray::destroy(%this) +{ + // Find objectList + %objectList = %this.findObjectByInternalName("ObjectList"); + + if( !isObject( %objectList ) ) + return; + + while( %objectList.getCount() > 0 ) + { + %object = %objectList.getObject( 0 ); + if( isObject( %object ) ) + %object.delete(); + else + %objectList.remove( %object ); + } +} + +//----------------------------------------------------------------------------- +// Add a T2D Object to the Object List +//----------------------------------------------------------------------------- +function GuiThumbnailCreator::AddObject( %this, %object, %data, %tooltip ) +{ + // Add to group + $LB::ObjectLibraryGroup.add( %object ); + + // Build Object Container + %container = new GuiControl() { profile = ToolsGuiButtonProfile; }; + + // Add to list. + %this.add( %container ); + + // Return Container + return %container; +} diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormClass.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormClass.ed.cs new file mode 100644 index 000000000..8946280a4 --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormClass.ed.cs @@ -0,0 +1,616 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +// This function will build out an empty frame and add it to its given parent. The newly +// built frame control is returned +function GuiFormClass::BuildEmptyFrame(%pos, %ext, %columns, %rows, %parentID) +{ + %frame = new GuiFrameSetCtrl() + { + profile = "ToolsGuiFrameSetProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = %pos; + extent = %ext; + columns = %columns; + rows = %rows; + borderWidth = "5"; //"4"; + //borderColor = "192 192 192"; + absoluteFrames = "1"; + relativeResizing = "1"; + specialHighlighting = "1"; + }; + + %parentID.add(%frame); + + return %frame; +} + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +// This function will build out a form control and add it to its parent. The newly built +// form control is returned. +function GuiFormClass::BuildFormControl( %parentID, %ContentLibrary ) +{ + // Find Default 'None' Content. + %contentNoneObj = GuiFormManager::FindFormContent( %ContentLibrary, "Scene View" ); + if( %contentNoneObj == 0 ) + { + error("GuiFormClass::BuildFormControl - Cannot find 'Scene View' Content Object!" ); + return false; + } + + %newFormObj = new GuiFormCtrl() + { + class = "FormControlClass"; + profile = "ToolsGuiFormProfile"; + canSaveDynamicFields = 1; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 455"; + minExtent = "20 20"; + visible = "1"; + caption = $FormClassNoContentCaption; + collapsable = "1"; + barBehindText = "1"; + hasMenu = true; + ContentLibrary = %ContentLibrary; + ContentID = %contentNoneObj; + Content = "Scene View"; + }; + %parentID.add( %newFormObj ); + + return %newFormObj; +} + + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +function FormControlClass::onWake( %this ) +{ + if( %this.ContentLibrary !$= "" && %this.Content !$= "" ) + { + %contentObj = GuiFormManager::FindFormContent( %this.ContentLibrary, %this.Content ); + if( %contentObj == 0 ) + { + error("GuiFormClass::onWake - Content Library Specified But Content Not Found!" ); + return; + } + + // Set Form Content + //if( %this.ContentID != %contentObj || !isObject( %this.ContentID ) ) + GuiFormClass::SetFormContent( %this, %contentObj ); + } + + %parentId = %this.getParent(); + %extent = %parentID.getExtent(); + %this.setExtent( GetWord(%extent, 0), GetWord(%extent, 1) ); + + GuiFormClass::BuildFormMenu( %this ); + +} + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +function GuiFormClass::BuildFormMenu( %formObj ) +{ + + if( !%formObj.hasMenu ) + return; + + // Menu Name. + %menuName = "FormMainMenu"; + + // Retrieve Menu ID. + %formMenu = %formObj.getMenuID(); + + %formMenu.clearMenuItems( %menuName ); + + //*** Setup the check mark bitmap index to start at the third bitmap + %formMenu.setCheckmarkBitmapIndex(1); + + //*** Add a menu to the menubar + %formMenu.addMenu( %menuName, %formObj); + %formMenu.setMenuBitmapIndex( %menuName, 0, true, false); + %formMenu.setMenuMargins(0, 0, 0); + + // Build Division Control Menu Items. + %formMenu.addMenuItem( %menuName, "Split This View Horizontally", 1); + %formMenu.addMenuItem( %menuName, "Split This View Vertically", 2); + %formMenu.addMenuItem( %menuName, "-", 0); + %formMenu.addMenuItem( %menuName, "Remove This View", 3); + +} + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +function GuiFormClass::SetFormContent( %formObj, %contentObj ) +{ + + // Menu Name. + %menuName = "FormMainMenu"; + + // Validate New Content. + if( !isObject( %contentObj ) ) + { + // Failure + error("GuiFormClass::SetFormContent- No Valid Content Object!" ); + return 0; + } + + // Remove any other content from the Form + %count = %formObj.getCount(); + if(%count > 1) + { + // Notify Script of Content Changing. + if( %formObj.isMethod("onContentChanging") ) + %formObj.onContentChanging( %contentObj ); + + // Object 0 is Always The Menu. + %currentContent = %formObj.getObject( 1 ); + if( isObject( %currentContent ) ) + { + // Remove from Reference List. + if( %formObj.contentID !$= "" ) + GuiFormManager::RemoveContentReference( %formObj.ContentLibrary, %formObj.contentID.Name, %currentContent ); + + // Delete the content. + %currentContent.delete(); + + // Update form Caption + %formObj.setCaption( $FormClassNoContentCaption ); + + } + } + + // Handle the Form content choices by obtaining the script build command + if( %contentObj.CreateFunction !$= "" ) + { + //*** Set the name first + %name = %contentObj.Name; + %formObj.setCaption(%name); + + // We set the content ID prior to calling the create function so + // that it may reference it's content to retrieve information about it. + %oldContentId = %formObj.contentID; + %formObj.contentID = %contentObj; + + %result = eval( %contentObj.CreateFunction @ "(" @ %formObj @ ");" ); + if(!%result) + { + //*** Couldn't set up the form's contents so set the name back. We need to + //*** do it like this to allow the form's contents to change the form caption + //*** if the above command worked. + %formObj.setCaption($FormClassNoContentCaption); + + // Restore Content ID. + %formObj.contentID = %oldContentID; + + // Notify Script of Failure. + if( %formObj.isMethod("onContentChangeFailure") ) + %formObj.onContentChangeFailure(); + } + else + { + // Add to Reference List. + %currentContent = %formObj.getObject( 1 ); + if( isObject( %currentContent ) ) + GuiFormManager::AddContentReference( %formObj.ContentLibrary, %contentObj.Name, %currentContent ); + + %formObj.Content = %formObj.contentId.name; + + // Notify Script of Content Change + if( %formObj.isMethod("onContentChanged") ) + %formObj.onContentChanged( %contentObj ); + + return %result; + } + } + return 0; +} + + +// +// Create a given content library content instance on a given parent control and +// reference count it in the ref manager. +// +function GuiFormClass::SetControlContent( %controlObj, %contentLibrary, %contentObj ) +{ + // Validate New Content. + if( !isObject( %contentObj ) ) + { + // Failure + error("GuiFormClass::SetControlContent- No Valid Content Object!" ); + return 0; + } + + // Remove any other content from the Form + if( isObject( %controlObj.ContentID ) ) + { + // Find Control of current content internal name on the control. + %currentContent = %controlObj.findObjectByInternalName( %controlObj.ContentID.Name ); + + if( isObject( %currentContent ) ) + { + + // Notify Script of Content Changing. + if( %controlObj.isMethod("onContentChanging") ) + %controlObj.onContentChanging( %contentObj ); + + // Remove from Reference List. + GuiFormManager::RemoveContentReference( %contentLibrary, %controlObj.contentID.Name, %currentContent ); + + // Delete the content. + %currentContent.delete(); + + } + } + + // Handle the Form content choices by obtaining the script build command + if( %contentObj.CreateFunction !$= "" ) + { + %name = %contentObj.Name; + + // We set the content ID prior to calling the create function so + // that it may reference it's content to retrieve information about it. + %oldContentId = %controlObj.contentID; + %controlObj.contentID = %contentObj; + + %currentContent = eval( %contentObj.CreateFunction @ "(" @ %controlObj @ ");" ); + if( !isObject( %currentContent ) ) + { + // Restore Content ID. + %controlObj.contentID = %oldContentID; + + // Notify Script of Failure. + if( %controlObj.isMethod("onContentChangeFailure") ) + %controlObj.onContentChangeFailure(); + } + else + { + // Add to Reference List. + GuiFormManager::AddContentReference( %contentLibrary, %contentObj.Name, %currentContent ); + + // Store Internal Name + %currentContent.setInternalName( %contentObj.Name ); + + // Store Content + %controlObj.Content = %controlObj.contentId.name; + + // Notify Script of Content Change + if( %controlObj.isMethod("onContentChanged") ) + %controlObj.onContentChanged( %contentObj ); + + return %currentContent; + } + } + return 0; +} + +// +// Remove a given library content instance from a control that is housing it. +// +function GuiFormClass::ClearControlContent( %controlObj, %contentLibrary ) +{ + + // Remove any other content from the Form + if( isObject( %controlObj.ContentID ) ) + { + // Find Control of current content internal name on the control. + %currentContent = %controlObj.findObjectByInternalName( %controlObj.ContentID.Name ); + + if( isObject( %currentContent ) ) + { + + // Notify Script of Content Changing. + if( %controlObj.isMethod("onContentClearing") ) + %controlObj.onContentClearing( %controlObj.ContentID ); + + // Remove from Reference List. + GuiFormManager::RemoveContentReference( %contentLibrary, %controlObj.contentID.Name, %currentContent ); + + // Delete the content. + %currentContent.delete(); + } + } +} + + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +// Turn a form into a split frame and add the form back and build a new blank +// form in the empty slot. %horizontal==ture then make a horizontal split, otherwise +// make a vertical one. +function GuiFormClass::AddFrameSplitToForm(%formid, %horizontal) +{ + %formparent = %formid.getGroup(); + + // Get form position and size + %pos = %formid.position; + %ext = %formid.extent; + %rows = "0"; + %columns = "0"; + if(%horizontal) + { + %framesplit = getWord(%ext,1) / 2; + %rows = "0 " @ %framesplit; + } + else + { + %framesplit = getWord(%ext,0) / 2; + %columns = "0 " @ %framesplit; + } + + // If the form's parent is a frame control and this form is the first control then + // we will need to move it to the front of the other children later on. Otherwise + // we'll be added to the bottom of the stack and the order will get messed up. + // This all assumes that a frame control only has two children. + %secondctrl = -1; + if(%formparent.getClassName() $= "GuiFrameSetCtrl") + { + //error("Form parent is GuiFrameSetCtrl"); + if(%formparent.getObject(0) == %formid) + { + // This form is the first child. + //error("Form is at the top"); + %secondctrl = %formparent.getObject(1); + } + } + + // If we're adding a frameset around the layout base, propogate the + // layoutRef and layoutObj's to the new parent. + if( %formID.LayoutRef !$= "" ) + %LayoutRef = %formID.LayoutRef; + else + %LayoutRef = 0; + + + // Remove form from parent, put a frame control in its place, and then add this form back to the frame + %formparent.remove(%formid); + %frame = GuiFormClass::BuildEmptyFrame(%pos, %ext, %columns, %rows, %formparent); + + if( %layoutRef != 0 ) + { + %frame.LayoutRef = %LayoutRef; + %frame.LayoutRef.layoutObj = %frame; + %frame.setCanSave( true ); + } + if(%secondctrl != -1) + { + // Move this frame to the top of its parent's children stack by removing the + // other child and adding it back again. This will force this second child to + // the bottom and our new frame back to the first child (the same location the + // original form was). Whew! Maybe the frame control needs to be modified to + // handle this. + //error("Moving to the top"); + %formparent.remove(%secondctrl); + %formparent.add(%secondctrl); + } + %frame.add(%formid); + + // Add a blank form to the bottom frame + GuiFormClass::BuildFormControl(%frame, %formid.ContentLibrary ); + + //error("New parent: " @ %frame SPC "(" @ %frame.getClassName() @ ")"); +} + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +//*** Remove a form's frame and any other of the frame's children and put the given +//*** form in its place, effectively removing the split. %keepform==true then remove +//*** all children of a parent Frame Set and keep the given Form. Otherwise, remove +//*** the given Form and keep the other child. +function GuiFormClass::RemoveFrameSplit(%formid, %keepform) +{ + //*** Get the form's parent and make sure it is a frame GUI. Other wise do nothing. + %frameID = %formid.getGroup(); + if(%frameID.getClassName() !$= "GuiFrameSetCtrl") + return; + + //*** Get frame's position and size + %pos = %frameID.position; + %ext = %frameID.extent; + + if(%keepform) + { + %form = %frameID.getObject(0); + + // Remove from Reference List. + if(%form.getClassName() $= "GuiFormCtrl") + GuiFormManager::RemoveContentReference( %form.ContentLibrary, %form.contentID.Name, %form.getObject(1) ); + + //*** Go through the frame's children and remove them (which includes our form) + %frameID.clear(); + } + else + { + + // Remove from Reference List. + if( %formId.getClassName() $= "GuiFormCtrl" ) + GuiFormManager::RemoveContentReference( %formId.ContentLibrary, %formId.contentID.Name, %formId.getObject(1) ); + + //*** Store the first child that is not the given Form + %count = %frameID.getCount(); + for(%i=0; %i < %count; %i++) + { + %child = %frameID.getObject(%i); + if(%child != %formid) + { + //*** This is the first child that isn't the given Form, so + //*** swap the given %formid with this new child so we keep it + %formid = %child; + break; + } + } + + //*** Now remove all children from the frame. + %frameID.clear(); + } + + //*** Obtain the frame's parent + %frameparentID = %frameID.getGroup(); + + //*** If the frame's parent is itself a frame, then track all of its children and add + //*** our form into the correct location, and remove our frame in the process. Otherwise + //*** just delete our frame and add our form to the parent. + if(%frameparentID.getClassName() $= "GuiFrameSetCtrl") + { + //*** Store the children + %count = %frameparentID.getCount(); + %check = -1; + for(%i=0; %i<%count; %i++) + { + %obj[%i] = %frameparentID.getObject(%i); + if(%obj[%i] == %frameID) + %check = %i; + } + + //*** Clear the existing children + %frameparentID.clear(); + + //*** Now add them back, including our form + for(%i=0; %i<%count; %i++) + { + if(%i == %check) + { + //*** Add our form + %frameparentID.add(%formid); + + } + else + { + //*** Add the old child back + %frameparentID.add(%obj[%i]); + } + } + + } else + { + // If we're about to remove a frame that has a layout ref move it to the new object (%formID) + if( %frameID.LayoutRef !$= "" ) + { + %formID.LayoutRef = %frameID.LayoutRef; + // By default if a control has been added to a form it will tag itself as cannot save. + // just to be safe, we mark it as we can since it's clearly now becoming the root of a layout. + %formID.LayoutRef.layoutObj = %formID; + %formID.setCanSave( true ); + } + //*** Remove old child and add our form to the parent + %frameparentID.remove(%frameID); + %frameparentID.add(%formid); + + } + + //*** Finally resize the form to fit + %formid.resize(getWord(%pos,0),getWord(%pos,1),getWord(%ext,0),getWord(%ext,1)); +} + + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +//*** Will resize the Form's content to fit. This is usually done at the beginning when +//*** the content is first added to the form. +function FormControlClass::sizeContentsToFit(%this, %content, %margin) +{ + %formext = %this.getExtent(); + %menupos = %this.getObject(0).getPosition(); + %menuext = %this.getObject(0).getExtent(); + + %ctrlposx = getWord(%menupos,0) + %this.contentID.Margin; + %ctrlposy = getWord(%menupos,1) + getWord(%menuext,1) + %this.contentID.Margin; + %ctrlextx = getWord(%formext,0) - %ctrlposx - %this.contentID.Margin; + %ctrlexty = getWord(%formext,1) - %ctrlposy - %this.contentID.Margin; + + %content.resize(%ctrlposx,%ctrlposy,%ctrlextx,%ctrlexty); +} + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +function FormControlClass::onResize(%this) +{ + //*** If this form has a content child, then pass along this resize notice + //*** to allow it to do something. + if(%this.getCount() > 1) + { + %child = %this.getObject(1); + if( isObject( %child ) ) + %this.sizeContentsToFit( %child ); + + if( %child.isMethod("onResize") ) + %child.onResize(%this); + } +} + +// +// This will change to something more abstract in the near future, or will be moved into +// the level editor if there is no concise way to abstract it. +// +function FormMenuBarClass::onMenuItemSelect(%this, %menuid, %menutext, %itemid, %itemtext) +{ + %formId = %menuid; // %menuid should contain the form's ID + + //error("FormMenuBarClass::onMenuSelect(): " @ %menuid SPC %menutext SPC %itemid SPC %itemtext SPC "parent: " @ %formparent); + + // If the ID is less than 1000, we know it's a layout menu item + if( %itemid < 1000 ) + { + // Handle the standard menu choices + switch(%itemid) + { + case "1": // Add horizontal split + GuiFormClass::AddFrameSplitToForm(%formid, true); + + case "2": // Add vertical split + GuiFormClass::AddFrameSplitToForm(%formid, false); + case "3": // Remove split and keep other child + GuiFormClass::RemoveFrameSplit(%formid, false); + } + + // We're Done Here. + return; + } + else + GuiFormClass::SetFormContent( %formId, %itemId ); + + +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormContentManager.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormContentManager.ed.cs new file mode 100644 index 000000000..5af210109 --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormContentManager.ed.cs @@ -0,0 +1,190 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +$FormClassNoContentCaption = "None"; + +//----------------------------------------------------------------------------- +// Add Form Content to a Library or Update if it Already Exists +// +// Returns : Content ID or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::AddFormContent( %library, %contentName, %contentCreate, %contentSave, %contentMargin ) +{ + // See if we were passed a library ID. + if( !isObject( %library ) ) + %libraryObj = GuiFormManager::FindLibrary( %library ); + else + %libraryObj = %library; + + // See if we Found the Library. + if( %libraryObj == 0 || !isObject( %libraryObj ) ) + { + error( "GuiFormManager::AddFormContent - Unable to Find Library by Name or ID!" ); + return 0; + } + + // See if this reference already exists. + %contentRef = GuiFormManager::FindFormContent( %libraryObj, %contentName ); + + // If it exists, just update it's create/save functions. + if( %contentRef != 0 ) + { + // Echo Update. + //echo( "GuiFormManager::AddFormContent - Found Existent Content Reference, Updating Create/Save Functions" ); + + // Apply Update. + %contentRef.CreateFunction = %contentCreate; + %contentRef.SaveFunction = %contentSave; + %contentRef.Margin = %contentMargin; + + // Return Success. + return %contentRef; + } + + // Create Content Reference List. + %refList = new SimSet(); + + // Add Reference List to Library. + %libraryObj.getObject(0).add( %refList ); + + // Create Content Reference Object. + %newContentRef = new ScriptObject() + { + Name = %contentName; + CreateFunction = %contentCreate; + SaveFunction = %contentSave; + Margin = %contentMargin; + RefList = %refList; + }; + + // Add to library. + %libraryObj.add( %newContentRef ); + + // Return Success. + return %newContentRef; +} + +//----------------------------------------------------------------------------- +// Remove Form Content from a Library +// +// Returns : True or False. +//----------------------------------------------------------------------------- +function GuiFormManager::RemoveFormContent( %library, %contentName ) +{ + // See if we were passed a library ID. + if( !isObject( %library ) ) + %libraryObj = GuiFormManager::FindLibrary( %library ); + else + %libraryObj = %library; + + // See if we Found the Library. + if( %libraryObj == 0 || !isObject( %libraryObj ) ) + return false; + + // See if this reference already exists. + %contentRef = GuiFormManager::FindFormContent( %libraryObj, %contentName ); + + // If it doesn't exist, just return success. + if( %contentRef == 0 || !isObject( %contentRef ) ) + return true; + + // Remove From Library. + %libraryObj.remove( %contentRef ); + + // Return Success. + return true; +} + + +//----------------------------------------------------------------------------- +// Find Form Content in a Library +// +// Returns : Content Reference Object ID or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::FindFormContent( %library, %contentName ) +{ + // See if we were passed a library ID. + if( !isObject( %library ) ) + %libraryObj = GuiFormManager::FindLibrary( %library ); + else + %libraryObj = %library; + + // See if we Found the Library. + if( %libraryObj == 0 || !isObject( %libraryObj ) ) + return 0; + + // Look for the content by name in our library. + for( %i = 0; %i < %libraryObj.getCount(); %i++ ) + { + %object = %libraryObj.getObject( %i ); + if( %object.Name $= %contentName ) + return %object; + } + + // Return Failure. + return 0; +} + +//----------------------------------------------------------------------------- +// Get Form Content in a Library by Index +// +// Returns : Content Reference Object ID or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::GetFormContentByIndex( %library, %index ) +{ + // See if we were passed a library ID. + if( !isObject( %library ) ) + %libraryObj = GuiFormManager::FindLibrary( %library ); + else + %libraryObj = %library; + + // See if we Found the Library. + if( %libraryObj == 0 || !isObject( %libraryObj ) ) + return 0; + + if( %index < %libraryObj.getCount() ) + return %libraryObj.getObject( %index ); + +} + + +//----------------------------------------------------------------------------- +// Get Form Content Count in a Library +// +// Returns : Number of content objects in this library or 0 +//----------------------------------------------------------------------------- +function GuiFormManager::GetFormContentCount( %library ) +{ + // See if we were passed a library ID. + if( !isObject( %library ) ) + %libraryObj = GuiFormManager::FindLibrary( %library ); + else + %libraryObj = %library; + + // See if we Found the Library. + if( %libraryObj == 0 || !isObject( %libraryObj ) ) + { + return 0; + } + + // Return Count. + return %libraryObj.getCount(); +} diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormLayoutManager.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormLayoutManager.ed.cs new file mode 100644 index 000000000..cc449b24c --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormLayoutManager.ed.cs @@ -0,0 +1,394 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// Register a Content Library Layout +// +// Returns : Layout Object ID or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::InitLayouts( %libraryName, %layoutName, %layoutObj ) +{ + // Retrieve Library Object + %libraryObj = GuiFormManager::FindLibrary( %libraryName ); + if( %libraryObj == 0 ) + { + error("GuiFormManager::RegisterLayout - Unable to find Library" SPC %libraryName ); + return 0; + } + + // Load up all Layouts in the layout base path. + loadDirectory( %libraryObj.basePath, "cs", "dso" ); + +} + +//----------------------------------------------------------------------------- +// Register a Content Library Layout +// +// Returns : True or False. +//----------------------------------------------------------------------------- +function GuiFormManager::RegisterLayout( %libraryName, %layoutName, %layoutObj ) +{ + // Retrieve Library Object + %libraryObj = GuiFormManager::FindLibrary( %libraryName ); + if( %libraryObj == 0 ) + { + error("GuiFormManager::RegisterLayout - Unable to find Library" SPC %libraryName ); + return false; + } + + // Retrieve Layout Group + %layoutGroup = %libraryObj.getObject( 1 ); + if( !isObject( %layoutGroup ) ) + { + error("GuiFormManager::RegisterLayout - Unable to locate layout group!"); + return false; + } + + // See if a layout with this name already exists. + if( GuiFormManager::FindLayout( %libraryName, %layoutName ) != 0 ) + { + error("GuiFormManager::RegisterLayout - Layout with name" SPC %layoutName SPC "already exists!"); + return false; + } + + %layoutRef = new ScriptObject() + { + layoutGroup = %layoutGroup; + layoutName = %layoutName; + layoutLibrary = %libraryObj; + layoutObj = %layoutObj; + layoutFile = %libraryObj.basePath @ %layoutName @ ".cs"; + }; + + // Tag Layout Object Properly so it can reset itself. + %layoutObj.layoutRef = %layoutRef; + + // Add Layout Object to group. + %layoutGroup.add( %layoutObj ); + + // Add Layout Object Ref to group. + %layoutGroup.add( %layoutRef ); + + // Return Success. + return true; +} + +//----------------------------------------------------------------------------- +// Unregister a Content Library Layout +// +// Returns : True or False. +//----------------------------------------------------------------------------- +function GuiFormManager::UnregisterLayout( %libraryName, %layoutName, %deleteFile ) +{ + %libraryObj = GuiFormManager::FindLibrary( %libraryName ); + if( %libraryObj == 0 ) + { + error("GuiFormManager::UnregisterLayout - Unable to find Library" SPC %libraryName ); + return false; + } + + // See if the layout exists. + %layoutObjRef = GuiFormManager::FindLayout( %libraryObj, %layoutName ); + + if( %layoutObjRef == 0 ) + return true; + + // Remove Layout File. + if( ( %deleteFile == true ) && isFile( %layoutObjRef.layoutFile ) ) + fileDelete( %layoutObjRef.layoutFile ); + + // Delete the Object. + if( isObject( %layoutObjRef.layoutObj ) ) + %layoutObjRef.layoutObj.delete(); + + // Delete the Reference + %layoutObjRef.delete(); + + // Layout Unregistered. + return true; + +} + +//----------------------------------------------------------------------------- +// Find a Content Library Layout +// +// Returns : Layout Object ID or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::FindLayout( %libraryName, %layoutName ) +{ + // Fetch Library Object. + if( isObject( %libraryName ) && %libraryName.Name !$= "" ) + %libraryName = %libraryName.Name; + + %libraryObj = GuiFormManager::FindLibrary( %libraryName ); + + if( %libraryObj == 0 ) + { + error("GuiFormManager::FindLayout - Unable to find Library" SPC %libraryName ); + return 0; + } + + // Retrieve Layout Group + %layoutGroup = %libraryObj.getObject( 1 ); + if( !isObject( %layoutGroup ) ) + { + error("GuiFormManager::FindLayout - Unable to locate layout group!"); + return 0; + } + + // Find Layout Object. + for( %i = 0; %i < %layoutGroup.getCount(); %i++ ) + { + %layoutGroupIter = %layoutGroup.getObject( %i ); + if( %layoutGroupIter.getClassName() $= "ScriptObject" && %layoutGroupIter.layoutName $= %layoutName ) + return %layoutGroupIter; + } + + // Not Found + return 0; +} + +//----------------------------------------------------------------------------- +// Save a Content Library Layout +// +// Returns : True or False +//----------------------------------------------------------------------------- +function GuiFormManager::SaveLayout( %library, %layoutName, %newName ) +{ + %libraryObj = GuiFormManager::FindLibrary( %library ); + if( %libraryObj == 0 ) + { + error("GuiFormManager::SaveLayout - Unable to find Library" SPC %library ); + return false; + } + + %layoutObjRef = GuiFormManager::FindLayout( %library, %layoutName ); + if( %layoutObjRef == 0 ) + { + error("GuiFormManager::SaveLayout - Cannot find layout" SPC %layoutName ); + return false; + } + + // Do any form layout specifics saving. + GuiFormManager::SaveLayoutContent( %layoutObjRef.layoutObj ); + + %newFile = %libraryObj.basePath @ "/" @ %newName @ ".cs"; + if( %newName $= "" ) + { + %newName = %layoutObjRef.layoutName; + %newFile = %layoutObjRef.layoutFile; + } + + // Open Layout File Object. + %layoutFile = new FileObject(); + if( !%layoutFile.openForWrite( %newFile ) ) + { + error("GuiFormManager::SaveLayout - Unable to open" SPC %newFile SPC "for writing!"); + %layoutFile.delete(); + return false; + } + + // Get Layout Object + %layoutObj = %layoutObjRef.layoutObj; + + // Write Layout Object to File + %layoutFile.writeObject( %layoutObj, "%layoutObj = " ); + %layoutFile.writeLine("GuiFormManager::RegisterLayout(\"" @ %libraryObj.name @ "\",\"" @ %newName @ "\",%layoutObj);" ); + %layoutFile.close(); + %layoutFile.delete(); + + // Layout Saved + return true; + +} + +//----------------------------------------------------------------------------- +// Reload The Current Layout from the version last stored on disk. +// +// Returns : True or False +//----------------------------------------------------------------------------- +function GuiFormManager::ReloadLayout( %libraryName, %layoutName, %parent ) +{ + %layoutObj = GuiFormManager::FindLayout( %libraryName, %layoutName ); + if( %layoutObj == 0 || !isObject( %layoutObj ) ) + { + error("GuiFormManager::ReloadLayout - Unable to locate layout" SPC %layoutName SPC "in library" SPC %libraryName ); + return 0; + } + + // Store necessary layout info before the object is destroyed in UnregisterLayout. + %layoutFile = %layoutObj.layoutFile; + + // Unregister Layout but don't delete the layout file from disk. + if( !GuiFormManager::UnregisterLayout( %libraryName, %layoutName, false ) ) + { + error("GuiFormManager::ReloadLayout - Unable to unregister layout file" SPC %layoutFile ); + return 0; + } + + // Load the layout from disk. + exec( %layoutFile ); + + // Set it active. + GuiFormManager::ActivateLayout( %libraryName, %layoutName, %parent ); + + return true; +} + + +//----------------------------------------------------------------------------- +// Activate a Layout on a Given Parent. +// +// Returns : True or False +//----------------------------------------------------------------------------- +function GuiFormManager::ActivateLayout( %library, %layoutName, %parent ) +{ + %libraryObj = GuiFormManager::FindLibrary( %library ); + if( %libraryObj == 0 ) + { + error("GuiFormManager::FindLayout - Unable to find Library" SPC %library ); + return 0; + } + + %layoutObjRef = GuiFormManager::FindLayout( %library, %layoutName ); + if( %layoutObjRef == 0 ) + { + error("GuiFormManager::ActivateLayout - Cannot find layout" SPC %layoutName ); + return false; + } + + // Clear parent for new layout. + %parent.clear(); + + %layoutObj = %layoutObjRef.layoutObj; + + // Size to fit parent container. + %extent = %parent.getExtent(); + %layoutObj.setExtent( GetWord(%extent, 0), GetWord(%extent, 1) ); + + // Add to parent. + %parent.add( %layoutObj ); + + // Not Found + return true; +} + +//----------------------------------------------------------------------------- +// Deactivate a given layout. +// +// Returns : True or False +//----------------------------------------------------------------------------- +function GuiFormManager::DeactivateLayout( %library, %layoutName ) +{ + %libraryObj = GuiFormManager::FindLibrary( %library ); + if( %libraryObj == 0 ) + { + error("GuiFormManager::DeactivateLayout - Unable to find Library" SPC %library ); + return 0; + } + + %layoutObjRef = GuiFormManager::FindLayout( %library, %layoutName ); + if( %layoutObjRef == 0 ) + { + error("GuiFormManager::DeactivateLayout - Cannot find layout" SPC %layoutName ); + return false; + } + + // Retrieve Layout Group + %layoutGroup = %libraryObj.getObject( 1 ); + if( !isObject( %layoutGroup ) ) + { + error("GuiFormManager::RegisterLayout - Unable to locate layout group!"); + return 0; + } + + // Fetch Layout Object + %layoutObj = %layoutObjRef.layoutObj; + + // Clear all forms content. + GuiFormManager::ClearLayoutContent( %layoutObj ); + + // Return layout to it's home. + %layoutGroup.add( %layoutObj ); + + // Not Found + return true; +} + +//----------------------------------------------------------------------------- +// Recursively Remove Form Content +// +// Returns : None. +//----------------------------------------------------------------------------- +function GuiFormManager::SaveLayoutContent( %layoutObj ) +{ + for( %i = 0; %i < %layoutObj.getCount(); %i++ ) + { + %object = %layoutObj.getObject( %i ); + if( %object.isMemberOfClass( "SimGroup" ) ) + { + %formContent = 0; + if (%object.getCount() > 0) + %formContent = %object.getObject( 1 ); + + if( isObject( %formContent ) && %object.ContentLibrary !$= "" && %object.Content !$= "" ) + { + %contentObj = GuiFormManager::FindFormContent( %object.ContentLibrary, %object.Content ); + if( %contentObj == 0 ) + { + error("GuiFormManager::SaveLayoutContent - Content Library Specified But Content Not Found!" ); + return; + } + + if( %contentObj.SaveFunction !$= "" ) + eval( %contentObj.SaveFunction @ "(" @ %object @ "," @ %formContent @ ");" ); + } + } + else + GuiFormManager::SaveLayoutContent( %object ); + } +} + +//----------------------------------------------------------------------------- +// Recursively Remove Form Content +// +// Returns : None. +//----------------------------------------------------------------------------- +function GuiFormManager::ClearLayoutContent( %layoutObj ) +{ + for( %i = 0; %i < %layoutObj.getCount(); %i++ ) + { + %object = %layoutObj.getObject( %i ); + if( %object.getClassName() $= "GuiFormCtrl" ) + { + // Clear Content ID So that onWake recreates the content. + %object.ContentID = ""; + + %formContent = %object.getObject( 1 ); + if( isObject( %formContent ) ) + %formContent.delete(); + } + else + GuiFormManager::ClearLayoutContent( %object ); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormLibraryManager.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormLibraryManager.ed.cs new file mode 100644 index 000000000..e8918aa92 --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormLibraryManager.ed.cs @@ -0,0 +1,161 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Register a Content Library +// +// Returns : Library Object ID or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::RegisterLibrary( %libraryName, %libraryBasePath ) +{ + %libraryPrepend = "GFCM"; + %newLibraryObjectName = %libraryPrepend @ %libraryName; + + // If the library already exists, just return it's object. + if( isObject( %newLibraryObjectName ) ) + return %newLibraryObjectName.getId(); + + // We must have the content manager to continue. + if( !isObject( FormContentManager ) ) + { + error("GuiFormManager::RegisterLibrary - Unable to find FormContentManager object!"); + return 0; + } + + // Create Content Library. + %newLibrary = new SimGroup( %newLibraryObjectName ) + { + Name = %libraryName; + }; + + // Expand Base Path + %libraryFullPath = getPrefsPath( %libraryBasePath ); + + // Store disk base path + %newLibrary.basePath = %libraryFullPath; + + // Ensure Path Exists + createPath( %libraryFullPath ); + + // Add Library to Content Manager. + FormContentManager.add( %newLibrary ); + + // Create Content Library Ref Group. + %newLibraryRefGroup = new SimGroup(); + %newLibraryRefGroup.setInternalName("RefGroup"); + %newLibrary.add( %newLibraryRefGroup ); + + // Create Content Library Layout Group. + %newLibraryLayoutGroup = new SimGroup(); + %newLibraryLayoutGroup.setInternalName("LayoutGroup"); + %newLibrary.add( %newLibraryLayoutGroup ); + + // Add Library to Content Manager. + FormContentManager.add( %newLibrary ); + + + // Add [none] Content. + GuiFormManager::AddFormContent( %libraryName, $FormClassNoContentCaption ); + + // Return Library Object. + return %newLibrary; + +} + +//----------------------------------------------------------------------------- +// Unregister a Content Library +// +// Returns : True or False. +//----------------------------------------------------------------------------- +function GuiFormManager::UnregisterLibrary( %libraryName ) +{ + // Find Library Object. + %libraryObj = GuiFormManager::FindLibrary( %libraryName ); + + if( !isObject( FormContentManager ) || !isObject( %libraryObj ) ) + { + error("GuiFormManager::RegisterLibrary - Unable to find GuiFormManager or Library!"); + return false; + } + + // Remove all Content Reference Objects in this Library. + while( %libraryObj.getCount() > 0 ) + { + if( isObject( %libraryObj.getObject( 0 ) ) ) + %libraryObj.getObject( 0 ).delete(); + %libraryObj.remove( 0 ); + } + // Delete the library + %libraryObj.delete(); + + // Return Success. + return true; + +} + + +//----------------------------------------------------------------------------- +// Find a Content Library +// +// Returns : Library Object ID or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::FindLibrary( %libraryName ) +{ + // Generate Library Name. + %libraryObjectName = "GFCM" @ %libraryName; + + // Find Library by Name. + if( isObject( %libraryObjectName ) ) + return %libraryObjectName.getId(); + + // Didn't find by name, see if this is already a library ID. + if( isObject( %libraryName ) ) + return %libraryName; + + // Couldn't Find Library + return 0; +} + + +function GuiFormManager::Init() +{ + // Create SimGroup. + new SimGroup( FormContentManager ){}; +} + + +function GuiFormManager::Destroy() +{ + while( FormContentManager.getCount() > 0 ) + { + %object = FormContentManager.getObject( 0 ); + + if( isObject( %object ) ) + GuiFormManager::BroadcastContentMessage( %object, FormContentManager, "onLibraryDestroyed" ); + + FormContentManager.remove( %object ); + } + + // Destroy SimGroup. + if( isObject( FormContentManager ) ) + FormContentManager.delete(); +} diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormMessageManager.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormMessageManager.ed.cs new file mode 100644 index 000000000..4fee6e8b7 --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormMessageManager.ed.cs @@ -0,0 +1,126 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Send a Message to all instances of a Content. +// +// Returns : The Number of Objects Communicated With or (0 if None). +//----------------------------------------------------------------------------- +function GuiFormManager::SendContentMessage( %contentObj, %sender, %message ) +{ + // See if we Found the content object. + if( %contentObj == 0 || !isObject( %contentObj ) ) + { + //error( "GuiFormManager::SendContentMessage - Invalid Content Specified!" ); + return 0; + } + + // Validate Ref List. + if( !isObject( %contentObj.RefList ) ) + { + //error( "GuiFormManager::SendContentMessage - Unable to find content RefList!" ); + return 0; + } + + %refListObj = %contentObj.RefList.getID(); + + %messagedObjects = 0; + // Look for the content by name in our library. + for( %i = 0; %i < %refListObj.getCount(); %i++ ) + { + %object = %refListObj.getObject( %i ); + + // Check for alternate MessageControl + if( isObject( %object.MessageControl ) && %object.MessageControl.isMethod("onContentMessage") ) + %object.MessageControl.onContentMessage( %sender, %message ); + else if( %object.isMethod("onContentMessage") ) // Check for Default + %object.onContentMessage( %sender, %message ); + else + continue; + %messagedObjects++; + } + + // Return Success. + return %messagedObjects; +} + + + +//----------------------------------------------------------------------------- +// Send a Message to all instances of all Content. +// +// Returns : The Number of Objects Communicated With or (0 if None). +//----------------------------------------------------------------------------- +function GuiFormManager::BroadcastContentMessage( %libraryName, %sender, %message ) +{ + %libraryObj = GuiFormManager::FindLibrary( %libraryName ); + // See if we Found the content object. + if( %libraryObj == 0 || !isObject( %libraryObj ) ) + { + //error( "GuiFormManager::BroadcastContentMessage - Invalid Library Specified!" ); + return 0; + } + + // In a library the 0 object is always the ref group. + %contentRefGroup = %libraryObj.getObject( 0 ); + + // Validate Ref Group. + if( !isObject( %contentRefGroup ) ) + { + //error( "GuiFormManager::BroadcastContentMessage - Unable to find library RefGroup!" ); + return 0; + } + + // Clear messaged object count + %messagedObjects = 0; + + // Iterate over all contents ref lists and message everyone + for( %refGroupIter = 0; %refGroupIter < %contentRefGroup.getCount(); %refGroupIter++ ) + { + + // Fetch the Object Reference List Set + %refListSet = %contentRefGroup.getObject( %refGroupIter ); + + + // Look for the content by name in our library. + for( %i = 0; %i < %refListSet.getCount(); %i++ ) + { + %object = %refListSet.getObject( %i ); + + // Check for alternate MessageControl + if( isObject( %object.MessageControl ) && %object.MessageControl.isMethod("onContentMessage") ) + %object.MessageControl.onContentMessage( %sender, %message ); + else if( %object.isMethod("onContentMessage") ) // Check for Default + %object.onContentMessage( %sender, %message ); + else + continue; + + // Increment Messaged Object Count. + %messagedObjects++; + } + + } + + // Return Success. + return %messagedObjects; +} + diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormReferenceManager.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormReferenceManager.ed.cs new file mode 100644 index 000000000..811947bbb --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/guiFormReferenceManager.ed.cs @@ -0,0 +1,119 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// Add Content Reference to RefList +// +// Returns : True or False. +//----------------------------------------------------------------------------- +function GuiFormManager::AddContentReference( %library, %contentName, %control ) +{ + // Fetch Content Object. + %contentObj = GuiFormManager::FindFormContent( %library, %contentName ); + + // See if we Found the Library. + if( %contentObj == 0 || !isObject( %contentObj ) ) + { + error( "GuiFormManager::AddContentReference - Unable to Find Library by Name or ID!" ); + return false; + } + + // Validate Ref List. + if( !isObject( %contentObj.RefList ) ) + { + error( "GuiFormManager::AddContentReference - Unable to find content RefList!" ); + return false; + } + + //error("adding ref for object" SPC %control ); + + // Add Control Reference. + %contentObj.RefList.add( %control ); + + // Return Success. + return true; +} + +//----------------------------------------------------------------------------- +// Remove Content Reference from RefList +// +// Returns : True or False. +//----------------------------------------------------------------------------- +function GuiFormManager::RemoveContentReference( %library, %contentName, %control ) +{ + // Fetch Content Object. + %contentObj = GuiFormManager::FindFormContent( %library, %contentName ); + + // See if we Found the Library. + if( %contentObj == 0 || !isObject( %contentObj ) ) + { + error( "GuiFormManager::AddContentReference - Unable to Find Library by Name or ID!" ); + return false; + } + + // Validate Ref List. + if( !isObject( %contentObj.RefList ) ) + { + error( "GuiFormManager::AddContentReference - Unable to find content RefList!" ); + return false; + } + + //error("removing ref for object" SPC %control ); + + // Add Control Reference. + %contentObj.RefList.remove( %control ); + + if( %control.isMethod("onFormRemove") ) + %control.onFormRemove(); + + // Return Success. + return true; +} + +//----------------------------------------------------------------------------- +// Gets the current number of instances of the specified content that are active +// +// Returns : Number of instances or 0. +//----------------------------------------------------------------------------- +function GuiFormManager::GetContentCount( %library, %contentName ) +{ + // Fetch Content Object. + %contentObj = GuiFormManager::FindFormContent( %library, %contentName ); + + // See if we Found the Library. + if( %contentObj == 0 || !isObject( %contentObj ) ) + { + error( "GuiFormManager::GetContentCount - Unable to Find Library by Name or ID!" ); + return 0; + } + + // Validate Ref List. + if( !isObject( %contentObj.RefList ) ) + { + error( "GuiFormManager::GetContentCount - Unable to find content RefList!" ); + return 0; + } + + // Return Count. + return %contentObj.RefList.getCount(); +} diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/input/applicationEvents.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/input/applicationEvents.ed.cs new file mode 100644 index 000000000..a4343f410 --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/input/applicationEvents.ed.cs @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +/// +/// Public Application Events +/// +Input::GetEventManager().registerEvent( "ClosePressed" ); +Input::GetEventManager().registerEvent( "BeginShutdown" ); +Input::GetEventManager().registerEvent( "FocusChanged" ); + +function onClosePressed() +{ + //error("% Application Close - User Pressed the X button on their window"); + Input::GetEventManager().postEvent( "ClosePressed" ); +} + +function onPreExit() +{ + //error("% Application Close - quit called or quit message received""); + Input::GetEventManager().postEvent( "BeginShutdown" ); +} + +function onWindowFocusChange( %focused ) +{ + //error("% Application Close - quit called or quit message received""); + Input::GetEventManager().postEvent( "FocusChanged", %focused ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/input/dragDropEvents.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/input/dragDropEvents.ed.cs new file mode 100644 index 000000000..70582bd20 --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/input/dragDropEvents.ed.cs @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +/// +/// Public DragDrop Events +/// +Input::GetEventManager().registerEvent( "BeginDropFiles" ); +Input::GetEventManager().registerEvent( "DropFile" ); +Input::GetEventManager().registerEvent( "EndDropFiles" ); + +function onDropBegin( %fileCount ) +{ + //error("% DragDrop - Beginning file dropping of" SPC %fileCount SPC " files."); + Input::GetEventManager().postEvent( "BeginDropFiles", %fileCount ); +} +function onDropFile( %filePath ) +{ + //error(" % DragDrop - Got File : " SPC %filePath ); + Input::GetEventManager().postEvent( "DropFile", %filePath ); +} +function onDropEnd( %fileCount ) +{ + + //error("% DragDrop - Completed file dropping"); + Input::GetEventManager().postEvent( "EndDropFiles" ); +} diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/input/inputEvents.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/input/inputEvents.ed.cs new file mode 100644 index 000000000..ba1b9e21a --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/input/inputEvents.ed.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +/// +/// Returns Projects API's EventManager Singleton +/// +function Input::GetEventManager() +{ + if( !isObject( $_Tools::InputEventManager ) ) + $_Tools::InputEventManager = new EventManager() { queue = "InputEventManager"; }; + + return $_Tools::InputEventManager; +} diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/platform/.gitignore b/Templates/BaseGame/game/tools/editorClasses/scripts/platform/.gitignore new file mode 100644 index 000000000..1bc0e838a --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/platform/.gitignore @@ -0,0 +1 @@ +# Keep directory in git repo diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/preferencesManager.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/preferencesManager.ed.cs new file mode 100644 index 000000000..62f84b0d3 --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/preferencesManager.ed.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//*** Initializes the Preferences Manager +function initPreferencesManager() +{ + // FIXME TGEA doesnt currently have these due to the way it's built + return; + + //*** Create the Preferences Manager singleton + %pm = new PreferencesManager(pref); + registerPreferencesManager(%pm.getId()); +} diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/projects/projectEvents.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/projects/projectEvents.ed.cs new file mode 100644 index 000000000..dc00a49a2 --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/projects/projectEvents.ed.cs @@ -0,0 +1,115 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +/// +/// Returns Projects API's EventManager Singleton +/// +function Projects::GetEventManager() +{ + if( !isObject( $_Tools::ProjectEventManager ) ) + $_Tools::ProjectEventManager = new EventManager() { queue = "ProjectEventManager"; }; + + return $_Tools::ProjectEventManager; +} + + +function Projects::DeclareProjectTarget( %projectTargetNamespace, %objectGlobalName ) +{ + // At some point it would be nice to have a console method + // on SimObject that supported validating that another object + // implemented all the methods provided by a given namespace. + // .validateInterface("myNamespace") or some such. + %projectObject = new ScriptMsgListener( %objectGlobalName ) + { + class = %projectTargetNamespace; + superclass = ProjectBase; + }; +} + +/// +/// Public Project Events +/// + +/// ProjectOpened +/// +/// is fired when a project has been opened and all bootstrap +/// processing has occured on the project object. +/// At this point it is safe for addons to do post-load processing +/// such as creating new create entries and other specific modifications +/// to the editor. +Projects::GetEventManager().registerEvent( "ProjectOpened" ); + +/// ProjectClosed +/// +/// is fired when a project is about to be closed and it's +/// resources destroyed by the base project class. Addons +/// should use this event to free any project specific resources +/// they have allocated, as well as saving of data where applicable. +Projects::GetEventManager().registerEvent( "ProjectClosed" ); + +/// ProjectDeploy +/// +/// is fired when a game is about to be run from the editor and on +/// this event addons and third party's should without scheduling or +/// other delaying calls, deploy any game data that the game will need +/// to it's game path. +/// +/// Example, the core package zip code intercepts this message and +/// builds and deploys a new core.zip if is necessary +Projects::GetEventManager().registerEvent( "ProjectDeploy" ); + +/// Currently Unused +Projects::GetEventManager().registerEvent( "ProjectFileAdded" ); +/// Currently Unused +Projects::GetEventManager().registerEvent( "ProjectFileRemoved" ); + +/// +/// ProjectOpen Event Handler +/// - %data is the project object to be opened +function ProjectBase::onProjectOpen( %this, %data ) +{ + error("onProjectOpen Handler not implemented for class -" SPC %this.class ); +} + +/// +/// ProjectClose Event Handler +/// +function ProjectBase::onProjectClose( %this, %data ) +{ + error("onProjectClose Handler not implemented for class -" SPC %this.class ); +} + +/// +/// ProjectAddFile Event Handler +/// +function ProjectBase::onProjectAddFile( %this, %data ) +{ + error("onProjectAddFile Handler not implemented for class -" SPC %this.class ); +} + +/// +/// ProjectRemoveFile Event Handler +/// +function ProjectBase::onProjectRemoveFile( %this, %data ) +{ + error("onProjectRemoveFile Handler not implemented for class -" SPC %this.class ); +} diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/projects/projectInternalInterface.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/projects/projectInternalInterface.ed.cs new file mode 100644 index 000000000..398eff6d9 --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/projects/projectInternalInterface.ed.cs @@ -0,0 +1,188 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +/// +/// Internal Project Events +/// +Projects::GetEventManager().registerEvent( "_ProjectCreate" ); +Projects::GetEventManager().registerEvent( "_ProjectOpen" ); +Projects::GetEventManager().registerEvent( "_ProjectClose" ); +Projects::GetEventManager().registerEvent( "_ProjectAddFile" ); +Projects::GetEventManager().registerEvent( "_ProjectRemoveFile" ); + +/// +/// Project Context Methods +/// + +function ProjectBase::isActive( %this ) +{ + if( Projects::GetEventManager().activeProject == %this.getId() ) + return true; + else + return false; +} + +function ProjectBase::getActiveProject( %this ) +{ + return Projects::GetEventManager().activeProject; +} + +function ProjectBase::setActive( %this ) +{ + %activeProject = %this.getActiveProject(); + + if( isObject( %activeProject ) ) + { + // If another is active, properly post a close event for now THEN + // and only then should we change the .activeProject field on the evtmgr + } + + Projects::GetEventManager().activeProject = %this; +} + +function ProjectBase::onAdd( %this ) +{ + // Subscribe to base events + Projects::GetEventManager().subscribe( %this, "_ProjectCreate", "_onProjectCreate" ); + Projects::GetEventManager().subscribe( %this, "_ProjectOpen", "_onProjectOpen" ); + Projects::GetEventManager().subscribe( %this, "_ProjectClose", "_onProjectClose" ); + Projects::GetEventManager().subscribe( %this, "_ProjectAddFile", "_onProjectAddFile" ); + Projects::GetEventManager().subscribe( %this, "_ProjectRemoveFile", "_onProjectRemoveFile" ); + +} + +function ProjectBase::onRemove( %this ) +{ + // Remove subscriptions to base events + Projects::GetEventManager().remove( %this, "_ProjectCreate" ); + Projects::GetEventManager().remove( %this, "_ProjectOpen" ); + Projects::GetEventManager().remove( %this, "_ProjectClose" ); + Projects::GetEventManager().remove( %this, "_ProjectAddFile" ); + Projects::GetEventManager().remove( %this, "_ProjectRemoveFile" ); + +} + +/// +/// Internal ProjectOpen Event Handler +/// - %data is the project file path to be opened +function ProjectBase::_onProjectOpen( %this, %data ) +{ + // Sanity check calling of this + if( !%this.isMethod( "onProjectOpen" ) ) + { + error("Incomplete Project Interface - onProjectOpen method is non-existent!"); + return false; + } + + if( !%this.LoadProject( %data ) ) + { + messageBox("Unable to Load Project", "The project file you're attempting to open was created with an incompatible version of this software\n\nConversion of 1.1.X projects will be addressed soon, we apologize for the inconvenience.","Ok","Error"); + + return false; + } + + %this.gamePath = filePath( %data ); + %this.projectFile = %data; + + %toggle = $Scripts::ignoreDSOs; + $Scripts::ignoreDSOs = true; + + %this.gameResPath = %this.gamePath @ "/*"; + + // Set current dir to game + setCurrentDirectory( %this.gamePath ); + + // Set ^game expando + setScriptPathExpando("project", %this.gamePath ); + setScriptPathExpando("game", %this.gamePath @ "/game" ); + + %this.onProjectOpen( %data ); + %this.setActive(); + + Projects::GetEventManager().postEvent( "ProjectOpened", %this ); + + $Scripts::ignoreDSOs = %toggle; + $pref::lastProject = %data; +} + +/// +/// Internal ProjectClose Event Handler +/// +function ProjectBase::_onProjectClose( %this, %data ) +{ + + Projects::GetEventManager().postEvent( "ProjectClosed", %this ); + + // Sanity check calling of this + if( !%this.isMethod( "onProjectClose" ) ) + error("Incomplete Project Interface - onProjectClose method is non-existent!"); + else + %this.onProjectClose( %data ); + + // Reset to tools directory + setCurrentDirectory( getMainDotCsDir() ); + + // Remove expandos + removeScriptPathExpando( "game" ); + removeScriptPathExpando( "project" ); +} + +/// +/// Internal ProjectCreate Event Handler (Optionally Inherited by public interface) +/// +function ProjectBase::_onProjectCreate( %this, %data ) +{ + // Force a write out of the project file + if( !%this.SaveProject( %data ) ) + return false; + + // Sanity check calling of this + if( %this.isMethod( "onProjectCreate" ) ) + %this.onProjectCreate( %data ); +} + + +/// +/// Internal ProjectAddFile Event Handler +/// +function ProjectBase::_onProjectAddFile( %this, %data ) +{ + // Sanity check calling of this + if( !%this.isMethod( "onProjectAddFile" ) ) + error("Incomplete Project Interface - onProjectAddFile method is non-existent!"); + else + %this.onProjectAddFile( %data ); + +} + +/// +/// Internal ProjectRemoveFile Event Handler +/// +function ProjectBase::_onProjectRemoveFile( %this, %data ) +{ + // Sanity check calling of this + if( !%this.isMethod( "onProjectRemoveFile" ) ) + error("Incomplete Project Interface - onProjectRemoveFile method is non-existent!"); + else + %this.onProjectRemoveFile( %data ); + +} diff --git a/Templates/BaseGame/game/tools/editorClasses/scripts/utility.ed.cs b/Templates/BaseGame/game/tools/editorClasses/scripts/utility.ed.cs new file mode 100644 index 000000000..e1dadfeee --- /dev/null +++ b/Templates/BaseGame/game/tools/editorClasses/scripts/utility.ed.cs @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function isInList( %word, %list ) +{ + %count = getWordCount( %list ); + for( %i = 0; %i < %count; %i++ ) + { + %entry = getWord( %list, %i ); + if( %word $= %entry ) + return true; + } + + return false; +} + +function isInFieldList(%word, %list) +{ + %count = getFieldCount( %list ); + for( %i = 0; %i < %count; %i++ ) + { + %entry = getField( %list, %i ); + if( %word $= %entry ) + return true; + } + + return false; +} diff --git a/Templates/BaseGame/game/tools/forestEditor/brushes.cs b/Templates/BaseGame/game/tools/forestEditor/brushes.cs new file mode 100644 index 000000000..e99d2e537 --- /dev/null +++ b/Templates/BaseGame/game/tools/forestEditor/brushes.cs @@ -0,0 +1,22 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + diff --git a/Templates/BaseGame/game/tools/forestEditor/forestEditToolbar.ed.gui b/Templates/BaseGame/game/tools/forestEditor/forestEditToolbar.ed.gui new file mode 100644 index 000000000..782383121 --- /dev/null +++ b/Templates/BaseGame/game/tools/forestEditor/forestEditToolbar.ed.gui @@ -0,0 +1,437 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ForestEditToolbar,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "306 0"; + Extent = "800 40"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ForestEditToolbar"; + canSaveDynamicFields = "1"; + enabled = "1"; + + new GuiTextCtrl() { + text = "Brush Settings"; + maxLength = "255"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "6 7"; + Extent = "70 16"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "760 40"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiControl(ForestBrushSizeTextEditContainer) { + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Size"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "21 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = "9"; + maxLength = "4"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "49 2"; + Extent = "42 18"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + AltCommand = "ForestTools->BrushTool.size = $ThisControl.getValue();"; + validate = "ForestEditorGui.validateBrushSize();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "textEdit"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/dropslider"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(ForestBrushSizeSliderCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes size of the brush"; + hovertime = "750"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapCtrl() { + bitmap = "tools/gui/images/separator-h.png"; + wrap = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "200 3"; + Extent = "2 26"; + MinExtent = "1 1"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiControl(ForestBrushPressureTextEditContainer) { + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "208 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Pressure"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = "100"; + maxLength = "3"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "49 2"; + Extent = "42 18"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ForestTools->BrushTool.pressure = $ThisControl.getValue() / 100;"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "textEdit"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/dropslider"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(ForestBrushPressureSliderCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes the pressure"; + hovertime = "750"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapCtrl() { + bitmap = "tools/gui/images/separator-h.png"; + wrap = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "336 3"; + Extent = "2 26"; + MinExtent = "1 1"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiControl(ForestBrushHardnessTextEditContainer) { + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "352 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Hardness"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = "1"; + maxLength = "3"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "49 2"; + Extent = "42 18"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ForestTools->BrushTool.hardness = $ThisControl.getValue() / 100);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "textEdit"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/dropslider"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(ForestBrushHardnessSliderCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes the hardness curve."; + hovertime = "750"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; + +new GuiMouseEventCtrl(ForestBrushSizeSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(ForestBrushSizeTextEditContainer.position) + firstWord(ForestEditToolbar.position)+11 SPC + (getWord(ForestBrushSizeTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ForestTools->BrushTool.size = $ThisControl.value;"; + range = "1" SPC getWord(ETerrainEditor.maxBrushSize, 0); + ticks = "0"; + value = "0"; + }; +}; + +new GuiMouseEventCtrl(ForestBrushPressureSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(ForestBrushPressureTextEditContainer.position) + firstWord(ForestEditToolbar.position) SPC + (getWord(ForestBrushPressureTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ForestTools->BrushTool.pressure = $ThisControl.value;"; + range = "0.01 1"; + ticks = "0"; + value = "0"; + }; +}; + +new GuiMouseEventCtrl(ForestBrushHardnessSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(ForestBrushHardnessTextEditContainer.position) + firstWord(ForestEditToolbar.position) SPC + (getWord(TForestBrushHardnessTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ForestTools->BrushTool.hardness = $ThisControl.value;"; + range = "0 1"; + ticks = "0"; + value = "0"; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/forestEditor/forestEditor.cs b/Templates/BaseGame/game/tools/forestEditor/forestEditor.cs new file mode 100644 index 000000000..274f735a5 --- /dev/null +++ b/Templates/BaseGame/game/tools/forestEditor/forestEditor.cs @@ -0,0 +1,27 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton GuiControlProfile (ForestEditorProfile) +{ + canKeyFocus = true; + category = "Editor"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/forestEditor/forestEditorGui.cs b/Templates/BaseGame/game/tools/forestEditor/forestEditorGui.cs new file mode 100644 index 000000000..e0e9f1ce4 --- /dev/null +++ b/Templates/BaseGame/game/tools/forestEditor/forestEditorGui.cs @@ -0,0 +1,502 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +// ForestEditorGui Script Methods + +function ForestEditorGui::setActiveTool( %this, %tool ) +{ + if ( %tool == ForestTools->BrushTool ) + ForestEditTabBook.selectPage(0); + + Parent::setActiveTool( %this, %tool ); +} + +/// This is called by the editor when the active forest has +/// changed giving us a chance to update the GUI. +function ForestEditorGui::onActiveForestUpdated( %this, %forest, %createNew ) +{ + %gotForest = isObject( %forest ); + + // Give the user a chance to add a forest. + if ( !%gotForest && %createNew ) + { + MessageBoxYesNo( "Forest", + "There is not a Forest in this mission. Do you want to add one?", + %this @ ".createForest();", "" ); + return; + } +} + +/// Called from a message box when a forest is not found. +function ForestEditorGui::createForest( %this ) +{ + %forestObject = parseMissionGroupForIds("Forest", ""); + + if ( isObject( %forestObject ) ) + { + error( "Cannot create a second 'theForest' Forest!" ); + return; + } + + // Allocate the Forest and make it undoable. + new Forest( theForest ) + { + dataFile = ""; + parentGroup = "MissionGroup"; + }; + + MECreateUndoAction::submit( theForest ); + + ForestEditorGui.setActiveForest( theForest ); + + //Re-initialize the editor settings so we can start using it immediately. + %tool = ForestEditorGui.getActiveTool(); + if ( isObject( %tool ) ) + %tool.onActivated(); + + if ( %tool == ForestTools->SelectionTool ) + { + %mode = GlobalGizmoProfile.mode; + switch$ (%mode) + { + case "None": + ForestEditorSelectModeBtn.performClick(); + case "Move": + ForestEditorMoveModeBtn.performClick(); + case "Rotate": + ForestEditorRotateModeBtn.performClick(); + case "Scale": + ForestEditorScaleModeBtn.performClick(); + } + } + else if ( %tool == ForestTools->BrushTool ) + { + %mode = ForestTools->BrushTool.mode; + switch$ (%mode) + { + case "Paint": + ForestEditorPaintModeBtn.performClick(); + case "Erase": + ForestEditorEraseModeBtn.performClick(); + case "EraseSelected": + ForestEditorEraseSelectedModeBtn.performClick(); + } + } + + EWorldEditor.isDirty = true; +} + +function ForestEditorGui::newBrush( %this ) +{ + %internalName = getUniqueInternalName( "Brush", ForestBrushGroup, true ); + + %brush = new ForestBrush() + { + internalName = %internalName; + parentGroup = ForestBrushGroup; + }; + + MECreateUndoAction::submit( %brush ); + + ForestEditBrushTree.open( ForestBrushGroup ); + ForestEditBrushTree.buildVisibleTree(true); + %item = ForestEditBrushTree.findItemByObjectId( %brush ); + ForestEditBrushTree.clearSelection(); + ForestEditBrushTree.addSelection( %item ); + ForestEditBrushTree.scrollVisible( %item ); + + ForestEditorPlugin.dirty = true; +} + +function ForestEditorGui::newElement( %this ) +{ + %sel = ForestEditBrushTree.getSelectedObject(); + + if ( !isObject( %sel ) ) + %parentGroup = ForestBrushGroup; + else + { + if ( %sel.getClassName() $= "ForestBrushElement" ) + %parentGroup = %sel.parentGroup; + else + %parentGroup = %sel; + } + + %internalName = getUniqueInternalName( "Element", ForestBrushGroup, true ); + + %element = new ForestBrushElement() + { + internalName = %internalName; + parentGroup = %parentGroup; + }; + + MECreateUndoAction::submit( %element ); + + ForestEditBrushTree.clearSelection(); + ForestEditBrushTree.buildVisibleTree( true ); + %item = ForestEditBrushTree.findItemByObjectId( %element.getId() ); + ForestEditBrushTree.scrollVisible( %item ); + ForestEditBrushTree.addSelection( %item ); + + ForestEditorPlugin.dirty = true; +} + +function ForestEditorGui::deleteBrushOrElement( %this ) +{ + ForestEditBrushTree.deleteSelection(); + ForestEditorPlugin.dirty = true; +} + +function ForestEditorGui::newMesh( %this ) +{ + %spec = "All Mesh Files|*.dts;*.dae|DTS|*.dts|DAE|*.dae"; + + %dlg = new OpenFileDialog() + { + Filters = %spec; + DefaultPath = $Pref::WorldEditor::LastPath; + DefaultFile = ""; + ChangePath = true; + }; + + %ret = %dlg.Execute(); + + if ( %ret ) + { + $Pref::WorldEditor::LastPath = filePath( %dlg.FileName ); + %fullPath = makeRelativePath( %dlg.FileName, getMainDotCSDir() ); + %file = fileBase( %fullPath ); + } + + %dlg.delete(); + + if ( !%ret ) + return; + + %name = getUniqueName( %file ); + + %str = "datablock TSForestItemData( " @ %name @ " ) { shapeFile = \"" @ %fullPath @ "\"; };"; + eval( %str ); + + if ( isObject( %name ) ) + { + ForestEditMeshTree.clearSelection(); + ForestEditMeshTree.buildVisibleTree( true ); + %item = ForestEditMeshTree.findItemByObjectId( %name.getId() ); + ForestEditMeshTree.scrollVisible( %item ); + ForestEditMeshTree.addSelection( %item ); + + ForestDataManager.setDirty( %name, "art/forest/managedItemData.cs" ); + + %element = new ForestBrushElement() + { + internalName = %name; + forestItemData = %name; + parentGroup = ForestBrushGroup; + }; + + ForestEditBrushTree.clearSelection(); + ForestEditBrushTree.buildVisibleTree( true ); + %item = ForestEditBrushTree.findItemByObjectId( %element.getId() ); + ForestEditBrushTree.scrollVisible( %item ); + ForestEditBrushTree.addSelection( %item ); + + pushInstantGroup(); + %action = new MECreateUndoAction() + { + actionName = "Create TSForestItemData"; + }; + popInstantGroup(); + + %action.addObject( %name ); + %action.addObject( %element ); + %action.addToManager( Editor.getUndoManager() ); + + ForestEditorPlugin.dirty = true; + } +} + +function ForestEditorGui::deleteMesh( %this ) +{ + %obj = ForestEditMeshTree.getSelectedObject(); + + // Can't delete itemData's that are in use without + // crashing at the moment... + + if ( isObject( %obj ) ) + { + MessageBoxOKCancel( "Warning", + "Deleting this mesh will also delete BrushesElements and ForestItems referencing it.", + "ForestEditorGui.okDeleteMesh(" @ %obj @ ");", + "" ); + } +} + +function ForestEditorGui::okDeleteMesh( %this, %mesh ) +{ + // Remove mesh from file + ForestDataManager.removeObjectFromFile( %mesh, "art/forest/managedItemData.cs" ); + + // Submitting undo actions is handled in code. + %this.deleteMeshSafe( %mesh ); + + // Update TreeViews. + ForestEditBrushTree.buildVisibleTree( true ); + ForestEditMeshTree.buildVisibleTree( true ); + + ForestEditorPlugin.dirty = true; +} + +function ForestEditorGui::validateBrushSize( %this ) +{ + %minBrushSize = 1; + %maxBrushSize = getWord(ETerrainEditor.maxBrushSize, 0); + + %val = $ThisControl.getText(); + if(%val < %minBrushSize) + $ThisControl.setValue(%minBrushSize); + else if(%val > %maxBrushSize) + $ThisControl.setValue(%maxBrushSize); +} + + + +// Child-control Script Methods + + +function ForestEditMeshTree::onSelect( %this, %obj ) +{ + ForestEditorInspector.inspect( %obj ); +} + +function ForestEditBrushTree::onRemoveSelection( %this, %obj ) +{ + %this.buildVisibleTree( true ); + ForestTools->BrushTool.collectElements(); + + if ( %this.getSelectedItemsCount() == 1 ) + ForestEditorInspector.inspect( %obj ); + else + ForestEditorInspector.inspect( "" ); +} + +function ForestEditBrushTree::onAddSelection( %this, %obj ) +{ + %this.buildVisibleTree( true ); + ForestTools->BrushTool.collectElements(); + + if ( %this.getSelectedItemsCount() == 1 ) + ForestEditorInspector.inspect( %obj ); + else + ForestEditorInspector.inspect( "" ); +} + +function ForestEditTabBook::onTabSelected( %this, %text, %idx ) +{ + %bbg = ForestEditorPalleteWindow.findObjectByInternalName("BrushButtonGroup"); + %mbg = ForestEditorPalleteWindow.findObjectByInternalName("MeshButtonGroup"); + + %bbg.setVisible( false ); + %mbg.setVisible( false ); + + if ( %text $= "Brushes" ) + { + %bbg.setVisible( true ); + %obj = ForestEditBrushTree.getSelectedObject(); + ForestEditorInspector.inspect( %obj ); + } + else if ( %text $= "Meshes" ) + { + %mbg.setVisible( true ); + %obj = ForestEditMeshTree.getSelectedObject(); + ForestEditorInspector.inspect( %obj ); + } +} + +function ForestEditBrushTree::onDeleteSelection( %this ) +{ + %list = ForestEditBrushTree.getSelectedObjectList(); + + MEDeleteUndoAction::submit( %list, true ); + + ForestEditorPlugin.dirty = true; +} + +function ForestEditBrushTree::onDragDropped( %this ) +{ + ForestEditorPlugin.dirty = true; +} + +function ForestEditMeshTree::onDragDropped( %this ) +{ + ForestEditorPlugin.dirty = true; +} + +function ForestEditMeshTree::onDeleteObject( %this, %obj ) +{ + // return true - skip delete. + return true; +} + +function ForestEditMeshTree::onDoubleClick( %this ) +{ + %obj = %this.getSelectedObject(); + + %name = getUniqueInternalName( %obj.getName(), ForestBrushGroup, true ); + + %element = new ForestBrushElement() + { + internalName = %name; + forestItemData = %obj.getName(); + parentGroup = ForestBrushGroup; + }; + + //ForestDataManager.setDirty( %element, "art/forest/brushes.cs" ); + + ForestEditBrushTree.clearSelection(); + ForestEditBrushTree.buildVisibleTree( true ); + %item = ForestEditBrushTree.findItemByObjectId( %element ); + ForestEditBrushTree.scrollVisible( %item ); + ForestEditBrushTree.addSelection( %item ); + + ForestEditorPlugin.dirty = true; +} + +function ForestEditBrushTree::handleRenameObject( %this, %name, %obj ) +{ + if ( %name !$= "" ) + { + %found = ForestBrushGroup.findObjectByInternalName( %name ); + if ( isObject( %found ) && %found.getId() != %obj.getId() ) + { + MessageBoxOK( "Error", "Brush or Element with that name already exists.", "" ); + + // true as in, we handled it, don't rename the object. + return true; + } + } + + // Since we aren't showing any groups whens inspecting a ForestBrushGroup + // we can't push this event off to the inspector to handle. + + //return GuiTreeViewCtrl::handleRenameObject( %this, %name, %obj ); + + + // The instant group will try to add our + // UndoAction if we don't disable it. + pushInstantGroup(); + + %nameOrClass = %obj.getName(); + if ( %nameOrClass $= "" ) + %nameOrClass = %obj.getClassname(); + + %action = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ "internalName" @ " Change"; + + objectId = %obj.getId(); + fieldName = "internalName"; + fieldValue = %obj.internalName; + arrayIndex = 0; + + inspectorGui = ""; + }; + + // Restore the instant group. + popInstantGroup(); + + %action.addToManager( Editor.getUndoManager() ); + EWorldEditor.isDirty = true; + + return false; +} + +function ForestEditorInspector::inspect( %this, %obj ) +{ + if ( isObject( %obj ) ) + %class = %obj.getClassName(); + + %this.showObjectName = false; + %this.showCustomFields = false; + + switch$ ( %class ) + { + case "ForestBrush": + %this.groupFilters = "+NOTHING,-Ungrouped"; + + case "ForestBrushElement": + %this.groupFilters = "+ForestBrushElement,-Ungrouped"; + + case "TSForestItemData": + %this.groupFilters = "+Media,+Wind"; + + default: + %this.groupFilters = ""; + } + + Parent::inspect( %this, %obj ); +} + +function ForestEditorInspector::onInspectorFieldModified( %this, %object, %fieldName, %oldValue, %newValue ) +{ + // The instant group will try to add our + // UndoAction if we don't disable it. + %instantGroup = $InstantGroup; + $InstantGroup = 0; + + %nameOrClass = %object.getName(); + if ( %nameOrClass $= "" ) + %nameOrClass = %object.getClassname(); + + %action = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ %fieldName @ " Change"; + + objectId = %object.getId(); + fieldName = %fieldName; + fieldValue = %oldValue; + + inspectorGui = %this; + }; + + // Restore the instant group. + $InstantGroup = %instantGroup; + + %action.addToManager( Editor.getUndoManager() ); + + if ( %object.getClassName() $= "TSForestItemData" ) + ForestDataManager.setDirty( %object ); + + ForestEditorPlugin.dirty = true; +} + +function ForestEditorInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + //FieldInfoControl.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} + +function ForestBrushSizeSliderCtrlContainer::onWake(%this) +{ + %this-->slider.range = "1" SPC getWord(ETerrainEditor.maxBrushSize, 0); + %this-->slider.setValue(ForestBrushSizeTextEditContainer-->textEdit.getValue()); +} diff --git a/Templates/BaseGame/game/tools/forestEditor/forestEditorGui.gui b/Templates/BaseGame/game/tools/forestEditor/forestEditorGui.gui new file mode 100644 index 000000000..e46a09f3d --- /dev/null +++ b/Templates/BaseGame/game/tools/forestEditor/forestEditorGui.gui @@ -0,0 +1,511 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new ForestEditorCtrl(ForestEditorGui,EditorGuiGroup) { + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "255 0 0 120"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + cameraZRot = "0"; + forceFOV = "0"; + reflectPriority = "1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ForestEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiWindowCollapseCtrl(ForestEditorPalleteWindow) { + CollapseGroup = "-1"; + CollapseGroupNum = "-1"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Forest Editor"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowCollapseProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1)-1; + Extent = "210 252"; + MinExtent = "210 100"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "PalleteWindow"; + canSaveDynamicFields = "0"; + + new GuiTabBookCtrl(ForestEditTabBook) { + TabPosition = "Top"; + TabMargin = "10"; + MinTabWidth = "60"; + TabHeight = "20"; + AllowReorder = "0"; + FrontTabPadding = "0"; + Docking = "Client"; + Margin = "3 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "3 44"; + Extent = "210 205"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl() { + fitBook = "0"; + text = "Brushes"; + maxLength = "1024"; + Docking = "Client"; + Margin = "-1 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 22"; + Extent = "210 194"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "BrushesTab"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "210 194"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(ForestEditBrushTree) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "1"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "1"; + ClearAllOnSingleSelection = "1"; + showRoot = "0"; + internalNamesOnly = "1"; + objectNamesOnly = "0"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "1"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "208 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiTabPageCtrl() { + fitBook = "0"; + text = "Meshes"; + maxLength = "1024"; + Docking = "Client"; + Margin = "-1 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 22"; + Extent = "210 183"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "MeshesTab"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "210 194"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(ForestEditMeshTree) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "0"; + DragToItemAllowed = "0"; + ClearAllOnSingleSelection = "1"; + showRoot = "0"; + internalNamesOnly = "0"; + objectNamesOnly = "1"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + compareToObjectID = "0"; + canRenameObjects = "1"; + renameInternal = "0"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 -67"; + Extent = "208 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "$ThisControl.onDoubleClick();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiStackControl() { + StackingType = "Horizontal"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "3"; + DynamicSize = "1"; + ChangeChildSizeToFit = "0"; + ChangeChildPosition = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "170 25"; + Extent = "35 17"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "MeshButtonGroup"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/forestEditor/images/new-mesh"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.newMesh();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Add New Mesh"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "19 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.deleteMesh();"; + tooltip = "Delete Selected"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiStackControl() { + StackingType = "Horizontal"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "3"; + DynamicSize = "1"; + ChangeChildSizeToFit = "0"; + ChangeChildPosition = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "151 25"; + Extent = "54 17"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "BrushButtonGroup"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/forestEditor/images/new-brush"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.newBrush();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Add New Brush Group"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/forestEditor/images/new-element"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "19 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.newElement();"; + tooltip = "Add New Brush Element"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "38 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.deleteBrushOrElement();"; + tooltip = "Delete Selected"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiWindowCollapseCtrl(ForestEditorPropertiesWindow) { + CollapseGroup = "-1"; + CollapseGroupNum = "-1"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Properties"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowCollapseProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(ForestEditorPalleteWindow.extent, 1) - 2; + Extent = "210 460"; + MinExtent = "210 50"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "PropertiesWindow"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Docking = "Client"; + Margin = "3 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "3 23"; + Extent = "210 263"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiInspector(ForestEditorInspector) { + dividerMargin = "5"; + showCustomFields = "0"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + DynamicSize = "1"; + ChangeChildSizeToFit = "1"; + ChangeChildPosition = "1"; + isContainer = "1"; + Profile = "GuiInspectorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "1 1"; + Extent = "193 16"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "Inspector"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/forestEditor/images/erase-all-btn_d.png b/Templates/BaseGame/game/tools/forestEditor/images/erase-all-btn_d.png new file mode 100644 index 000000000..24af47fb0 Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/erase-all-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/erase-all-btn_h.png b/Templates/BaseGame/game/tools/forestEditor/images/erase-all-btn_h.png new file mode 100644 index 000000000..66d75bb5b Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/erase-all-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/erase-all-btn_n.png b/Templates/BaseGame/game/tools/forestEditor/images/erase-all-btn_n.png new file mode 100644 index 000000000..ec82f5ac0 Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/erase-all-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/erase-element-btn_d.png b/Templates/BaseGame/game/tools/forestEditor/images/erase-element-btn_d.png new file mode 100644 index 000000000..8f45d199e Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/erase-element-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/erase-element-btn_h.png b/Templates/BaseGame/game/tools/forestEditor/images/erase-element-btn_h.png new file mode 100644 index 000000000..26189746f Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/erase-element-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/erase-element-btn_n.png b/Templates/BaseGame/game/tools/forestEditor/images/erase-element-btn_n.png new file mode 100644 index 000000000..05fb6690f Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/erase-element-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/forest-editor-btn_d.png b/Templates/BaseGame/game/tools/forestEditor/images/forest-editor-btn_d.png new file mode 100644 index 000000000..79745e5bd Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/forest-editor-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/forest-editor-btn_h.png b/Templates/BaseGame/game/tools/forestEditor/images/forest-editor-btn_h.png new file mode 100644 index 000000000..5351983f6 Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/forest-editor-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/forest-editor-btn_n.png b/Templates/BaseGame/game/tools/forestEditor/images/forest-editor-btn_n.png new file mode 100644 index 000000000..3c305350f Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/forest-editor-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/new-brush_d.png b/Templates/BaseGame/game/tools/forestEditor/images/new-brush_d.png new file mode 100644 index 000000000..df1e11c35 Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/new-brush_d.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/new-brush_h.png b/Templates/BaseGame/game/tools/forestEditor/images/new-brush_h.png new file mode 100644 index 000000000..57391fe5f Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/new-brush_h.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/new-brush_n.png b/Templates/BaseGame/game/tools/forestEditor/images/new-brush_n.png new file mode 100644 index 000000000..e5d51f5d0 Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/new-brush_n.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/new-element_d.png b/Templates/BaseGame/game/tools/forestEditor/images/new-element_d.png new file mode 100644 index 000000000..bac080398 Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/new-element_d.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/new-element_h.png b/Templates/BaseGame/game/tools/forestEditor/images/new-element_h.png new file mode 100644 index 000000000..c9ddc03f0 Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/new-element_h.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/new-element_n.png b/Templates/BaseGame/game/tools/forestEditor/images/new-element_n.png new file mode 100644 index 000000000..61f42fb9c Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/new-element_n.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/new-mesh_d.png b/Templates/BaseGame/game/tools/forestEditor/images/new-mesh_d.png new file mode 100644 index 000000000..c21bb3969 Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/new-mesh_d.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/new-mesh_h.png b/Templates/BaseGame/game/tools/forestEditor/images/new-mesh_h.png new file mode 100644 index 000000000..705a7a836 Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/new-mesh_h.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/new-mesh_n.png b/Templates/BaseGame/game/tools/forestEditor/images/new-mesh_n.png new file mode 100644 index 000000000..c4c01754c Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/new-mesh_n.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/paint-forest-btn_d.png b/Templates/BaseGame/game/tools/forestEditor/images/paint-forest-btn_d.png new file mode 100644 index 000000000..2d2facc71 Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/paint-forest-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/paint-forest-btn_h.png b/Templates/BaseGame/game/tools/forestEditor/images/paint-forest-btn_h.png new file mode 100644 index 000000000..8a2bda1eb Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/paint-forest-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/images/paint-forest-btn_n.png b/Templates/BaseGame/game/tools/forestEditor/images/paint-forest-btn_n.png new file mode 100644 index 000000000..ad9242ead Binary files /dev/null and b/Templates/BaseGame/game/tools/forestEditor/images/paint-forest-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/forestEditor/main.cs b/Templates/BaseGame/game/tools/forestEditor/main.cs new file mode 100644 index 000000000..346365b04 --- /dev/null +++ b/Templates/BaseGame/game/tools/forestEditor/main.cs @@ -0,0 +1,311 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function initializeForestEditor() +{ + echo(" % - Initializing Forest Editor"); + + exec( "./forestEditor.cs" ); + exec( "./forestEditorGui.gui" ); + exec( "./forestEditToolbar.ed.gui" ); + + exec( "./forestEditorGui.cs" ); + exec( "./tools.cs" ); + + ForestEditorGui.setVisible( false ); + ForestEditorPalleteWindow.setVisible( false ); + ForestEditorPropertiesWindow.setVisible( false ); + ForestEditToolbar.setVisible( false ); + + EditorGui.add( ForestEditorGui ); + EditorGui.add( ForestEditorPalleteWindow ); + EditorGui.add( ForestEditorPropertiesWindow ); + EditorGui.add( ForestEditToolbar ); + + new ScriptObject( ForestEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = ForestEditorGui; + }; + + new SimSet(ForestTools) + { + new ForestBrushTool() + { + internalName = "BrushTool"; + toolTip = "Paint Tool"; + buttonImage = "tools/forest/images/brushTool"; + }; + + new ForestSelectionTool() + { + internalName = "SelectionTool"; + toolTip = "Selection Tool"; + buttonImage = "tools/forest/images/selectionTool"; + }; + }; + + %map = new ActionMap(); + %map.bindCmd( keyboard, "1", "ForestEditorSelectModeBtn.performClick();", "" ); // Select + %map.bindCmd( keyboard, "2", "ForestEditorMoveModeBtn.performClick();", "" ); // Move + %map.bindCmd( keyboard, "3", "ForestEditorRotateModeBtn.performClick();", "" ); // Rotate + %map.bindCmd( keyboard, "4", "ForestEditorScaleModeBtn.performClick();", "" ); // Scale + %map.bindCmd( keyboard, "5", "ForestEditorPaintModeBtn.performClick();", "" ); // Paint + %map.bindCmd( keyboard, "6", "ForestEditorEraseModeBtn.performClick();", "" ); // Erase + %map.bindCmd( keyboard, "7", "ForestEditorEraseSelectedModeBtn.performClick();", "" ); // EraseSelected + //%map.bindCmd( keyboard, "backspace", "ForestEditorGui.onDeleteKey();", "" ); + //%map.bindCmd( keyboard, "delete", "ForestEditorGui.onDeleteKey();", "" ); + ForestEditorPlugin.map = %map; +} + +function destroyForestEditor() +{ +} + +// NOTE: debugging helper. +function reinitForest() +{ + exec( "./main.cs" ); + exec( "./forestEditorGui.cs" ); + exec( "./tools.cs" ); +} + +function ForestEditorPlugin::onWorldEditorStartup( %this ) +{ + new PersistenceManager( ForestDataManager ); + + %brushPath = "tools/forestEditor/brushes.cs"; + + if ( !isFile( %brushPath ) ) + %successfulFile = createPath( %brushPath ); + + // This creates the ForestBrushGroup, all brushes, and elements. + exec( %brushpath ); + + if ( !isObject( ForestBrushGroup ) ) + { + new SimGroup( ForestBrushGroup ); + %this.showError = true; + } + + ForestEditBrushTree.open( ForestBrushGroup ); + + if ( !isObject( ForestItemDataSet ) ) + new SimSet( ForestItemDataSet ); + + ForestEditMeshTree.open( ForestItemDataSet ); + + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Forest Editor", "", ForestEditorPlugin ); + + // Add ourselves to the tools menu. + %tooltip = "Forest Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "ForestEditorPlugin", "ForestEditorPalette", expandFilename("tools/forestEditor/images/forest-editor-btn"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( ForestEditorPropertiesWindow, ForestEditorPalleteWindow ); + ForestEditTabBook.selectPage(0); +} + +function ForestEditorPlugin::onWorldEditorShutdown( %this ) +{ + if ( isObject( ForestBrushGroup ) ) + ForestBrushGroup.delete(); + if ( isObject( ForestDataManager ) ) + ForestDataManager.delete(); +} + +function ForestEditorPlugin::onActivated( %this ) +{ + EditorGui.bringToFront( ForestEditorGui ); + ForestEditorGui.setVisible( true ); + ForestEditorPalleteWindow.setVisible( true ); + ForestEditorPropertiesWindow.setVisible( true ); + ForestEditorGui.makeFirstResponder( true ); + //ForestEditToolbar.setVisible( true ); + + //Get our existing forest object in our current mission if we have one + %forestObject = parseMissionGroupForIds("Forest", ""); + if(isObject(%forestObject)) + { + ForestEditorGui.setActiveForest(%forestObject.getName()); + } + + %this.map.push(); + Parent::onActivated(%this); + + ForestEditBrushTree.open( ForestBrushGroup ); + ForestEditMeshTree.open( ForestItemDataSet ); + + // Open the Brush tab. + ForestEditTabBook.selectPage(0); + + // Sync the pallete button state + + // And toolbar. + %tool = ForestEditorGui.getActiveTool(); + if ( isObject( %tool ) ) + %tool.onActivated(); + + if ( !isObject( %tool ) ) + { + ForestEditorPaintModeBtn.performClick(); + + if ( ForestEditBrushTree.getItemCount() > 0 ) + { + ForestEditBrushTree.selectItem( 0, true ); + } + } + else if ( %tool == ForestTools->SelectionTool ) + { + %mode = GlobalGizmoProfile.mode; + switch$ (%mode) + { + case "None": + ForestEditorSelectModeBtn.performClick(); + case "Move": + ForestEditorMoveModeBtn.performClick(); + case "Rotate": + ForestEditorRotateModeBtn.performClick(); + case "Scale": + ForestEditorScaleModeBtn.performClick(); + } + } + else if ( %tool == ForestTools->BrushTool ) + { + %mode = ForestTools->BrushTool.mode; + switch$ (%mode) + { + case "Paint": + ForestEditorPaintModeBtn.performClick(); + case "Erase": + ForestEditorEraseModeBtn.performClick(); + case "EraseSelected": + ForestEditorEraseSelectedModeBtn.performClick(); + } + } + + if ( %this.showError ) + MessageBoxOK( "Error", "Your tools/forestEditor folder does not contain a valid brushes.cs. Brushes you create will not be saved!" ); +} + +function ForestEditorPlugin::onDeactivated( %this ) +{ + ForestEditorGui.setVisible( false ); + ForestEditorPalleteWindow.setVisible( false ); + ForestEditorPropertiesWindow.setVisible( false ); + + %tool = ForestEditorGui.getActiveTool(); + if ( isObject( %tool ) ) + %tool.onDeactivated(); + + // Also take this opportunity to save. + ForestDataManager.saveDirty(); + + %this.map.pop(); + + Parent::onDeactivated(%this); +} + +function ForestEditorPlugin::isDirty( %this ) +{ + %dirty = %this.dirty || ForestEditorGui.isDirty(); + return %dirty; +} + +function ForestEditorPlugin::clearDirty( %this ) +{ + %this.dirty = false; +} + +function ForestEditorPlugin::onSaveMission( %this, %missionFile ) +{ + ForestDataManager.saveDirty(); + + //First, find out if we have an existing forest object + %forestObject = parseMissionGroupForIds("Forest", ""); + + if ( isObject( %forestObject ) ) + { + //We do. Next, see if we have a file already by polling the datafield. + if(%forestObject.dataFile !$= "") + { + //If we do, just save to the provided file. + %forestObject.saveDataFile(%forestObject.dataFile); + } + else + { + //We don't, so we'll save in the same place as the mission file and give it the missionpath\missionName.forest + //naming convention. + %path = filePath(%missionFile); + %missionName = fileBase(%missionFile); + %forestObject.saveDataFile(%path @ "/" @ %missionName @ ".forest"); + } + } + + ForestBrushGroup.save( "tools/forestEditor/brushes.cs" ); +} + +function ForestEditorPlugin::onEditorSleep( %this ) +{ +} + +function ForestEditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %hasSelection = false; + + %selTool = ForestTools->SelectionTool; + if ( ForestEditorGui.getActiveTool() == %selTool ) + if ( %selTool.getSelectionCount() > 0 ) + %hasSelection = true; + + %editMenu.enableItem( 3, %hasSelection ); // Cut + %editMenu.enableItem( 4, %hasSelection ); // Copy + %editMenu.enableItem( 5, %hasSelection ); // Paste + %editMenu.enableItem( 6, %hasSelection ); // Delete + %editMenu.enableItem( 8, %hasSelection ); // Deselect +} + +function ForestEditorPlugin::handleDelete( %this ) +{ + ForestTools->SelectionTool.deleteSelection(); +} + +function ForestEditorPlugin::handleDeselect( %this ) +{ + ForestTools->SelectionTool.clearSelection(); +} + +function ForestEditorPlugin::handleCut( %this ) +{ + ForestTools->SelectionTool.cutSelection(); +} + +function ForestEditorPlugin::handleCopy( %this ) +{ + ForestTools->SelectionTool.copySelection(); +} + +function ForestEditorPlugin::handlePaste( %this ) +{ + ForestTools->SelectionTool.pasteSelection(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/forestEditor/tools.cs b/Templates/BaseGame/game/tools/forestEditor/tools.cs new file mode 100644 index 000000000..e6f28e8be --- /dev/null +++ b/Templates/BaseGame/game/tools/forestEditor/tools.cs @@ -0,0 +1,61 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function ForestBrushTool::onActivated( %this ) +{ + ForestEditToolbar.setVisible( true ); + %this.syncBrushToolbar(); +} + +function ForestBrushTool::onDeactivated( %this ) +{ + ForestEditToolbar.setVisible( false ); +} + +function ForestBrushTool::syncBrushToolbar( %this ) +{ + %size = %this.size; + ForestBrushSizeSliderCtrlContainer->slider.setValue( %size ); + ForestBrushSizeTextEditContainer-->textEdit.setValue( %size ); + + %pres = %this.pressure; + ForestBrushPressureSliderCtrlContainer->slider.setValue( %pres ); + ForestBrushPressureTextEditContainer-->textEdit.setValue( mCeil(100 * %pres) @ "%" ); + + %hard = %this.hardness; + ForestBrushHardnessSliderCtrlContainer->slider.setValue( %hard ); + ForestBrushHardnessTextEditContainer-->textEdit.setValue( mCeil(100 * %hard) @ "%"); +} + +function ForestBrushTool::onMouseDown( %this ) +{ + ForestEditTabBook.selectPage( 0 ); +} + +function ForestSelectionTool::onActivated( %this ) +{ +} + +function ForestSelectionTool::onDeactivated( %this ) +{ + %this.clearSelection(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/gui/EditorLoadingGui.gui b/Templates/BaseGame/game/tools/gui/EditorLoadingGui.gui new file mode 100644 index 000000000..7641fd9a0 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/EditorLoadingGui.gui @@ -0,0 +1,72 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(EditorLoadingGui, EditorGuiGroup) { + isContainer = "1"; + Profile = "GuiOverlayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiControl() { + isContainer = "1"; + Profile = "editorMenu_wBorderProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "277 271"; + Extent = "245 57"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "Dialog"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Loading the World Editor..."; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextBoldCenterProfile"; + HorizSizing = "width"; + VertSizing = "center"; + position = "5 19"; + Extent = "236 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function EditorLoadingGui::onWake(%this) +{ + %res = %this.getExtent(); + %resX = getWord(%res, 0); + %resY = getWord(%res, 1); + + %dialog = %this-->Dialog; + %dialogExtent = %dialog.getExtent(); + %dialogWidth = getWord(%dialogExtent, 0); + %dialogHeight = getWord(%dialogExtent, 1); + %dialogPostion = %dialog.getPosition(); + + %posX = (%resX / 2) - (%dialogWidth / 2); + %posY = (%resY / 2) - (%dialogHeight / 2); + %dialog.setPosition(%posX, %posY); +} diff --git a/Templates/BaseGame/game/tools/gui/GuiEaseEditDlg.ed.cs b/Templates/BaseGame/game/tools/gui/GuiEaseEditDlg.ed.cs new file mode 100644 index 000000000..44345f9f4 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/GuiEaseEditDlg.ed.cs @@ -0,0 +1,183 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------------------------- + +function GetEaseF( %currentEase, %callback, %root ) +{ + GuiEaseEditDlg.init( %currentEase, %callback ); + + if( !isObject( %root ) ) + %root = Canvas; + + %root.pushDialog( GuiEaseEditDlg ); +} + +//============================================================================================= +// GuiEaseEditDlg +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDlg::init( %this, %ease, %callback ) +{ + // Initialize direction popup. + + %directionList = %this-->directionList; + if( !%directionList.size() ) + { + %directionList.add( "InOut", $Ease::InOut ); + %directionList.add( "In", $Ease::In ); + %directionList.add( "Out", $Ease::Out ); + } + + // Initialize type popup. + + %typeList = %this-->typeList; + if( !%typeList.size() ) + { + %typeList.add( "Linear", $Ease::Linear ); + %typeList.add( "Quadratic", $Ease::Quadratic ); + %typeList.add( "Cubic", $Ease::Cubic ); + %typeList.add( "Quartic", $Ease::Quartic ); + %typeList.add( "Quintic", $Ease::Quintic ); + %typeList.add( "Sinusoidal", $Ease::Sinusoidal ); + %typeList.add( "Exponential", $Ease::Exponential ); + %typeList.add( "Circular", $Ease::Circular ); + %typeList.add( "Elastic", $Ease::Elastic ); + %typeList.add( "Back", $Ease::Back ); + %typeList.add( "Bounce", $Ease::Bounce ); + } + + // Set the initial easing curve. + + %this.oldEase = %ease; + %this.setEase( %ease ); + + // Remember callback. + + %this.callback = %callback; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDlg::setEase( %this, %ease ) +{ + %this-->easeView.ease = %ease; + %this-->directionList.setSelected( getWord( %ease, 0 ), false ); + %this-->typeList.setSelected( getWord( %ease, 1 ), false ); + %this-->param1Value.setValue( getWord( %ease, 2 ) ); + %this-->param2Value.setValue( getWord( %ease, 3 ) ); + + %this.onEaseTypeSet(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDlg::onEaseTypeSet( %this ) +{ + switch( %this-->typeList.getSelected() ) + { + case $Ease::Elastic: + %this-->param1Value.setActive( true ); + %this-->param2Value.setActive( true ); + + case $Ease::Back: + %this-->param1Value.setActive( true ); + %this-->param2Value.setActive( false ); + + default: + %this-->param1Value.setActive( false ); + %this-->param2Value.setActive( false ); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDlg::onOK( %this ) +{ + eval( %this.callback @ "( \"" @ %this-->easeView.ease @ "\" );" ); + %this.getRoot().popDialog( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDlg::onCancel( %this ) +{ + %this.getRoot().popDialog( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDlg::onSetParam1( %this, %value ) +{ + %easeView = %this-->easeView; + + %ease = %easeView.ease; + %ease = setWord( %ease, 2, %value ); + %easeView.ease = %ease; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDlg::onSetParam2( %this, %value ) +{ + %easeView = %this-->easeView; + + %ease = %easeView.ease; + %ease = setWord( %ease, 3, %value ); + %easeView.ease = %ease; +} + +//============================================================================================= +// GuiEaseEditDirectionList +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditDirectionList::onSelect( %this, %id, %text ) +{ + %easeView = GuiEaseEditDlg-->easeView; + + %ease = %easeView.ease; + %ease = setWord( %ease, 0, %id ); + %easeview.ease = %ease; +} + +//============================================================================================= +// GuiEaseEditTypeList +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEaseEditTypeList::onSelect( %this, %id, %text ) +{ + %easeView = GuiEaseEditDlg-->easeView; + + %ease = %easeView.ease; + %ease = setWord( %ease, 1, %id ); + %easeview.ease = %ease; + + GuiEaseEditDlg.onEaseTypeSet(); +} diff --git a/Templates/BaseGame/game/tools/gui/GuiEaseEditDlg.ed.gui b/Templates/BaseGame/game/tools/gui/GuiEaseEditDlg.ed.gui new file mode 100644 index 000000000..4c76d8388 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/GuiEaseEditDlg.ed.gui @@ -0,0 +1,332 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(GuiEaseEditDlg,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl() { + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "GuiEaseEditDlg.onCancel();"; + EdgeSnap = "1"; + text = "Edit Easing Curve"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "334 145"; + Extent = "269 214"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "window"; + canSaveDynamicFields = "0"; + + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "ToolsGuiGroupBorderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 27"; + Extent = "95 151"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Direction"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 3"; + Extent = "43 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 20"; + Extent = "83 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "directionList"; + canSaveDynamicFields = "0"; + class = "GuiEaseEditDirectionList"; + className = "GuiEaseEditDirectionList"; + }; + new GuiTextCtrl() { + text = "Type"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 40"; + Extent = "25 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 57"; + Extent = "83 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "typeList"; + canSaveDynamicFields = "0"; + class = "GuiEaseEditTypeList"; + className = "GuiEaseEditTypeList"; + }; + new GuiTextCtrl() { + text = "Param1"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 76"; + Extent = "38 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Param2"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 111"; + Extent = "38 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditSliderCtrl() { + format = "%3.2f"; + range = "-1e+03 1e+03"; + increment = "0.1"; + focusOnMouseWheel = "0"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + text = "-1.00"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 93"; + Extent = "83 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "GuiEaseEditDlg.onSetParam1( $ThisControl.getValue() );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "param1Value"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditSliderCtrl() { + format = "%3.2f"; + range = "-1e+03 1e+03"; + increment = "0.1"; + focusOnMouseWheel = "0"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + text = "-1.00"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "6 128"; + Extent = "83 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "GuiEaseEditDlg.onSetParam2( $ThisControl.getValue() );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "param2Value"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "67 184"; + Extent = "115 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GuiEaseEditDlg.onOK();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "184 184"; + Extent = "73 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GuiEaseEditDlg.onCancel();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiEaseViewCtrl() { + wrap = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "107 28"; + Extent = "150 150"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "easeView"; + canSaveDynamicFields = "0"; + ease = "1 2 -1 -1"; + easeColor = "0.537255 0.537255 0.537255 1"; + easeWidth = "4"; + axisColor = "0.509804 0.509804 0.509804 1"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/gui/colladaImport.ed.gui b/Templates/BaseGame/game/tools/gui/colladaImport.ed.gui new file mode 100644 index 000000000..30838c76d --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/colladaImport.ed.gui @@ -0,0 +1,1698 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ColladaImportDlg,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiWindowCtrl() { + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "Canvas.popDialog(ColladaImportDlg);"; + EdgeSnap = "1"; + text = ""; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "254 136"; + Extent = "516 447"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Accelerator = "escape"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "window"; + canSaveDynamicFields = "0"; + + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "8 24"; + Extent = "238 417"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 3"; + Extent = "238 366"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTreeViewCtrl(ColladaImportTreeView) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "0"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "0"; + DragToItemAllowed = "0"; + ClearAllOnSingleSelection = "1"; + showRoot = "1"; + internalNamesOnly = "0"; + objectNamesOnly = "0"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "0"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "1 1"; + Extent = "74 63"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "254 24"; + Extent = "254 417"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "ToolsGuiGroupBorderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 3"; + Extent = "254 60"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Nodes"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "42 2"; + Extent = "32 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "90 2"; + Extent = "60 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "nodes"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Meshes"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "36 22"; + Extent = "38 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "90 22"; + Extent = "60 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "meshes"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Polygons"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "132 22"; + Extent = "47 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "193 22"; + Extent = "60 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "polygons"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Materials"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "135 2"; + Extent = "44 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "193 2"; + Extent = "60 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "Materials"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Lights"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "23 41"; + Extent = "52 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "91 41"; + Extent = "60 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "lights"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Animations"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "127 41"; + Extent = "52 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "191 41"; + Extent = "60 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "animations"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "ToolsGuiGroupBorderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 68"; + Extent = "254 153"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "LOD"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "59 6"; + Extent = "22 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "DetectDTS"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "97 6"; + Extent = "92 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Method used to determine LOD for meshes in the model"; + hovertime = "1000"; + internalName = "lodType"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "196 6"; + Extent = "49 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Detail size for all meshes in this model (when LOD type is SingleSize)"; + hovertime = "1000"; + internalName = "singleDetailSize"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Materials Prefix"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 32"; + Extent = "73 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "97 32"; + Extent = "148 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ColladaImportTreeView.refresh(\"materials\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "materialPrefix"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Import Nodes"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "13 58"; + Extent = "72 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "97 58"; + Extent = "148 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ColladaImportTreeView.refresh(\"nodes\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "alwaysImport"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Ignore Nodes"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 82"; + Extent = "65 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "97 82"; + Extent = "148 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ColladaImportTreeView.refresh(\"nodes\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "neverImport"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Import Meshes"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "13 106"; + Extent = "72 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "97 106"; + Extent = "148 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ColladaImportTreeView.refresh(\"nodes\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "alwaysImportMesh"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Ignore Meshes"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "13 130"; + Extent = "72 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "97 130"; + Extent = "148 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ColladaImportTreeView.refresh(\"nodes\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "neverImportMesh"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "ToolsGuiGroupBorderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 226"; + Extent = "254 105"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Override up_axis"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 7"; + Extent = "102 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ColladaImportDlg.updateOverrideUpAxis($ThisControl.getValue());"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Overrides the <up_axis> specified in the DAE file"; + hovertime = "1000"; + internalName = "overrideUpAxis"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "151 6"; + Extent = "66 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "upAxis"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Override scale"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 27"; + Extent = "92 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ColladaImportDlg.updateOverrideScale($ThisControl.getValue());"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Overrides the <unit> scale specified in the DAE file"; + hovertime = "1000"; + internalName = "overrideScale"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "151 27"; + Extent = "66 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "scale"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Ignore bone scaling"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 48"; + Extent = "114 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Ignores <scale> elements within <node>s to fix issues with some models"; + hovertime = "1000"; + internalName = "ignoreNodeScale"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Center model"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 67"; + Extent = "82 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Translates model so the origin is at the center"; + hovertime = "1000"; + internalName = "adjustCenter"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Floor model"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "151 67"; + Extent = "72 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Translates model so the origin is at the bottom"; + hovertime = "1000"; + internalName = "adjustFloor"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Force update materials.cs"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 86"; + Extent = "148 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Forces update of materials.cs (even if Materials already exist)"; + hovertime = "1000"; + internalName = "forceUpdateMaterials"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "ToolsGuiGroupBorderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 338"; + Extent = "254 24"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Add lights to scene"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 5"; + Extent = "148 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Loads the lights from the DAE file and adds them to the current scene."; + hovertime = "1000"; + internalName = "loadLights"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Load from .cfg"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 368"; + Extent = "86 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ColladaImportDlg.readDtsConfig();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Save to .cfg"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 395"; + Extent = "86 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ColladaImportDlg.writeDtsConfig();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "159 368"; + Extent = "86 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ColladaImportDlg.onOK();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Load the COLLADA model"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "159 395"; + Extent = "86 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ColladaImportDlg.onCancel();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Exit without loading the COLLADA model"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- + +new GuiControl(ColladaImportProgress,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiWindowCtrl() { + internalName = "window"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Importing cowboy.dae"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "362 338"; + Extent = "300 92"; + MinExtent = "48 92"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiProgressBitmapCtrl() { + internalName = "progressBar"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiRLProgressBitmapProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "10 34"; + Extent = "280 24"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + internalName = "progressText"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "10 62"; + Extent = "280 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; + +function ColladaImportTreeView::onDefineIcons(%this) +{ + // Set the tree view icon indices and texture paths + %this._imageNone = 0; + %this._imageNode = 1; + %this._imageMesh = 2; + %this._imageMaterial = 3; + %this._imageLight = 4; + %this._imageAnimation = 5; + %this._imageExNode = 6; + %this._imageExMaterial = 7; + + %icons = ":" @ // no icon + "tools/gui/images/ColladaImport/iconNode:" @ // normal node + "tools/gui/images/ColladaImport/iconMesh:" @ // mesh + "tools/gui/images/ColladaImport/iconMaterial:" @ // new material + "tools/gui/images/ColladaImport/iconLight:" @ // light + "tools/gui/images/ColladaImport/iconAnimation:" @ // sequence + "tools/gui/images/ColladaImport/iconIgnoreNode:" @ // ignored node + "tools/gui/images/ColladaImport/iconExistingMaterial"; // existing material + + %this.buildIconTable( %icons ); +} + +function ColladaImportDlg::showDialog(%this, %shapePath, %cmd) +{ + %this.path = %shapePath; + %this.cmd = %cmd; + + // Only allow loading lights if creating a new scene object + %canLoadLights = (strstr(%this.cmd, "EWCreatorWindow.create") != -1); + + // Check for an existing TSShapeConstructor object. Need to exec the script + // manually as the DAE resource may not have been loaded yet + %csPath = filePath(%this.path) @ "/" @ fileBase(%this.path) @ ".cs"; + if (isFile(%csPath)) + exec(%csPath); + + %this.constructor = ShapeEditor.findConstructor(%this.path); + + // Only show the import dialog if required. Note that 'enumColladaScene' will + // fail if the COLLADA file is missing, or a cached.dts is available. + $collada::forceLoadDAE = EditorSettings.value("forceLoadDAE"); + if ( (fileExt(%shapePath) $= ".dts") || + !enumColladaForImport(%shapePath, ColladaImportTreeView) ) + { + eval(%cmd); + $collada::forceLoadDAE = false; + + // Load lights from the DAE if possible + if (%canLoadLights && (%this.constructor > 0) && (%this.constructor.loadLights == 1)) + %this.loadLights(); + + return; + } + $collada::forceLoadDAE = false; + + // Initialise GUI + ColladaImportTreeView.onDefineIcons(); + + %this-->window.text = "COLLADA Import:" SPC %this.path; + + %this-->upAxis.clear(); + %this-->upAxis.add("X_AXIS", 1); + %this-->upAxis.add("Y_AXIS", 2); + %this-->upAxis.add("Z_AXIS", 3); + + %this-->lodType.clear(); + %this-->lodType.add("DetectDTS", 1); + %this-->lodType.add("SingleSize", 2); + %this-->lodType.add("TrailingNumber", 3); + + %this-->loadLights.setActive(%canLoadLights); + + // Set model details + %this-->nodes.setText(ColladaImportTreeView._nodeCount); + %this-->meshes.setText(ColladaImportTreeView._meshCount); + %this-->polygons.setText(ColladaImportTreeView._polygonCount); + %this-->materials.setText(ColladaImportTreeView._materialCount); + %this-->lights.setText(ColladaImportTreeView._lightCount); + %this-->animations.setText(ColladaImportTreeView._animCount); + + %this.updateOverrideUpAxis(false); + %this.updateOverrideScale(false); + + if (%this.constructor > 0) + { + if (%this.constructor.upAxis !$= "DEFAULT") + { + %this-->upAxis.setText(%this.constructor.upAxis); + %this.updateOverrideUpAxis(true); + } + if (%this.constructor.unit > 0) + { + %this-->scale.setText(%this.constructor.unit); + %this.updateOverrideScale(true); + } + + %this-->lodType.setText(%this.constructor.lodType); + %this-->singleDetailSize.setText(%this.constructor.singleDetailSize); + %this-->materialPrefix.setText(%this.constructor.matNamePrefix); + %this-->alwaysImport.setText(strreplace(%this.constructor.alwaysImport, "\t", ";")); + %this-->neverImport.setText(strreplace(%this.constructor.neverImport, "\t", ";")); + %this-->alwaysImportMesh.setText(strreplace(%this.constructor.alwaysImportMesh, "\t", ";")); + %this-->neverImportMesh.setText(strreplace(%this.constructor.neverImportMesh, "\t", ";")); + %this-->ignoreNodeScale.setStateOn(%this.constructor.ignoreNodeScale); + %this-->adjustCenter.setStateOn(%this.constructor.adjustCenter); + %this-->adjustFloor.setStateOn(%this.constructor.adjustFloor); + %this-->forceUpdateMaterials.setStateOn(%this.constructor.forceUpdateMaterials); + %this-->loadLights.setStateOn(%this.constructor.loadLights); + } + else + { + // Default settings + %this-->lodType.setText("DetectDTS"); + %this-->singleDetailSize.setText("2"); + %this-->materialPrefix.setText(""); + %this-->alwaysImport.setText(""); + %this-->neverImport.setText(""); + %this-->alwaysImportMesh.setText(""); + %this-->neverImportMesh.setText(""); + %this-->ignoreNodeScale.setStateOn(0); + %this-->adjustCenter.setStateOn(0); + %this-->adjustFloor.setStateOn(0); + %this-->forceUpdateMaterials.setStateOn(0); + %this-->loadLights.setStateOn(0); + } + + Canvas.pushDialog(%this); + + ColladaImportTreeView.refresh("all"); +} + +function ColladaImportDlg::readDtsConfig(%this) +{ + %filename = filePath( %this.path ) @ "/" @ fileBase( %this.path ) @ ".cfg"; + %filename2 = filePath( %this.path ) @ "/" @ "dtsScene.cfg"; + + %fo = new FileObject(); + if ( %fo.openForRead( %filename ) || %fo.openForRead( %filename2 ) ) + { + %alwaysImport = ""; + %neverImport = ""; + + %mode = "none"; + while ( !%fo.isEOF() ) + { + %line = trim( %fo.readLine() ); + + if ( %line $= "AlwaysExport:" ) // Start of the AlwaysExport list + %mode = "always"; + else if ( %line $= "NeverExport:" ) // Start of the NeverExport list + %mode = "never"; + else if ( startswith( %line, "+" ) || startswith( %line, "-" ) ) // Boolean parameters (not supported) + %mode = "none"; + else if ( startswith( %line, "=" ) ) // Float and integer parameters (not supported) + %mode = "none"; + else if ( !startswith( %line, "//" ) ) // Non-commented lines + { + switch$ (%mode) + { + case "always": + %alwaysImport = %alwaysImport TAB %line; + case "never": + %neverImport = %neverImport TAB %line; + } + } + } + %fo.close(); + + %alwaysImport = strreplace( trim( %alwaysImport ), "\t", ";" ); + %neverImport = strreplace( trim( %neverImport ), "\t", ";" ); + + %this-->alwaysImport.setText( %alwaysImport ); + %this-->neverImport.setText( %neverImport ); + } + else + { + error( "Failed to open " @ %filename @ " or " @ %filename2 @ " for reading" ); + } + + %fo.delete(); +} + +function ColladaImportDlg::writeDtsConfig(%this) +{ + %filename = filePath( %this.path ) @ "/" @ fileBase( %this.path ) @ ".cfg"; + + %fo = new FileObject(); + if ( %fo.openForWrite( %filename ) ) + { + // AlwaysImport + %fo.writeLine("AlwaysExport:"); + %alwaysImport = trim( strreplace( %this-->alwaysImport.getText(), ";", "\t" ) ); + %count = getFieldCount( %alwaysImport ); + for (%i = 0; %i < %count; %i++) + %fo.writeLine( getField( %alwaysImport, %i ) ); + %fo.writeLine(""); + + // NeverImport + %fo.writeLine("NeverExport:"); + %neverImport = trim( strreplace( %this-->neverImport.getText(), ";", "\t" ) ); + %count = getFieldCount( %neverImport ); + for (%i = 0; %i < %count; %i++) + %fo.writeLine( getField( %neverImport, %i ) ); + %fo.writeLine(""); + + %fo.close(); + } + else + { + error( "Failed to open " @ %filename @ " for writing" ); + } + + %fo.delete(); +} + +function ColladaImportDlg::updateOverrideUpAxis(%this, %override) +{ + %this-->overrideUpAxis.setStateOn(%override); + %this-->upAxis.setActive(%override); + if (!%override) + %this-->upAxis.setText(ColladaImportTreeView._upAxis); +} + +function ColladaImportDlg::updateOverrideScale(%this, %override) +{ + %this-->overrideScale.setStateOn(%override); + %this-->scale.setActive(%override); + if (!%override) + %this-->scale.setText(ColladaImportTreeView._unit); +} + +function ColladaImportTreeView::refresh(%this, %what) +{ + %shapeRoot = %this.getFirstRootItem(); + %materialsRoot = %this.getNextSibling(%shapeRoot); + %animRoot = %this.getNextSibling(%materialsRoot); + + // Refresh nodes + if ((%what $= "all") || (%what $= "nodes")) + { + // Indicate whether nodes will be ignored on import + %this._alwaysImport = strreplace(ColladaImportDlg-->alwaysImport.getText(), ";", "\t"); + %this._neverImport = strreplace(ColladaImportDlg-->neverImport.getText(), ";", "\t"); + %this._alwaysImportMesh = strreplace(ColladaImportDlg-->alwaysImportMesh.getText(), ";", "\t"); + %this._neverImportMesh = strreplace(ColladaImportDlg-->neverImportMesh.getText(), ";", "\t"); + %this.refreshNode(%this.getChild(%shapeRoot)); + } + + // Refresh materials + if ((%what $= "all") || (%what $= "materials")) + { + %matPrefix = ColladaImportDlg-->materialPrefix.getText(); + %id = %this.getChild(%materialsRoot); + while (%id > 0) + { + %baseName = %this.getItemValue(%id); + %name = %matPrefix @ %baseName; + + // Indicate whether material name is already mapped + %this.editItem(%id, %name, %baseName); + %mapped = getMaterialMapping(%name); + if (%mapped $= "") + { + %this.setItemTooltip(%id, "A new material will be mapped to this name"); + %this.setItemImages(%id, %this._imageMaterial, %this._imageMaterial); + } + else + { + %this.setItemTooltip(%id, %mapped SPC "is already mapped to this material name"); + %this.setItemImages(%id, %this._imageExMaterial, %this._imageExMaterial); + } + + %id = %this.getNextSibling(%id); + } + } + + // Refresh animations + if ((%what $= "all") || (%what $= "animations")) + { + %id = %this.getChild(%animRoot); + while (%id > 0) + { + %this.setItemImages(%id, %this._imageAnim, %this._imageAnim); + %id = %this.getNextSibling(%id); + } + } +} + +function ColladaImportTreeView::refreshNode(%this, %id) +{ + while (%id > 0) + { + switch$ (%this.getItemValue(%id)) + { + case "mesh": + // Check if this mesh will be ignored on import + if (strIsMatchMultipleExpr(%this._alwaysImportMesh, %this.getItemText(%id)) || + !strIsMatchMultipleExpr(%this._neverImportMesh, %this.getItemText(%id)) ) + { + %this.setItemTooltip(%id, ""); + %this.setItemImages(%id, %this._imageMesh, %this._imageMesh); + } + else + { + %this.setItemTooltip(%id, "This mesh will be ignored on import"); + %this.setItemImages(%id, %this._imageExNode, %this._imageExNode); + } + + case "light": + %this.setItemImages(%id, %this._imageLight, %this._imageLight); + + case "node": + // Check if this node will be ignored on import + if (strIsMatchMultipleExpr(%this._alwaysImport, %this.getItemText(%id)) || + !strIsMatchMultipleExpr(%this._neverImport, %this.getItemText(%id)) ) + { + %this.setItemTooltip(%id, ""); + %this.setItemImages(%id, %this._imageNode, %this._imageNode); + } + else + { + %this.setItemTooltip(%id, "This node will be ignored on import"); + %this.setItemImages(%id, %this._imageExNode, %this._imageExNode); + } + } + + // recurse through children and siblings + %this.refreshNode(%this.getChild(%id)); + %id = %this.getNextSibling(%id); + } +} + +function ColladaImportDlg::onCancel(%this) +{ + Canvas.popDialog(%this); + ColladaImportTreeView.clear(); +} + +function ColladaImportDlg::onOK(%this) +{ + Canvas.popDialog(%this); + ColladaImportTreeView.clear(); + + // Need to create a TSShapeConstructor object if any settings are not + // at the default values + if ((%this-->overrideUpAxis.getValue() != 0) || + (%this-->overrideScale.getValue() != 0) || + (%this-->lodType.getText() !$= "DetectDTS") || + (%this-->singleDetailSize.getText() !$= "2") || + (%this-->materialPrefix.getText() !$= "") || + (%this-->alwaysImport.getText() !$= "") || + (%this-->neverImport.getText() !$= "") || + (%this-->alwaysImportMesh.getText() !$= "") || + (%this-->neverImportMesh.getText() !$= "") || + (%this-->ignoreNodeScale.getValue() != 0) || + (%this-->adjustCenter.getValue() != 0) || + (%this-->adjustFloor.getValue() != 0) || + (%this-->forceUpdateMaterials.getValue() != 0) || + (%this-->loadLights.getValue() != 0)) + { + if (%this.constructor <= 0) + { + // Create a new TSShapeConstructor object + %this.constructor = ShapeEditor.createConstructor(%this.path); + } + } + + if (%this.constructor > 0) + { + // Store values from GUI + if (%this-->overrideUpAxis.getValue()) + %this.constructor.upAxis = %this-->upAxis.getText(); + else + %this.constructor.upAxis = "DEFAULT"; + + if (%this-->overrideScale.getValue()) + %this.constructor.unit = %this-->scale.getText(); + else + %this.constructor.unit = -1; + + %this.constructor.lodType = %this-->lodType.getText(); + %this.constructor.singleDetailSize = %this-->singleDetailSize.getText(); + %this.constructor.matNamePrefix = %this-->materialPrefix.getText(); + %this.constructor.alwaysImport = strreplace(%this-->alwaysImport.getText(), ";", "\t"); + %this.constructor.neverImport = strreplace(%this-->neverImport.getText(), ";", "\t"); + %this.constructor.alwaysImportMesh = strreplace(%this-->alwaysImportMesh.getText(), ";", "\t"); + %this.constructor.neverImportMesh = strreplace(%this-->neverImportMesh.getText(), ";", "\t"); + %this.constructor.ignoreNodeScale = %this-->ignoreNodeScale.getValue(); + %this.constructor.adjustCenter = %this-->adjustCenter.getValue(); + %this.constructor.adjustFloor = %this-->adjustFloor.getValue(); + %this.constructor.forceUpdateMaterials = %this-->forceUpdateMaterials.getValue(); + %this.constructor.loadLights = %this-->loadLights.getValue(); + + // Save new settings to file + ShapeEditor.saveConstructor( %this.constructor ); + } + + // Load the shape (always from the DAE) + $collada::forceLoadDAE = true; + eval(%this.cmd); + $collada::forceLoadDAE = false; + + // Optionally load the lights from the DAE as well (only if adding a new shape + // to the scene) + if (%this-->loadLights.getValue()) + %this.loadLights(); +} + +function ColladaImportDlg::loadLights(%this) +{ + // Get the ID of the last object added + %obj = MissionGroup.getObject(MissionGroup.getCount()-1); + + // Create a new SimGroup to hold the model and lights + %group = new SimGroup(); + loadColladaLights(%this.path, %group, %obj); + + // Delete the SimGroup if no lights were found. Otherwise, add the model to + // the group as well. + if (%group.getCount() > 0) + { + %group.add(%obj); + %group.bringToFront(%obj); + MissionGroup.add(%group); + if (EditorTree.isVisible()) + { + EditorTree.removeItem(EditorTree.findItemByObjectId(%obj)); + EditorTree.buildVisibleTree(true); + } + } + else + { + %group.delete(); + } +} + +function updateTSShapeLoadProgress(%progress, %msg) +{ + // Check if the loading GUI is visible and use that instead of the + // separate import progress GUI if possible + if ( isObject(LoadingGui) && LoadingGui.isAwake() ) + { + // Save/Restore load progress at the start/end of the import process + if ( %progress == 0 ) + { + ColladaImportProgress.savedProgress = LoadingProgress.getValue(); + ColladaImportProgress.savedText = LoadingProgressTxt.getValue(); + + ColladaImportProgress.msgPrefix = "Importing " @ %msg; + %msg = "Reading file into memory..."; + } + else if ( %progress == 1.0 ) + { + LoadingProgress.setValue( ColladaImportProgress.savedProgress ); + LoadingProgressTxt.setValue( ColladaImportProgress.savedText ); + } + + %msg = ColladaImportProgress.msgPrefix @ ": " @ %msg; + + %progressCtrl = LoadingProgress; + %textCtrl = LoadingProgressTxt; + } + else + { + // Show/Hide gui at the start/end of the import process + if ( %progress == 0 ) + { + ColladaImportProgress-->window.text = "Importing" SPC %msg; + %msg = "Reading file into memory..."; + Canvas.pushDialog(ColladaImportProgress); + } + else if ( %progress == 1.0 ) + { + Canvas.popDialog(ColladaImportProgress); + } + + %progressCtrl = ColladaImportProgress-->progressBar; + %textCtrl = ColladaImportProgress-->progressText; + } + + // Update progress indicators + if (%progress == 0) + { + %progressCtrl.setValue(0.001); + %textCtrl.setText(%msg); + } + else if (%progress != 1.0) + { + %progressCtrl.setValue(%progress); + %textCtrl.setText(%msg); + } + + Canvas.repaint(33); +} + + +// Convert all COLLADA models that match the given pattern (defaults to *) to DTS +function convertColladaModels(%pattern) +{ + // Force loading the COLLADA file (to ensure cached DTS is updated) + $collada::forceLoadDAE = true; + + %fullPath = findFirstFile("*.dae"); + while (%fullPath !$= "") + { + // Check if this file is inside the given path + %fullPath = makeRelativePath(%fullPath, getMainDotCSDir()); + if ((%pattern $= "") || strIsMatchMultipleExpr(%pattern, %fullPath)) + { + // Load the model by creating a temporary TSStatic + echo("Converting " @ %fullPath @ " to DTS..."); + %temp = new TSStatic() { + shapeName = %fullPath; + collisionType = "None"; + }; + %temp.delete(); + } + + %fullPath = findNextFile("*.dae"); + } + + $collada::forceLoadDAE = false; +} diff --git a/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui b/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui new file mode 100644 index 000000000..d8f15e76b --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui @@ -0,0 +1,1149 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiColorPickerCtrl(ColorPickerDlg,EditorGuiGroup) { + displayMode = "Dropper"; // this makes the background visible + actionOnMove = "1"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiWindowCtrl(GuiPickerDlg) { + text = "Color Picker"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "DoColorPickerCancelCallback(); ColorPickerDlg.getRoot().popDialog(ColorPickerDlg);"; + position = "170 100"; + extent = "439 317"; + minExtent = "8 2"; + horizSizing = "windowRelative"; + vertSizing = "windowRelative"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapBorderCtrl(){ // color blend + position = "3 24"; + extent = "255 258"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiGroupBorderProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiColorPickerCtrl(ColorBlendSelect) { + baseColor = "1 0 0 1"; + pickColor = "0 0 0 1"; + selectorGap = "1"; + displayMode = "BlendColor"; + actionOnMove = "1"; + position = "1 0"; + extent = "255 258"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "updateRGBValues(1);"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl(){ // Hue + position = "263 23"; + extent = "25 261"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiGroupBorderProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiColorPickerCtrl(ColorRangeSelect) { + baseColor = "1 0 0 1"; + pickColor = "1 0 0 1"; + selectorGap = "1"; + displayMode = "VertColor"; + actionOnMove = "1"; + position = "1 1"; + extent = "21 257"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "updatePickerBaseColor(1);"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTextCtrl() { + text = "New"; + position = "306 22"; + extent = "26 14"; + profile = "GuiDefaultProfile"; + }; + new GuiBitmapBorderCtrl(){ // new old color + position = "292 37"; + extent = "52 99"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiGroupBorderProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSwatchButtonCtrl(myColor){ // New Color // + position = "1 1"; + extent = "50 50"; + profile = "GuiDefaultProfile"; + }; + new GuiSwatchButtonCtrl(oldColor){ // Old Color // + position = "1 48"; + extent = "50 50"; + profile = "GuiDefaultProfile"; + }; + }; + new GuiTextCtrl() { + text = "Old"; + position = "310 138"; + extent = "26 14"; + profile = "GuiDefaultProfile"; + }; + new GuiBitmapBorderCtrl(){ // Color Text Fields + position = "291 165"; + extent = "141 118"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiGroupBorderProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { // rgb + position = "4 0"; + extent = "52 75"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "R"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 6"; + extent = "8 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Red Channel color value."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(Channel_R_Val) { // Red Channal + text = "0"; + maxLength = "4"; + position = "14 6"; + extent = "34 18"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfileNumbersOnly"; + class = "ColorPickerRGBClass"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Red Channel color value."; + }; + new GuiTextCtrl() { + text = "G"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "4 29"; + extent = "8 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Green Channel color value."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(Channel_G_Val) { // Green Channal + text = "0"; + maxLength = "4"; + position = "14 29"; + extent = "34 18"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfileNumbersOnly"; + class = "ColorPickerRGBClass"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Green Channel color value."; + }; + new GuiTextCtrl() { + text = "B"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 52"; + extent = "8 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Blue Channel color value."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(Channel_B_Val) { // Blue Channal + text = "0"; + maxLength = "4"; + position = "14 52"; + extent = "34 18"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfileNumbersOnly"; + class = "ColorPickerRGBClass"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Blue Channel color value."; + }; + }; + new GuiControl() { + position = "71 0"; + extent = "61 75"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "H"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 6"; + extent = "8 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Hue Channel color value."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(Channel_H_Val) { // Hue Channal + text = "0"; + maxLength = "4"; + position = "14 6"; + extent = "34 18"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfileNumbersOnly"; + class = "ColorPickerHSBClass"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Hue Channel color value."; + }; + new GuiTextCtrl() { + text = "o"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "51 2"; + extent = "8 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "S"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "4 29"; + extent = "8 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Saturation Channel color value."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(Channel_S_Val) { // Saturation Channal + text = "0"; + maxLength = "4"; + position = "14 29"; + extent = "34 18"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfileNumbersOnly"; + class = "ColorPickerHSBClass"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Saturation Channel color value."; + }; + new GuiTextCtrl() { + text = "%"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "51 29"; + extent = "10 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "B"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 52"; + extent = "8 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Brightness Channel color value. Aka value or lightness."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(Channel_Br_Val) { // Brightness Channal + text = "0"; + maxLength = "4"; + position = "14 52"; + extent = "34 18"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfileNumbersOnly"; + class = "ColorPickerHSBClass"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Brightness Channel color value. Aka value or lightness."; + }; + new GuiTextCtrl() { + text = "%"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "51 52"; + extent = "10 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + position = "3 87"; + extent = "138 24"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "#"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "3 5"; + extent = "8 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Hex representation of Red, Green, Blue Color value."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(HexColor_Val) { // Hex Color Field + text = "0"; + maxLength = "6"; + position = "13 5"; + extent = "116 18"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Hex representation of Red, Green, Blue Color value."; + command = "$thisControl.onKeyDown();"; + }; + }; + }; + new GuiBitmapBorderCtrl(){ // alpha + position = "3 287"; + extent = "429 24"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiGroupBorderProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { + position = "-1 3"; + extent = "428 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "AggregateControl"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSliderCtrl(ColorAlphaSelect) { + range = "0 1"; + ticks = "0"; + value = "1"; + position = "5 3"; + extent = "341 13"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); updateColorPickerAlpha( $ThisControl.getValue() );"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "slider"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Alpha"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "355 0"; + extent = "28 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(Channel_A_Val) { // Alpha Channal + text = "0"; + maxLength = "4"; + position = "392 0"; + extent = "34 18"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfileNumbersOnly"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); updateColorPickerAlpha( $ThisControl.getValue() );"; + internalName = "TextEdit"; + }; + }; + }; + new GuiButtonCtrl() { + text = "Select"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "349 37"; + extent = "84 24"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "DoColorPickerCallback();"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "349 68"; + extent = "84 24"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "DoColorPickerCancelCallback();"; + Clickable = "1"; + AffectChildren = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + text = "use sRGB"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "360 105"; + extent = "66 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + variable = "$displayAsSRGB"; + command = "useSRGBctrl($displayAsSRGB);"; + }; + }; +}; +//--- OBJECT WRITE END --- + +$ColorPickerCallback = ""; // Control that we need to update +$ColorPickerCancelCallback = ""; +$ColorPickerUpdateCallback = ""; +$ColorCallbackType = 1; // ColorI + +function useSRGBctrl(%colorScale) +{ +ColorPickerDlg.useSRGB = %colorScale; +ColorRangeSelect.useSRGB = %colorScale; +ColorBlendSelect.useSRGB = %colorScale; +myColor.useSRGB = %colorScale; +oldColor.useSRGB = %colorScale; +} + +// This function pushes the color picker dialog and returns to a callback the selected value +function GetColorI( %currentColor, %callback, %root, %updateCallback, %cancelCallback ) +{ + $ColorPickerSignal = 1; + $ColorPickerCallback = %callback; + $ColorPickerCancelCallback = %cancelCallback; + $ColorPickerUpdateCallback = %updateCallback; + $ColorCallbackType = 1; // ColorI + + oldColor.color = ColorIntToFloat( %currentColor ); + myColor.color = ColorIntToFloat( %currentColor ); + + ColorRangeSelect.showReticle = true; + ColorBlendSelect.showReticle = true; + + // Set the range according to int + ColorAlphaSelect.range = "0 255"; + + // Set the RGBA displays accordingly + %red = getWord(%currentColor, 0); + %green = getWord(%currentColor, 1); + %blue = getWord(%currentColor, 2); + %alpha = getWord(%currentColor, 3); + + //Set the red green blue text fields + Channel_R_Val.setValue(%red); + Channel_G_Val.setValue(%green); + Channel_B_Val.setValue(%blue); + + //Have the rgb text fields update the rest + Channel_R_Val.onValidate(); + + if(!isObject(%root)) + %root = Canvas; + + %root.pushDialog(ColorPickerDlg); + + // update the alpha value first + ColorAlphaSelect.setValue( %alpha ); + Channel_A_Val.setText( %alpha ); +} + +function GetColorF( %currentColor, %callback, %root, %updateCallback, %cancelCallback ) +{ + $ColorPickerSignal = 1; + $ColorPickerCallback = %callback; + $ColorPickerCancelCallback = %cancelCallback; + $ColorPickerUpdateCallback = %updateCallback; + $ColorCallbackType = 2; // ColorF + + oldColor.color = %currentColor; + myColor.color = %currentColor; + + ColorRangeSelect.showReticle = true; + ColorBlendSelect.showReticle = true; + + // Set the range according to float + ColorAlphaSelect.range = "0 1"; + + // Set the RGBA displays accordingly + %red = mRoundColour(getWord(%currentColor, 0), 3); + %green = mRoundColour(getWord(%currentColor, 1), 3); + %blue = mRoundColour(getWord(%currentColor, 2), 3); + %alpha = mRoundColour(getWord(%currentColor, 3), 3); + + //Set the red green blue text fields + Channel_R_Val.setValue(%red); + Channel_G_Val.setValue(%green); + Channel_B_Val.setValue(%blue); + + //Have the rgb text fields update the rest + Channel_R_Val.onValidate(); + + if(!isObject(%root)) + %root = Canvas; + %root.pushDialog(ColorPickerDlg); + + // update the alpha value first + ColorAlphaSelect.setValue( %alpha ); + Channel_A_Val.setText( %alpha ); +} + +function ColorPickerRGBClass::onValidate(%this) +{ + %red = Channel_R_Val.getValue(); + %green = Channel_G_Val.getValue(); + %blue = Channel_B_Val.getValue(); + + //Rest of the fields just do everything with ints so convert + if( $ColorCallbackType != 1 ) + { + %rgb = ColorFloatToInt(%red SPC %green SPC %blue SPC "1.0"); + %red = getWord(%rgb, 0); + %green = getWord(%rgb, 1); + %blue = getWord(%rgb, 2); + } + + //Update all the other color fields + %hsb = ColorRGBToHSB(%red SPC %green SPC %blue); + Channel_H_Val.setValue(getWord(%hsb, 0)); + Channel_S_Val.setValue(getWord(%hsb, 1)); + Channel_Br_Val.setValue(getWord(%hsb, 2)); + + %hex = ColorRGBToHEX(%red SPC %green SPC %blue); + HexColor_Val.setValue(%hex); + HexColor_Val.onKeyDown(); + + //Update everything else with our new color + setColorInfo(); +} + +function ColorPickerHSBClass::onValidate(%this) +{ + %hue = Channel_H_Val.getValue(); + %saturation = Channel_S_Val.getValue(); + %brightness = Channel_Br_Val.getValue(); + + //Update all the other color fields + %rgb = ColorHSBToRGB(%hue SPC %saturation SPC %brightness); + %hex = ColorRGBToHEX(%rgb); + HexColor_Val.setValue(%hex); + HexColor_Val.onKeyDown(); + + //convert to float for rgb if we need to + if( $ColorCallbackType != 1 ) + { + %rgb = ColorIntToFloat(%rgb); + } + %red = getWord(%rgb, 0); + %green = getWord(%rgb, 1); + %blue = getWord(%rgb, 2); + Channel_R_Val.setValue(%red); + Channel_G_Val.setValue(%green); + Channel_B_Val.setValue(%blue); + + //Update everything else with our new color + setColorInfo(); +} + +function HexColor_Val::onKeyDown(%this) +{ + //Get the value + %value = %this.getValue(); + + //It's hex so keep it all uppercase + %value = strupr(%value); + %pos = %this.getCursorPos(); + %this.setValue(%value); + %this.setCursorPos(%pos); + + //Verify that it's a hex value + %value = stripChars(%value, "0123456789ABCDEF"); + if(%value $= "") + { + %this.validText(); + } + else + { + %this.invalidText(false); + } +} + +function HexColor_Val::onValidate(%this) +{ + //if the current text is invalid don't do anyting + if(!%this.isValidText()) + { + %this.invalidText(true); + return; + } + + //Get the current value + %hex = %this.getValue(); + + //Make sure we have 6 characters + while(strlen(%hex) < 6) + { + %hex = "0" @ %hex; + } + %hex = strupr(%hex); + + //Update the value in case there were missing characters + %this.setValue(%hex); + + //Update all the other color fields + %rgb = ColorHEXToRGB(%hex); + %hsb = ColorRGBToHSB(%rgb); + + //convert to float for rgb if we need to + if( $ColorCallbackType != 1 ) + { + %rgb = ColorIntToFloat(%rgb); + } + + %red = getWord(%rgb, 0); + %green = getWord(%rgb, 1); + %blue = getWord(%rgb, 2); + Channel_R_Val.setValue(%red); + Channel_G_Val.setValue(%green); + Channel_B_Val.setValue(%blue); + + Channel_H_Val.setValue(getWord(%hsb, 0)); + Channel_S_Val.setValue(getWord(%hsb, 1)); + Channel_Br_Val.setValue(getWord(%hsb, 2)); + + //Update everything else with our new color + setColorInfo(); +} + +// This function is used to update the text controls at the top +function setColorInfo() +{ + %red = Channel_R_Val.getValue(); + %green = Channel_G_Val.getValue(); + %blue = Channel_B_Val.getValue(); + + if( $ColorCallbackType == 1) + %rgb = ColorIntToFloat(%red SPC %green SPC %blue SPC "255"); + else + %rgb = %red SPC %green SPC %blue SPC "1.0"; + + $ColorPickerSignal = 0; + + //Convert color over to hue color + %hsb = ColorRGBToHSB(ColorFloatToInt(%rgb)); + %tempColor = ColorHSBToRGB( getWord(%hsb, 0) SPC 100 SPC 50); + %tempColor = ColorIntToFloat(setWord(%tempColor, 3, 255)); + + //Make sure all the text fields and everything don't update because of the cursors + ColorRangeSelect.update = false; + ColorBlendSelect.update = false; + + //Set values for the hue color picker + ColorRangeSelect.baseColor = %tempColor; + ColorRangeSelect.pickColor = %tempColor; + ColorRangeSelect.updateColor(); + + //Set the cursor for the hue picker + ColorRangeSelect.setSelectorColor(%tempColor); + + //Set the values for the gradient color picker + ColorBlendSelect.baseColor = %tempColor; + ColorBlendSelect.pickColor = %rgb; + ColorBlendSelect.updateColor(); + + //Set the cursor for the gradiant color picker + ColorBlendSelect.setSelectorColor(%rgb); + + //Update our current color + %alpha = getWord(myColor.color, 3); + myColor.color = setWord(%rgb, 3, %alpha); +} + +// return mycolor.color +function DoColorPickerCallback() +{ + eval( $ColorPickerCallback @ "(\"" @ constructNewColor(mycolor.color, $ColorCallbackType) @"\");" ); + ColorPickerDlg.getRoot().popDialog(ColorPickerDlg); +} + +function DoColorPickerCancelCallback() +{ + ColorPickerDlg.getRoot().popDialog( ColorPickerDlg ); + if( $ColorPickerCancelCallback !$= "" ) + eval( $ColorPickerCancelCallback @ "(\"" @ constructNewColor( oldColor.color, $ColorCallbackType ) @ "\");" ); +} + +function DoColorPickerUpdateCallback() +{ + if( $ColorPickerUpdateCallback !$= "" ) + eval( $ColorPickerUpdateCallback @ "(\"" @ constructNewColor( myColor.color, $ColorCallbackType ) @ "\");" ); +} + +// this is called from ColorRangeSelect.updateColor +function updatePickerBaseColor( %location ) +{ + if(!ColorRangeSelect.update) + { + ColorRangeSelect.update = true; + return; + } + + if( $ColorPickerSignal && %location ) + %pickColor = ColorRangeSelect.baseColor; + else + %pickColor = ColorRangeSelect.pickColor; + $ColorPickerSignal = 0; + + %red = getWord(%pickColor, 0); + %green = getWord(%pickColor, 1); + %blue = getWord(%pickColor, 2); + %alpha = getWord(%pickColor, 3); + + ColorBlendSelect.baseColor = %red SPC %green SPC %blue SPC "1.0"; + ColorBlendSelect.updateColor(); +} + +// this is called from ColorBlendSelect.updateColor +function updateRGBValues( %location ) +{ + if(!ColorBlendSelect.update) + { + ColorBlendSelect.update = true; + return; + } + + //update the color based on where it came from + if( $ColorPickerSignal && %location ) + %pickColor = ColorBlendSelect.baseColor; + else + %pickColor = ColorBlendSelect.pickColor; + + //lets prepare the color + %red = getWord(%pickColor, 0); + %green = getWord(%pickColor, 1); + %blue = getWord(%pickColor, 2); + //the alpha should be grabbed from mycolor + %alpha = getWord(myColor.color, 3); + + // set the color! + myColor.color = %red SPC %green SPC %blue SPC %alpha; + + DoColorPickerUpdateCallback(); + + //update differently depending on type + if( $ColorCallbackType == 1 ) + { + %red = mCeil(%red * 255); + %blue = mCeil(%blue * 255); + %green = mCeil(%green * 255); + } + else + { + %red = mFloatLength(%red, 3); + %blue = mFloatLength(%blue, 3); + %green = mFloatLength(%green, 3); + } + + // changes current color values + Channel_R_Val.setValue(%red); + Channel_G_Val.setValue(%green); + Channel_B_Val.setValue(%blue); + + //Rest of the fields just do everything with ints so convert + if( $ColorCallbackType != 1 ) + { + %rgb = ColorFloatToInt(%red SPC %green SPC %blue SPC "1.0"); + %red = getWord(%rgb, 0); + %green = getWord(%rgb, 1); + %blue = getWord(%rgb, 2); + } + + //Update all the other color fields + %hsb = ColorRGBToHSB(%red SPC %green SPC %blue); + Channel_H_Val.setValue(getWord(%hsb, 0)); + Channel_S_Val.setValue(getWord(%hsb, 1)); + Channel_Br_Val.setValue(getWord(%hsb, 2)); + + %hex = ColorRGBToHEX(%red SPC %green SPC %blue); + HexColor_Val.setValue(%hex); + HexColor_Val.onKeyDown(); + + $ColorPickerSignal = 0; +} + +function updateColorPickerAlpha( %alphaVal ) +{ + //lets prepare the color + %red = getWord(myColor.color, 0); + %green = getWord(myColor.color, 1); + %blue = getWord(myColor.color, 2); + %alpha = %alphaVal; + + if( $ColorCallbackType == 1 ) + %alpha = (%alpha / 255); + + myColor.color = %red SPC %green SPC %blue SPC %alpha ; + + DoColorPickerUpdateCallback(); +} + +function constructNewColor(%pickColor, %colorType ) +{ + %red = getWord(%pickColor, 0); + %green = getWord(%pickColor, 1); + %blue = getWord(%pickColor, 2); + %alpha = ColorAlphaSelect.getValue(); + + // Update the text controls to reflect new color + //setColorInfo(%red, %green, %blue, %alpha); + if ( %colorType == 1 ) // ColorI + return mCeil( %red * 255 ) SPC mCeil( %green * 255 ) SPC mCeil( %blue * 255 ) SPC %alpha; + else // ColorF + return %red SPC %green SPC %blue SPC %alpha; +} diff --git a/Templates/BaseGame/game/tools/gui/cursors.ed.cs b/Templates/BaseGame/game/tools/gui/cursors.ed.cs new file mode 100644 index 000000000..7e1ffbf7c --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/cursors.ed.cs @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +new GuiCursor(LeftRightCursor) +{ + hotSpot = "0.5 0"; + renderOffset = "0.5 0"; + bitmapName = "./Images/leftRight"; +}; + +new GuiCursor(UpDownCursor) +{ + hotSpot = "1 1"; + renderOffset = "0 1"; + bitmapName = "./Images/upDown"; +}; + +new GuiCursor(NWSECursor) +{ + hotSpot = "1 1"; + renderOffset = "0.5 0.5"; + bitmapName = "./Images/NWSE"; +}; + +new GuiCursor(NESWCursor) +{ + hotSpot = "1 1"; + renderOffset = "0.5 0.5"; + bitmapName = "./Images/NESW"; +}; + +new GuiCursor(MoveCursor) +{ + hotSpot = "1 1"; + renderOffset = "0.5 0.5"; + bitmapName = "./Images/move"; +}; + +new GuiCursor(TextEditCursor) +{ + hotSpot = "1 1"; + renderOffset = "0.5 0.5"; + bitmapName = "./Images/textEdit"; +}; diff --git a/Templates/BaseGame/game/tools/gui/fileDialogBase.ed.cs b/Templates/BaseGame/game/tools/gui/fileDialogBase.ed.cs new file mode 100644 index 000000000..9d40e0434 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/fileDialogBase.ed.cs @@ -0,0 +1,331 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// File Dialog Base - Add to Sim Callback +// Purpose : Intitialize Variables and Setup State. +//----------------------------------------------------------------------------- +function FileDialogBase::onAdd( %this ) +{ + // Callback function Succeed + %this.SuccessCallback = 0; + // Callback function Cancel + %this.CancelCallback = 0; + + // Multiple Select Flag + %this.MultipleSelect = false; + + // File Extensions Group + %this.FileExtensions = new SimGroup(); + + %this.AddFilter("*.*","All Files"); +} + +//----------------------------------------------------------------------------- +// File Dialog Base - Remove from Sim Callback +// Purpose : Destroy Resources. +//----------------------------------------------------------------------------- +function FileDialogBase::onRemove( %this ) +{ + + // Remove FileExtensions Group + if ( isObject( %this.FileExtensions ) ) + %this.FileExtensions.delete(); + + // Remove Returned Files Group + if( isObject( %this.ReturnFiles ) ) + %this.ReturnFiles.delete(); +} + +//----------------------------------------------------------------------------- +// File Dialog Base - Show on Screen Callback +// Purpose : Destroy Resources. +//----------------------------------------------------------------------------- +function FileDialogBase::onWake( %this ) +{ + // Necessary + %dirTree = %this.findObjectByInternalName("DirectoryTree", true); + %fileList = %this.findObjectByInternalName("FileList", true); + %filterList = %this.findObjectByInternalName("FilterList", true); + %cancelButton = %this.findObjectByInternalName("CancelButton", true); + %okButton = %this.findObjectByInternalName("OkButton", true); + + // Optional + %fileName = %this.findObjectByInternalName("FileName", true); + + // Check for functionality Components. + if( !isObject( %dirTree ) || !isObject( %fileList ) || !isObject( %filterList ) ) + { + error("FileDialogBase::onWake - Unable to find NECESSARY child controls."); + return false; + } + + // Check for button components. + if( !isObject( %cancelButton ) || !isObject( %okButton ) ) + { + error("FileDialogBase::onWake - Unable to find accept and cancel buttons!"); + return false; + } + + // Tag controls so that they can navigate our dialog. + %dirTree.parent = %this; + %fileList.parent = %this; + %filterList.parent = %this; + %okButton.parent = %this; + %cancelButton.parent = %this; + + // Tag optionals + if( isObject( %fileName ) ) + %fileName.parent = %this; + + // Finally, make sure our ReturnFiles group is empty. + if( isObject( %this.ReturnFiles ) ) + %this.ReturnFiles.delete(); + + %this.ReturnFiles = new SimGroup(); + %this.add( %this.ReturnFiles ); + + // If no filters + if( %this.GetFilterCount() == 0 ) + %this.addfilter("*.*","All Files"); + + %this.PopulateFilters(); + +} + +//----------------------------------------------------------------------------- +// File Dialog Base - Add a file extension filter to the list +//----------------------------------------------------------------------------- +function FileDialogBase::AddFilter( %this, %extension, %caption ) +{ + if( !isObject( %this.FileExtensions ) ) + { + error("OpenFileDialog::AddFilter - FileExtensions Group does not exist!"); + return false; + } + + %filter = new ScriptObject() + { + extension = %extension; + caption = %caption; + }; + + // Add to filter list + %this.FileExtensions.add( %filter ); + + return %filter; +} + +//----------------------------------------------------------------------------- +// File Dialog Base - Clear filters by file extension +//----------------------------------------------------------------------------- +function FileDialogBase::ClearFilters( %this ) +{ + if( isObject( %this.FileExtensions ) ) + %this.FileExtensions.delete(); + + %this.FileExtensions = new SimGroup(); +} + + +//----------------------------------------------------------------------------- +// File Dialog Base - Get number of filters +//----------------------------------------------------------------------------- +function FileDialogBase::GetFilterCount( %this ) +{ + if( !isObject( %this.FileExtensions ) ) + return 0; + + // Return Count + return %this.FileExtensions.getCount(); + +} + +//----------------------------------------------------------------------------- +// File Dialog Base - Populate dropdown with filter options +//----------------------------------------------------------------------------- +function FileDialogBase::PopulateFilters( %this ) +{ + %fileExtensions = %this.FileExtensions; + if( !isObject( %fileExtensions ) ) + { + error("OpenFileDialog::PopulateFilters - FileExtensions Group does not exist!"); + return false; + } + + %filterList = %this.findObjectByInternalName("FilterList", true); + if( !isObject( %filterList ) ) + { + error("FileDialogBase::PopulateFilters - Filter List Dropdown not found!"); + return false; + } + + // Clear filter list + %filterList.clear(); + + // Populate List + for( %i = 0; %i < %fileExtensions.getCount(); %i++ ) + { + // Fetch Filter Script Object + %filter = %fileExtensions.getObject( %i ); + + // Add item to list + %filterList.add( %filter.Caption SPC "(" SPC %filter.Extension SPC ")", %filter.getID() ); + } + + // Set First Item to Selected. + %filterList.setFirstSelected(); + + +} + +function FileDialogOkButton::onClick( %this ) +{ + if( !isObject( %this.parent ) ) + { + error("FileDialogBase->FileDialogOkButton::onClick - Unable to find proper parent control! Functionality Compromised!"); + return; + } + + %dirTree = %this.parent.findObjectByInternalName("DirectoryTree", true); + %fileList = %this.parent.findObjectByInternalName("FileList", true); + %filterList = %this.parent.findObjectByInternalName("FilterList", true); + + // Check for functionality Components. + if( !isObject( %dirTree ) || !isObject( %fileList ) || !isObject( %filterList ) ) + { + error("FileDialogOkButton::onClick - Unable to find NECESSARY sibling controls."); + return; + } + + // + // Fetch Path + // + %path = %dirTree.getSelectedPath(); + + // + // Compose File Name + // + %fileNameCtrl = %this.parent.findObjectByInternalName("FileName", true); + + // FileName TextEdit? + if( isObject( %fileNameCtrl ) ) + { + // Get FileName from TextEdit + %fileName = %fileNameCtrl.getText(); + + // Get Filter Object from dropdown list + %filterObj = %filterList.getSelected(); + + // Validate File Extension + if( fileExt( %fileName ) $= "" && isObject( %filterObj ) ) + { + // Append Extension to FileName + %fileName = %fileName @ fileExt( %filterObj.Extension ); + } + } + else + %fileName = %fileList.getSelectedFile(); + + // + // Build Full Path + // + %fullPath = %path @ "/" @ %fileName; + + Canvas.popDialog( %this.parent ); + + // Callback + eval( %this.parent.SuccessCallback @ "(\"" @ %fullPath @"\");" ); + + %parent.SuccessCallback = 0; + + //error("Ok"); + +} + +function FileDialogCancelButton::onClick( %this ) +{ + Canvas.popDialog( %this.parent ); + //error("Cancel"); +} + + +function FileDialogDirectoryTree::onSelectPath( %this, %path ) +{ + %fileList = %this.parent.findObjectByInternalName("FileList", true); + %filterList = %this.parent.findObjectByInternalName("FilterList", true); + + + %filterObj = %filterList.getSelected(); + if( !isObject( %filterObj ) ) + %filter = "*.*"; + else + %filter = %filterObj.Extension; + + %fileList.setPath( %path, %filter ); +} + + +function FileDialogFilterList::onSelect( %this, %id, %text ) +{ + if( !isObject( %id ) ) + { + error("FileDialogFilterList::onSelect - Invalid Filter Object!"); + return; + } + + %fileList = %this.parent.findObjectByInternalName("FileList", true); + + %fileList.setFilter( %id.Extension ); + +} + + +function FileDialogFileList::onDoubleClick( %this ) +{ + //error("DoubleClick"); + %okButton = %this.parent.findObjectByInternalName("OkButton", true); + + if( isObject( %okButton ) ) + %okButton.performClick(); +} + +function FileDialogFileList::onSelect( %this, %listid, %file ) +{ + %fileNameCtrl = %this.parent.findObjectByInternalName("FileName", true); + + // FileName TextEdit? + if( !isObject( %fileNameCtrl ) ) + return; + + // Update our file name to the one selected + %fileNameCtrl.setText( %file ); +} + +function FileDialogFileName::onReturn( %this ) +{ + //error("onReturn"); + %okButton = %this.parent.findObjectByInternalName("OkButton", true); + + if( isObject( %okButton ) ) + %okButton.performClick(); +} diff --git a/Templates/BaseGame/game/tools/gui/guiDialogs.ed.cs b/Templates/BaseGame/game/tools/gui/guiDialogs.ed.cs new file mode 100644 index 000000000..db09e8570 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/guiDialogs.ed.cs @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +exec("./fileDialogBase.ed.cs"); +exec("./openFileDialog.ed.cs"); +exec("./saveFileDialog.ed.cs"); +exec("./saveChangesMBDlg.ed.gui"); +exec("./simViewDlg.ed.gui"); +exec("./colorPicker.ed.gui"); +exec("./materialSelector.ed.gui"); +exec("./scriptEditorDlg.ed.gui"); +exec("./colladaImport.ed.gui"); +exec("./EditorLoadingGui.gui"); +exec("./GuiEaseEditDlg.ed.gui"); +exec("./GuiEaseEditDlg.ed.cs"); +exec("./guiObjectInspector.ed.cs"); +exec("./uvEditor.ed.gui"); +exec("./objectSelection.ed.cs"); +exec("./guiPlatformGenericMenubar.ed.cs"); diff --git a/Templates/BaseGame/game/tools/gui/guiObjectInspector.ed.cs b/Templates/BaseGame/game/tools/gui/guiObjectInspector.ed.cs new file mode 100644 index 000000000..33b65f6bd --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/guiObjectInspector.ed.cs @@ -0,0 +1,248 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// The "Object Inspector" is a useful little window for browsing and editing SimObject +// hierarchies. Be aware that there is no undo in the inspector. + +//--------------------------------------------------------------------------------------------- + +/// Bring up a new inspector window on the given object. +function inspectObject( %object ) +{ + if( !isObject( %object ) ) + { + error( "inspectObject: no object '" @ %object @ "'" ); + return; + } + + // Create a new object inspector window. + exec( "./guiObjectInspector.ed.gui" ); + + if( !isObject( %guiContent) ) + { + error( "InspectObject: failed to create GUI from 'guiObjectInspector.ed.gui'" ); + return; + } + + // Initialize the inspector. + + %guiContent.init( %object ); + + Canvas.getContent().add( %guiContent ); +} + +//============================================================================================= +// GuiObjectInspector +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspector::init( %this, %object ) +{ + if( !%object.isMemberOfClass( "SimSet" ) ) + { + // Complete deletely the splitter and the left-side part of the inspector + // leaving only the field inspector. + + %this.add( %this-->panel2 ); + %this-->splitter.delete(); + %this-->inspector.inspect( %object ); + %this-->methodList.init( %object ); + } + else + { + %treeView = %this-->treeView; + %treeView.inspectorCtrl = %this-->inspector; + %treeView.methodList = %this-->methodList; + + %treeView.open( %object ); + } + + // Set window caption. + + %caption = "Object Inspector - " @ %object.getId() @ " : " @ %object.getClassName(); + + %name = %object.getName(); + if( %name !$= "" ) + %caption = %caption @ " - " @ %name; + + %this.text = %caption; +} + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspector::onClose( %this ) +{ + // Delete us. + %this.schedule( 1, "delete" ); +} + +//============================================================================================= +// GuiObjectInspectorTree +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspectorTree::onSelect( %this, %object ) +{ + if( isObject( %object ) ) + { + %this.inspectorCtrl.inspect( %object ); + %this.methodList.init( %object ); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspectorTree::onRightMouseUp( %this, %itemId, %mousePos, %object ) +{ + if( !isObject( GuiObjectInspectorTreePopup ) ) + new PopupMenu( GuiObjectInspectorTreePopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.object );"; + + object = ""; + }; + + GuiObjectInspectorTreePopup.object = %object; + GuiObjectInspectorTreePopup.showPopup( Canvas ); +} + +//============================================================================================= +// GuiObjectInspectorMethodList +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspectorMethodList::init( %this, %object ) +{ + %this.clear(); + + %methods = %object.dumpMethods(); + %count = %methods.count(); + %methodsGroup = %this.insertItem( 0, "Methods" ); + %parentScripted = %this.insertItem( %methodsGroup, "Scripted" ); + %parentNative = %this.insertItem( %methodsGroup, "Native" ); + + for( %i = 0; %i < %count; %i ++ ) + { + %name = %methods.getKey( %i ); + %value = %methods.getValue( %i ); + %prototype = getRecord( %value, 2 ); + %fileName = getRecord( %value, 3 ); + %lineNumber = getRecord( %value, 4 ); + %usage = getRecords( %value, 5 ); + + %tooltip = %prototype; + if( isFile( %fileName ) ) + { + %parent = %parentScripted; + %tooltip = %tooltip NL "Declared in: " @ %fileName @ ":" @ %lineNumber; + } + else + %parent = %parentNative; + + %tooltip = %tooltip @ "\n\n" @ %usage; + + %id = %this.insertItem( %parent, %prototype, %fileName NL %lineNumber ); + %this.setItemTooltip( %id, %tooltip ); + } + + %methods.delete(); + + if( %object.isMethod( "getDebugInfo" ) ) + { + %debugInfo = %object.getDebugInfo(); + %count = %debugInfo.count(); + %parent = %this.insertItem( 0, "Debug Info" ); + + for( %i = 0; %i < %count; %i ++ ) + %id = %this.insertItem( %parent, %debugInfo.getKey( %i ) @ ": " @ %debugInfo.getValue( %i ) ); + + %debugInfo.delete(); + } + + %this.sort( 0, true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspectorMethodList::onRightMouseUp( %this, %item, %mousePos ) +{ + %value = %this.getItemValue( %item ); + if( %value $= "" ) + return; + + %fileName = getRecord( %value, 0 ); + %lineNumber = getRecord( %value, 1 ); + + if( isFile( %fileName ) ) + { + if( !isObject( GuiInspectorMethodListPopup ) ) + new PopupMenu( GuiInspectorMethodListPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenFileInTorsion( %this.jumpFileName, %this.jumpLineNumber );"; + + jumpFileName = ""; + jumpLineNumber = ""; + }; + + GuiInspectorMethodListPopup.jumpFileName = %fileName; + GuiInspectorMethodListPopup.jumpLineNumber = %lineNumber; + + GuiInspectorMethodListPopup.showPopup( Canvas ); + } +} + +//============================================================================================= +// GuiObjectInspectorTreeFilter +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspectorTreeFilter::onWake( %this ) +{ + %treeView = %this.getParent()-->TreeView; + if( isObject( %treeView ) ) + %this.treeView = %treeView; + + Parent::onWake( %this ); +} + +//============================================================================================= +// GuiObjectInspectorTreeFilter +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiObjectInspectorTreeFilterClearButton::onWake( %this ) +{ + %filterText = %this.getParent()-->FilterText; + if( isObject( %filterText ) ) + %this.textCtrl = %filterText; +} diff --git a/Templates/BaseGame/game/tools/gui/guiObjectInspector.ed.gui b/Templates/BaseGame/game/tools/gui/guiObjectInspector.ed.gui new file mode 100644 index 000000000..596e8e216 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/guiObjectInspector.ed.gui @@ -0,0 +1,401 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiWindowCollapseCtrl() { + collapseGroup = "-1"; + collapseGroupNum = "-1"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "1"; + canMaximize = "1"; + minSize = "50 50"; + closeCommand = "$ThisControl.onClose();"; + edgeSnap = "1"; + text = "Object Inspector"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "ToolsGuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "152 130"; + extent = "658 472"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "GuiObjectInspector"; + className = "GuiObjectInspector"; + + new GuiSplitContainer() { + orientation = "Vertical"; + splitterSize = "2"; + splitPoint = "300 100"; + fixedPanel = "None"; + fixedSize = "100"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "1 21"; + extent = "656 448"; + minExtent = "64 64"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "Splitter"; + canSaveDynamicFields = "0"; + + new GuiPanel() { + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "0 0"; + extent = "298 448"; + minExtent = "16 16"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "Panel1"; + canSaveDynamicFields = "0"; + + new GuiTextEditCtrl() { + position = "2 3"; + extent = "278 18"; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + superClass = "GuiTreeViewFilterText"; + class = "GuiObjectInspectorTreeFilter"; + internalName = "FilterText"; + }; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "281 4"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + superClass = "GuiTreeViewFilterClearButton"; + class = "GuiObjectInspectorTreeFilterClearButton"; + }; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "ToolsGuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "1 22"; + extent = "297 426"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl() { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "0"; + mouseDragging = "0"; + multipleSelections = "0"; + deleteObjectAllowed = "0"; + dragToItemAllowed = "0"; + clearAllOnSingleSelection = "1"; + showRoot = "1"; + internalNamesOnly = "0"; + objectNamesOnly = "0"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "0"; + isContainer = "1"; + profile = "ToolsGuiTreeViewProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "1 1"; + extent = "166 21"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "TreeView"; + canSaveDynamicFields = "0"; + class = "GuiObjectInspectorTree"; + }; + }; + }; + new GuiPanel() { + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "302 0"; + extent = "354 448"; + minExtent = "16 16"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "panel2"; + canSaveDynamicFields = "0"; + + new GuiSplitContainer() { + orientation = "Horizontal"; + splitterSize = "2"; + splitPoint = "100 300"; + fixedPanel = "None"; + fixedSize = "100"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 2"; + extent = "354 448"; + minExtent = "64 64"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiPanel() { + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "354 298"; + minExtent = "16 16"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "Panel1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "ToolsGuiScrollProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "354 298"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiInspector() { + dividerMargin = "5"; + showCustomFields = "1"; + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "1"; + dynamicSize = "1"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + isContainer = "1"; + profile = "GuiInspectorProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "1 1"; + extent = "337 16"; + minExtent = "16 16"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "inspector"; + canSaveDynamicFields = "0"; + class = "GuiObjectInspectorFields"; + className = "GuiObjectInspectorFields"; + superClass = "EditorInspectorBase"; + }; + }; + }; + new GuiPanel() { + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 302"; + extent = "354 146"; + minExtent = "16 50"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "panel2"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + docking = "Client"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "ToolsGuiScrollProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "354 146"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl() { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + mouseDragging = "0"; + multipleSelections = "0"; + deleteObjectAllowed = "0"; + dragToItemAllowed = "0"; + clearAllOnSingleSelection = "1"; + showRoot = "1"; + internalNamesOnly = "0"; + objectNamesOnly = "0"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "0"; + isContainer = "1"; + profile = "ToolsGuiTreeViewProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "1 1"; + extent = "109 42"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "methodList"; + canSaveDynamicFields = "0"; + class = "GuiObjectInspectorMethodList"; + className = "GuiObjectInspectorMethodList"; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.cs b/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.cs new file mode 100644 index 000000000..089b0b8fa --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.cs @@ -0,0 +1,19 @@ +if(isClass(GuiPlatformGenericMenuBar)) +{ + exec("./guiPlatformGenericMenubar.ed.gui"); +} +else +{ + %guiContent = new GuiControl(PlatformGenericMenubar) { + profile = "GuiModelessDialogProfile"; + + new GuiControl() + { + internalName = "menubar"; + extent = "1024 20"; + minExtent = "320 20"; + horizSizing = "width"; + profile = "GuiMenuBarProfile"; + }; + }; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.gui b/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.gui new file mode 100644 index 000000000..8d2cbcd74 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/guiPlatformGenericMenubar.ed.gui @@ -0,0 +1,14 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(PlatformGenericMenubar) { + profile = "GuiModelessDialogProfile"; + + new GuiPlatformGenericMenuBar() + { + internalName = "menubar"; + extent = "1024 20"; + minExtent = "320 20"; + horizSizing = "width"; + profile = "GuiMenuBarProfile"; + }; +}; +//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconAnimation.png b/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconAnimation.png new file mode 100644 index 000000000..480dfce70 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconAnimation.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconExistingMaterial.png b/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconExistingMaterial.png new file mode 100644 index 000000000..a7e472232 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconExistingMaterial.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconIgnoreNode.png b/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconIgnoreNode.png new file mode 100644 index 000000000..744df795a Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconIgnoreNode.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconLight.png b/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconLight.png new file mode 100644 index 000000000..bd47c6187 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconLight.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconMaterial.png b/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconMaterial.png new file mode 100644 index 000000000..e5c83d942 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconMaterial.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconMesh.png b/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconMesh.png new file mode 100644 index 000000000..e0b7e7f94 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconMesh.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconNode.png b/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconNode.png new file mode 100644 index 000000000..a24d6052d Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/ColladaImport/iconNode.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-bottom_d.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-bottom_d.png new file mode 100644 index 000000000..57abbf499 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-bottom_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-bottom_h.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-bottom_h.png new file mode 100644 index 000000000..f506cda5a Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-bottom_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-bottom_n.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-bottom_n.png new file mode 100644 index 000000000..38fcc753d Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-bottom_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-left_d.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-left_d.png new file mode 100644 index 000000000..585cee321 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-left_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-left_h.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-left_h.png new file mode 100644 index 000000000..88ad2882a Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-left_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-left_n.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-left_n.png new file mode 100644 index 000000000..a86581d31 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-left_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-right_d.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-right_d.png new file mode 100644 index 000000000..7ac9b2eb4 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-right_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-right_h.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-right_h.png new file mode 100644 index 000000000..7ae17f933 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-right_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-right_n.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-right_n.png new file mode 100644 index 000000000..4ba926e19 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-right_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-top_d.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-top_d.png new file mode 100644 index 000000000..5380df5c4 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-top_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-top_h.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-top_h.png new file mode 100644 index 000000000..368fcab20 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-top_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-top_n.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-top_n.png new file mode 100644 index 000000000..be9738647 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/align-top_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/bring-to-front_d.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/bring-to-front_d.png new file mode 100644 index 000000000..a98c192dd Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/bring-to-front_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/bring-to-front_h.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/bring-to-front_h.png new file mode 100644 index 000000000..c8289f7a0 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/bring-to-front_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/bring-to-front_n.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/bring-to-front_n.png new file mode 100644 index 000000000..0f768fbc6 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/bring-to-front_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/centersnap_d.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/centersnap_d.png new file mode 100644 index 000000000..fc95fc3e6 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/centersnap_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/centersnap_h.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/centersnap_h.png new file mode 100644 index 000000000..b6a4015a3 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/centersnap_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/centersnap_n.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/centersnap_n.png new file mode 100644 index 000000000..189932ef9 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/centersnap_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-horizontal_d.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-horizontal_d.png new file mode 100644 index 000000000..204b03d47 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-horizontal_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-horizontal_h.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-horizontal_h.png new file mode 100644 index 000000000..886496372 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-horizontal_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-horizontal_n.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-horizontal_n.png new file mode 100644 index 000000000..5025483b5 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-horizontal_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-vertical_d.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-vertical_d.png new file mode 100644 index 000000000..205af2b98 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-vertical_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-vertical_h.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-vertical_h.png new file mode 100644 index 000000000..1dc903759 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-vertical_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-vertical_n.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-vertical_n.png new file mode 100644 index 000000000..fd4de0f1a Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/distribute-vertical_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/edgesnap_d.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/edgesnap_d.png new file mode 100644 index 000000000..a368096d8 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/edgesnap_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/edgesnap_h.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/edgesnap_h.png new file mode 100644 index 000000000..ad60be2bf Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/edgesnap_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/edgesnap_n.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/edgesnap_n.png new file mode 100644 index 000000000..b39ed929b Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/edgesnap_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/gui-library_d.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/gui-library_d.png new file mode 100644 index 000000000..0aaa49872 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/gui-library_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/gui-library_h.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/gui-library_h.png new file mode 100644 index 000000000..aeb7e4b5e Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/gui-library_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/gui-library_n.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/gui-library_n.png new file mode 100644 index 000000000..abeaba153 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/gui-library_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/horizontal-center_d.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/horizontal-center_d.png new file mode 100644 index 000000000..554647640 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/horizontal-center_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/horizontal-center_h.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/horizontal-center_h.png new file mode 100644 index 000000000..e02673324 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/horizontal-center_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/horizontal-center_n.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/horizontal-center_n.png new file mode 100644 index 000000000..0233a804c Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/horizontal-center_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/send-to-back_d.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/send-to-back_d.png new file mode 100644 index 000000000..4c405c57e Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/send-to-back_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/send-to-back_h.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/send-to-back_h.png new file mode 100644 index 000000000..d25111b61 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/send-to-back_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/send-to-back_n.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/send-to-back_n.png new file mode 100644 index 000000000..70721965f Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/send-to-back_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/snap-grid_d.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/snap-grid_d.png new file mode 100644 index 000000000..e97dd429d Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/snap-grid_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/snap-grid_h.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/snap-grid_h.png new file mode 100644 index 000000000..fa681e049 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/snap-grid_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/snap-grid_n.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/snap-grid_n.png new file mode 100644 index 000000000..ca97f4e92 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/snap-grid_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/vertical-center_d.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/vertical-center_d.png new file mode 100644 index 000000000..9b580ad5b Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/vertical-center_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/vertical-center_h.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/vertical-center_h.png new file mode 100644 index 000000000..a2d561142 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/vertical-center_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/GUI-editor/vertical-center_n.png b/Templates/BaseGame/game/tools/gui/images/GUI-editor/vertical-center_n.png new file mode 100644 index 000000000..d0f6c45e5 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/GUI-editor/vertical-center_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/NESW.png b/Templates/BaseGame/game/tools/gui/images/NESW.png new file mode 100644 index 000000000..2f73696c8 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/NESW.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/NWSE.png b/Templates/BaseGame/game/tools/gui/images/NWSE.png new file mode 100644 index 000000000..c952a3e45 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/NWSE.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_ctrl_d.png b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_ctrl_d.png new file mode 100644 index 000000000..c8a9417b4 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_ctrl_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_ctrl_h.png b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_ctrl_h.png new file mode 100644 index 000000000..fa7c424b7 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_ctrl_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_ctrl_n.png b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_ctrl_n.png new file mode 100644 index 000000000..47842cd61 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_ctrl_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_d.png b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_d.png new file mode 100644 index 000000000..c8a9417b4 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_h.png b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_h.png new file mode 100644 index 000000000..fa7c424b7 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_n.png b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_n.png new file mode 100644 index 000000000..68252b834 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/arrowbtn_d.png b/Templates/BaseGame/game/tools/gui/images/arrowbtn_d.png new file mode 100644 index 000000000..be39b42bd Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/arrowbtn_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/arrowbtn_n.png b/Templates/BaseGame/game/tools/gui/images/arrowbtn_n.png new file mode 100644 index 000000000..0c0fd526d Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/arrowbtn_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/axis-icon_-x.png b/Templates/BaseGame/game/tools/gui/images/axis-icon_-x.png new file mode 100644 index 000000000..6f52027b7 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/axis-icon_-x.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/axis-icon_-y.png b/Templates/BaseGame/game/tools/gui/images/axis-icon_-y.png new file mode 100644 index 000000000..613dcc43f Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/axis-icon_-y.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/axis-icon_-z.png b/Templates/BaseGame/game/tools/gui/images/axis-icon_-z.png new file mode 100644 index 000000000..6bdc9cb91 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/axis-icon_-z.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/axis-icon_x.png b/Templates/BaseGame/game/tools/gui/images/axis-icon_x.png new file mode 100644 index 000000000..305caf6b5 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/axis-icon_x.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/axis-icon_y.png b/Templates/BaseGame/game/tools/gui/images/axis-icon_y.png new file mode 100644 index 000000000..6f7988bdf Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/axis-icon_y.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/axis-icon_z.png b/Templates/BaseGame/game/tools/gui/images/axis-icon_z.png new file mode 100644 index 000000000..1b3c12f80 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/axis-icon_z.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/button.png b/Templates/BaseGame/game/tools/gui/images/button.png new file mode 100644 index 000000000..1c7361e25 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/button.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/camera-btn_d.png b/Templates/BaseGame/game/tools/gui/images/camera-btn_d.png new file mode 100644 index 000000000..6029aa915 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/camera-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/camera-btn_h.png b/Templates/BaseGame/game/tools/gui/images/camera-btn_h.png new file mode 100644 index 000000000..a088f2213 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/camera-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/camera-btn_n.png b/Templates/BaseGame/game/tools/gui/images/camera-btn_n.png new file mode 100644 index 000000000..372a267bb Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/camera-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/checkbox-list.png b/Templates/BaseGame/game/tools/gui/images/checkbox-list.png new file mode 100644 index 000000000..04ca2b0dc Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/checkbox-list.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/checkbox-list_fliped.png b/Templates/BaseGame/game/tools/gui/images/checkbox-list_fliped.png new file mode 100644 index 000000000..2db4489de Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/checkbox-list_fliped.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/checkbox-menubar.png b/Templates/BaseGame/game/tools/gui/images/checkbox-menubar.png new file mode 100644 index 000000000..a3314baff Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/checkbox-menubar.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/checkbox.png b/Templates/BaseGame/game/tools/gui/images/checkbox.png new file mode 100644 index 000000000..46e0ac959 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/checkbox.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/clear-btn_d.png b/Templates/BaseGame/game/tools/gui/images/clear-btn_d.png new file mode 100644 index 000000000..229c71e8b Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/clear-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/clear-btn_h.png b/Templates/BaseGame/game/tools/gui/images/clear-btn_h.png new file mode 100644 index 000000000..5e67cb13b Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/clear-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/clear-btn_n.png b/Templates/BaseGame/game/tools/gui/images/clear-btn_n.png new file mode 100644 index 000000000..ecb13a8d6 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/clear-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/clear-icon_d.png b/Templates/BaseGame/game/tools/gui/images/clear-icon_d.png new file mode 100644 index 000000000..ffca76c89 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/clear-icon_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/clear-icon_h.png b/Templates/BaseGame/game/tools/gui/images/clear-icon_h.png new file mode 100644 index 000000000..e424b7e0e Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/clear-icon_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/clear-icon_n.png b/Templates/BaseGame/game/tools/gui/images/clear-icon_n.png new file mode 100644 index 000000000..a82689274 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/clear-icon_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/collapse-toolbar_d.png b/Templates/BaseGame/game/tools/gui/images/collapse-toolbar_d.png new file mode 100644 index 000000000..984a63853 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/collapse-toolbar_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/collapse-toolbar_h.png b/Templates/BaseGame/game/tools/gui/images/collapse-toolbar_h.png new file mode 100644 index 000000000..7e3de8387 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/collapse-toolbar_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/collapse-toolbar_n.png b/Templates/BaseGame/game/tools/gui/images/collapse-toolbar_n.png new file mode 100644 index 000000000..b36de3ae0 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/collapse-toolbar_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/copy-btn_d.png b/Templates/BaseGame/game/tools/gui/images/copy-btn_d.png new file mode 100644 index 000000000..4212ecae0 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/copy-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/copy-btn_h.png b/Templates/BaseGame/game/tools/gui/images/copy-btn_h.png new file mode 100644 index 000000000..3de0ae110 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/copy-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/copy-btn_i.png b/Templates/BaseGame/game/tools/gui/images/copy-btn_i.png new file mode 100644 index 000000000..528d6bf93 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/copy-btn_i.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/copy-btn_n.png b/Templates/BaseGame/game/tools/gui/images/copy-btn_n.png new file mode 100644 index 000000000..b2e88b654 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/copy-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/crosshair.png b/Templates/BaseGame/game/tools/gui/images/crosshair.png new file mode 100644 index 000000000..06bcf5c6c Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/crosshair.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/crosshair_blue.png b/Templates/BaseGame/game/tools/gui/images/crosshair_blue.png new file mode 100644 index 000000000..d5b0485d7 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/crosshair_blue.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/delete_d.png b/Templates/BaseGame/game/tools/gui/images/delete_d.png new file mode 100644 index 000000000..6ffdf6d2e Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/delete_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/delete_h.png b/Templates/BaseGame/game/tools/gui/images/delete_h.png new file mode 100644 index 000000000..7a1ac2e31 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/delete_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/delete_n.png b/Templates/BaseGame/game/tools/gui/images/delete_n.png new file mode 100644 index 000000000..1cbe067cf Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/delete_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/dropDown-tab.png b/Templates/BaseGame/game/tools/gui/images/dropDown-tab.png new file mode 100644 index 000000000..d79c6c70e Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/dropDown-tab.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/dropDown.png b/Templates/BaseGame/game/tools/gui/images/dropDown.png new file mode 100644 index 000000000..9b7414acc Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/dropDown.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow.png b/Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow.png new file mode 100644 index 000000000..8c420ab85 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/dropdown-textEdit.png b/Templates/BaseGame/game/tools/gui/images/dropdown-textEdit.png new file mode 100644 index 000000000..3966efbb5 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/dropdown-textEdit.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/dropslider_d.png b/Templates/BaseGame/game/tools/gui/images/dropslider_d.png new file mode 100644 index 000000000..0c65347aa Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/dropslider_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/dropslider_h.png b/Templates/BaseGame/game/tools/gui/images/dropslider_h.png new file mode 100644 index 000000000..bd2cb89d8 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/dropslider_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/dropslider_n.png b/Templates/BaseGame/game/tools/gui/images/dropslider_n.png new file mode 100644 index 000000000..a4577f9ea Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/dropslider_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/expand-toolbar_d.png b/Templates/BaseGame/game/tools/gui/images/expand-toolbar_d.png new file mode 100644 index 000000000..a3415c7d0 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/expand-toolbar_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/expand-toolbar_h.png b/Templates/BaseGame/game/tools/gui/images/expand-toolbar_h.png new file mode 100644 index 000000000..c50608264 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/expand-toolbar_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/expand-toolbar_n.png b/Templates/BaseGame/game/tools/gui/images/expand-toolbar_n.png new file mode 100644 index 000000000..d6c63504e Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/expand-toolbar_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/folder.png b/Templates/BaseGame/game/tools/gui/images/folder.png new file mode 100644 index 000000000..571a904d0 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/folder.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/folderUp.png b/Templates/BaseGame/game/tools/gui/images/folderUp.png new file mode 100644 index 000000000..c188909a1 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/folderUp.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/folderUp_d.png b/Templates/BaseGame/game/tools/gui/images/folderUp_d.png new file mode 100644 index 000000000..c329f0372 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/folderUp_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/folderUp_h.png b/Templates/BaseGame/game/tools/gui/images/folderUp_h.png new file mode 100644 index 000000000..953fe8b40 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/folderUp_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/group-border.png b/Templates/BaseGame/game/tools/gui/images/group-border.png new file mode 100644 index 000000000..61234ae1f Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/group-border.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconAccept.png b/Templates/BaseGame/game/tools/gui/images/iconAccept.png new file mode 100644 index 000000000..a24d6052d Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconAccept.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconAdd.png b/Templates/BaseGame/game/tools/gui/images/iconAdd.png new file mode 100644 index 000000000..323edb029 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconAdd.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconCancel.png b/Templates/BaseGame/game/tools/gui/images/iconCancel.png new file mode 100644 index 000000000..744df795a Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconCancel.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconCollada.png b/Templates/BaseGame/game/tools/gui/images/iconCollada.png new file mode 100644 index 000000000..0f4017014 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconCollada.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconDelete.png b/Templates/BaseGame/game/tools/gui/images/iconDelete.png new file mode 100644 index 000000000..3ba9615b4 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconDelete.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconIcon.png b/Templates/BaseGame/game/tools/gui/images/iconIcon.png new file mode 100644 index 000000000..e5c83d942 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconIcon.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconInformation.png b/Templates/BaseGame/game/tools/gui/images/iconInformation.png new file mode 100644 index 000000000..a7e472232 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconInformation.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconList.png b/Templates/BaseGame/game/tools/gui/images/iconList.png new file mode 100644 index 000000000..39b80d238 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconList.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconLocked.png b/Templates/BaseGame/game/tools/gui/images/iconLocked.png new file mode 100644 index 000000000..2e72d2fb2 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconLocked.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconNew.png b/Templates/BaseGame/game/tools/gui/images/iconNew.png new file mode 100644 index 000000000..2446ae662 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconNew.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconOpen.png b/Templates/BaseGame/game/tools/gui/images/iconOpen.png new file mode 100644 index 000000000..29e80d77a Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconOpen.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconRefresh.png b/Templates/BaseGame/game/tools/gui/images/iconRefresh.png new file mode 100644 index 000000000..cce137ba5 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconRefresh.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconSave.png b/Templates/BaseGame/game/tools/gui/images/iconSave.png new file mode 100644 index 000000000..50e70bd70 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconSave.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconUnlocked.png b/Templates/BaseGame/game/tools/gui/images/iconUnlocked.png new file mode 100644 index 000000000..a471765ff Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconUnlocked.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconVisible.png b/Templates/BaseGame/game/tools/gui/images/iconVisible.png new file mode 100644 index 000000000..92c857866 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconVisible.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconbutton.png b/Templates/BaseGame/game/tools/gui/images/iconbutton.png new file mode 100644 index 000000000..b6f3bb6b7 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconbutton.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/iconbuttonsmall.png b/Templates/BaseGame/game/tools/gui/images/iconbuttonsmall.png new file mode 100644 index 000000000..25d5ae80b Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/iconbuttonsmall.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/inactive-overlay.png b/Templates/BaseGame/game/tools/gui/images/inactive-overlay.png new file mode 100644 index 000000000..feab83209 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/inactive-overlay.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/layers-btn_d.png b/Templates/BaseGame/game/tools/gui/images/layers-btn_d.png new file mode 100644 index 000000000..6694b71eb Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/layers-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/layers-btn_h.png b/Templates/BaseGame/game/tools/gui/images/layers-btn_h.png new file mode 100644 index 000000000..ec27d03ce Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/layers-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/layers-btn_n.png b/Templates/BaseGame/game/tools/gui/images/layers-btn_n.png new file mode 100644 index 000000000..eb0f253ed Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/layers-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/leftRight.png b/Templates/BaseGame/game/tools/gui/images/leftRight.png new file mode 100644 index 000000000..c29b7a9f8 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/leftRight.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/lock_d.png b/Templates/BaseGame/game/tools/gui/images/lock_d.png new file mode 100644 index 000000000..b7177a257 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/lock_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/lock_h.png b/Templates/BaseGame/game/tools/gui/images/lock_h.png new file mode 100644 index 000000000..b4eac3fcd Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/lock_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/lock_n.png b/Templates/BaseGame/game/tools/gui/images/lock_n.png new file mode 100644 index 000000000..91ec2a444 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/lock_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/arrow_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/arrow_d.png new file mode 100644 index 000000000..783480242 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/arrow_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/arrow_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/arrow_h.png new file mode 100644 index 000000000..2afa04469 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/arrow_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/arrow_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/arrow_n.png new file mode 100644 index 000000000..9f924edf1 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/arrow_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/bounds-center_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/bounds-center_d.png new file mode 100644 index 000000000..e063a47cd Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/bounds-center_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/bounds-center_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/bounds-center_h.png new file mode 100644 index 000000000..898ccfffb Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/bounds-center_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/bounds-center_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/bounds-center_n.png new file mode 100644 index 000000000..3bcbcf525 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/bounds-center_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/delete-btn_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/delete-btn_d.png new file mode 100644 index 000000000..4d1d130b3 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/delete-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/delete-btn_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/delete-btn_h.png new file mode 100644 index 000000000..90709bd63 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/delete-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/delete-btn_i.png b/Templates/BaseGame/game/tools/gui/images/menubar/delete-btn_i.png new file mode 100644 index 000000000..49af5bf83 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/delete-btn_i.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/delete-btn_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/delete-btn_n.png new file mode 100644 index 000000000..b5c09a25d Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/delete-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/explode-prefab_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/explode-prefab_d.png new file mode 100644 index 000000000..8e27bfefd Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/explode-prefab_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/explode-prefab_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/explode-prefab_h.png new file mode 100644 index 000000000..2ff2bf46a Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/explode-prefab_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/explode-prefab_i.png b/Templates/BaseGame/game/tools/gui/images/menubar/explode-prefab_i.png new file mode 100644 index 000000000..54e78d5c1 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/explode-prefab_i.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/explode-prefab_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/explode-prefab_n.png new file mode 100644 index 000000000..09a7ddb22 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/explode-prefab_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/fit-selection_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/fit-selection_d.png new file mode 100644 index 000000000..75159d266 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/fit-selection_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/fit-selection_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/fit-selection_h.png new file mode 100644 index 000000000..a2c39cff4 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/fit-selection_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/fit-selection_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/fit-selection_n.png new file mode 100644 index 000000000..5b159dd02 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/fit-selection_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/object-center_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/object-center_d.png new file mode 100644 index 000000000..284165852 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/object-center_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/object-center_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/object-center_h.png new file mode 100644 index 000000000..bc725fd9b Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/object-center_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/object-center_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/object-center_n.png new file mode 100644 index 000000000..b8ea86567 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/object-center_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/object-node-icon_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/object-node-icon_d.png new file mode 100644 index 000000000..d005211cc Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/object-node-icon_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/object-node-icon_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/object-node-icon_h.png new file mode 100644 index 000000000..e0b74fe41 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/object-node-icon_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/object-node-icon_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/object-node-icon_n.png new file mode 100644 index 000000000..b50616a38 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/object-node-icon_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/object-node-lable_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/object-node-lable_d.png new file mode 100644 index 000000000..765d60e8c Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/object-node-lable_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/object-node-lable_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/object-node-lable_h.png new file mode 100644 index 000000000..6202e4083 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/object-node-lable_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/object-node-lable_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/object-node-lable_n.png new file mode 100644 index 000000000..3bcc5e3d0 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/object-node-lable_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/object-transform_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/object-transform_d.png new file mode 100644 index 000000000..88aa68825 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/object-transform_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/object-transform_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/object-transform_h.png new file mode 100644 index 000000000..46d471f2d Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/object-transform_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/object-transform_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/object-transform_n.png new file mode 100644 index 000000000..065cb1fc7 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/object-transform_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/orbit-cam_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/orbit-cam_d.png new file mode 100644 index 000000000..48b686e75 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/orbit-cam_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/orbit-cam_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/orbit-cam_h.png new file mode 100644 index 000000000..34f5439d1 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/orbit-cam_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/orbit-cam_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/orbit-cam_n.png new file mode 100644 index 000000000..0e34db316 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/orbit-cam_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/rotate_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/rotate_d.png new file mode 100644 index 000000000..597c85dcb Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/rotate_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/rotate_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/rotate_h.png new file mode 100644 index 000000000..8f0535f8f Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/rotate_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/rotate_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/rotate_n.png new file mode 100644 index 000000000..65530d3a9 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/rotate_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/scale_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/scale_d.png new file mode 100644 index 000000000..eae3c8394 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/scale_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/scale_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/scale_h.png new file mode 100644 index 000000000..c43e55ff5 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/scale_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/scale_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/scale_n.png new file mode 100644 index 000000000..fee27ffe0 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/scale_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/select-bounds_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/select-bounds_d.png new file mode 100644 index 000000000..7c39417de Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/select-bounds_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/select-bounds_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/select-bounds_h.png new file mode 100644 index 000000000..4fdd99e3b Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/select-bounds_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/select-bounds_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/select-bounds_n.png new file mode 100644 index 000000000..8a322ce89 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/select-bounds_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/selection-to-prefab_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/selection-to-prefab_d.png new file mode 100644 index 000000000..94016aa37 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/selection-to-prefab_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/selection-to-prefab_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/selection-to-prefab_h.png new file mode 100644 index 000000000..4448d3393 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/selection-to-prefab_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/selection-to-prefab_i.png b/Templates/BaseGame/game/tools/gui/images/menubar/selection-to-prefab_i.png new file mode 100644 index 000000000..9f9b1c55b Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/selection-to-prefab_i.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/selection-to-prefab_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/selection-to-prefab_n.png new file mode 100644 index 000000000..d30c67f4f Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/selection-to-prefab_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/show-grid_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/show-grid_d.png new file mode 100644 index 000000000..e149a7e99 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/show-grid_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/show-grid_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/show-grid_h.png new file mode 100644 index 000000000..5a3f34518 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/show-grid_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/show-grid_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/show-grid_n.png new file mode 100644 index 000000000..618f71d52 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/show-grid_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/show-preview_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/show-preview_d.png new file mode 100644 index 000000000..56d08e5d3 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/show-preview_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/show-preview_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/show-preview_h.png new file mode 100644 index 000000000..39df58c9d Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/show-preview_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/show-preview_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/show-preview_n.png new file mode 100644 index 000000000..4571767ae Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/show-preview_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam-rot_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam-rot_d.png new file mode 100644 index 000000000..8c8e2c69c Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam-rot_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam-rot_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam-rot_h.png new file mode 100644 index 000000000..3af52d968 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam-rot_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam-rot_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam-rot_n.png new file mode 100644 index 000000000..a6f3081fd Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam-rot_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam_d.png new file mode 100644 index 000000000..7b0bb6d3a Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam_h.png new file mode 100644 index 000000000..b7988511c Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam_n.png new file mode 100644 index 000000000..6168a6613 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/smooth-cam_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/snap-bounds_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/snap-bounds_d.png new file mode 100644 index 000000000..3da4ee311 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/snap-bounds_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/snap-bounds_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/snap-bounds_h.png new file mode 100644 index 000000000..b0f4346a0 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/snap-bounds_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/snap-bounds_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/snap-bounds_n.png new file mode 100644 index 000000000..4c6d83529 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/snap-bounds_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/snap-grid_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/snap-grid_d.png new file mode 100644 index 000000000..e97dd429d Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/snap-grid_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/snap-grid_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/snap-grid_h.png new file mode 100644 index 000000000..fa681e049 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/snap-grid_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/snap-grid_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/snap-grid_n.png new file mode 100644 index 000000000..ca97f4e92 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/snap-grid_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/snap-objects_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/snap-objects_d.png new file mode 100644 index 000000000..934fd5013 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/snap-objects_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/snap-objects_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/snap-objects_h.png new file mode 100644 index 000000000..07f0aea50 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/snap-objects_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/snap-objects_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/snap-objects_n.png new file mode 100644 index 000000000..22e45dc64 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/snap-objects_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/snap-terrain_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/snap-terrain_d.png new file mode 100644 index 000000000..13dfc2e1e Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/snap-terrain_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/snap-terrain_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/snap-terrain_h.png new file mode 100644 index 000000000..47cc46b21 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/snap-terrain_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/snap-terrain_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/snap-terrain_n.png new file mode 100644 index 000000000..4d8534c5e Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/snap-terrain_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/snapping-settings_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/snapping-settings_d.png new file mode 100644 index 000000000..a879682d1 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/snapping-settings_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/snapping-settings_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/snapping-settings_h.png new file mode 100644 index 000000000..d11d45932 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/snapping-settings_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/snapping-settings_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/snapping-settings_n.png new file mode 100644 index 000000000..caac7467d Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/snapping-settings_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/translate_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/translate_d.png new file mode 100644 index 000000000..39a3487bd Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/translate_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/translate_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/translate_h.png new file mode 100644 index 000000000..b6e08379f Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/translate_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/translate_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/translate_n.png new file mode 100644 index 000000000..17f197247 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/translate_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/visibility-toggle_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/visibility-toggle_d.png new file mode 100644 index 000000000..14e658f0c Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/visibility-toggle_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/visibility-toggle_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/visibility-toggle_h.png new file mode 100644 index 000000000..0f2fb1f02 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/visibility-toggle_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/visibility-toggle_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/visibility-toggle_n.png new file mode 100644 index 000000000..25a2d20d8 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/visibility-toggle_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/world-transform_d.png b/Templates/BaseGame/game/tools/gui/images/menubar/world-transform_d.png new file mode 100644 index 000000000..bafcde2ba Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/world-transform_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/world-transform_h.png b/Templates/BaseGame/game/tools/gui/images/menubar/world-transform_h.png new file mode 100644 index 000000000..2a34b9071 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/world-transform_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/menubar/world-transform_n.png b/Templates/BaseGame/game/tools/gui/images/menubar/world-transform_n.png new file mode 100644 index 000000000..0aa45e46c Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/menubar/world-transform_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/move.png b/Templates/BaseGame/game/tools/gui/images/move.png new file mode 100644 index 000000000..70f9cd540 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/move.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/new-folder-btn_d.png b/Templates/BaseGame/game/tools/gui/images/new-folder-btn_d.png new file mode 100644 index 000000000..c8a9417b4 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/new-folder-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/new-folder-btn_h.png b/Templates/BaseGame/game/tools/gui/images/new-folder-btn_h.png new file mode 100644 index 000000000..fa7c424b7 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/new-folder-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/new-folder-btn_n.png b/Templates/BaseGame/game/tools/gui/images/new-folder-btn_n.png new file mode 100644 index 000000000..68252b834 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/new-folder-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/new_d.png b/Templates/BaseGame/game/tools/gui/images/new_d.png new file mode 100644 index 000000000..bdfc9400d Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/new_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/new_h.png b/Templates/BaseGame/game/tools/gui/images/new_h.png new file mode 100644 index 000000000..1f9b722c1 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/new_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/new_n.png b/Templates/BaseGame/game/tools/gui/images/new_n.png new file mode 100644 index 000000000..06531327d Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/new_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/open-file_d.png b/Templates/BaseGame/game/tools/gui/images/open-file_d.png new file mode 100644 index 000000000..00b709b86 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/open-file_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/open-file_h.png b/Templates/BaseGame/game/tools/gui/images/open-file_h.png new file mode 100644 index 000000000..daf4b14c9 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/open-file_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/open-file_n.png b/Templates/BaseGame/game/tools/gui/images/open-file_n.png new file mode 100644 index 000000000..8e84251c5 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/open-file_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/radioButton.png b/Templates/BaseGame/game/tools/gui/images/radioButton.png new file mode 100644 index 000000000..d5ecc9853 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/radioButton.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/reset-icon_d.png b/Templates/BaseGame/game/tools/gui/images/reset-icon_d.png new file mode 100644 index 000000000..6c9c08a87 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/reset-icon_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/reset-icon_h.png b/Templates/BaseGame/game/tools/gui/images/reset-icon_h.png new file mode 100644 index 000000000..c0dc85cd6 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/reset-icon_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/reset-icon_n.png b/Templates/BaseGame/game/tools/gui/images/reset-icon_n.png new file mode 100644 index 000000000..f34269670 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/reset-icon_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/retarget-btn_d.png b/Templates/BaseGame/game/tools/gui/images/retarget-btn_d.png new file mode 100644 index 000000000..a8854b3f8 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/retarget-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/retarget-btn_h.png b/Templates/BaseGame/game/tools/gui/images/retarget-btn_h.png new file mode 100644 index 000000000..1cc9a078d Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/retarget-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/retarget-btn_i.png b/Templates/BaseGame/game/tools/gui/images/retarget-btn_i.png new file mode 100644 index 000000000..60f8b3d4a Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/retarget-btn_i.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/retarget-btn_n.png b/Templates/BaseGame/game/tools/gui/images/retarget-btn_n.png new file mode 100644 index 000000000..2a25e1288 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/retarget-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/rl-loadingbar.png b/Templates/BaseGame/game/tools/gui/images/rl-loadingbar.png new file mode 100644 index 000000000..7116eec14 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/rl-loadingbar.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/save-all_d.png b/Templates/BaseGame/game/tools/gui/images/save-all_d.png new file mode 100644 index 000000000..c2c272de5 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/save-all_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/save-all_h.png b/Templates/BaseGame/game/tools/gui/images/save-all_h.png new file mode 100644 index 000000000..220cc9313 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/save-all_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/save-all_i.png b/Templates/BaseGame/game/tools/gui/images/save-all_i.png new file mode 100644 index 000000000..1bc06998f Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/save-all_i.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/save-all_n.png b/Templates/BaseGame/game/tools/gui/images/save-all_n.png new file mode 100644 index 000000000..36f0d1553 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/save-all_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/save-as_d.png b/Templates/BaseGame/game/tools/gui/images/save-as_d.png new file mode 100644 index 000000000..a1905924d Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/save-as_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/save-as_h.png b/Templates/BaseGame/game/tools/gui/images/save-as_h.png new file mode 100644 index 000000000..e36c98a3b Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/save-as_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/save-as_i.png b/Templates/BaseGame/game/tools/gui/images/save-as_i.png new file mode 100644 index 000000000..1f52b6499 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/save-as_i.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/save-as_n.png b/Templates/BaseGame/game/tools/gui/images/save-as_n.png new file mode 100644 index 000000000..e60ceaef4 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/save-as_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/save-icon_d.png b/Templates/BaseGame/game/tools/gui/images/save-icon_d.png new file mode 100644 index 000000000..bbb28701f Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/save-icon_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/save-icon_h.png b/Templates/BaseGame/game/tools/gui/images/save-icon_h.png new file mode 100644 index 000000000..3803ec01e Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/save-icon_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/save-icon_i.png b/Templates/BaseGame/game/tools/gui/images/save-icon_i.png new file mode 100644 index 000000000..7da2c6fdf Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/save-icon_i.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/save-icon_n.png b/Templates/BaseGame/game/tools/gui/images/save-icon_n.png new file mode 100644 index 000000000..9c6a959a7 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/save-icon_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/scrollBar.png b/Templates/BaseGame/game/tools/gui/images/scrollBar.png new file mode 100644 index 000000000..e8c34dc85 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/scrollBar.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/separator-h.png b/Templates/BaseGame/game/tools/gui/images/separator-h.png new file mode 100644 index 000000000..339c0fbe0 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/separator-h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/separator-v.png b/Templates/BaseGame/game/tools/gui/images/separator-v.png new file mode 100644 index 000000000..6a0f87361 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/separator-v.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/slider-w-box.png b/Templates/BaseGame/game/tools/gui/images/slider-w-box.png new file mode 100644 index 000000000..d9ef04961 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/slider-w-box.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/slider.png b/Templates/BaseGame/game/tools/gui/images/slider.png new file mode 100644 index 000000000..92fee1e9c Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/slider.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/tab-border.png b/Templates/BaseGame/game/tools/gui/images/tab-border.png new file mode 100644 index 000000000..6703924d4 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/tab-border.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/tab.png b/Templates/BaseGame/game/tools/gui/images/tab.png new file mode 100644 index 000000000..ecd81daf7 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/tab.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/textEdit.png b/Templates/BaseGame/game/tools/gui/images/textEdit.png new file mode 100644 index 000000000..cc3da5f85 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/textEdit.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/textEditFrame.png b/Templates/BaseGame/game/tools/gui/images/textEditFrame.png new file mode 100644 index 000000000..5a65fac3c Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/textEditFrame.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/textEditSliderBox.png b/Templates/BaseGame/game/tools/gui/images/textEditSliderBox.png new file mode 100644 index 000000000..57a0c49d3 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/textEditSliderBox.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/thumbHightlightButton.png b/Templates/BaseGame/game/tools/gui/images/thumbHightlightButton.png new file mode 100644 index 000000000..9d83b75f3 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/thumbHightlightButton.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/toolbar-window.png b/Templates/BaseGame/game/tools/gui/images/toolbar-window.png new file mode 100644 index 000000000..fa57993c2 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/toolbar-window.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/transp_grid.png b/Templates/BaseGame/game/tools/gui/images/transp_grid.png new file mode 100644 index 000000000..e6b9db4cc Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/transp_grid.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/treeView.png b/Templates/BaseGame/game/tools/gui/images/treeView.png new file mode 100644 index 000000000..cbc20d49e Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/treeView.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/treeview/default.png b/Templates/BaseGame/game/tools/gui/images/treeview/default.png new file mode 100644 index 000000000..ceadfa861 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/treeview/default.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/treeview/hidden.png b/Templates/BaseGame/game/tools/gui/images/treeview/hidden.png new file mode 100644 index 000000000..0fbcf3840 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/treeview/hidden.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/upDown.png b/Templates/BaseGame/game/tools/gui/images/upDown.png new file mode 100644 index 000000000..377217897 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/upDown.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/uv-editor-btn_d.png b/Templates/BaseGame/game/tools/gui/images/uv-editor-btn_d.png new file mode 100644 index 000000000..ad481414d Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/uv-editor-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/uv-editor-btn_h.png b/Templates/BaseGame/game/tools/gui/images/uv-editor-btn_h.png new file mode 100644 index 000000000..0de6d9ebb Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/uv-editor-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/uv-editor-btn_n.png b/Templates/BaseGame/game/tools/gui/images/uv-editor-btn_n.png new file mode 100644 index 000000000..5ae9ded23 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/uv-editor-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/visible_d.png b/Templates/BaseGame/game/tools/gui/images/visible_d.png new file mode 100644 index 000000000..329dc6a58 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/visible_d.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/visible_h.png b/Templates/BaseGame/game/tools/gui/images/visible_h.png new file mode 100644 index 000000000..5125d50ef Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/visible_h.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/visible_i.png b/Templates/BaseGame/game/tools/gui/images/visible_i.png new file mode 100644 index 000000000..eb5e3b267 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/visible_i.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/visible_n.png b/Templates/BaseGame/game/tools/gui/images/visible_n.png new file mode 100644 index 000000000..77d302629 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/visible_n.png differ diff --git a/Templates/BaseGame/game/tools/gui/images/window.png b/Templates/BaseGame/game/tools/gui/images/window.png new file mode 100644 index 000000000..d9e8006e4 Binary files /dev/null and b/Templates/BaseGame/game/tools/gui/images/window.png differ diff --git a/Templates/BaseGame/game/tools/gui/materialSelector.ed.gui b/Templates/BaseGame/game/tools/gui/materialSelector.ed.gui new file mode 100644 index 000000000..a4d2f6078 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/materialSelector.ed.gui @@ -0,0 +1,2003 @@ +new GuiControl(MaterialSelectorOverlay, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Profile = "GuiOverlayProfile"; + Enabled = "1"; + isContainer = "1"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(MaterialSelector){ + profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + resizeWidth = "1"; + resizeHeight = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + position = "72 98"; + extent =" 766 550"; + MinExtent = "383 274"; + text = "Material Selector"; + closeCommand = "MaterialSelector::hideDialog();"; + EdgeSnap = "0"; + canCollapse = "0"; + visible = "0"; + + new GuiContainer(){ + isContainer = "1"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "4 22"; + Extent = "120 31"; + Profile = "inspectorStyleRolloutDarkProfile"; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 23"; + extent = "30 16"; + text = "Filters"; + }; + new GuiContainer(){ + profile = "ToolsGuiDefaultProfile"; + Position = "4 39"; + Extent = "120 507"; + HorizSizing = "right"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "128 355"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiDefaultProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + + new GuiDynamicCtrlArrayControl() { + canSaveDynamicFields = "0"; + internalName = "filterArray"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "18 0"; + Extent = "128 195"; + MinExtent = "8 8"; + dynamicSize = "1"; + rowSpacing = "2"; + colSize = "128"; + rowSize = "18"; + }; + }; + }; + new GuiContainer(){ + Profile = "inspectorStyleRolloutDarkProfile"; + Position = "128 22"; + Extent = "480 31"; + HorizSizing = "width"; + VertSizing = "bottom"; + isContainer = "1"; + }; + new GuiTextCtrl(){ + profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "133 23"; + extent = "53 16"; + text = "Materials"; + }; + // Create New Material + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "594 24"; + Extent = "15 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialSelector.createNewMaterial();"; + hovertime = "1000"; + tooltip = "Create New Unmapped Material"; + bitmap = "tools/gui/images/new"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "578 24"; + Extent = "15 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialSelector.showDeleteDialog();"; + hovertime = "1000"; + tooltip = "Delete Material"; + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiContainer(){ // Materials + profile = "ToolsGuiDefaultProfile"; + Position = "128 39"; + Extent = "480 507"; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "480 507"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiDefaultProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiStackControl(){ + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "128 0"; + changeChildPosition = 0; + changeChildSizeToFit = 1; + + new GuiControl(){ + Extent = "0 4"; + }; + new GuiDynamicCtrlArrayControl() { + canSaveDynamicFields = "0"; + internalName = "materialSelection"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "3 0"; + Extent = "128 0"; + MinExtent = "8 8"; + dynamicSize = "1"; + autoCellSize = "1"; + rowSpacing = "2"; + colSpacing = "2"; + margin = "2"; + }; + }; + }; + + new GuiContainer(){ + internalName = "materialPreviewControlContainer"; + profile = "ToolsGuiDefaultProfile"; + Position = "0 0"; + Extent = "480 20"; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + Docking = "Bottom"; + + new GuiTextCtrl(){ + profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + extent = "100 16"; + text = "Thumbnails per Page:"; + }; + new GuiPopupMenuCtrlEx(){ + internalName = "materialPreviewCountPopup"; + Profile = "ToolsGuiPopUpMenuProfile"; + Position = "104 2"; + Extent = "40 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + Command = "MaterialSelector.thumbnailCountUpdate();"; + reverseTextList = "0"; + Text = "16"; + }; + + new GuiStackControl(){ + internalName = "materialPreviewButtonStack"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "480 2"; + Extent = "0 16"; + dynamic = 1; + dynamicPos = 1; + stackingType = "Horizontal"; + changeChildPosition = 1; + changeChildSizeToFit = 1; + padding = 2; + + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "20 16"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "MaterialSelector::firstPage();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "First"; + hovertime = "1000"; + text = "|<"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "20 16"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "MaterialSelector::previousPage();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Previous"; + hovertime = "1000"; + text = "<"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + }; + new GuiStackControl(){ + internalName = "materialPreviewPagesStack"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "0 16"; + dynamic = 1; + stackingType = "Horizontal"; + changeChildPosition = 1; + changeChildSizeToFit = 1; + padding = 2; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "20 16"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "MaterialSelector::nextPage();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Next"; + hovertime = "1000"; + text = ">"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "20 16"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "MaterialSelector::lastPage();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Last"; + hovertime = "1000"; + text = ">|"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + }; + + }; + }; + }; + new GuiContainer(){ + Profile = "inspectorStyleRolloutDarkProfile"; + Position = "612 206"; + Extent = "150 31"; + HorizSizing = "left"; + VertSizing = "bottom"; + isContainer = "1"; + }; + new GuiTextCtrl(){ + profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "618 207"; + extent = "84 16"; + text = "Material Tags"; + }; + new GuiContainer(){ // Filter Selection + profile = "ToolsGuiDefaultProfile"; + Position = "612 223"; + Extent = "150 295"; + HorizSizing = "left"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "128 195"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiDefaultProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiDynamicCtrlArrayControl() { + canSaveDynamicFields = "0"; + internalName = "materialCategories"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "128 195"; + MinExtent = "8 8"; + dynamicSize = "1"; + rowSpacing = "2"; + colSize = "128"; + rowSize = "18"; + }; + }; + }; + new GuiContainer(){ + Profile = "inspectorStyleRolloutDarkProfile"; + Position = "612 22"; + Extent = "150 167"; + HorizSizing = "left"; + VertSizing = "bottom"; + isContainer = "1"; + + new GuiBitmapCtrl(){ + internalName = "previewSelection"; + HorizSizing = "left"; + VertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + position = "1 18"; + extent = "148 148"; + bitmap = ""; + }; + }; + new GuiTextCtrl(){ + profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "618 23"; + extent = "84 16"; + text = "Diffuse Preview"; + }; + + new GuiBitmapCtrl(){ + HorizSizing = "left"; + VertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + position = "612 39"; + extent = "150 150"; + bitmap = "tools/worldEditor/images/terrainpainter/terrain-painter-border-large"; + visible = false; + }; + new GuiTextCtrl(){ + internalName = "previewSelectionText"; + HorizSizing = "left"; + VertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + position = "613 189"; + extent = "149 16"; + text = ""; + }; + new GuiButtonCtrl(){ + internalName = "SelectButton"; + HorizSizing = "left"; + VertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + position = "612 522"; + extent = "94 24"; + text = "Select"; + command = "MaterialSelector.selectMaterial( MaterialSelector.selectedMaterial );"; + }; + new GuiButtonCtrl(){ + HorizSizing = "left"; + VertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + position = "710 522"; + extent = "52 24"; + text = "Cancel"; + command = "MaterialSelector.hideDialog();"; + }; + }; + + new GuiWindowCtrl(MaterialSelector_addFilterWindow) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "362 333"; + Extent = "272 99"; + MinExtent = "48 92"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Create New Tag"; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "tagName"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "64 35"; + Extent = "196 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "12 35"; + Extent = "52 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + text = "Tag Name"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "64 68"; + Extent = "126 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + text = "Create"; + Command = "MaterialSelector.createFilter( MaterialSelector_addFilterWindow-->tagName.getText() );MaterialSelector_addFilterWindow.setVisible(0);"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "196 68"; + Extent = "64 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + text = "Cancel"; + Command = "MaterialSelector_addFilterWindow.setVisible(0);"; + }; + }; +}; + +$Pref::MaterialSelector::CurrentStaticFilter = "MaterialFilterAllArray"; +$Pref::MaterialSelector::CurrentFilter = ""; //ALL +$Pref::MaterialSelector::ThumbnailCountIndex = 0; + +new PersistenceManager(MaterialSelectorPerMan); + +new ArrayObject(UnlistedMaterials); +UnlistedMaterials.add( "unlistedMaterials", WarningMaterial ); +UnlistedMaterials.add( "unlistedMaterials", materialEd_previewMaterial ); +UnlistedMaterials.add( "unlistedMaterials", notDirtyMaterial ); +UnlistedMaterials.add( "unlistedMaterials", materialEd_cubemapEd_cubeMapPreview ); +UnlistedMaterials.add( "unlistedMaterials", matEdCubeMapPreviewMat ); +UnlistedMaterials.add( "unlistedMaterials", materialEd_justAlphaMaterial ); +UnlistedMaterials.add( "unlistedMaterials", materialEd_justAlphaShader ); + +function MaterialSelector::selectMaterial( %this, %material ) +{ + %name = ""; + + if( MaterialSelector.terrainMaterials ) + { + %name = %material; + %material = TerrainMaterialSet.findObjectByInternalName( %material ); + } + else + { + %name = %material.getName(); + } + + // The callback function should be ready to intake the returned material + //eval("materialEd_previewMaterial." @ %propertyField @ " = " @ %value @ ";"); + if( MaterialSelector.returnType $= "name" ) + eval( "" @ MaterialSelector.selectCallback @ "(" @ %name @ ");"); + else if( MaterialSelector.returnType $= "index" ) + { + %index = -1; + if( MaterialSelector.terrainMaterials ) + { + // Obtain the index into the terrain's material list + %mats = ETerrainEditor.getMaterials(); + for(%i = 0; %i < getRecordCount( %mats ); %i++) + { + %matInternalName = getRecord( %mats, %i ); + if( %matInternalName $= %name ) + { + %index = %i; + break; + } + } + } + else + { + // Obtain the index into the material set + for(%i = 0; %i < materialSet.getCount(); %i++) + { + %obj = materialSet.getObject(%i); + if( %obj.getName() $= %name ) + { + %index = %i; + break; + } + } + } + + eval( "" @ MaterialSelector.selectCallback @ "(" @ %index @ ");"); + } + else + eval( "" @ MaterialSelector.selectCallback @ "(" @ %material.getId() @ ");"); + MaterialSelector.hideDialog(); +} + +function MaterialSelector::showDialog( %this, %selectCallback, %returnType) +{ + if( MaterialSelector.isVisible() ) + return; + + %this.showDialogBase(%selectCallback, %returnType, false); +} + +function MaterialSelector::showTerrainDialog( %this, %selectCallback, %returnType) +{ + %this.showDialogBase(%selectCallback, %returnType, true); +} + +function MaterialSelector::showDialogBase( %this, %selectCallback, %returnType, %useTerrainMaterials) +{ + // Set the select callback + MaterialSelector.selectCallback = %selectCallback; + MaterialSelector.returnType = %returnType; + + MaterialSelector.currentStaticFilter = $Pref::MaterialSelector::CurrentStaticFilter; + MaterialSelector.currentFilter = $Pref::MaterialSelector::CurrentFilter; + + MaterialSelector.terrainMaterials = %useTerrainMaterials; + + MaterialSelector-->materialPreviewCountPopup.clear(); + MaterialSelector-->materialPreviewCountPopup.add( "10", 0 ); + MaterialSelector-->materialPreviewCountPopup.add( "15", 1 ); + MaterialSelector-->materialPreviewCountPopup.add( "25", 2 ); + MaterialSelector-->materialPreviewCountPopup.add( "50", 3 ); + MaterialSelector-->materialPreviewCountPopup.add( "75", 4 ); + MaterialSelector-->materialPreviewCountPopup.add( "100", 5 ); + MaterialSelector-->materialPreviewCountPopup.setSelected( $Pref::MaterialSelector::ThumbnailCountIndex ); + + Canvas.pushDialog(MaterialSelectorOverlay); + MaterialSelector.setVisible(1); + MaterialSelector.buildStaticFilters(); + + MaterialSelector.selectedMaterial = ""; + MaterialSelector.loadMaterialFilters(); +} + +function MaterialSelector::hideDialog( %this ) +{ + MaterialSelector.breakdown(); + MaterialSelector.setVisible(0); + Canvas.popDialog(MaterialSelectorOverlay); +} + +function MaterialSelector::breakdown( %this ) +{ + $Pref::MaterialSelector::CurrentStaticFilter = MaterialSelector.currentStaticFilter; + $Pref::MaterialSelector::CurrentFilter = MaterialSelector.currentFilter; + + MaterialSelector-->filterArray.deleteAllObjects(); + MaterialSelector-->materialSelection.deleteAllObjects(); + MatEdPreviewArray.delete(); + + MaterialSelector-->materialCategories.deleteAllObjects(); + MaterialFilterAllArray.delete(); + MaterialFilterMappedArray.delete(); + MaterialFilterUnmappedArray.delete(); + +} + +function MaterialSelector::buildStaticFilters( %this ) +{ + // if you want to add any more containers to staticFilterObjects, here's + // where to do it + + %staticFilterContainer = new GuiControl (){ + new GuiContainer(){ + profile = "ToolsGuiDefaultProfile"; + Position = "0 0"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + parentGroup = %filterArray; + + new GuiContainer(){ + profile = "inspectorStyleRolloutDarkProfile"; + Position = "-1 0"; + Extent = "128 32"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + }; + new GuiTextCtrl(){ + Profile = "EditorTextProfile"; + position = "5 0"; + Extent = "118 18"; + text = "Types"; + }; + }; + new GuiContainer(){ // All + profile = "ToolsGuiDefaultProfile"; + Position = "415 191"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + parentGroup = %filterArray; + + new GuiCheckBoxCtrl(MaterialFilterAllArrayCheckbox){ + Profile = "ToolsGuiCheckBoxListProfile"; + position = "5 2"; + Extent = "118 18"; + text = "All"; + Command = "MaterialSelector.switchStaticFilters(\"MaterialFilterAllArray\");"; + }; + }; + new GuiContainer(){ // Mapped + profile = "ToolsGuiDefaultProfile"; + Position = "415 191"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + parentGroup = %filterArray; + + new GuiCheckBoxCtrl(MaterialFilterMappedArrayCheckbox){ + Profile = "ToolsGuiCheckBoxListProfile"; + position = "5 2"; + Extent = "118 18"; + text = "Mapped"; + Command = "MaterialSelector.switchStaticFilters(\"MaterialFilterMappedArray\");"; + }; + }; + new GuiContainer(){ // Unmapped + profile = "ToolsGuiDefaultProfile"; + Position = "415 191"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + parentGroup = %filterArray; + + new GuiCheckBoxCtrl(MaterialFilterUnmappedArrayCheckbox){ + Profile = "ToolsGuiCheckBoxListProfile"; + position = "5 2"; + Extent = "118 18"; + text = "Unmapped"; + Command = "MaterialSelector.switchStaticFilters(\"MaterialFilterUnmappedArray\");"; + }; + }; + new GuiContainer(){ + profile = "ToolsGuiDefaultProfile"; + Position = "0 0"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + parentGroup = %filterArray; + + new GuiContainer(){ + profile = "inspectorStyleRolloutDarkProfile"; + Position = "-1 0"; + Extent = "128 32"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + }; + + new GuiTextCtrl(){ + Profile = "EditorTextProfile"; + position = "5 0"; + Extent = "118 18"; + text = "Tags"; + }; + // Create New Tag + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "105 2"; + Extent = "15 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialSelector_addFilterWindow.setVisible(1); MaterialSelectorOverlay.pushToBack(MaterialSelector_addFilterWindow);"; + hovertime = "1000"; + tooltip = "Create New Tag"; + bitmap = "tools/gui/images/new"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "89 2"; + Extent = "13 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialSelector.clearMaterialFilters();"; + hovertime = "1000"; + tooltip = "Clear Selected Tag"; + bitmap = "tools/gui/images/clear-btn"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + }; + + %i = %staticFilterContainer.getCount(); + for( ; %i != 0; %i--) + MaterialSelector-->filterArray.addGuiControl(%staticFilterContainer.getObject(0)); + + MaterialSelector.staticFilterObjects = MaterialSelector-->filterArray.getCount(); + + %staticFilterContainer.delete(); + + // Create our category array used in the selector, this code should be taken out + // in order to make the material selector agnostic + new ArrayObject(MaterialFilterAllArray); + new ArrayObject(MaterialFilterMappedArray); + new ArrayObject(MaterialFilterUnmappedArray); + + %mats = ""; + %count = 0; + if( MaterialSelector.terrainMaterials ) + { + %mats = ETerrainEditor.getTerrainBlocksMaterialList(); + %count = getRecordCount( %mats ); + } + else + { + %count = materialSet.getCount(); + } + + for(%i = 0; %i < %count; %i++) + { + // Process terrain materials + if( MaterialSelector.terrainMaterials ) + { + %matInternalName = getRecord( %mats, %i ); + %material = TerrainMaterialSet.findObjectByInternalName( %matInternalName ); + + // Is there no material info for this slot? + if ( !isObject( %material ) ) + continue; + + // Add to the appropriate filters + MaterialFilterMappedArray.add( "", %material ); + MaterialFilterAllArray.add( "", %material ); + + continue; + } + + // Process regular materials here + %material = materialSet.getObject(%i); + + for( %k = 0; %k < UnlistedMaterials.count(); %k++ ) + { + %unlistedFound = 0; + if( UnlistedMaterials.getValue(%k) $= %material.name ) + { + %unlistedFound = 1; + break; + } + } + + if( %unlistedFound ) + continue; + + if( %material.mapTo $= "" || %material.mapTo $= "unmapped_mat" ) + { + MaterialFilterUnmappedArray.add( "", %material.name ); + //running through the existing tag names + for( %j = 0; %material.getFieldValue("materialTag" @ %j) !$= ""; %j++ ) + MaterialFilterUnmappedArray.add( %material.getFieldValue("materialTag" @ %j), %material.name ); + } + else + { + MaterialFilterMappedArray.add( "", %material.name ); + for( %j = 0; %material.getFieldValue("materialTag" @ %j) !$= ""; %j++ ) + MaterialFilterMappedArray.add( %material.getFieldValue("materialTag" @ %j), %material.name ); + } + + MaterialFilterAllArray.add( "", %material.name ); + for( %j = 0; %material.getFieldValue("materialTag" @ %j) !$= ""; %j++ ) + MaterialFilterAllArray.add( %material.getFieldValue("materialTag" @ %j), %material.name ); + + } + + MaterialFilterAllArrayCheckbox.setText("All ( " @ MaterialFilterAllArray.count() @" ) "); + MaterialFilterMappedArrayCheckbox.setText("Mapped ( " @ MaterialFilterMappedArray.count() @" ) "); + MaterialFilterUnmappedArrayCheckbox.setText("Unmapped ( " @ MaterialFilterUnmappedArray.count() @" ) "); +} + +function MaterialSelector::preloadFilter( %this ) +{ + %selectedFilter = ""; + for( %i = MaterialSelector.staticFilterObjects; %i < MaterialSelector-->filterArray.getCount(); %i++ ) + { + if( MaterialSelector-->filterArray.getObject(%i).getObject(0).getValue() == 1 ) + { + if( %selectedFilter $= "" ) + %selectedFilter = MaterialSelector-->filterArray.getObject(%i).getObject(0).filter; + else + %selectedFilter = %selectedFilter @ " " @ MaterialSelector-->filterArray.getObject(%i).getObject(0).filter; + } + } + MaterialSelector.loadFilter( %selectedFilter ); +} + +function MaterialSelector::loadFilter( %this, %selectedFilter, %staticFilter ) +{ + // manage schedule array properly + if(!isObject(MatEdScheduleArray)) + new ArrayObject(MatEdScheduleArray); + + // if we select another list... delete all schedules that were created by + // previous load + for( %i = 0; %i < MatEdScheduleArray.count(); %i++ ) + cancel(MatEdScheduleArray.getKey(%i)); + + // we have to empty out the list; so when we create new schedules, these dont linger + MatEdScheduleArray.empty(); + + // manage preview array + if(!isObject(MatEdPreviewArray)) + new ArrayObject(MatEdPreviewArray); + + // we have to empty out the list; so when we create new guicontrols, these dont linger + MatEdPreviewArray.empty(); + MaterialSelector-->materialSelection.deleteAllObjects(); + MaterialSelector-->materialPreviewPagesStack.deleteAllObjects(); + + // changed to accomadate tagging. dig through the array for each tag name, + // call unique value, sort, and we have a perfect set of materials + if( %staticFilter !$= "" ) + MaterialSelector.currentStaticFilter = %staticFilter; + + MaterialSelector.currentFilter = %selectedFilter; + + %filteredObjectsArray = new ArrayObject(); + + %previewsPerPage = MaterialSelector-->materialPreviewCountPopup.getTextById( MaterialSelector-->materialPreviewCountPopup.getSelected() ); + + %tagCount = getWordCount( MaterialSelector.currentFilter ); + if( %tagCount != 0 ) + { + for( %j = 0; %j < %tagCount; %j++ ) + { + for( %i = 0; %i < MaterialSelector.currentStaticFilter.count(); %i++ ) + { + %currentTag = getWord( MaterialSelector.currentFilter, %j ); + if( MaterialSelector.currentStaticFilter.getKey(%i) $= %currentTag) + %filteredObjectsArray.add( MaterialSelector.currentStaticFilter.getKey(%i), MaterialSelector.currentStaticFilter.getValue(%i) ); + } + } + + %filteredObjectsArray.uniqueValue(); + %filteredObjectsArray.sortd(); + + MaterialSelector.totalPages = mCeil( %filteredObjectsArray.count() / %previewsPerPage ); + + //Can we maintain the current preview page, or should we go to page 1? + if( (MaterialSelector.currentPreviewPage * %previewsPerPage) >= %filteredObjectsArray.count() ) + MaterialSelector.currentPreviewPage = 0; + + // Build out the pages buttons + MaterialSelector.buildPagesButtons( MaterialSelector.currentPreviewPage, MaterialSelector.totalPages ); + + %previewCount = %previewsPerPage; + %possiblePreviewCount = %filteredObjectsArray.count() - MaterialSelector.currentPreviewPage * %previewsPerPage; + if( %possiblePreviewCount < %previewCount ) + %previewCount = %possiblePreviewCount; + + %start = MaterialSelector.currentPreviewPage * %previewsPerPage; + for( %i = %start; %i < %start + %previewCount; %i++ ) + MaterialSelector.buildPreviewArray( %filteredObjectsArray.getValue(%i) ); + + %filteredObjectsArray.delete(); + } + else + { + MaterialSelector.currentStaticFilter.sortd(); + + // Rebuild the static filter list without tagged materials + %noTagArray = new ArrayObject(); + for( %i = 0; %i < MaterialSelector.currentStaticFilter.count(); %i++ ) + { + if( MaterialSelector.currentStaticFilter.getKey(%i) !$= "") + continue; + + %material = MaterialSelector.currentStaticFilter.getValue(%i); + + // CustomMaterials are not available for selection + if ( !isObject( %material ) || %material.isMemberOfClass( "CustomMaterial" ) ) + continue; + + %noTagArray.add( "", %material ); + } + + MaterialSelector.totalPages = mCeil( %noTagArray.count() / %previewsPerPage ); + + //Can we maintain the current preview page, or should we go to page 1? + if( (MaterialSelector.currentPreviewPage * %previewsPerPage) >= %noTagArray.count() ) + MaterialSelector.currentPreviewPage = 0; + + // Build out the pages buttons + MaterialSelector.buildPagesButtons( MaterialSelector.currentPreviewPage, MaterialSelector.totalPages ); + + %previewCount = %previewsPerPage; + %possiblePreviewCount = %noTagArray.count() - MaterialSelector.currentPreviewPage * %previewsPerPage; + if( %possiblePreviewCount < %previewCount ) + %previewCount = %possiblePreviewCount; + + %start = MaterialSelector.currentPreviewPage * %previewsPerPage; + for( %i = %start; %i < %start + %previewCount; %i++ ) + { + MaterialSelector.buildPreviewArray( %noTagArray.getValue(%i) ); + } + } + + + MaterialSelector.loadImages( 0 ); +} + + + +function MaterialSelector::buildPreviewArray( %this, %material ) +{ + %matName = ""; + + // CustomMaterials are not available for selection + if ( !isObject( %material ) || %material.isMemberOfClass( "CustomMaterial" ) ) + return; + + if( %material.isMemberOfClass("TerrainMaterial") ) + { + %matName = %material.getInternalName(); + + if( %material.diffuseMap $= "") + %previewImage = "core/art/warnmat"; + else + %previewImage = %material.diffuseMap; + } + else if( %material.toneMap[0] $= "" && %material.diffuseMap[0] $= "" && !isObject(%material.cubemap) ) + { + %matName = %material.name; + %previewImage = "core/art/warnmat"; + } + else + { + %matName = %material.name; + + if( %material.toneMap[0] !$= "" ) + %previewImage = %material.toneMap[0]; + else if( %material.diffuseMap[0] !$= "" ) + %previewImage = %material.diffuseMap[0]; + else if( %material.cubemap.cubeFace[0] !$= "" ) + %previewImage = %material.cubemap.cubeFace[0]; + + //%previewImage = MaterialEditorGui.searchForTexture( %material, %previewImage ); + + // were going to use a couple of string commands in order to properly + // find out what the img src path is + // **NEW** this needs to be updated with the above, but has some timing issues + %materialDiffuse = %previewImage; + %materialPath = %material.getFilename(); + + if( strchr( %materialDiffuse, "/") $= "" ) + { + %k = 0; + while( strpos( %materialPath, "/", %k ) != -1 ) + { + %foo = strpos( %materialPath, "/", %k ); + %k = %foo + 1; + } + + %foobar = getSubStr( %materialPath , %k , 99 ); + %previewImage = strreplace( %materialPath, %foobar, %previewImage ); + } + else + %previewImage = strreplace( %materialPath, %materialPath, %previewImage ); + } + + // it may seem goofy why the checkbox can't be instanciated inside the container + // reason being its because we need to store the checkbox ctrl in order to make changes + // on it later in the function. + + %container = new GuiControl(){ + profile = "ToolsGuiDefaultProfile"; + Position = "0 0"; + Extent = "74 87"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + + new GuiTextCtrl(){ + position = "7 71"; + profile = "ToolsGuiTextCenterProfile"; + extent = "64 16"; + text = %matName; + }; + }; + + %previewButton = new GuiBitmapButtonCtrl(){ + internalName = %matName; + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + position = "7 4"; + extent = "64 64"; + buttonType = "PushButton"; + bitmap = ""; + Command = ""; + text = "Loading..."; + useStates = false; + + new GuiBitmapButtonCtrl(){ + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + position = "0 0"; + extent = "64 64"; + Variable = ""; + buttonType = "toggleButton"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + groupNum = "0"; + text = ""; + }; + }; + + %previewBorder = new GuiButtonCtrl(){ + internalName = %matName@"Border"; + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiThumbHighlightButtonProfile"; + position = "3 0"; + extent = "72 88"; + Variable = ""; + buttonType = "toggleButton"; + tooltip = %matName; + Command = "MaterialSelector.updateSelection( $ThisControl.getParent().getObject(1).internalName, $ThisControl.getParent().getObject(1).bitmap );"; + groupNum = "0"; + text = ""; + }; + + %container.add(%previewButton); + %container.add(%previewBorder); + // add to the gui control array + MaterialSelector-->materialSelection.add(%container); + + // add to the array object for reference later + MatEdPreviewArray.add( %previewButton, %previewImage ); +} + +function MaterialSelector::loadImages( %this, %materialNum ) +{ + // this will save us from spinning our wheels in case we don't exist + if( !MaterialSelector.visible ) + return; + + // this schedule is here to dynamically load images + %previewButton = MatEdPreviewArray.getKey(%materialNum); + %previewImage = MatEdPreviewArray.getValue(%materialNum); + + %previewButton.setBitmap(%previewImage); + %previewButton.setText(""); + + %materialNum++; + + if( %materialNum < MatEdPreviewArray.count() ) + { + %tempSchedule = %this.schedule(64, "loadImages", %materialNum); + MatEdScheduleArray.add( %tempSchedule, %materialNum ); + } +} + +function MaterialSelector::clearMaterialFilters( %this ) +{ + for( %i = MaterialSelector.staticFilterObjects; %i < MaterialSelector-->filterArray.getCount(); %i++ ) + MaterialSelector-->filterArray.getObject(%i).getObject(0).setStateOn(0); + + MaterialSelector.loadFilter( "", "" ); +} + +function MaterialSelector::loadMaterialFilters( %this ) +{ + %filteredTypesArray = new ArrayObject(); + + %filteredTypesArray.duplicate( MaterialFilterAllArray ); + %filteredTypesArray.uniqueKey(); + + // sort the the keys before we do anything + %filteredTypesArray.sortkd(); + + eval( MaterialSelector.currentStaticFilter @ "Checkbox.setStateOn(1);" ); + // it may seem goofy why the checkbox can't be instanciated inside the container + // reason being its because we need to store the checkbox ctrl in order to make changes + // on it later in the function. + %selectedFilter = ""; + for( %i = 0; %i < %filteredTypesArray.count(); %i++ ) + { + %filter = %filteredTypesArray.getKey(%i); + if(%filter $= "") + continue; + + %container = new GuiControl(){ + profile = "ToolsGuiDefaultProfile"; + Position = "0 0"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + }; + + %checkbox = new GuiCheckBoxCtrl(){ + Profile = "ToolsGuiCheckBoxListProfile"; + position = "5 1"; + Extent = "118 18"; + Command = ""; + groupNum = "0"; + buttonType = "ToggleButton"; + text = %filter @ " ( " @ MaterialFilterAllArray.countKey(%filter) @ " )"; + filter = %filter; + Command = "MaterialSelector.preloadFilter();"; + }; + %container.add( %checkbox ); + MaterialSelector-->filterArray.add( %container ); + + %tagCount = getWordCount( MaterialSelector.currentFilter ); + for( %j = 0; %j < %tagCount; %j++ ) + { + if( %filter $= getWord( MaterialSelector.currentFilter, %j ) ) + { + if( %selectedFilter $= "" ) + %selectedFilter = %filter; + else + %selectedFilter = %selectedFilter @ " " @ %filter; + + %checkbox.setStateOn(1); + } + } + } + + MaterialSelector.loadFilter( %selectedFilter ); + + %filteredTypesArray.delete(); +} + +// create category and update current material if there is one +function MaterialSelector::createFilter( %this, %filter ) +{ + if( %filter $= %existingFilters ) + { + MessageBoxOK( "Error", "Can not create blank filter."); + return; + } + + for( %i = MaterialSelector.staticFilterObjects; %i < MaterialSelector-->filterArray.getCount() ; %i++ ) + { + %existingFilters = MaterialSelector-->filterArray.getObject(%i).getObject(0).filter; + if( %filter $= %existingFilters ) + { + MessageBoxOK( "Error", "Can not create two filters of the same name."); + return; + } + } + %container = new GuiControl(){ + profile = "ToolsGuiDefaultProfile"; + Position = "0 0"; + Extent = "128 18"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + + new GuiCheckBoxCtrl(){ + Profile = "ToolsGuiCheckBoxListProfile"; + position = "5 1"; + Extent = "118 18"; + Command = ""; + groupNum = "0"; + buttonType = "ToggleButton"; + text = %filter @ " ( " @ MaterialFilterAllArray.countKey(%filter) @ " )"; + filter = %filter; + Command = "MaterialSelector.preloadFilter();"; + }; + }; + + MaterialSelector-->filterArray.add( %container ); + + // if selection exists, lets reselect it to refresh it + if( isObject(MaterialSelector.selectedMaterial) ) + MaterialSelector.updateSelection( MaterialSelector.selectedMaterial, MaterialSelector.selectedPreviewImagePath ); + + // material category text field to blank + MaterialSelector_addFilterWindow-->tagName.setText(""); +} + +function MaterialSelector::updateSelection( %this, %material, %previewImagePath ) +{ + // the material selector will visually update per material information + // after we move away from the material. eg: if we remove a field from the material, + // the empty checkbox will still be there until you move fro and to the material again + + %isMaterialBorder = 0; + eval("%isMaterialBorder = isObject(MaterialSelector-->"@%material@"Border);"); + if( %isMaterialBorder ) + { + eval( "MaterialSelector-->"@%material@"Border.setStateOn(1);"); + } + + %isMaterialBorderPrevious = 0; + eval("%isMaterialBorderPrevious = isObject(MaterialSelector-->"@$prevSelectedMaterialHL@"Border);"); + if( %isMaterialBorderPrevious ) + { + eval( "MaterialSelector-->"@$prevSelectedMaterialHL@"Border.setStateOn(0);"); + } + + MaterialSelector-->materialCategories.deleteAllObjects(); + MaterialSelector.selectedMaterial = %material; + MaterialSelector.selectedPreviewImagePath = %previewImagePath; + MaterialSelector-->previewSelectionText.setText( %material ); + MaterialSelector-->previewSelection.setBitmap( %previewImagePath ); + + // running through the existing list of categorynames in the left, so yes + // some might exist on the left only temporary if not given a home + for( %i = MaterialSelector.staticFilterObjects; %i < MaterialSelector-->filterArray.getCount() ; %i++ ) + { + %filter = MaterialSelector-->filterArray.getObject(%i).getObject(0).filter; + + %checkbox = new GuiCheckBoxCtrl(){ + materialName = %material.name; + Profile = "ToolsGuiCheckBoxListProfile"; + position = "5 2"; + Extent = "118 18"; + Command = "MaterialSelector.updateMaterialTags( $ThisControl.materialName, $ThisControl.getText(), $ThisControl.getValue() );"; + text = %filter; + }; + + MaterialSelector-->materialCategories.add( %checkbox ); + // crawl through material for categories in order to check or not + %filterFound = 0; + for( %j = 0; %material.getFieldValue("materialTag" @ %j) !$= ""; %j++ ) + { + %tag = %material.getFieldValue("materialTag" @ %j); + + if( %tag $= %filter ) + { + %filterFound = 1; + break; + } + } + + if( %filterFound ) + %checkbox.setStateOn(1); + else + %checkbox.setStateOn(0); + } + + $prevSelectedMaterialHL = %material; +} + +function MaterialSelector::updateMaterialTags( %this, %material, %tag, %tagValue ) +{ + if( %tagValue == 1 ) + { + MaterialFilterAllArray.add( %tag, %material ); + if( %material.mapTo $= "" || %material.mapTo $= "unmapped_mat" ) + %secondStaticFilter = MaterialFilterUnmappedArray; + else + %secondStaticFilter = MaterialFilterMappedArray; + + %secondStaticFilter.add( %tag, %material ); + + %createdTag = 0; + for( %i = 0; %createdTag == 0; %i++ ) + { + %materialTag = %material.getFieldValue("materialTag" @ %i); + if( %materialTag $= "" ) + { + eval( %material @ ".materialTag" @ %i @ "=" @ %tag @ ";" ); + %createdTag = 1; + + for( %j = MaterialSelector.staticFilterObjects; %j < MaterialSelector-->filterArray.getCount() ; %j++ ) + { + if( %tag $= MaterialSelector-->filterArray.getObject(%j).getObject(0).filter ) + { + %count = getWord( MaterialSelector-->filterArray.getObject(%j).getObject(0).getText(), 2 ); + %count++; + MaterialSelector-->filterArray.getObject(%j).getObject(0).setText( %tag @ " ( "@ %count @ " )"); + } + } + + break; + } + } + + } + else + { + // Remove the material from the "all" category + for( %i = 0; %i < MaterialFilterAllArray.count(); %i++ ) + { + if( MaterialFilterAllArray.getKey(%i) $= %tag ) + { + if( MaterialFilterAllArray.getValue(%i) $= %material ) + { + MaterialFilterAllArray.erase(%i); + break; + } + } + } + + // Figure out what the material's other category is + if( %material.mapTo $= "" || %material.mapTo $= "unmapped_mat" ) + %secondStaticFilter = MaterialFilterUnmappedArray; + else + %secondStaticFilter = MaterialFilterMappedArray; + + // Remove the material from its other category + for( %i = 0; %i < %secondStaticFilter.count(); %i++ ) + { + if( %secondStaticFilter.getKey(%i) $= %tag ) + { + if( %secondStaticFilter.getValue(%i) $= %material ) + { + %secondStaticFilter.erase( %i ); + break; + } + } + } + + + MaterialSelector.updateFilterCount( %tag, false ); + + %tagField = MaterialSelector.getTagField( %material, %tag ); + %lastTagField = MaterialSelector.getLastTagField( %material ); + %lastValidTagField = MaterialSelector.getLastValidTagField( %material, %tag ); + + if( %tagField $= %lastValidTagField || %lastValidTagField $= "" ) + { + MaterialSelectorPerMan.removeField( %material, %tagField ); + } + else + { + // Replace the current tagFieldValue with the last tagFieldValue + %lastValidTag = %material.getFieldValue( %lastValidTagField ); + %material.setFieldValue( %tagField, %lastValidTag ); + + // Remove the last tagFieldValue + MaterialSelectorPerMan.removeField( %material, %lastTagField ); + } + } + + // so were not going to save materials that dont current exist... + // technically all the data is stored in dynamic fields if the user feels like saving + // their auto-generated or new material + if( %material.getFilename() !$= "" && + %material.getFilename() !$= "tools/gui/MaterialSelector.ed.gui" && + %material.getFilename() !$= "tools/materialEditor/scripts/materialEditor.ed.cs" ) + { + MaterialSelectorPerMan.setDirty( %material ); + MaterialSelectorPerMan.saveDirty(); + MaterialSelectorPerMan.removeDirty( %material ); + + if(!%tagValue) + %material.setFieldValue( %lastTagField, "" ); + } +} + +function MaterialSelector::updateFilterCount( %this, %tag, %add ) +{ + for( %i = MaterialSelector.staticFilterObjects; %i < MaterialSelector-->filterArray.getCount() ; %i++ ) + { + if( %tag $= MaterialSelector-->filterArray.getObject(%i).getObject(0).filter ) + { + // Get the filter count and apply the operation + %idx = getWord( MaterialSelector-->filterArray.getObject(%i).getObject(0).getText(), 2 ); + + if( %add ) + %idx++; + else + %idx--; + + MaterialSelector-->filterArray.getObject(%i).getObject(0).setText( %tag @ " ( "@ %idx @ " )"); + } + } +} + +// this should create a new material pretty nicely +function MaterialSelector::createNewMaterial( %this ) +{ + // look for a newMaterial name to grab + %material = getUniqueName( "newMaterial" ); + + new Material(%material) + { + diffuseMap[0] = "core/art/warnMat"; + mapTo = "unmapped_mat"; + parentGroup = RootGroup; + }; + + // add one to All filter + MaterialFilterAllArray.add( "", %material.name ); + MaterialFilterAllArrayCheckbox.setText("All ( " @ MaterialFilterAllArray.count() + 1 @ " ) "); + + MaterialFilterUnmappedArray.add( "", %material.name ); + MaterialFilterUnmappedArrayCheckbox.setText("Unmapped ( " @ MaterialFilterUnmappedArray.count() + 1 @ " ) "); + + if( MaterialSelector.currentStaticFilter !$= "MaterialFilterMappedArray" ) + { + // create the new material gui + %container = new GuiControl(){ + profile = "ToolsGuiDefaultProfile"; + Position = "0 0"; + Extent = "74 85"; + HorizSizing = "right"; + VertSizing = "bottom"; + isContainer = "1"; + new GuiTextCtrl(){ + position = "10 70"; + profile = "ToolsGuiTextCenterProfile"; + extent = "64 16"; + text = %material.name; + }; + }; + + %previewButton = new GuiBitmapButtonCtrl(){ + internalName = %material.name; + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + position = "7 4"; + extent = "64 64"; + buttonType = "PushButton"; + bitmap = "core/art/warnMat"; + Command = ""; + text = "Loading..."; + useStates = false; + + new GuiBitmapButtonCtrl(){ + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + position = "0 0"; + extent = "64 64"; + Variable = ""; + buttonType = "toggleButton"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + groupNum = "0"; + text = ""; + }; + }; + + %previewBorder = new GuiButtonCtrl(){ + internalName = %material.name@"Border"; + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiThumbHighlightButtonProfile"; + position = "3 0"; + extent = "72 88"; + Variable = ""; + buttonType = "toggleButton"; + tooltip = %material.name; + Command = "MaterialSelector.updateSelection( $ThisControl.getParent().getObject(1).internalName, $ThisControl.getParent().getObject(1).bitmap );"; + groupNum = "0"; + text = ""; + }; + + %container.add(%previewButton); + %container.add(%previewBorder); + // add to the gui control array + MaterialSelector-->materialSelection.add(%container); + } + + // select me + MaterialSelector.updateSelection( %material, "core/art/warnMat.png" ); +} + +//needs to be deleted with the persistence manager and needs to be blanked out of the matmanager +//also need to update instances... i guess which is the tricky part.... +function MaterialSelector::showDeleteDialog( %this ) +{ + %material = MaterialSelector.selectedMaterial; + %secondFilter = "MaterialFilterMappedArray"; + %secondFilterName = "Mapped"; + + for( %i = 0; %i < MaterialFilterUnmappedArray.count(); %i++ ) + { + if( MaterialFilterUnmappedArray.getValue(%i) $= %material ) + { + %secondFilter = "MaterialFilterUnmappedArray"; + %secondFilterName = "Unmapped"; + break; + } + } + + if( isObject( %material ) ) + { + MessageBoxYesNoCancel("Delete Material?", + "Are you sure you want to delete<br><br>" @ %material.getName() @ "<br><br> Material deletion won't take affect until the engine is quit.", + "MaterialSelector.deleteMaterial( " @ %material @ ", " @ %secondFilter @ ", " @ %secondFilterName @" );", + "", + "" ); + } +} + +function MaterialSelector::deleteMaterial( %this, %materialName, %secondFilter, %secondFilterName ) +{ + if( !isObject( %materialName ) ) + return; + + for( %i = 0; %i <= MaterialFilterAllArray.countValue( %materialName ); %i++) + { + %index = MaterialFilterAllArray.getIndexFromValue( %materialName ); + MaterialFilterAllArray.erase( %index ); + } + MaterialFilterAllArrayCheckbox.setText("All ( " @ MaterialFilterAllArray.count() - 1 @ " ) "); + + %checkbox = %secondFilter @ "Checkbox"; + for( %k = 0; %k <= %secondFilter.countValue( %materialName ); %k++) + { + %index = %secondFilter.getIndexFromValue( %materialName ); + %secondFilter.erase( %index ); + } + %checkbox.setText( %secondFilterName @ " ( " @ %secondFilter.count() - 1 @ " ) "); + + for( %i = 0; %materialName.getFieldValue("materialTag" @ %i) !$= ""; %i++ ) + { + %materialTag = %materialName.getFieldValue("materialTag" @ %i); + + for( %j = MaterialSelector.staticFilterObjects; %j < MaterialSelector-->filterArray.getCount() ; %j++ ) + { + if( %materialTag $= MaterialSelector-->filterArray.getObject(%j).getObject(0).filter ) + { + %count = getWord( MaterialSelector-->filterArray.getObject(%j).getObject(0).getText(), 2 ); + %count--; + MaterialSelector-->filterArray.getObject(%j).getObject(0).setText( %materialTag @ " ( "@ %count @ " )"); + } + } + + } + + UnlistedMaterials.add( "unlistedMaterials", %materialName ); + + if( %materialName.getFilename() !$= "" && + %materialName.getFilename() !$= "tools/gui/MaterialSelector.ed.gui" && + %materialName.getFilename() !$= "tools/materialEditor/scripts/materialEditor.ed.cs" ) + { + MaterialSelectorPerMan.removeObjectFromFile(%materialName); + MaterialSelectorPerMan.saveDirty(); + } + + MaterialSelector.preloadFilter(); + //MaterialSelector.selectMaterial( "WarningMaterial" ); +} + +function MaterialSelector::switchStaticFilters( %this, %staticFilter) +{ + switch$(%staticFilter) + { + case "MaterialFilterAllArray": + MaterialFilterAllArrayCheckbox.setStateOn(1); + + MaterialFilterMappedArrayCheckbox.setStateOn(0); + MaterialFilterUnmappedArrayCheckbox.setStateOn(0); + case "MaterialFilterMappedArray": + MaterialFilterMappedArrayCheckbox.setStateOn(1); + + MaterialFilterAllArrayCheckbox.setStateOn(0); + MaterialFilterUnmappedArrayCheckbox.setStateOn(0); + case "MaterialFilterUnmappedArray": + MaterialFilterUnmappedArrayCheckbox.setStateOn(1); + + MaterialFilterAllArrayCheckbox.setStateOn(0); + MaterialFilterMappedArrayCheckbox.setStateOn(0); + } + + // kinda goofy were passing a class variable... we can't do an empty check right now + // on load filter because we actually pass "" as a filter... + MaterialSelector.loadFilter( MaterialSelector.currentFilter, %staticFilter ); +} + +// Tagging Functionality + +function MaterialSelector::getTagField( %this, %material, %tag ) +{ + for( %i = 0; %material.getFieldValue("materialTag" @ %i) !$= ""; %i++ ) + { + %loopTag = %material.getFieldValue("materialTag" @ %i); + if( %tag $= %loopTag ) + { + %tagField = "materialTag" @ %i; + break; + } + } + + return %tagField; +} + +function MaterialSelector::getLastTagField( %this, %material ) +{ + for( %i = 0; %material.getFieldValue("materialTag" @ %i) !$= ""; %i++ ) + { + %tagField = "materialTag" @ %i; + } + + return %tagField; +} + +function MaterialSelector::getLastValidTagField( %this, %material, %invalidTag ) +{ + for( %i = 0; %material.getFieldValue("materialTag" @ %i) !$= ""; %i++ ) + { + %tag = %material.getFieldValue("materialTag" @ %i); + // Can't equal our invalid tag + if( %tag $= %invalidTag ) + continue; + + // Set our last found tag + %tagField = "materialTag" @ %i; + } + + return %tagField; +} + +// Preview Page Navigation + +function MaterialSelector::firstPage(%this) +{ + MaterialSelector.currentPreviewPage = 0; + MaterialSelector.LoadFilter( MaterialSelector.currentFilter, MaterialSelector.currentStaticFilter ); +} + +function MaterialSelector::previousPage(%this) +{ + MaterialSelector.currentPreviewPage--; + if( MaterialSelector.currentPreviewPage < 0) + MaterialSelector.currentPreviewPage = 0; + + MaterialSelector.LoadFilter( MaterialSelector.currentFilter, MaterialSelector.currentStaticFilter ); +} + +function MaterialSelector::nextPage(%this) +{ + MaterialSelector.currentPreviewPage++; + if( MaterialSelector.currentPreviewPage >= MaterialSelector.totalPages) + MaterialSelector.currentPreviewPage = MaterialSelector.totalPages - 1; + if( MaterialSelector.currentPreviewPage < 0) + MaterialSelector.currentPreviewPage = 0; + + MaterialSelector.LoadFilter( MaterialSelector.currentFilter, MaterialSelector.currentStaticFilter ); +} + +function MaterialSelector::lastPage(%this) +{ + MaterialSelector.currentPreviewPage = MaterialSelector.totalPages - 1; + if( MaterialSelector.currentPreviewPage < 0) + MaterialSelector.currentPreviewPage = 0; + + MaterialSelector.LoadFilter( MaterialSelector.currentFilter, MaterialSelector.currentStaticFilter ); +} + +function MaterialSelector::selectPage(%this, %page) +{ + MaterialSelector.currentPreviewPage = %page; + MaterialSelector.LoadFilter( MaterialSelector.currentFilter, MaterialSelector.currentStaticFilter ); +} + +function MaterialSelector::thumbnailCountUpdate(%this) +{ + $Pref::MaterialSelector::ThumbnailCountIndex = MaterialSelector-->materialPreviewCountPopup.getSelected(); + MaterialSelector.LoadFilter( MaterialSelector.currentFilter, MaterialSelector.currentStaticFilter ); +} + +function MaterialSelector::buildPagesButtons(%this, %currentPage, %totalPages) +{ + // We don't want any more than 8 pages at a time. + if( %totalPages > 8 ) + { + // We attempt to display up to 2 pages before the current page + %start = %currentPage - 2; + if( %start <= 0 ) + { + %start = 0; + %startbracket = false; + } + else + { + %startbracket = true; + } + + if( (%totalPages - %start) < 8 ) + { + // Move %start closer to the beginning to maintain 8 pages + %start = %totalPages - 8; + } + + %end = %start + 8; + if( %end >= %totalPages ) + { + %end = %totalPages; + %endbracket = false; + } + else + { + %endbracket = true; + } + } + else + { + %start = 0; + %end = %totalPages; + %startbracket = false; + %endbracket = false; + } + + if( %startbracket ) + { + %control = new GuiTextCtrl(){ + profile = "ToolsGuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + extent = "14 16"; + MinExtent = "8 8"; + text = "..."; + }; + MaterialSelector-->materialPreviewPagesStack.add( %control ); + } + + for( %i = %start; %i < %end; %i++ ) + { + if( %i != %currentPage ) + { + %control = new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "14 16"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "MaterialSelector.schedule(0, selectPage, " @ %i @ ");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = %i+1; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + }; + } + else + { + %control = new GuiTextCtrl(){ + profile = "ToolsGuiTextBoldCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + extent = "14 16"; + MinExtent = "8 8"; + text = %i+1; + }; + } + + MaterialSelector-->materialPreviewPagesStack.add( %control ); + } + + if( %endbracket ) + { + %control = new GuiTextCtrl(){ + profile = "ToolsGuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + extent = "14 16"; + MinExtent = "8 8"; + text = "..."; + }; + MaterialSelector-->materialPreviewPagesStack.add( %control ); + } +} diff --git a/Templates/BaseGame/game/tools/gui/messageBoxes/messageBox.ed.cs b/Templates/BaseGame/game/tools/gui/messageBoxes/messageBox.ed.cs new file mode 100644 index 000000000..95592c016 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/messageBoxes/messageBox.ed.cs @@ -0,0 +1,325 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +// Cleanup Dialog created by 'core' +if( isObject( MessagePopupDlg ) ) + MessagePopupDlg.delete(); +if( isObject( MessageBoxYesNoDlg ) ) + MessageBoxYesNoDlg.delete(); +if( isObject( MessageBoxYesNoCancelDlg ) ) + MessageBoxYesNoCancelDlg.delete(); +if( isObject( MessageBoxOKCancelDetailsDlg ) ) + MessageBoxOKCancelDetailsDlg.delete(); +if( isObject( MessageBoxOKCancelDlg ) ) + MessageBoxOKCancelDlg.delete(); +if( isObject( MessageBoxOKDlg ) ) + MessageBoxOKDlg.delete(); +if( isObject( IODropdownDlg ) ) + IODropdownDlg.delete(); + + +// Load Editor Dialogs +exec("./messageBoxOK.ed.gui"); +exec("./messageBoxYesNo.ed.gui"); +exec("./messageBoxYesNoCancel.ed.gui"); +exec("./messageBoxOKCancel.ed.gui"); +exec("./messageBoxOKCancelDetailsDlg.ed.gui"); +exec("./messagePopup.ed.gui"); + + + +// -------------------------------------------------------------------- +// Message Sound +// -------------------------------------------------------------------- +/*new SFXDescription(MessageBoxAudioDescription) +{ + volume = 1.0; + isLooping = false; + is3D = false; + channel = $GuiAudioType; +}; + +new SFXProfile(messageBoxBeep) +{ + filename = "./messageBoxSound"; + description = MessageBoxAudioDescription; + preload = true; +};*/ + + + + +//--------------------------------------------------------------------------------------------- +// messageCallback +// Calls a callback passed to a message box. +//--------------------------------------------------------------------------------------------- +function messageCallback(%dlg, %callback) +{ + Canvas.popDialog(%dlg); + eval(%callback); +} + +//The # in the function passed replaced with the output +//of the preset menu. +function IOCallback(%dlg, %callback) +{ + %id = IODropdownMenu.getSelected(); + %text = IODropdownMenu.getTextById(%id); + %callback = strreplace(%callback, "#", %text); + eval(%callback); + + Canvas.popDialog(%dlg); +} + +//--------------------------------------------------------------------------------------------- +// MBSetText +// Sets the text of a message box and resizes it to accomodate the new string. +//--------------------------------------------------------------------------------------------- +function MBSetText(%text, %frame, %msg) +{ + // Get the extent of the text box. + %ext = %text.getExtent(); + // Set the text in the center of the text box. + %text.setText("<just:center>" @ %msg); + // Force the textbox to resize itself vertically. + %text.forceReflow(); + // Grab the new extent of the text box. + %newExtent = %text.getExtent(); + + // Get the vertical change in extent. + %deltaY = getWord(%newExtent, 1) - getWord(%ext, 1); + + // Resize the window housing the text box. + %windowPos = %frame.getPosition(); + %windowExt = %frame.getExtent(); + %frame.resize(getWord(%windowPos, 0), getWord(%windowPos, 1) - (%deltaY / 2), + getWord(%windowExt, 0), getWord(%windowExt, 1) + %deltaY); + + %frame.canMove = "0"; + //%frame.canClose = "0"; + %frame.resizeWidth = "0"; + %frame.resizeHeight = "0"; + %frame.canMinimize = "0"; + %frame.canMaximize = "0"; + + //sfxPlayOnce( messageBoxBeep ); +} + +//--------------------------------------------------------------------------------------------- +// Various message box display functions. Each one takes a window title, a message, and a +// callback for each button. +//--------------------------------------------------------------------------------------------- + +function MessageBoxOK(%title, %message, %callback) +{ + MBOKFrame.text = %title; + Canvas.pushDialog(MessageBoxOKDlg); + MBSetText(MBOKText, MBOKFrame, %message); + MessageBoxOKDlg.callback = %callback; +} + +function MessageBoxOKDlg::onSleep( %this ) +{ + %this.callback = ""; +} + +function MessageBoxOKCancel(%title, %message, %callback, %cancelCallback) +{ + MBOKCancelFrame.text = %title; + Canvas.pushDialog(MessageBoxOKCancelDlg); + MBSetText(MBOKCancelText, MBOKCancelFrame, %message); + MessageBoxOKCancelDlg.callback = %callback; + MessageBoxOKCancelDlg.cancelCallback = %cancelCallback; +} + +function MessageBoxOKCancelDlg::onSleep( %this ) +{ + %this.callback = ""; +} + +function MessageBoxOKCancelDetails(%title, %message, %details, %callback, %cancelCallback) +{ + if(%details $= "") + { + MBOKCancelDetailsButton.setVisible(false); + } + + MBOKCancelDetailsScroll.setVisible(false); + + MBOKCancelDetailsFrame.setText( %title ); + + Canvas.pushDialog(MessageBoxOKCancelDetailsDlg); + MBSetText(MBOKCancelDetailsText, MBOKCancelDetailsFrame, %message); + MBOKCancelDetailsInfoText.setText(%details); + + %textExtent = MBOKCancelDetailsText.getExtent(); + %textExtentY = getWord(%textExtent, 1); + %textPos = MBOKCancelDetailsText.getPosition(); + %textPosY = getWord(%textPos, 1); + + %extentY = %textPosY + %textExtentY + 65; + + MBOKCancelDetailsInfoText.setExtent(285, 128); + + MBOKCancelDetailsFrame.setExtent(300, %extentY); + + MessageBoxOKCancelDetailsDlg.callback = %callback; + MessageBoxOKCancelDetailsDlg.cancelCallback = %cancelCallback; + + MBOKCancelDetailsFrame.defaultExtent = MBOKCancelDetailsFrame.getExtent(); +} + +function MBOKCancelDetailsToggleInfoFrame() +{ + if(!MBOKCancelDetailsScroll.isVisible()) + { + MBOKCancelDetailsScroll.setVisible(true); + MBOKCancelDetailsText.forceReflow(); + %textExtent = MBOKCancelDetailsText.getExtent(); + %textExtentY = getWord(%textExtent, 1); + %textPos = MBOKCancelDetailsText.getPosition(); + %textPosY = getWord(%textPos, 1); + + %verticalStretch = %textExtentY; + + if((%verticalStretch > 260) || (%verticalStretch < 0)) + %verticalStretch = 260; + + %extent = MBOKCancelDetailsFrame.defaultExtent; + %height = getWord(%extent, 1); + + %posY = %textPosY + %textExtentY + 10; + %posX = getWord(MBOKCancelDetailsScroll.getPosition(), 0); + MBOKCancelDetailsScroll.setPosition(%posX, %posY); + MBOKCancelDetailsScroll.setExtent(getWord(MBOKCancelDetailsScroll.getExtent(), 0), %verticalStretch); + MBOKCancelDetailsFrame.setExtent(300, %height + %verticalStretch + 10); + } else + { + %extent = MBOKCancelDetailsFrame.defaultExtent; + %width = getWord(%extent, 0); + %height = getWord(%extent, 1); + MBOKCancelDetailsFrame.setExtent(%width, %height); + MBOKCancelDetailsScroll.setVisible(false); + } +} + +function MessageBoxOKCancelDetailsDlg::onSleep( %this ) +{ + %this.callback = ""; +} + +function MessageBoxYesNo(%title, %message, %yesCallback, %noCallback) +{ + MBYesNoFrame.text = %title; + MessageBoxYesNoDlg.profile = "GuiOverlayProfile"; + Canvas.pushDialog(MessageBoxYesNoDlg); + MBSetText(MBYesNoText, MBYesNoFrame, %message); + MessageBoxYesNoDlg.yesCallBack = %yesCallback; + MessageBoxYesNoDlg.noCallback = %noCallBack; +} + +function MessageBoxYesNoCancel(%title, %message, %yesCallback, %noCallback, %cancelCallback) +{ + MBYesNoCancelFrame.text = %title; + MessageBoxYesNoDlg.profile = "GuiOverlayProfile"; + Canvas.pushDialog(MessageBoxYesNoCancelDlg); + MBSetText(MBYesNoCancelText, MBYesNoCancelFrame, %message); + MessageBoxYesNoCancelDlg.yesCallBack = %yesCallback; + MessageBoxYesNoCancelDlg.noCallback = %noCallBack; + MessageBoxYesNoCancelDlg.cancelCallback = %cancelCallback; +} + +function MessageBoxYesNoDlg::onSleep( %this ) +{ + %this.yesCallback = ""; + %this.noCallback = ""; +} + +//--------------------------------------------------------------------------------------------- +// MessagePopup +// Displays a message box with no buttons. Disappears after %delay milliseconds. +//--------------------------------------------------------------------------------------------- +function MessagePopup(%title, %message, %delay) +{ + // Currently two lines max. + MessagePopFrame.setText(%title); + Canvas.pushDialog(MessagePopupDlg); + MBSetText(MessagePopText, MessagePopFrame, %message); + if (%delay !$= "") + schedule(%delay, 0, CloseMessagePopup); +} + +//--------------------------------------------------------------------------------------------- +// IODropdown +// By passing in a simgroup or simset, the user will be able to choose a child of that group +// through a guiPopupMenuCtrl +//--------------------------------------------------------------------------------------------- + +function IODropdown(%title, %message, %simgroup, %callback, %cancelCallback) +{ + IODropdownFrame.text = %title; + Canvas.pushDialog(IODropdownDlg); + MBSetText(IODropdownText, IODropdownFrame, %message); + + if(isObject(%simgroup)) + { + for(%i = 0; %i < %simgroup.getCount(); %i++) + IODropdownMenu.add(%simgroup.getObject(%i).getName()); + + } + + IODropdownMenu.sort(); + IODropdownMenu.setFirstSelected(0); + + IODropdownDlg.callback = %callback; + IODropdownDlg.cancelCallback = %cancelCallback; +} + +function IODropdownDlg::onSleep( %this ) +{ + %this.callback = ""; + %this.cancelCallback = ""; + IODropdownMenu.clear(); +} + +function CloseMessagePopup() +{ + Canvas.popDialog(MessagePopupDlg); +} + +//--------------------------------------------------------------------------------------------- +// "Old" message box function aliases for backwards-compatibility. +//--------------------------------------------------------------------------------------------- + +function MessageBoxOKOld( %title, %message, %callback ) +{ + MessageBoxOK( %title, %message, %callback ); +} +function MessageBoxOKCancelOld( %title, %message, %callback, %cancelCallback ) +{ + MessageBoxOKCancel( %title, %message, %callback, %cancelCallback ); +} +function MessageBoxYesNoOld( %title, %message, %yesCallback, %noCallback ) +{ + MessageBoxYesNo( %title, %message, %yesCallback, %noCallback ); +} diff --git a/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxOK.ed.gui b/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxOK.ed.gui new file mode 100644 index 000000000..52e119ea6 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxOK.ed.gui @@ -0,0 +1,60 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxOKDlg) { + profile = "GuiOverlayProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiWindowCtrl(MBOKFrame) { + profile = "GuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "170 175"; + extent = "300 107"; + minExtent = "48 95"; + visible = "1"; + helpTag = "0"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = ""; + + new GuiMLTextCtrl(MBOKText) { + profile = "GuiMLTextProfile"; + horizSizing = "center"; + vertSizing = "bottom"; + position = "9 35"; + extent = "281 24"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "111 75"; + extent = "80 24"; + minExtent = "8 8"; + visible = "1"; + command = "MessageCallback(MessageBoxOKDlg,MessageBoxOKDlg.callback);"; + accelerator = "return"; + helpTag = "0"; + text = "Ok"; + simpleStyle = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxOKBuy.ed.gui b/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxOKBuy.ed.gui new file mode 100644 index 000000000..87dd913e0 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxOKBuy.ed.gui @@ -0,0 +1,85 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxOKBuyDlg) { + profile = "ToolsGuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiWindowCtrl(MBOKBuyFrame) { + profile = "ToolsGuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "170 175"; + extent = "300 100"; + minExtent = "48 92"; + visible = "1"; + helpTag = "0"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = ""; + closeCommand = "MessageCallback(MessageBoxOKBuyDlg,MessageBoxOKBuyDlg.noCallback);"; + + new GuiMLTextCtrl(MBOKBuyText) { + profile = "ToolsGuiMLTextProfile"; + horizSizing = "center"; + vertSizing = "bottom"; + position = "11 38"; + extent = "280 14"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "70 68"; + extent = "80 22"; + minExtent = "8 8"; + visible = "1"; + command = "MessageCallback(MessageBoxOKBuyDlg,MessageBoxOKBuyDlg.OKCallback);"; + accelerator = "return"; + helpTag = "0"; + text = "OK"; + simpleStyle = "0"; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "167 68"; + extent = "80 22"; + minExtent = "8 8"; + visible = "1"; + command = "MessageCallback(MessageBoxOKBuyDlg,MessageBoxOKBuyDlg.BuyCallback);"; + accelerator = "escape"; + helpTag = "0"; + text = "Buy Now!"; + simpleStyle = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function MessageBoxOKBuy(%title, %message, %OKCallback, %BuyCallback) +{ + MBOKBuyFrame.text = %title; + MessageBoxOKBuyDlg.profile = "ToolsGuiOverlayProfile"; + Canvas.pushDialog(MessageBoxOKBuyDlg); + MBSetText(MBOKBuyText, MBOKBuyFrame, %message); + MessageBoxOKBuyDlg.OKCallback = %OKCallback; + MessageBoxOKBuyDlg.BuyCallback = %BuyCallback; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxOKCancel.ed.gui b/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxOKCancel.ed.gui new file mode 100644 index 000000000..5f9c8f5dc --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxOKCancel.ed.gui @@ -0,0 +1,75 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxOKCancelDlg) { + profile = "GuiOverlayProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiWindowCtrl(MBOKCancelFrame) { + profile = "GuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "170 175"; + extent = "300 100"; + minExtent = "48 92"; + visible = "1"; + helpTag = "0"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = ""; + + new GuiMLTextCtrl(MBOKCancelText) { + profile = "GuiMLTextProfile"; + horizSizing = "center"; + vertSizing = "bottom"; + position = "8 34"; + extent = "283 24"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "66 68"; + extent = "80 24"; + minExtent = "8 8"; + visible = "1"; + command = "MessageCallback(MessageBoxOKCancelDlg,MessageBoxOKCancelDlg.callback);"; + accelerator = "return"; + helpTag = "0"; + text = "Ok"; + simpleStyle = "0"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "156 68"; + extent = "80 24"; + minExtent = "8 8"; + visible = "1"; + command = "MessageCallback(MessageBoxOKCancelDlg,MessageBoxOKCancelDlg.cancelCallback);"; + accelerator = "escape"; + helpTag = "0"; + text = "Cancel"; + simpleStyle = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxOKCancelDetailsDlg.ed.gui b/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxOKCancelDetailsDlg.ed.gui new file mode 100644 index 000000000..bf746ea09 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxOKCancelDetailsDlg.ed.gui @@ -0,0 +1,137 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxOKCancelDetailsDlg) { + canSaveDynamicFields = "0"; + Profile = "GuiOverlayProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(MBOKCancelDetailsFrame) { + canSaveDynamicFields = "0"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "362 219"; + Extent = "300 330"; + MinExtent = "48 92"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = ""; + + new GuiMLTextCtrl(MBOKCancelDetailsText) { + canSaveDynamicFields = "0"; + Profile = "GuiMLTextProfile"; + HorizSizing = "center"; + VertSizing = "bottom"; + position = "32 39"; + Extent = "236 70"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "158 273"; + Extent = "110 23"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "MessageCallback(MessageBoxOKCancelDetailsDlg,MessageBoxOKCancelDetailsDlg.callback);"; + Accelerator = "return"; + hovertime = "1000"; + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "30 273"; + Extent = "110 23"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "MessageCallback(MessageBoxOKCancelDetailsDlg,MessageBoxOKCancelDetailsDlg.cancelCallback);"; + Accelerator = "escape"; + hovertime = "1000"; + text = "CANCEL"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + new GuiButtonCtrl(MBOKCancelDetailsButton) { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "9 302"; + Extent = "86 17"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "MBOKCancelDetailsToggleInfoFrame();"; + hovertime = "1000"; + text = "Details"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + new GuiScrollCtrl(MBOKCancelDetailsScroll) { + canSaveDynamicFields = "0"; + Profile = "GuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 115"; + Extent = "281 138"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiMLTextCtrl(MBOKCancelDetailsInfoText) { + canSaveDynamicFields = "0"; + Profile = "GuiMLTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "259 56"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxYesNo.ed.gui b/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxYesNo.ed.gui new file mode 100644 index 000000000..3cd7d18ef --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxYesNo.ed.gui @@ -0,0 +1,75 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxYesNoDlg) { + profile = "GuiOverlayProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiWindowCtrl(MBYesNoFrame) { + profile = "GuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "170 175"; + extent = "300 100"; + minExtent = "48 92"; + visible = "1"; + helpTag = "0"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = ""; + closeCommand = "MessageCallback(MessageBoxYesNoDlg,MessageBoxYesNoDlg.noCallback);"; + + new GuiMLTextCtrl(MBYesNoText) { + profile = "GuiMLTextProfile"; + horizSizing = "center"; + vertSizing = "bottom"; + position = "11 38"; + extent = "280 14"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "70 68"; + extent = "80 22"; + minExtent = "8 8"; + visible = "1"; + command = "MessageCallback(MessageBoxYesNoDlg,MessageBoxYesNoDlg.yesCallback);"; + accelerator = "return"; + helpTag = "0"; + text = "Yes"; + simpleStyle = "0"; + }; + new GuiButtonCtrl() { + profile = "GuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "167 68"; + extent = "80 22"; + minExtent = "8 8"; + visible = "1"; + command = "MessageCallback(MessageBoxYesNoDlg,MessageBoxYesNoDlg.noCallback);"; + accelerator = "escape"; + helpTag = "0"; + text = "No"; + simpleStyle = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxYesNoCancel.ed.gui b/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxYesNoCancel.ed.gui new file mode 100644 index 000000000..03257494d --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/messageBoxes/messageBoxYesNoCancel.ed.gui @@ -0,0 +1,103 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxYesNoCancelDlg) { + canSaveDynamicFields = "0"; + Profile = "GuiOverlayProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(MBYesNoCancelFrame) { + canSaveDynamicFields = "0"; + Profile = "GuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "250 235"; + Extent = "300 102"; + MinExtent = "48 92"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = ""; + closeCommand="MessageCallback(MessageBoxYesNoCancelDlg,MessageBoxYesNoCancelDlg.cancelCallback);"; + + new GuiMLTextCtrl(MBYesNoCancelText) { + canSaveDynamicFields = "0"; + Profile = "GuiMLTextProfile"; + HorizSizing = "center"; + VertSizing = "bottom"; + position = "7 38"; + Extent = "286 14"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "7 71"; + Extent = "80 22"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "MessageCallback(MessageBoxYesNoCancelDlg,MessageBoxYesNoCancelDlg.yesCallback);"; + Accelerator = "return"; + hovertime = "1000"; + text = "Yes"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "92 71"; + Extent = "80 22"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "MessageCallback(MessageBoxYesNoCancelDlg,MessageBoxYesNoCancelDlg.noCallback);"; + hovertime = "1000"; + text = "No"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "213 71"; + Extent = "80 22"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "MessageCallback(MessageBoxYesNoCancelDlg,MessageBoxYesNoCancelDlg.cancelCallback);"; + Accelerator = "escape"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/gui/messageBoxes/messagePopup.ed.gui b/Templates/BaseGame/game/tools/gui/messageBoxes/messagePopup.ed.gui new file mode 100644 index 000000000..806f12204 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/messageBoxes/messagePopup.ed.gui @@ -0,0 +1,46 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessagePopupDlg) { + profile = "GuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiWindowCtrl(MessagePopFrame) { + profile = "GuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "170 175"; + extent = "300 92"; + minExtent = "48 92"; + visible = "1"; + helpTag = "0"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + text = ""; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + + new GuiMLTextCtrl(MessagePopText) { + profile = "GuiMLTextProfile"; + horizSizing = "center"; + vertSizing = "bottom"; + position = "32 39"; + extent = "236 24"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/gui/objectSelection.ed.cs b/Templates/BaseGame/game/tools/gui/objectSelection.ed.cs new file mode 100644 index 000000000..bd2fa67d9 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/objectSelection.ed.cs @@ -0,0 +1,368 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Common code for object selection dialogs. + + +//============================================================================================= +// Initialization. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::init( %this ) +{ + // Initialize the class list. + + %classList = %this-->classList; + if( isObject( %classList ) ) + %this.initClassList(); + + // Initialize the filter list. + + %filterList = %this-->filterList; + if( isObject( %filterList ) ) + %this.initFilterList(); + + // Initialize the group list. + + %groupList = %this-->groupList; + if( isObject( %groupList ) ) + %this.initGroupList(); +} + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::cleanup( %this ) +{ + // Clear the class list. + + %classList = %this-->classList; + if( isObject( %classList ) ) + %classList.clear(); + + // Clear the filter list. + + %filterList = %this-->filterList; + if( isObject( %filterList ) ) + %filterList.clear(); + + // Clear the group list. + + %groupList = %this-->groupList; + if( isObject( %groupList ) ) + %groupList.clear(); + + // Delete the class array. + + if( isObject( %this.classArray ) ) + %this.classArray.delete(); +} + +//============================================================================================= +// Methods to override in a subclass. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +/// Return the group object where onSelectObjects should begin searching for objects. +function EObjectSelection::getRootGroup( %this ) +{ + return RootGroup; +} + +//--------------------------------------------------------------------------------------------- + +/// Return a set that contains all filter objects to include in the filter list. +/// Returning 0 will leave the filter list empty. +function EObjectSelection::getFilterSet( %this ) +{ + return 0; +} + +//--------------------------------------------------------------------------------------------- + +/// Return true if the given class should be included in the class list. +function EObjectSelection::includeClass( %this, %className ) +{ + return true; +} + +//--------------------------------------------------------------------------------------------- + +/// The object has met the given criteria. Select or deselect it depending on %val. +function EObjectSelection::selectObject( %this, %object, %val ) +{ +} + +//============================================================================================= +// Events. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::onSelectObjects( %this, %val ) +{ + // Get the root group to search in. + + %groupList = %this-->groupList; + if( !isObject( %groupList ) ) + %root = %this.getRootGroup(); + else + %root = %groupList.getSelected(); + + if( !isObject( %root ) ) + return; + + // Fetch the object name pattern. + + %namePatternField = %this-->namePattern; + if( isObject( %namePatternField ) ) + %this.namePattern = %namePatternField.getText(); + else + %this.namePattern = ""; + + // Clear current selection first, if need be. + + if( %val ) + { + %retainSelectionBox = %this-->retainSelection; + if( isObject( %retainSelectionBox ) && !%retainSelectionBox.isStateOn() ) + %this.clearSelection(); + } + + // (De)Select all matching objects in it. + + %this.selectObjectsIn( %root, %val, true ); +} + +//============================================================================================= +// Selection. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::selectObjectsIn( %this, %group, %val, %excludeGroup ) +{ + // Match to the group itself. + + if( !%excludeGroup && %this.objectMatchesCriteria( %group ) ) + %this.selectObject( %group, %val ); + + // Recursively match all children. + + foreach( %obj in %group ) + { + if( %obj.isMemberOfClass( "SimSet" ) ) + %this.selectObjectsIn( %obj, %val ); + else if( %this.objectMatchesCriteria( %obj ) ) + %this.selectObject( %obj, %val ); + } +} + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::objectMatchesCriteria( %this, %object ) +{ + // Check name. + + if( %this.namePattern !$= "" && !strIsMatchExpr( %this.namePattern, %object.getName() ) ) + return false; + + // Check class. + + if( !%this.isClassEnabled( %object.getClassName() ) ) + return false; + + return true; +} + +//============================================================================================= +// Groups. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::initGroupList( %this ) +{ + %groupList = %this-->groupList; + + %selected = 0; + if( %groupList.size() > 0 ) + %selected = %groupList.getSelected(); + + %groupList.clear(); + + %root = %this.getRootGroup(); + if( !isObject( %root ) ) + return; + + // Add all non-empty groups. + + %this.scanGroup( %root, %groupList, 0 ); + + // Select initial group. + + if( %selected != 0 && isObject( %selected ) ) + %groupList.setSelected( %selected ); + else + %groupList.setSelected( %root.getId() ); +} + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::scanGroup( %this, %group, %list, %indentLevel ) +{ + // Create a display name for the group. + + %text = %group.getName(); + if( %text $= "" ) + %text = %group.getClassName(); + + %internalName = %group.getInternalName(); + if( %internalName !$= "" ) + %text = %text @ " [" @ %internalName @ "]"; + + // Indent the name according to the depth in the hierarchy. + + if( %indentLevel > 0 ) + %text = strrepeat( " ", %indentLevel ) @ %text; + + // Add it to the list. + + %list.add( %text, %group.getId() ); + + // Recurse into SimSets with at least one child. + + foreach ( %obj in %group ) + { + if( !%obj.isMemberOfClass( "SimSet" ) + || %obj.getCount() == 0 ) + continue; + + %this.scanGroup( %obj, %list, %indentLevel + 1 ); + } +} + +//============================================================================================= +// Filters. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::initFilterList( %this ) +{ + %filterList = %this-->filterList; +} + +//============================================================================================= +// Classes. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +/// Initialize the list of class toggles. +function EObjectSelection::initClassList( %this ) +{ + %classArray = new ArrayObject(); + %this.classArray = %classArray; + + // Add all classes to the array. + + %classes = enumerateConsoleClasses(); + foreach$( %className in %classes ) + { + if( !%this.includeClass( %className ) ) + continue; + + %classArray.push_back( %className, true ); + } + + // Sort the class list. + + %classArray.sortk( true ); + + // Add checkboxes for all classes to the list. + + %classList = %this-->classList; + %count = %classArray.count(); + for( %i = 0; %i < %count; %i ++ ) + { + %className = %classArray.getKey( %i ); + %textLength = strlen( %className ); + %text = " " @ %className; + + %checkBox = new GuiCheckBoxCtrl() + { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxListFlipedProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = ( %textLength * 4 ) @ " 18"; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Include/exclude all " @ %className @ " objects."; + text = %text; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + command = %classArray @ ".setValue( $ThisControl.getValue(), " @ %i @ " );"; + }; + + %checkBox.setStateOn( true ); + %classList.addGuiControl( %checkBox ); + } +} + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::selectAllInClassList( %this, %state ) +{ + %classList = %this-->classList; + + foreach( %ctrl in %classList ) + { + if( %ctrl.getValue() == %state ) + %ctrl.performClick(); + } +} + +//--------------------------------------------------------------------------------------------- + +function EObjectSelection::isClassEnabled( %this, %className ) +{ + // Look up the class entry in the array. + + %index = %this.classArray.getIndexFromKey( %className ); + if( %index == -1 ) + return false; + + // Return the flag. + + return %this.classArray.getValue( %index ); +} diff --git a/Templates/BaseGame/game/tools/gui/openFileDialog.ed.cs b/Templates/BaseGame/game/tools/gui/openFileDialog.ed.cs new file mode 100644 index 000000000..50c7cdfcc --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/openFileDialog.ed.cs @@ -0,0 +1,81 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function getLoadFilename(%filespec, %callback, %currentFile, %getRelative, %defaultPath) +{ + //If no default path passed in then try to get one from the file + if(%defaultPath $= "") + { + if ( filePath( %currentFile ) !$= "" ) + %defaultPath = filePath(%currentFile); + } + + %dlg = new OpenFileDialog() + { + Filters = %filespec; + DefaultFile = %currentFile; + DefaultPath = %defaultPath; + ChangePath = false; + MustExist = true; + MultipleFiles = false; + }; + + %ok = %dlg.Execute(); + if ( %ok ) + { + %file = %dlg.FileName; + if(%getRelative) + %file = strreplace(%file,getWorkingDirectory() @ "/", ""); + eval(%callback @ "(\"" @ %file @ "\");"); + $Tools::FileDialogs::LastFilePath = filePath( %dlg.FileName ); + } + + %dlg.delete(); + + return %ok; +} + +// Opens a choose file dialog with format filters already loaded +// in. This avoids the issue of passing a massive list of format +// filters into a function as an arguement. +function getLoadFormatFilename(%callback, %currentFile) +{ + %dlg = new OpenFileDialog() + { + Filters = getFormatFilters() @ "(All Files (*.*)|*.*|"; + DefaultFile = %currentFile; + ChangePath = false; + MustExist = true; + MultipleFiles = false; + }; + + if ( filePath( %currentFile ) !$= "" ) + %dlg.DefaultPath = filePath(%currentFile); + + if ( %dlg.Execute() ) + { + eval(%callback @ "(\"" @ %dlg.FileName @ "\");"); + $Tools::FileDialogs::LastFilePath = filePath( %dlg.FileName ); + } + + %dlg.delete(); +} diff --git a/Templates/BaseGame/game/tools/gui/profilerGraph.cs b/Templates/BaseGame/game/tools/gui/profilerGraph.cs new file mode 100644 index 000000000..07cc2b940 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/profilerGraph.cs @@ -0,0 +1,113 @@ +$ProfilerGraph::refreshRate = 32; +// Profiles +new GuiControlProfile (ProfilerGraphProfile) +{ + modal = false; + opaque = false; + canKeyFocus = false; +}; + +new GuiControlProfile (ProfilerGraphKeyContainerProfile) +{ + border = true; + opaque = true; + fillColor = "100 100 100 200"; +}; +new GuiControlProfile (ProfilerGraphGraphFrameRateProfile) +{ + border = false; + fontColor = "255 255 255"; +}; +new GuiControlProfile (ProfilerGraphPolyCountProfile) +{ + border = false; + fontColor = "255 0 0"; +}; +new GuiControlProfile (ProfilerGraphDrawCountProfile) +{ + border = false; + fontColor = "0 255 0"; +}; +new GuiControlProfile (ProfilerGraphRTChangesProfile) +{ + border = false; + fontColor = "0 0 255"; +}; +new GuiControlProfile (ProfilerGraphLatencyProfile) +{ + border = false; + fontColor = "0 255 255"; +}; +new GuiControlProfile (ProfilerGraphPacketLossProfile) +{ + border = false; + fontColor = "0 0 0"; +}; + +function toggleProfilerGraph() +{ + if(!$ProfilerGraph::isInitialized) + { + ProfilerGraph::updateStats(); + $ProfilerGraph::isInitialized = true; + } + + if(!Canvas.isMember(ProfilerGraphGui)) + { + Canvas.add(ProfilerGraphGui); + } + else + Canvas.remove(ProfilerGraphGui); +} + +function ProfilerGraph::updateStats() +{ + $ProfilerGraphThread = ProfilerGraph.schedule($ProfilerGraph::refreshRate, "updateStats"); + + if(!$Stats::netGhostUpdates) + return; + + if(isobject(ProfilerGraph)) + { + GhostsActive.setText("Frame Rate: " @ $fps::real); + ProfilerGraph.addDatum(1,$fps::real); + + GhostUpdates.setText("Poly Count: " @ $GFXDeviceStatistics::polyCount); + ProfilerGraph.addDatum(2,$GFXDeviceStatistics::polyCount); + + BitsSent.setText("Draw Calls: " @ $GFXDeviceStatistics::drawCalls); + ProfilerGraph.addDatum(3,$GFXDeviceStatistics::drawCalls); + + BitsReceived.setText("Render Target Changes: " @ $GFXDeviceStatistics::renderTargetChanges); + ProfilerGraph.addDatum(4,$GFXDeviceStatistics::renderTargetChanges); + + ProfilerGraph.matchScale(2,3); + + //Latency.setText("Latency: " @ ServerConnection.getPing()); + //ProfilerGraph.addDatum(5,ServerConnection.getPacketLoss()); + + //PacketLoss.setText("Packet Loss: " @ ServerConnection.getPacketLoss()); + } +} + +function ProfilerGraph::toggleKey() +{ + if(!GhostsActive.visible) + { + GhostsActive.visible = 1; + GhostUpdates.visible = 1; + BitsSent.visible = 1; + BitsReceived.visible = 1; + Latency.visible = 1; + PacketLoss.visible = 1; + } + else + { + GhostsActive.visible = 0; + GhostUpdates.visible = 0; + BitsSent.visible = 0; + BitsReceived.visible = 0; + Latency.visible = 0; + PacketLoss.visible = 0; + } +} diff --git a/Templates/BaseGame/game/tools/gui/profilerGraph.gui b/Templates/BaseGame/game/tools/gui/profilerGraph.gui new file mode 100644 index 000000000..a008c227a --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/profilerGraph.gui @@ -0,0 +1,370 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ProfilerGraphGui) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ProfilerGraphProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + noCursor = "1"; + + new GuiWindowCtrl() { + text = "Profiler"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "1"; + canMaximize = "1"; + canCollapse = "0"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "96 232"; + extent = "558 283"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTabBookCtrl() { + tabPosition = "Top"; + tabMargin = "7"; + minTabWidth = "64"; + tabHeight = "20"; + allowReorder = "0"; + defaultPage = "-1"; + selectedPage = "0"; + frontTabPadding = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 22"; + extent = "554 261"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabBookProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl() { + fitBook = "1"; + text = "Main Render"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 20"; + extent = "554 241"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTabPageProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { + position = "6 13"; + extent = "103 223"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ProfilerGraphKeyContainerProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl(GhostsActive) { + text = "Ghosts Active"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 0"; + extent = "100 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(GhostUpdates) { + text = "Ghost Updates"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "3 72"; + extent = "100 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(BitsSent) { + text = "Bytes Sent"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 18"; + extent = "100 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(BitsReceived) { + text = "Bytes Received"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "3 90"; + extent = "100 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(Latency) { + text = "Latency"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 36"; + extent = "100 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ProfilerGraphLatencyProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl(PacketLoss) { + text = "Packet Loss"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "3 108"; + extent = "59 18"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ProfilerGraphPacketLossProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiGraphCtrl(ProfilerGraph) { + centerY = "1"; + plotColor[0] = "1 1 1 1"; + plotColor[1] = "1 0 0 1"; + plotColor[2] = "0 1 0 1"; + plotColor[3] = "0 0 1 1"; + plotColor[4] = "0 1 1 1"; + plotColor[5] = "0 0 0 1"; + plotType[0] = "PolyLine"; + plotType[1] = "PolyLine"; + plotType[2] = "PolyLine"; + plotType[3] = "PolyLine"; + plotType[4] = "PolyLine"; + plotType[5] = "PolyLine"; + plotInterval[0] = "0"; + plotInterval[1] = "0"; + plotInterval[2] = "0"; + plotInterval[3] = "0"; + plotInterval[4] = "0"; + plotInterval[5] = "0"; + position = "112 5"; + extent = "440 231"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ProfilerGraphKeyContainerProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + text = "Frame Rate"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "9 0"; + extent = "99 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + text = "Poly Count"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "9 32"; + extent = "99 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + text = "Draw Count"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "9 64"; + extent = "99 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + text = "RT Changes"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "9 96"; + extent = "99 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/gui/profiles.ed.cs b/Templates/BaseGame/game/tools/gui/profiles.ed.cs new file mode 100644 index 000000000..04e8df5b2 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/profiles.ed.cs @@ -0,0 +1,1079 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function execEditorProfilesCS() +{ + exec("./profiles.ed.cs"); +} + +$Gui::clipboardFile = expandFilename("./clipboard.gui"); + + +if( !isObject( ToolsGuiDefaultProfile ) ) +new GuiControlProfile (ToolsGuiDefaultProfile) +{ + tab = false; + canKeyFocus = false; + hasBitmapArray = false; + mouseOverSelected = false; + + // fill color + opaque = false; + fillColor = "242 241 240"; + fillColorHL ="228 228 235"; + fillColorSEL = "98 100 137"; + fillColorNA = "255 255 255 "; + + // border color + border = 0; + borderColor = "100 100 100"; + borderColorHL = "50 50 50 50"; + borderColorNA = "75 75 75"; + + // font + fontType = "Arial"; + fontSize = 14; + fontCharset = ANSI; + + fontColor = "0 0 0"; + fontColorHL = "0 0 0"; + fontColorNA = "0 0 0"; + fontColorSEL= "255 255 255"; + + // bitmap information + bitmap = ""; + bitmapBase = ""; + textOffset = "0 0"; + + // used by guiTextControl + modal = true; + justify = "left"; + autoSizeWidth = false; + autoSizeHeight = false; + returnTab = false; + numbersOnly = false; + cursorColor = "0 0 0 255"; + + // sounds + //soundButtonDown = ""; + //soundButtonOver = ""; +}; + +if( !isObject( ToolsGuiSolidDefaultProfile ) ) +new GuiControlProfile (ToolsGuiSolidDefaultProfile) +{ + opaque = true; + border = true; + category = "Tools"; +}; + +if( !isObject( ToolsGuiTransparentProfile ) ) +new GuiControlProfile (ToolsGuiTransparentProfile) +{ + opaque = false; + border = false; + category = "Tools"; +}; + +if( !isObject( ToolsGuiGroupBorderProfile ) ) +new GuiControlProfile( ToolsGuiGroupBorderProfile ) +{ + border = false; + opaque = false; + hasBitmapArray = true; + bitmap = "./images/group-border"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiTabBorderProfile ) ) +new GuiControlProfile( ToolsGuiTabBorderProfile ) +{ + border = false; + opaque = false; + hasBitmapArray = true; + bitmap = "./images/tab-border"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiToolTipProfile ) ) +new GuiControlProfile (ToolsGuiToolTipProfile) +{ + // fill color + fillColor = "239 237 222"; + + // border color + borderColor = "138 134 122"; + + // font + fontType = "Arial"; + fontSize = 14; + fontColor = "0 0 0"; + + category = "Tools"; +}; + +if( !isObject( ToolsGuiModelessDialogProfile ) ) +new GuiControlProfile( ToolsGuiModelessDialogProfile ) +{ + modal = false; + category = "Tools"; +}; + +if( !isObject( ToolsGuiFrameSetProfile ) ) +new GuiControlProfile (ToolsGuiFrameSetProfile) +{ + fillcolor = "255 255 255"; + borderColor = "246 245 244"; + border = 1; + opaque = true; + border = true; + category = "Tools"; +}; + +if( !isObject( ToolsGuiWindowProfile ) ) +new GuiControlProfile (ToolsGuiWindowProfile) +{ + opaque = false; + border = 2; + fillColor = "242 241 240"; + fillColorHL = "221 221 221"; + fillColorNA = "200 200 200"; + fontColor = "50 50 50"; + fontColorHL = "0 0 0"; + bevelColorHL = "255 255 255"; + bevelColorLL = "0 0 0"; + text = "untitled"; + bitmap = "./images/window"; + textOffset = "8 4"; + hasBitmapArray = true; + justify = "left"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiToolbarWindowProfile ) ) +new GuiControlProfile(ToolsGuiToolbarWindowProfile : ToolsGuiWindowProfile) +{ + bitmap = "./images/toolbar-window"; + text = ""; + category = "Tools"; +}; + +if( !isObject( ToolsGuiWindowCollapseProfile ) ) +new GuiControlProfile (ToolsGuiWindowCollapseProfile : ToolsGuiWindowProfile) +{ + category = "Tools"; +}; + +if( !isObject( ToolsGuiTextProfile ) ) +new GuiControlProfile (ToolsGuiTextProfile) +{ + justify = "left"; + fontColor = "20 20 20"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiTextBoldCenterProfile ) ) +new GuiControlProfile (ToolsGuiTextBoldCenterProfile : ToolsGuiTextProfile) +{ + fontColor = "50 50 50"; + fontType = "Arial Bold"; + fontSize = 16; + justify = "center"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiTextRightProfile ) ) +new GuiControlProfile (ToolsGuiTextRightProfile : ToolsGuiTextProfile) +{ + justify = "right"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiTextCenterProfile ) ) +new GuiControlProfile (ToolsGuiTextCenterProfile : ToolsGuiTextProfile) +{ + justify = "center"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiInspectorTitleTextProfile ) ) +new GuiControlProfile (ToolsGuiInspectorTitleTextProfile) +{ + fontColor = "100 100 100"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiAutoSizeTextProfile ) ) +new GuiControlProfile (ToolsGuiAutoSizeTextProfile) +{ + fontColor = "0 0 0"; + autoSizeWidth = true; + autoSizeHeight = true; + category = "Tools"; +}; + +if( !isObject( ToolsGuiMLTextProfile ) ) +new GuiControlProfile( ToolsGuiMLTextProfile ) +{ + fontColorLink = "100 100 100"; + fontColorLinkHL = "255 255 255"; + autoSizeWidth = true; + autoSizeHeight = true; + border = false; + category = "Tools"; +}; + +if( !isObject( ToolsGuiTextArrayProfile ) ) +new GuiControlProfile( ToolsGuiTextArrayProfile : ToolsGuiTextProfile ) +{ + fontColor = "50 50 50"; + fontColorHL = " 0 0 0"; + fontColorSEL = "0 0 0"; + fillColor ="200 200 200"; + fillColorHL = "228 228 235"; + fillColorSEL = "200 200 200"; + border = false; + category = "Tools"; +}; + +if( !isObject( ToolsGuiTextListProfile ) ) +new GuiControlProfile( ToolsGuiTextListProfile : ToolsGuiTextProfile ) +{ + tab = true; + canKeyFocus = true; + category = "Tools"; +}; + +if( !isObject( ToolsGuiTextEditProfile ) ) +new GuiControlProfile( ToolsGuiTextEditProfile ) +{ + opaque = true; + bitmap = "./images/textEditFrame"; + hasBitmapArray = true; + border = -2; // fix to display textEdit img + //borderWidth = "1"; // fix to display textEdit img + //borderColor = "100 100 100"; + fillColor = "242 241 240 0"; + fillColorHL = "255 255 255"; + fontColor = "0 0 0"; + fontColorHL = "255 255 255"; + fontColorSEL = "98 100 137"; + fontColorNA = "200 200 200"; + textOffset = "4 2"; + autoSizeWidth = false; + autoSizeHeight = true; + justify = "left"; + tab = true; + canKeyFocus = true; + category = "Tools"; +}; + +if( !isObject( ToolsGuiNumericTextEditProfile ) ) +new GuiControlProfile( ToolsGuiNumericTextEditProfile : ToolsGuiTextEditProfile ) +{ + numbersOnly = true; + category = "Tools"; +}; + +if( !isObject( ToolsGuiNumericDropSliderTextProfile ) ) +new GuiControlProfile( ToolsGuiNumericDropSliderTextProfile : ToolsGuiTextEditProfile ) +{ + bitmap = "./images/textEditSliderBox"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiRLProgressBitmapProfile ) ) +new GuiControlProfile( ToolsGuiRLProgressBitmapProfile ) +{ + border = false; + hasBitmapArray = true; + bitmap = "./images/rl-loadingbar"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiProgressTextProfile ) ) +new GuiControlProfile( ToolsGuiProgressTextProfile ) +{ + fontSize = "14"; + fontType = "Arial"; + fontColor = "0 0 0"; + justify = "center"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiButtonProfile ) ) +new GuiControlProfile( ToolsGuiButtonProfile ) +{ + opaque = true; + border = true; + fontColor = "50 50 50"; + fontColorHL = "0 0 0"; + fontColorNA = "200 200 200"; + fixedExtent = false; + justify = "center"; + canKeyFocus = false; + bitmap = "./images/button"; + hasBitmapArray = false; + category = "Tools"; +}; + +if( !isObject( ToolsGuiThumbHighlightButtonProfile ) ) +new GuiControlProfile( ToolsGuiThumbHighlightButtonProfile : ToolsGuiButtonProfile ) +{ + bitmap = "./images/thumbHightlightButton"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiIconButtonProfile ) ) +new GuiControlProfile( ToolsGuiIconButtonProfile ) +{ + opaque = true; + border = true; + fontColor = "50 50 50"; + fontColorHL = "0 0 0"; + fontColorNA = "200 200 200"; + fixedExtent = false; + justify = "center"; + canKeyFocus = false; + bitmap = "./images/iconbutton"; + hasBitmapArray = true; + category = "Tools"; +}; + +if( !isObject( ToolsGuiIconButtonSmallProfile ) ) +new GuiControlProfile( ToolsGuiIconButtonSmallProfile : ToolsGuiIconButtonProfile ) +{ + bitmap = "./images/iconbuttonsmall"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiEditorTabPage ) ) +new GuiControlProfile(ToolsGuiEditorTabPage) +{ + opaque = true; + border = false; + fontColor = "0 0 0"; + fontColorHL = "0 0 0"; + fixedExtent = false; + justify = "center"; + canKeyFocus = false; + bitmap = "./images/tab"; + hasBitmapArray = true; + category = "Tools"; +}; + +if( !isObject( ToolsGuiCheckBoxProfile ) ) +new GuiControlProfile( ToolsGuiCheckBoxProfile ) +{ + opaque = false; + fillColor = "232 232 232"; + border = false; + borderColor = "100 100 100"; + fontSize = 14; + fontColor = "20 20 20"; + fontColorHL = "80 80 80"; + fontColorNA = "200 200 200"; + fixedExtent = true; + justify = "left"; + bitmap = "./images/checkbox"; + hasBitmapArray = true; + category = "Tools"; +}; + +if( !isObject( ToolsGuiCheckBoxListProfile ) ) +new GuiControlProfile( ToolsGuiCheckBoxListProfile : ToolsGuiCheckBoxProfile) +{ + bitmap = "./images/checkbox-list"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiCheckBoxListFlipedProfile ) ) +new GuiControlProfile( ToolsGuiCheckBoxListFlipedProfile : ToolsGuiCheckBoxProfile) +{ + bitmap = "./images/checkbox-list_fliped"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiInspectorCheckBoxTitleProfile ) ) +new GuiControlProfile( ToolsGuiInspectorCheckBoxTitleProfile : ToolsGuiCheckBoxProfile ){ + fontColor = "100 100 100"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiRadioProfile ) ) +new GuiControlProfile( ToolsGuiRadioProfile ) +{ + fontSize = 14; + fillColor = "232 232 232"; + fontColor = "20 20 20"; + fontColorHL = "80 80 80"; + fixedExtent = true; + bitmap = "./images/radioButton"; + hasBitmapArray = true; + category = "Tools"; +}; + +if( !isObject( ToolsGuiScrollProfile ) ) +new GuiControlProfile( ToolsGuiScrollProfile ) +{ + opaque = true; + fillcolor = "255 255 255"; + fontColor = "0 0 0"; + fontColorHL = "150 150 150"; + border = true; + bitmap = "./images/scrollBar"; + hasBitmapArray = true; + category = "Tools"; +}; + +if( !isObject( ToolsGuiOverlayProfile ) ) +new GuiControlProfile( ToolsGuiOverlayProfile ) +{ + opaque = true; + fillcolor = "255 255 255"; + fontColor = "0 0 0"; + fontColorHL = "255 255 255"; + fillColor = "0 0 0 100"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiSliderProfile ) ) +new GuiControlProfile( ToolsGuiSliderProfile ) +{ + bitmap = "./images/slider"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiSliderBoxProfile ) ) +new GuiControlProfile( ToolsGuiSliderBoxProfile ) +{ + bitmap = "./images/slider-w-box"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiPopupMenuItemBorder ) ) +new GuiControlProfile( ToolsGuiPopupMenuItemBorder : ToolsGuiButtonProfile ) +{ + opaque = true; + border = true; + fontColor = "0 0 0"; + fontColorHL = "0 0 0"; + fontColorNA = "255 255 255"; + fixedExtent = false; + justify = "center"; + canKeyFocus = false; + bitmap = "./images/button"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiPopUpMenuDefault ) ) +new GuiControlProfile( ToolsGuiPopUpMenuDefault : ToolsGuiDefaultProfile ) +{ + opaque = true; + mouseOverSelected = true; + textOffset = "3 3"; + border = 0; + borderThickness = 0; + fixedExtent = true; + bitmap = "./images/scrollbar"; + hasBitmapArray = true; + profileForChildren = ToolsGuiPopupMenuItemBorder; + fillColor = "242 241 240 ";//"255 255 255";//100 + fillColorHL = "228 228 235 ";//"204 203 202"; + fillColorSEL = "98 100 137 ";//"204 203 202"; + // font color is black + fontColorHL = "0 0 0 ";//"0 0 0"; + fontColorSEL = "255 255 255";//"0 0 0"; + borderColor = "100 100 100"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiPopUpMenuProfile ) ) +new GuiControlProfile( ToolsGuiPopUpMenuProfile : ToolsGuiPopUpMenuDefault ) +{ + textOffset = "6 4"; + bitmap = "./images/dropDown"; + hasBitmapArray = true; + border = 1; + profileForChildren = ToolsGuiPopUpMenuDefault; + category = "Tools"; +}; + +if( !isObject( ToolsGuiPopUpMenuTabProfile ) ) +new GuiControlProfile( ToolsGuiPopUpMenuTabProfile : ToolsGuiPopUpMenuDefault ) +{ + bitmap = "./images/dropDown-tab"; + textOffset = "6 4"; + canKeyFocus = true; + hasBitmapArray = true; + border = 1; + profileForChildren = ToolsGuiPopUpMenuDefault; + category = "Tools"; +}; + +if( !isObject( ToolsGuiPopUpMenuEditProfile ) ) +new GuiControlProfile( ToolsGuiPopUpMenuEditProfile : ToolsGuiPopUpMenuDefault ) +{ + textOffset = "6 4"; + canKeyFocus = true; + bitmap = "./images/dropDown"; + hasBitmapArray = true; + border = 1; + profileForChildren = ToolsGuiPopUpMenuDefault; + category = "Tools"; +}; + +if( !isObject( ToolsGuiListBoxProfile ) ) +new GuiControlProfile( ToolsGuiListBoxProfile ) +{ + tab = true; + canKeyFocus = true; + category = "Tools"; +}; + +if( !isObject( ToolsGuiTabBookProfile ) ) +new GuiControlProfile( ToolsGuiTabBookProfile ) +{ + fillColorHL = "100 100 100"; + fillColorNA = "150 150 150"; + fontColor = "30 30 30"; + fontColorHL = "0 0 0"; + fontColorNA = "50 50 50"; + fontType = "Arial"; + fontSize = 14; + justify = "center"; + bitmap = "./images/tab"; + tabWidth = 64; + tabHeight = 24; + tabPosition = "Top"; + tabRotation = "Horizontal"; + textOffset = "0 -3"; + tab = true; + cankeyfocus = true; + category = "Tools"; +}; + +if( !isObject( ToolsGuiTabBookNoBitmapProfile ) ) +new GuiControlProfile( ToolsGuiTabBookNoBitmapProfile : ToolsGuiTabBookProfile ) +{ + bitmap = ""; + category = "Tools"; +}; + +if( !isObject( ToolsGuiTabPageProfile ) ) +new GuiControlProfile( ToolsGuiTabPageProfile : ToolsGuiDefaultProfile ) +{ + fontType = "Arial"; + fontSize = 10; + justify = "center"; + bitmap = "./images/tab"; + opaque = false; + fillColor = "240 239 238"; + category = "Tools"; +}; + +if( !isObject( ToolsGuiTreeViewProfile ) ) +new GuiControlProfile( ToolsGuiTreeViewProfile ) +{ + bitmap = "./images/treeView"; + autoSizeHeight = true; + canKeyFocus = true; + fillColor = "255 255 255"; + fillColorHL = "228 228 235"; + fillColorSEL = "98 100 137"; + fillColorNA = "255 255 255"; + fontColor = "0 0 0"; + fontColorHL = "0 0 0"; + fontColorSEL= "255 255 255"; + fontColorNA = "200 200 200"; + borderColor = "128 000 000"; + borderColorHL = "255 228 235"; + fontSize = 14; + opaque = false; + border = false; + category = "Tools"; +}; + +if( !isObject( ToolsGuiTextPadProfile ) ) +new GuiControlProfile( ToolsGuiTextPadProfile ) +{ + fontType = ($platform $= "macos") ? "Monaco" : "Lucida Console"; + fontSize = ($platform $= "macos") ? 13 : 12; + tab = true; + canKeyFocus = true; + + // Deviate from the Default + opaque=true; + fillColor = "255 255 255"; + border = 0; + category = "Tools"; +}; + +if( !isObject( ToolsGuiFormProfile ) ) +new GuiControlProfile( ToolsGuiFormProfile : ToolsGuiTextProfile ) +{ + opaque = false; + border = 5; + justify = "center"; + profileForChildren = ToolsGuiButtonProfile; + opaque = false; + hasBitmapArray = true; + bitmap = "./images/button"; + category = "Tools"; +}; + +// ---------------------------------------------------------------------------- + +singleton GuiControlProfile( GuiEditorClassProfile ) +{ + opaque = true; + fillColor = "232 232 232"; + border = 1; + borderColor = "40 40 40 140"; + borderColorHL = "127 127 127"; + fontColor = "0 0 0"; + fontColorHL = "50 50 50"; + fixedExtent = true; + justify = "center"; + bitmap = "tools/gui/images/scrollBar"; + hasBitmapArray = true; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiBackFillProfile ) +{ + opaque = true; + fillColor = "0 94 94"; + border = true; + borderColor = "255 128 128"; + fontType = "Arial"; + fontSize = 12; + fontColor = "0 0 0"; + fontColorHL = "50 50 50"; + fixedExtent = true; + justify = "center"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiControlListPopupProfile ) +{ + opaque = true; + fillColor = "255 255 255"; + fillColorHL = "204 203 202"; + border = false; + //borderColor = "0 0 0"; + fontColor = "0 0 0"; + fontColorHL = "0 0 0"; + fontColorNA = "50 50 50"; + textOffset = "0 2"; + autoSizeWidth = false; + autoSizeHeight = true; + tab = true; + canKeyFocus = true; + bitmap = "tools/gui/images/scrollBar"; + hasBitmapArray = true; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiSceneGraphEditProfile ) +{ + canKeyFocus = true; + tab = true; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorButtonProfile : ToolsGuiButtonProfile ) +{ + //border = 1; + justify = "Center"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorSwatchButtonProfile ) +{ + borderColor = "100 100 100 255"; + borderColorNA = "200 200 200 255"; + fillColorNA = "255 255 255 0"; + borderColorHL = "0 0 0 255"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorTextEditProfile ) +{ + // Transparent Background + opaque = true; + fillColor = "0 0 0 0"; + fillColorHL = "255 255 255"; + + // No Border (Rendered by field control) + border = false; + + tab = true; + canKeyFocus = true; + + // font + fontType = "Arial"; + fontSize = 14; + + fontColor = "0 0 0"; + fontColorSEL = "43 107 206"; + fontColorHL = "244 244 244"; + fontColorNA = "100 100 100"; + category = "Editor"; +}; +singleton GuiControlProfile( GuiDropdownTextEditProfile : ToolsGuiTextEditProfile ) +{ + bitmap = "tools/gui/images/dropdown-textEdit"; + category = "Editor"; +}; +singleton GuiControlProfile( GuiInspectorTextEditRightProfile : GuiInspectorTextEditProfile ) +{ + justify = "right"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorGroupProfile ) +{ + fontType = "Arial"; + fontSize = "14"; + + fontColor = "0 0 0 150"; + fontColorHL = "25 25 25 220"; + fontColorNA = "128 128 128"; + + justify = "left"; + opaque = false; + border = false; + + bitmap = "tools/editorClasses/gui/images/rollout"; + + textOffset = "20 0"; + + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorFieldProfile) +{ + // fill color + opaque = false; + fillColor = "255 255 255"; + fillColorHL = "204 203 202"; + fillColorNA = "244 244 244"; + + // border color + border = false; + borderColor = "190 190 190"; + borderColorHL = "156 156 156"; + borderColorNA = "200 200 200"; + + //bevelColorHL = "255 255 255"; + //bevelColorLL = "0 0 0"; + + // font + fontType = "Arial"; + fontSize = 14; + + fontColor = "32 32 32"; + fontColorHL = "50 50 50"; + fontColorNA = "190 190 190"; + textOffset = "10 0"; + + tab = true; + canKeyFocus = true; + category = "Editor"; +}; + +/* +singleton GuiControlProfile( GuiInspectorMultiFieldProfile : GuiInspectorFieldProfile ) +{ + opaque = true; + fillColor = "50 50 230 30"; +}; +*/ + +singleton GuiControlProfile( GuiInspectorMultiFieldDifferentProfile : GuiInspectorFieldProfile ) +{ + border = true; + borderColor = "190 100 100"; +}; + +singleton GuiControlProfile( GuiInspectorDynamicFieldProfile : GuiInspectorFieldProfile ) +{ + // Transparent Background + opaque = true; + fillColor = "0 0 0 0"; + fillColorHL = "255 255 255"; + + // No Border (Rendered by field control) + border = false; + + tab = true; + canKeyFocus = true; + + // font + fontType = "Arial"; + fontSize = 14; + + fontColor = "0 0 0"; + fontColorSEL = "43 107 206"; + fontColorHL = "244 244 244"; + fontColorNA = "100 100 100"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiRolloutProfile ) +{ + border = 1; + borderColor = "200 200 200"; + + hasBitmapArray = true; + bitmap = "tools/editorClasses/gui/images/rollout"; + + textoffset = "17 0"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorRolloutProfile0 ) +{ + // font + fontType = "Arial"; + fontSize = 14; + + fontColor = "32 32 32"; + fontColorHL = "32 100 100"; + fontColorNA = "0 0 0"; + + justify = "left"; + opaque = false; + + border = 0; + borderColor = "190 190 190"; + borderColorHL = "156 156 156"; + borderColorNA = "64 64 64"; + + bitmap = "tools/editorclasses/gui/images/rollout_plusminus_header"; + + textOffset = "20 0"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorStackProfile ) +{ + opaque = false; + border = false; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorProfile : GuiInspectorFieldProfile ) +{ + opaque = true; + fillColor = "255 255 255 255"; + border = 0; + cankeyfocus = true; + tab = true; + category = "Editor"; +}; +singleton GuiControlProfile( GuiInspectorInfoProfile : GuiInspectorFieldProfile ) +{ + opaque = true; + fillColor = "242 241 240"; + border = 0; + cankeyfocus = true; + tab = true; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorBackgroundProfile : GuiInspectorFieldProfile ) +{ + border = 0; + cankeyfocus=true; + tab = true; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorTypeFileNameProfile ) +{ + // Transparent Background + opaque = false; + + // No Border (Rendered by field control) + border = 0; + + tab = true; + canKeyFocus = true; + + // font + fontType = "Arial"; + fontSize = 14; + + // Center text + justify = "center"; + + fontColor = "32 32 32"; + fontColorHL = "50 50 50"; + fontColorNA = "0 0 0"; + + fillColor = "255 255 255"; + fillColorHL = "204 203 202"; + fillColorNA = "244 244 244"; + + borderColor = "190 190 190"; + borderColorHL = "156 156 156"; + borderColorNA = "64 64 64"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorColumnCtrlProfile : GuiInspectorFieldProfile ) +{ + opaque = true; + fillColor = "210 210 210"; + border = 0; + category = "Editor"; +}; + +singleton GuiControlProfile( InspectorTypeEnumProfile : GuiInspectorFieldProfile ) +{ + mouseOverSelected = true; + bitmap = "tools/gui/images/scrollBar"; + hasBitmapArray = true; + opaque=true; + border=true; + textOffset = "4 0"; + category = "Editor"; +}; + +singleton GuiControlProfile( InspectorTypeCheckboxProfile : GuiInspectorFieldProfile ) +{ + bitmap = "tools/gui/images/checkBox"; + hasBitmapArray = true; + opaque=false; + border=false; + textOffset = "4 0"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiToolboxButtonProfile : ToolsGuiButtonProfile ) +{ + justify = "center"; + fontColor = "0 0 0"; + border = 0; + textOffset = "0 0"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiDirectoryTreeProfile : ToolsGuiTreeViewProfile ) +{ + fontColor = "40 40 40"; + fontColorSEL= "250 250 250 175"; + fillColorHL = "0 60 150"; + fontColorNA = "240 240 240"; + fontType = "Arial"; + fontSize = 14; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiDirectoryFileListProfile ) +{ + fontColor = "40 40 40"; + fontColorSEL= "250 250 250 175"; + fillColorHL = "0 60 150"; + fontColorNA = "240 240 240"; + fontType = "Arial"; + fontSize = 14; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiDragAndDropProfile ) +{ + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorFieldInfoPaneProfile ) +{ + opaque = false; + fillcolor = GuiInspectorBackgroundProfile.fillColor; + borderColor = ToolsGuiDefaultProfile.borderColor; + border = 1; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiInspectorFieldInfoMLTextProfile : ToolsGuiMLTextProfile ) +{ + opaque = false; + border = 0; + textOffset = "5 0"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiEditorScrollProfile ) +{ + opaque = true; + fillcolor = GuiInspectorBackgroundProfile.fillColor; + borderColor = ToolsGuiDefaultProfile.borderColor; + border = 1; + bitmap = "tools/gui/images/scrollBar"; + hasBitmapArray = true; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiCreatorIconButtonProfile ) +{ + opaque = true; + fillColor = "225 243 252 255"; + fillColorHL = "225 243 252 0"; + fillColorNA = "225 243 252 0"; + fillColorSEL = "225 243 252 0"; + + //tab = true; + //canKeyFocus = true; + + fontType = "Arial"; + fontSize = 14; + + fontColor = "0 0 0"; + fontColorSEL = "43 107 206"; + fontColorHL = "244 244 244"; + fontColorNA = "100 100 100"; + + border = 1; + borderColor = "153 222 253 255"; + borderColorHL = "156 156 156"; + borderColorNA = "153 222 253 0"; + + //bevelColorHL = "255 255 255"; + //bevelColorLL = "0 0 0"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiMenuBarProfile ) +{ + fillcolor = "255 255 255"; + fillcolorHL = "213 231 248"; + borderColor = "98 163 229"; + borderColorHL = "122 177 232"; + border = 0; + borderThickness = 1; + opaque = true; + mouseOverSelected = true; + category = "Editor"; + bitmap = "tools/gui/images/checkbox-menubar"; +}; diff --git a/Templates/BaseGame/game/tools/gui/saveChangesMBDlg.ed.gui b/Templates/BaseGame/game/tools/gui/saveChangesMBDlg.ed.gui new file mode 100644 index 000000000..ec1a3e4ff --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/saveChangesMBDlg.ed.gui @@ -0,0 +1,180 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MessageBoxSaveChangesDlg, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(MBSaveChangesFrame) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "362 274"; + Extent = "340 164"; + MinExtent = "48 92"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Save Changes"; + maxLength = "255"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + + new GuiIconButtonCtrl(mbSaveDlgSaveButton) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "240 117"; + Extent = "83 25"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Save"; + groupNum = "-1"; + buttonType = "PushButton"; + iconBitmap = "~/levelEditor/gui/images/iconAccept.png"; + sizeIconToButton = "0"; + textLocation = "Center"; + textMargin = "4"; + buttonMargin = "4 4"; + }; + new GuiIconButtonCtrl(mbSaveDlgCancelButton) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "158 117"; + Extent = "83 25"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + iconBitmap = "~/levelEditor/gui/images/iconCancel.png"; + sizeIconToButton = "0"; + textLocation = "Center"; + textMargin = "4"; + buttonMargin = "4 4"; + }; + new GuiIconButtonCtrl(mbSaveDlgDontButton) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "14 117"; + Extent = "124 25"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Don\'t Save"; + groupNum = "-1"; + buttonType = "PushButton"; + sizeIconToButton = "0"; + textLocation = "Center"; + textMargin = "4"; + buttonMargin = "4 4"; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "13 31"; + Extent = "310 73"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Profile = "EditorTextHLBoldLeft"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "15 9"; + Extent = "281 26"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Do you want to save changes to this document?"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "15 38"; + Extent = "258 21"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "If you don\'t save, your changes may be lost."; + maxLength = "1024"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- + +function MessageBoxSaveChangesDlg::onWake( %this ) +{ + MBSaveChangesFrame.setText( %this.Data ); +} + +function mbSaveDlgSaveButton::onClick( %this ) +{ + if( MessageBoxSaveChangesDlg.SaveCallback !$= "" ) + eval( MessageBoxSaveChangesDlg.SaveCallback @ "(" @ MessageBoxSaveChangesDlg.Data @ ");" ); + Canvas.popDialog( MessageBoxSaveChangesDlg ); +} + +function mbSaveDlgCancelButton::onClick( %this ) +{ + Canvas.popDialog( MessageBoxSaveChangesDlg ); +} + +function mbSaveDlgDontButton::onClick( %this ) +{ + if( MessageBoxSaveChangesDlg.DontSaveCallback !$= "" ) + eval( MessageBoxSaveChangesDlg.DontSaveCallback @ "(" @ MessageBoxSaveChangesDlg.Data @ ");" ); + Canvas.popDialog( MessageBoxSaveChangesDlg ); +} + +// Deprecated when platform layers are all sufficient +function checkSaveChangesOld( %data, %saveCallback, %dontSaveCallback ) +{ + // Sanity Check + if( MessageBoxSaveChangesDlg.isAwake() ) + { + warn("Save Changes Dialog already Awake, NOT creating second instance."); + return; + } + + // Set Proper State + MessageBoxSaveChangesDlg.SaveCallback = %saveCallback; + MessageBoxSaveChangesDlg.DontSaveCallback = %dontSaveCallback; + MessageBoxSaveChangesDlg.Data = %data; + + // Show Dialog + Canvas.pushDialog( MessageBoxSaveChangesDlg ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/gui/saveFileDialog.ed.cs b/Templates/BaseGame/game/tools/gui/saveFileDialog.ed.cs new file mode 100644 index 000000000..8756c2eab --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/saveFileDialog.ed.cs @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function getSaveFilename( %filespec, %callback, %currentFile, %overwrite ) +{ + if( %overwrite $= "" ) + %overwrite = true; + + %dlg = new SaveFileDialog() + { + Filters = %filespec; + DefaultFile = %currentFile; + ChangePath = false; + OverwritePrompt = %overwrite; + }; + + if( filePath( %currentFile ) !$= "" ) + %dlg.DefaultPath = filePath( %currentFile ); + else + %dlg.DefaultPath = getMainDotCSDir(); + + if( %dlg.Execute() ) + { + %filename = %dlg.FileName; + eval( %callback @ "(\"" @ %filename @ "\");" ); + } + + %dlg.delete(); +} diff --git a/Templates/BaseGame/game/tools/gui/scriptEditorDlg.ed.gui b/Templates/BaseGame/game/tools/gui/scriptEditorDlg.ed.gui new file mode 100644 index 000000000..852d347a9 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/scriptEditorDlg.ed.gui @@ -0,0 +1,210 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ScriptEditorDlg,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiWindowCtrl() { + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "1"; + canMaximize = "1"; + minSize = "50 50"; + closeCommand = "ScriptEditorDlg.close();"; + EdgeSnap = "1"; + text = "Text Pad"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "176 120"; + Extent = "656 464"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ScriptEditorDlg.close();"; + Accelerator = "escape"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "8 24"; + Extent = "640 392"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "8 7"; + Extent = "627 380"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "0"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "1 1"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "627 380"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiMLTextEditCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextPadProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "2 2"; + Extent = "623 380"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "TextPad"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiIconButtonCtrl() { + buttonMargin = "4 4"; + iconBitmap = "tools/gui/images/iconCancel.png"; + iconLocation = "Left"; + sizeIconToButton = "0"; + makeIconSquare = "0"; + textLocation = "Center"; + textMargin = "4"; + autoSize = "0"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "460 424"; + Extent = "80 25"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ScriptEditorDlg.close();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiIconButtonCtrl() { + buttonMargin = "4 4"; + iconBitmap = "tools/gui/images/iconAccept.png"; + iconLocation = "Left"; + sizeIconToButton = "0"; + makeIconSquare = "0"; + textLocation = "Center"; + textMargin = "4"; + autoSize = "0"; + text = "Ok"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "560 424"; + Extent = "80 25"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "_TextPadOnOk();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function TextPad(%text, %callback, %root) +{ + ScriptEditorDlg-->textpad.setText(%text); + ScriptEditorDlg.callback = %callback; + + if(!isObject(%root)) + %root = Canvas; + + %root.pushDialog(ScriptEditorDlg); +} + +function _TextPadOnOk() +{ + if(ScriptEditorDlg.callback !$= "") + { + %text = ScriptEditorDlg-->textpad.getText(); + %command = ScriptEditorDlg.callback @ "( %text );"; + eval(%command); + } + ScriptEditorDlg.callback = ""; + ScriptEditorDlg.getRoot().popDialog(ScriptEditorDlg); +} + +function ScriptEditorDlg::close(%this) +{ + %this.getRoot().popDialog(%this); +} diff --git a/Templates/BaseGame/game/tools/gui/simViewDlg.ed.gui b/Templates/BaseGame/game/tools/gui/simViewDlg.ed.gui new file mode 100644 index 000000000..14bc25b57 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/simViewDlg.ed.gui @@ -0,0 +1,348 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(simViewDlg, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "70 43"; + Extent = "685 489"; + MinExtent = "602 440"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Torque SimView"; + maxLength = "1024"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "1"; + canMaximize = "1"; + minSize = "50 50"; + closeCommand = "Canvas.popDialog(simViewDlg);"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "10 28"; + Extent = "255 448"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiTreeViewCtrl(InspectTreeView) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "212 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "1"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "1"; + }; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "left"; + VertSizing = "height"; + position = "272 96"; + Extent = "404 380"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(InspectFields) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + canSaveDynamicFields = "0"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "382 8"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + }; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "272 28"; + Extent = "403 61"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextEditCtrl(InspectObjectName) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "121 8"; + Extent = "195 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Profile = "EditorTextHLRight"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "217 35"; + Extent = "44 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Sim ID:"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Profile = "EditorTextHLRight"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 35"; + Extent = "106 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Internal Name:"; + maxLength = "1024"; + }; + new GuiTextEditCtrl(InspectObjectInternalName) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "121 35"; + Extent = "93 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Profile = "EditorTextHLBoldRight"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 8"; + Extent = "106 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Selected Object:"; + maxLength = "1024"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "321 33"; + Extent = "76 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "InspectApply();"; + hovertime = "1000"; + text = "Refresh"; + groupNum = "-1"; + buttonType = "PushButton"; + iconBitmap = "./images/iconRefresh.png"; + sizeIconToButton = "0"; + textLocation = "Right"; + textMargin = "4"; + buttonMargin = "4 4"; + }; + new GuiTextCtrl(InspectObjectSimID) { + canSaveDynamicFields = "0"; + Profile = "EditorTextHLBoldCenter"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "265 35"; + Extent = "51 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "0"; + maxLength = "1024"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "321 6"; + Extent = "76 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "InspectDelete();"; + hovertime = "1000"; + text = "Delete"; + groupNum = "-1"; + buttonType = "PushButton"; + iconBitmap = "./images/iconDelete.png"; + sizeIconToButton = "0"; + textLocation = "Right"; + textMargin = "4"; + buttonMargin = "4 4"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- + +function Inspect(%obj) +{ + // Don't inspect the root group. + if( %obj == -1 ) + return; + + InspectFields.inspect(%obj); + + // Update selected object properties + InspectObjectName.setValue(%obj.getName()); + InspectObjectInternalName.setValue( %obj.getInternalName() ); + InspectObjectSimID.setValue( %obj.getId() ); + + // Store Object Reference + InspectObjectName.refObj = %obj; + +} + +function InspectApply() +{ + %obj = InspectObjectName.refObj; + if( !isObject( %obj ) ) + return; + + // Update name and internal name + %obj.setName( InspectObjectName.getValue() ); + %obj.setInternalName( InspectObjectInternalName.getValue() ); + + // Update inspected object information. + InspectFields.inspect( %obj ); +} + +function InspectDelete() +{ + %obj = InspectObjectName.refObj; + if( !isObject( %obj ) ) + return; + + %obj.delete(); + + // Update inspected object information. + InspectFields.inspect( 0 ); + + // Update selected object properties + InspectObjectName.setValue(""); + InspectObjectInternalName.setValue( "" ); + InspectObjectSimID.setValue( 0 ); + + +} + + +function InspectTreeView::onSelect(%this, %obj) +{ + Inspect(%obj); +} + +function Tree(%obj) +{ + Canvas.popDialog("simViewDlg"); + Canvas.pushDialog("simViewDlg", 20); + InspectTreeView.open(%obj); +} + +// MM: Added Dynamic group toggle support. +function GuiInspector::toggleDynamicGroupScript(%this, %obj) +{ + %this.toggleDynamicGroupExpand(); + %this.inspect(%obj); +} +// MM: Added group toggle support. +function GuiInspector::toggleGroupScript(%this, %obj, %fieldName) +{ + %this.toggleGroupExpand(%obj, %fieldName); + %this.inspect(%obj); +} + +// MM: Set All Group State support. +function GuiInspector::setAllGroupStateScript(%this, %obj, %groupState) +{ + %this.setAllGroupState(%groupState); + %this.inspect(%obj); +} diff --git a/Templates/BaseGame/game/tools/gui/uvEditor.ed.gui b/Templates/BaseGame/game/tools/gui/uvEditor.ed.gui new file mode 100644 index 000000000..c27f8498e --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/uvEditor.ed.gui @@ -0,0 +1,645 @@ +new GuiControl(UVEditorOverlay, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiOverlayProfile"; + Enabled = "1"; + isContainer = "1"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(UVEditor){ + profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + resizeWidth = "0"; + resizeHeight = "0"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + position = "72 98"; + extent =" 453 340"; + MinExtent = "453 340"; + text = "UV Editor"; + closeCommand = "UVEditor.hideDialog();"; + EdgeSnap = "0"; + canCollapse = "0"; + visible = "0"; + + new GuiTextCtrl() { + text = "0.0"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "26 24"; + Extent = "32 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "U"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "138 24"; + Extent = "32 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "1.0"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "250 24"; + Extent = "32 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + + new GuiTextCtrl() { + text = "0.0"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 36"; + Extent = "18 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "V"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 159"; + Extent = "18 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "1.0"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 282"; + Extent = "18 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + + new GuiControl(){ + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiSolidDefaultProfile"; + position = "25 37"; + extent = "258 258"; + }; + + new GuiBitmapCtrl(){ + internalName = "bitmapPreview"; + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + position = "26 38"; + extent = "256 256"; + wrap = "0"; + bitmap = ""; + }; + new GuiRectHandles(){ + internalName = "uvHandles"; + class = "UVEditorRectHandles"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "26 38"; + extent = "256 256"; + }; + + new GuiBitmapBorderCtrl() { + profile = "ToolsGuiGroupBorderProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "26 300"; + extent = "256 30"; + minExtent = "0 0"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + + new GuiTextCtrl() { + text = "Handle Color:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 7"; + Extent = "70 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopupMenuCtrlEx(){ + internalName = "colorPopup"; + Profile = "ToolsGuiPopUpMenuProfile"; + Position = "80 5"; + Extent = "126 20"; + HorizSizing = "right"; + VertSizing = "bottom"; + Command = "UVEditor.onColorSelect();"; + reverseTextList = "0"; + }; + }; + + new GuiBitmapBorderCtrl() { + profile = "ToolsGuiGroupBorderProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "292 38"; + extent = "151 256"; + minExtent = "0 0"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + + new GuiTextCtrl() { + text = "U:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 12"; + Extent = "32 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + internalName = "UVX"; + class = "UVEditorUVTextEdit"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "44 10"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextCtrl() { + text = "V:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 32"; + Extent = "32 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + internalName = "UVY"; + class = "UVEditorUVTextEdit"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "44 30"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextCtrl() { + text = "Width:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 52"; + Extent = "32 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + internalName = "UVW"; + class = "UVEditorUVTextEdit"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "44 50"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextCtrl() { + text = "Height:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 72"; + Extent = "32 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + internalName = "UVH"; + class = "UVEditorUVTextEdit"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "44 70"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiButtonCtrl(){ + HorizSizing = "right"; + VertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + position = "44 94"; + extent = "64 20"; + text = "Reset"; + command = "UVEditor.reset();"; + tooltip = "Reset the UV fields to their original values."; + }; + }; + new GuiButtonCtrl(){ + internalName = "OKButton"; + HorizSizing = "left"; + VertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + position = "292 306"; + extent = "94 24"; + text = "OK"; + command = "UVEditor.apply();"; + Accelerator = "return"; + }; + new GuiButtonCtrl(){ + HorizSizing = "left"; + VertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + position = "391 306"; + extent = "52 24"; + text = "Cancel"; + command = "UVEditor.hideDialog();"; + Accelerator = "escape"; + }; + }; +}; + +//----------------------------------------------------------------------------- + +function UVEditor::showDialog( %this, %applyCallback, %obj, %uv) +{ + // Set the select callback + UVEditor.applyCallback = %applyCallback; + + // Set the initial UV coordinates + UVEditor.originalUV = %uv; + UVEditor-->uvHandles.handleRect = %uv; + UVEditor.setTextValues(%uv); + + // Get the preview bitmap. Code copied from Material Selector. + %material = %obj.material; + if( %material.toneMap[0] $= "" && %material.diffuseMap[0] $= "" && !isObject(%material.cubemap) ) + { + %previewImage = "core/art/warnmat"; + } + else + { + if( %material.toneMap[0] !$= "" ) + %previewImage = %material.toneMap[0]; + else if( %material.diffuseMap[0] !$= "" ) + %previewImage = %material.diffuseMap[0]; + else if( %material.cubemap.cubeFace[0] !$= "" ) + %previewImage = %material.cubemap.cubeFace[0]; + + %materialDiffuse = %previewImage; + %materialPath = %material.getFilename(); + if( strchr( %materialDiffuse, "/") $= "" ) + { + %k = 0; + while( strpos( %materialPath, "/", %k ) != -1 ) + { + %foo = strpos( %materialPath, "/", %k ); + %k = %foo + 1; + } + + %foobar = getSubStr( %materialPath , %k , 99 ); + %previewImage = strreplace( %materialPath, %foobar, %previewImage ); + } + else + %previewImage = strreplace( %materialPath, %materialPath, %previewImage ); + } + + UVEditor-->bitmapPreview.setBitmap(%previewImage); + + // Set up the color popup + %popup = UVEditor-->colorPopup; + %popup.clear(); + %popup.add("Default1|255|134|0"); + %popup.add("Default2|0|121|255"); + %popup.add("Black|0|0|0"); + %popup.add("Gray|100|100|100"); + %popup.add("White|255|255|255"); + %popup.add("Red|255|0|0"); + %popup.add("Green|0|255|0"); + %popup.add("Blue|0|0|255"); + %popup.add("Yellow|255|255|0"); + %popup.add("Magenta|255|0|255"); + %popup.add("Cyan|0|255|255"); + %popup.setSelected(EditorSettings.value("WorldEditor/Color/uvEditorHandleColor")); + UVEditor-->uvHandles.useCustomColor = true; + UVEditor-->uvHandles.handleColor = %popup.getColorById(%popup.getSelected()); + + Canvas.pushDialog(UVEditorOverlay); + UVEditor.setVisible(1); +} + +function UVEditor::hideDialog( %this ) +{ + UVEditor.setVisible(0); + Canvas.popDialog(UVEditorOverlay); +} + +function UVEditor::apply( %this ) +{ + eval( "" @ UVEditor.applyCallback @ "(\"" @ UVEditor-->uvHandles.handleRect @ "\");"); + UVEditor.hideDialog(); +} + +function UVEditor::reset( %this ) +{ + UVEditor-->uvHandles.handleRect = UVEditor.originalUV; + UVEditor.setTextValues(UVEditor.originalUV); +} + +function UVEditor::setTextValues( %this, %uv ) +{ + UVEditor-->UVX.setText( getWord(%uv, 0) ); + UVEditor-->UVY.setText( getWord(%uv, 1) ); + UVEditor-->UVW.setText( getWord(%uv, 2) ); + UVEditor-->UVH.setText( getWord(%uv, 3) ); +} + +function UVEditor::onColorSelect( %this ) +{ + UVEditor-->uvHandles.useCustomColor = true; + %sel = $ThisControl.getSelected(); + UVEditor-->uvHandles.handleColor = $ThisControl.getColorById(%sel); + EditorSettings.setValue( "WorldEditor/Color/uvEditorHandleColor", %sel ); +} + +//----------------------------------------------------------------------------- + +function UVEditorRectHandles::onHandleRectChange( %this ) +{ + %uv = UVEditor-->uvHandles.handleRect; + UVEditor.setTextValues(%uv); +} + +//----------------------------------------------------------------------------- + +function UVEditorUVTextEdit::onValidate( %this ) +{ + %u = UVEditor-->UVX.getValue(); + %v = UVEditor-->UVY.getValue(); + %w = UVEditor-->UVW.getValue(); + %h = UVEditor-->UVH.getValue(); + + // Check limits + + if(%u < 0) + %u = 0; + if(%u > 1) + %u = 1; + if(%v < 0) + %v = 0; + if(%v > 1) + %v = 1; + + if(%w < 0) + %w = 0; + if(%w > 1) + %w = 1; + if(%h < 0) + %h = 0; + if(%h > 1) + %h = 1; + + if((%u+%w) > 1) + %w = 1 - %u; + if((%v+%h) > 1) + %h = 1 - %v; + + // Apply values + UVEditor-->UVX.setText( %u ); + UVEditor-->UVY.setText( %v ); + UVEditor-->UVW.setText( %w ); + UVEditor-->UVH.setText( %h ); + + UVEditor-->uvHandles.handleRect = %u SPC %v SPC %w SPC %h; +} + +function UVEditorUVTextEdit::onGainFirstResponder( %this ) +{ + %this.selectAllText(); +} diff --git a/Templates/BaseGame/game/tools/guiEditor/gui/EditorChooseGUI.ed.gui b/Templates/BaseGame/game/tools/guiEditor/gui/EditorChooseGUI.ed.gui new file mode 100644 index 000000000..02d9e04b3 --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/gui/EditorChooseGUI.ed.gui @@ -0,0 +1,229 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiChunkedBitmapCtrl(EditorChooseGUI, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiContentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + bitmap = "art/gui/background"; + useVariable = "0"; + tile = "0"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "476 191"; + Extent = "211 351"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "GUI Selector"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 23"; + Extent = "188 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "1: Edit an Existing GUI"; + maxLength = "255"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "46 317"; + Extent = "120 23"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "GE_ReturnToMainMenu();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Play Game"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 41"; + Extent = "192 200"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "alwaysOn"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "4 0"; + + new GuiMLTextCtrl(GE_GUIList) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiMLTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 1"; + Extent = "169 560"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "1"; + }; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "112 267"; + Extent = "90 23"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GE_OpenGUIFile();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Browse"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 244"; + Extent = "183 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "2: Create New or Open Existing GUI"; + maxLength = "255"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 267"; + Extent = "93 23"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GuiEditorNewGuiDialog.init( \"NewGui\", \"GuiControl\" );" @ "Canvas.pushdialog(GuiEditorNewGuiDialog);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "New GUI"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 294"; + Extent = "183 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "3: Play Game from Start"; + maxLength = "255"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/guiEditor/gui/gridTiny2.PNG b/Templates/BaseGame/game/tools/guiEditor/gui/gridTiny2.PNG new file mode 100644 index 000000000..8a2d1bd89 Binary files /dev/null and b/Templates/BaseGame/game/tools/guiEditor/gui/gridTiny2.PNG differ diff --git a/Templates/BaseGame/game/tools/guiEditor/gui/guiEditor.ed.gui b/Templates/BaseGame/game/tools/guiEditor/gui/guiEditor.ed.gui new file mode 100644 index 000000000..cc03cbd07 --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/gui/guiEditor.ed.gui @@ -0,0 +1,1535 @@ +//--------------------------------------------------------------------------------------------- +// Torque Game Builder +// Copyright (C) GarageGames.com, Inc. +//--------------------------------------------------------------------------------------------- + +%guiContent = new GuiControl(GuiEditorGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiFrameSetCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiFrameSetProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 583"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + columns = "0 631"; + rows = "0"; + borderWidth = "1"; + border = "0"; + borderEnable = "dynamic"; + borderMovable = "dynamic"; + autoBalance = "1"; + fudgeFactor = "3"; + + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "627 583"; + MinExtent = "64 64"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiContainer(GHToolBar) { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "menubarProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "16000 32"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl(GHWorldEditor) { + bitmap = "tools/worldEditor/images/toolbar/world"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 3"; + extent = "29 27"; + minExtent = "8 8"; + canSave = "1"; + visible = "1"; + command = "toggleEditor(1);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "World Editor"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl(GHGuiEditor) { + bitmap = "tools/worldEditor/images/toolbar/gui"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "34 3"; + extent = "29 27"; + minExtent = "8 8"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "Gui Editor"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/worldEditor/images/toolbar/playbutton"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "64 3"; + extent = "29 27"; + minExtent = "8 8"; + canSave = "1"; + visible = "1"; + command = "GuiEdit(); Editor.close(\"PlayGui\");"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "Play Game"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl() { + bitmap = "tools/gui/images/separator-h.png"; + wrap = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "98 3"; + extent = "2 26"; + minExtent = "1 1"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "99 0"; + extent = "723 32"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiPopUpMenuCtrl(GuiEditorContentList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "NewGui - 8844"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiPopUpMenuProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "8 7"; + extent = "145 18"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(GuiEditorResList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "1024 x 768 (XGA, 4:3)"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiPopUpMenuProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "161 7"; + extent = "136 18"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl() { + bitmap = "tools/gui/images/separator-h.png"; + wrap = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "307 3"; + extent = "2 26"; + minExtent = "1 1"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "312 3"; + extent = "95 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl(GuiEditorSnapCheckBox) { + bitmap = "tools/gui/images/GUI-editor/snap-grid"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "Snap gui controls to a grid. Modify grid size under edit."; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl(GuiEditorEdgeSnapping_btn) { + bitmap = "tools/gui/images/GUI-editor/edgesnap"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "31 0"; + extent = "29 27"; + minExtent = "120 21"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.toggleEdgeSnap();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggles Edge Smart Snapping"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl(GuiEditorCenterSnapping_btn) { + bitmap = "tools/gui/images/GUI-editor/centersnap"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "62 0"; + extent = "29 27"; + minExtent = "120 21"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.toggleCenterSnap();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggles Center Smart Snapping"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapCtrl() { + bitmap = "tools/gui/images/separator-h.png"; + wrap = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "415 3"; + extent = "2 26"; + minExtent = "1 1"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "422 3"; + extent = "95 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/align-left"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "29 27"; + minExtent = "120 21"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(0);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "Align Left"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/vertical-center"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(1);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "Center Vertically "; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/align-right"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "40 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(2);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "Align Right"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "498 3"; + extent = "95 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/align-top"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "29 27"; + minExtent = "120 21"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(3);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "Align Top"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/horizontal-center"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "25 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(7);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "Center Horizontally"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/align-bottom"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "50 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(4);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "Align Bottom"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapCtrl() { + bitmap = "tools/gui/images/separator-h.png"; + wrap = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "582 3"; + extent = "2 26"; + minExtent = "1 1"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl() { + bitmap = "tools/gui/images/separator-h.png"; + wrap = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "639 3"; + extent = "2 26"; + minExtent = "1 1"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "615 3"; + extent = "117 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/send-to-back"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "49 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.PushToBack();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "Send to Back"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/bring-to-front"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "27 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.BringToFront();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "Send to Front"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "583 3"; + extent = "60 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/distribute-horizontal"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(6);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "Distribute Horizontally"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/GUI-editor/distribute-vertical"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "25 0"; + extent = "29 27"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditor.Justify(5);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + ToolTip = "Distribute Vertically"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + //--------------------- + new GuiEditorRuler(GuiEditorTopRuler) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "10 32"; + Extent = "614 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + refCtrl = "GuiEditorScroll"; + editCtrl = "GuiEditor"; + }; + new GuiEditorRuler(GuiEditorLeftRuler) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "height"; + Position = "0 42"; + Extent = "10 523"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + refCtrl = "GuiEditorScroll"; + editCtrl = "GuiEditor"; + }; + + new GuiScrollCtrl(GuiEditorScroll) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "10 41"; + Extent = "617 543"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiControl(GuiEditorRegion) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "1 1"; + Extent = "640 480"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiBackFillProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "640 480"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/guiEditor/gui/gridTiny2"; + wrap = "1"; + }; + new GuiControl(GuiEditorContent) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "640 480"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + }; + new GuiEditCtrl(GuiEditor) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Docking = "None"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "640 480"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + }; + }; + }; + }; + new GuiControl(GuiEditorSidebar) { + isContainer = "1"; + Profile = "menubarProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "798 0"; + Extent = "226 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTabBookCtrl(GuiEditorTabBook) { + tabPosition = "Top"; + tabMargin = "7"; + minTabWidth = "40"; + tabHeight = "20"; + allowReorder = "1"; + defaultPage = "0"; + selectedPage = "0"; + FrontTabPadding = "0"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 12"; + Extent = "223 754"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl() { + fitBook = "1"; + text = "GUI"; + maxLength = "1024"; + docking = "client"; + Margin = "-1 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 20"; + Extent = "223 734"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + internalName = "guiPage"; + + new GuiFrameSetCtrl() { + columns = "0"; + rows = "0 338"; + borderWidth = "1"; + borderColor = "207 207 207 207"; + borderEnable = "dynamic"; + borderMovable = "dynamic"; + autoBalance = "1"; + fudgeFactor = "2"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiFrameSetProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "222 734"; + MinExtent = "8 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiPanel() { + position = "0 0"; + extent = "222 337"; + + new GuiTextEditCtrl( GuiEditorTreeFilter ) { + position = "2 4"; + extent = "200 18"; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + class = "GuiTreeViewFilterText"; + treeView = GuiEditorTreeView; + }; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "205 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + class = "GuiTreeViewFilterClearButton"; + textCtrl = GuiEditorTreeFilter; + }; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 25"; + Extent = "222 312"; + MinExtent = "8 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(GuiEditorTreeView) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "0"; + MouseDragging = "1"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + ClearAllOnSingleSelection = "1"; + showRoot = "1"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "0"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 22"; + Extent = "89 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + showObjectIds = "0"; + showClassNames = "0"; + showObjectNames = "1"; + showInternalNames = "1"; + showClassNameForUnnamedObjects = "1"; + }; + }; + }; + + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 338"; + Extent = "222 396"; + MinExtent = "8 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 2"; + Extent = "223 341"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiInspector(GuiEditorInspectFields) { + dividerMargin = "5"; + showCustomFields = "1"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + DynamicSize = "1"; + ChangeChildSizeToFit = "1"; + ChangeChildPosition = "1"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "221 24"; + MinExtent = "8 24"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + superClass = "EditorInspectorBase"; + }; + }; + new GuiMLTextCtrl(GuiEditorFieldInfo) { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + position = "0 349"; + Extent = "213 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + + new GuiTabPageCtrl() { + fitBook = "1"; + text = "Library"; + maxLength = "1024"; + docking = "client"; + Margin = "-1 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 20"; + Extent = "223 734"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + internalName = "toolboxPage"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + docking = "client"; + + new GuiStackControl(GuiEditorToolbox) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "2"; + DynamicSize = "1"; + ChangeChildSizeToFit = "1"; + ChangeChildPosition = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "3 3"; + Extent = "419 10008"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + + new GuiTabPageCtrl() { + fitBook = "1"; + text = "Profiles"; + maxLength = "1024"; + docking = "client"; + Margin = "-1 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 20"; + Extent = "223 734"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + internalName = "profilesPage"; + + new GuiFrameSetCtrl() { + columns = "0"; + rows = "0 338"; + borderWidth = "1"; + borderColor = "207 207 207 207"; + borderEnable = "dynamic"; + borderMovable = "dynamic"; + autoBalance = "1"; + fudgeFactor = "2"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiFrameSetProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "222 734"; + MinExtent = "8 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiPanel() { + position = "0 0"; + extent = "222 337"; + + new GuiTextEditCtrl( GuiEditorProfilesTreeFilter ) { + position = "2 4"; + extent = "200 18"; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + class = "GuiTreeViewFilterText"; + treeView = GuiEditorProfilesTree; + }; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "205 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + class = "GuiTreeViewFilterClearButton"; + textCtrl = GuiEditorProfilesTreeFilter; + }; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 25"; + Extent = "222 312"; + MinExtent = "8 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(GuiEditorProfilesTree) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "0"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "0"; + DragToItemAllowed = "0"; + ClearAllOnSingleSelection = "1"; + showRoot = "1"; + internalNamesOnly = "0"; + objectNamesOnly = "0"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "0"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "89 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 338"; + Extent = "222 396"; + MinExtent = "8 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextEditCtrl(GuiEditorProfileFileName) { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 2"; + Extent = "180 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/save-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "184 2"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GuiEditor.saveProfile( GuiEditorProfilesTree.getSelectedProfile(), GuiEditorProfileFileName.getText() );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Save the currently selected profile."; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/save-as"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "205 2"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GuiEditor.showSaveProfileDialog( GuiEditorProfileFileName.getText() );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Save the currently selected profile to a different file."; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 22"; + Extent = "223 321"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiInspector(GuiEditorProfileInspector) { + dividerMargin = "5"; + showCustomFields = "1"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + DynamicSize = "1"; + ChangeChildSizeToFit = "1"; + ChangeChildPosition = "1"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "221 24"; + MinExtent = "8 24"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + superClass = "EditorInspectorBase"; + }; + }; + new GuiMLTextCtrl(GuiEditorProfileFieldInfo) { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + position = "0 349"; + Extent = "213 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + }; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "156 12"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "button1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "174 12"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "button2"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "192 12"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "button3"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "207 12"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "button4"; + canSaveDynamicFields = "0"; + }; + }; + }; + + new GuiControl() { + position = "0 583"; + extent = "800 17"; + horizSizing = "width"; + vertSizing = "top"; + minExtent = "64 17"; + canSave = "1"; + visible = "1"; + isContainer = "1"; + profile = "menubarProfile"; + + new GuiTextCtrl( GuiEditorStatusBar ) { + profile = "ToolsGuiTextProfile"; + position = "5 0"; + extent = "500 17"; + minExtent = "64 17"; + canSave = "1"; + visible = "1"; + }; + new GuiSeparatorCtrl() { + profile = "ToolsGuiDefaultProfile"; + position = "505 0"; + extent = "10 17"; + minExtent = "10 17"; + canSave = "1"; + visible = "1"; + horizSizing = "left"; + }; + new GuiTextCtrl( GuiEditorSelectionStatus ) { + profile = "ToolsGuiTextProfile"; + position = "515 0"; + extent = "100 17"; + minExtent = "100 17"; + canSave = "1"; + visible = "1"; + horizSizing = "left"; + }; + }; +}; diff --git a/Templates/BaseGame/game/tools/guiEditor/gui/guiEditorNewGuiDialog.ed.gui b/Templates/BaseGame/game/tools/guiEditor/gui/guiEditorNewGuiDialog.ed.gui new file mode 100644 index 000000000..98252410a --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/gui/guiEditorNewGuiDialog.ed.gui @@ -0,0 +1,199 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(GuiEditorNewGuiDialog,EditorGuiGroup) { + isContainer = "1"; + profile = "ToolsGuiOverlayProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + enabled = "1"; + + new GuiWindowCtrl() { + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + edgeSnap = "0"; + text = "Create new GUI"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "ToolsGuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "357 303"; + extent = "310 161"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "228 114"; + extent = "63 25"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditorNewGuiDialog.onCancel();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Create"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "101 114"; + extent = "124 25"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + command = "GuiEditorNewGuiDialog.onOK();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + accelerator = "enter"; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "15 28"; + extent = "278 76"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "GUI Name"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "14 13"; + extent = "80 18"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "103 13"; + extent = "160 17"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "nameField"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "GUI Class"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "14 44"; + extent = "80 18"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiPopUpMenuProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "103 44"; + extent = "160 18"; + minExtent = "8 2"; + canSave = "1"; + visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "classDropdown"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/guiEditor/gui/guiEditorPrefsDlg.ed.gui b/Templates/BaseGame/game/tools/guiEditor/gui/guiEditorPrefsDlg.ed.gui new file mode 100644 index 000000000..6f901d1a8 --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/gui/guiEditorPrefsDlg.ed.gui @@ -0,0 +1,181 @@ +%guiContent = new GuiControl(GuiEditorPrefsDlg, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "250 210"; + Extent = "280 95"; + MinExtent = "344 144"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "Canvas.popDialog(\"GuiEditorPrefsDlg\");"; + EdgeSnap = "0"; + text = "Gui Editor Grid Preferences"; + + new GuiButtonCtrl(GuiEditorPrefsDlgCancelBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "100 60"; + Extent = "80 25"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Accelerator = "escape"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl(GuiEditorPrefsDlgOkBtn) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "190 60"; + Extent = "80 25"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Ok"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl(GuiEditorPrefsDlgDefaultsBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "10 60"; + Extent = "60 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Reset"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "center"; + VertSizing = "bottom"; + position = "-3 20"; + Extent = "288 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "16 10"; + Extent = "48 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Grid Size:"; + maxLength = "1024"; + }; + new GuiTextEditCtrl(GuiEditorPrefsDlgGridEdit) { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + Enabled = "1"; + Component = "textEdit"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 11"; + Extent = "32 18"; + MinExtent = "8 18"; + canSave = "1"; + Visible = "1"; + Command = "GuiEditorPrefsDlgGridEdit.onAction();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + new GuiSliderCtrl(GuiEditorPrefsDlgGridSlider) { + canSaveDynamicFields = "0"; + internalName = "Slider"; + Enabled = "1"; + Component = "Slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "112 14"; + Extent = "160 12"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "GuiEditorPrefsDlgGridSlider.onAction();"; + hovertime = "1000"; + range = "0 64"; + ticks = "0"; + value = "0"; + }; + }; + }; +}; + diff --git a/Templates/BaseGame/game/tools/guiEditor/gui/guiEditorSelectDlg.ed.gui b/Templates/BaseGame/game/tools/guiEditor/gui/guiEditorSelectDlg.ed.gui new file mode 100644 index 000000000..1794a238d --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/gui/guiEditorSelectDlg.ed.gui @@ -0,0 +1,566 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(GuiEditorSelectDlgContainer,EditorGuiGroup) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl(GuiEditorSelectDlg) { + text = "Select Controls"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "1"; + closeCommand = "$ThisControl.toggleVisibility();"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "268 177"; + extent = "380 373"; + minExtent = "200 100"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + class = "EObjectSelection"; + internalName = "SelectControlsDlg"; + + new GuiBitmapBorderCtrl() { + position = "7 104"; + extent = "265 262"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiGroupBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "10 25"; + extent = "246 200"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "0"; + dynamicSize = "1"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "246 1242"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "classList"; + canSave = "1"; + canSaveDynamicFields = "0"; + + }; + }; + new GuiButtonCtrl() { + text = "Select All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "10 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "GuiEditorSelectDlg.selectAllInClassList( true );"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Classes"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "113 6"; + extent = "40 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Deselect All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "76 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "GuiEditorSelectDlg.selectAllInClassList( false );"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + position = "7 25"; + extent = "366 74"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiGroupBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Name Pattern"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 9"; + extent = "67 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Retain Current Selection"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "216 46"; + extent = "140 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "retainSelection"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Create Selection Set"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "13 73"; + extent = "117 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiCheckBoxProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "createSelectionSet"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "•"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "157 80"; + extent = "199 17"; + minExtent = "20 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiTextEditProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "selectionSetName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "•"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "91 9"; + extent = "265 17"; + minExtent = "20 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "namePattern"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Select Child Controls Of:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 30"; + extent = "119 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "138 30"; + extent = "218 17"; + minExtent = "20 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "groupList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + position = "246 104"; + extent = "233 262"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiGroupBorderProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "9 25"; + extent = "215 200"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "0"; + dynamicSize = "1"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "215 16"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "filterList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Select All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "9 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Filters"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "101 6"; + extent = "30 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Deselect All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "75 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Select"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "278 104"; + extent = "95 30"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "GuiEditorSelectDlg.onSelectObjects(true);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Deselect"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "278 137"; + extent = "95 30"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "GuiEditorSelectDlg.onSelectObjects(false);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/guiEditor/main.cs b/Templates/BaseGame/game/tools/guiEditor/main.cs new file mode 100644 index 000000000..da793b380 --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/main.cs @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function initializeGuiEditor() +{ + echo( " % - Initializing Gui Editor" ); + + // GUIs. + + exec( "./gui/guiEditor.ed.gui" ); + exec( "./gui/guiEditorNewGuiDialog.ed.gui" ); + exec( "./gui/guiEditorPrefsDlg.ed.gui" ); + exec( "./gui/guiEditorSelectDlg.ed.gui" ); + exec( "./gui/EditorChooseGUI.ed.gui" ); + + // Scripts. + + exec( "./scripts/guiEditor.ed.cs" ); + exec( "./scripts/guiEditorTreeView.ed.cs" ); + exec( "./scripts/guiEditorInspector.ed.cs" ); + exec( "./scripts/guiEditorProfiles.ed.cs" ); + exec( "./scripts/guiEditorGroup.ed.cs" ); + exec( "./scripts/guiEditorUndo.ed.cs" ); + exec( "./scripts/guiEditorCanvas.ed.cs" ); + exec( "./scripts/guiEditorContentList.ed.cs" ); + exec( "./scripts/guiEditorStatusBar.ed.cs" ); + exec( "./scripts/guiEditorToolbox.ed.cs" ); + exec( "./scripts/guiEditorSelectDlg.ed.cs" ); + + exec( "./scripts/guiEditorNewGuiDialog.ed.cs" ); + exec( "./scripts/fileDialogs.ed.cs" ); + exec( "./scripts/guiEditorPrefsDlg.ed.cs" ); + exec( "./scripts/EditorChooseGUI.ed.cs" ); +} + +function destroyGuiEditor() +{ +} diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/EditorChooseGUI.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/EditorChooseGUI.ed.cs new file mode 100644 index 000000000..d59c61225 --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/EditorChooseGUI.ed.cs @@ -0,0 +1,105 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function GE_ReturnToMainMenu() +{ + loadMainMenu(); +} + +function GE_OpenGUIFile() +{ + %openFileName = GuiBuilder::getOpenName(); + if( %openFileName $= "" ) + return; + + // Make sure the file is valid. + if ((!isFile(%openFileName)) && (!isFile(%openFileName @ ".dso"))) + return; + + // Allow stomping objects while exec'ing the GUI file as we want to + // pull the file's objects even if we have another version of the GUI + // already loaded. + + %oldRedefineBehavior = $Con::redefineBehavior; + $Con::redefineBehavior = "replaceExisting"; + + // Load up the level. + exec( %openFileName ); + + $Con::redefineBehavior = %oldRedefineBehavior; + + // The level file should have contained a scenegraph, which should now be in the instant + // group. And, it should be the only thing in the group. + if( !isObject( %guiContent ) ) + { + MessageBox( getEngineName(), + "You have loaded a Gui file that was created before this version. It has been loaded but you must open it manually from the content list dropdown", + "Ok", "Information" ); + GuiEditContent( Canvas.getContent() ); + return 0; + } + + GuiEditContent( %guiContent ); +} + +function GE_GUIList::onURL(%this, %url) +{ + // Remove 'gamelink:' from front + %gui = getSubStr(%url, 9, 1024); + GuiEditContent(%gui); +} + +function EditorChooseGUI::onWake() +{ + // Build the text list + GE_GUIList.clear(); + + %list = "<linkcolor:0000FF><linkcolorhl:FF0000>"; + %list = GE_ScanGroupForGuis(GuiGroup, %list); + GE_GUIList.setText(%list); + GE_GUIList.forceReflow(); + GE_GUIList.scrollToTop(); +} + +function GE_ScanGroupForGuis(%group, %text) +{ + %count = %group.getCount(); + for(%i=0; %i < %count; %i++) + { + %obj = %group.getObject(%i); + if(%obj.getClassName() $= "GuiCanvas") + { + %text = %text @ GE_ScanGroupForGuis(%obj, %text); + } + else + { + if(%obj.getName() $= "") + %name = "(unnamed) - " @ %obj; + else + %name = %obj.getName() @ " - " @ %obj; + + %text = %text @ "<a:gamelink:" @ %obj @ ">" @ %name @ "</a><br>"; + } + } + + return %text; +} diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/fileDialogs.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/fileDialogs.ed.cs new file mode 100644 index 000000000..dbb1a2a37 --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/fileDialogs.ed.cs @@ -0,0 +1,98 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +$GUI::FileSpec = "Torque Gui Files (*.gui)|*.gui|All Files (*.*)|*.*|"; + +/// GuiBuilder::getSaveName - Open a Native File dialog and retrieve the +/// location to save the current document. +/// @arg defaultFileName The FileName to default in the field and to be selected when a path is opened +function GuiBuilder::getSaveName( %defaultFileName ) +{ + %defaultPath = GuiEditor.LastPath; + + if( %defaultFileName $= "" ) + { + %prefix = ""; + if( isFunction( "isScriptPathExpando" ) ) + { + // if we're editing a game, we want to default to the games dir. + // if we're not, then we default to the tools directory or the base. + if( isScriptPathExpando( "^game") ) + %prefix = "^game/"; + else if( isScriptPathExpando( "^tools" ) ) + %prefix = "^tools/"; + } + + %defaultFileName = expandFilename( %prefix @ "gui/untitled.gui" ); + } + else + %defaultPath = filePath( %defaultFileName ); + + %dlg = new SaveFileDialog() + { + Filters = $GUI::FileSpec; + DefaultPath = makeFullPath( %defaultPath ); + DefaultFile = %defaultFileName; + ChangePath = false; + OverwritePrompt = true; + }; + + if( %dlg.Execute() ) + { + GuiEditor.LastPath = filePath( %dlg.FileName ); + %filename = %dlg.FileName; + if( fileExt( %filename ) !$= ".gui" ) + %filename = %filename @ ".gui"; + } + else + %filename = ""; + + %dlg.delete(); + + return %filename; +} + +function GuiBuilder::getOpenName( %defaultFileName ) +{ + if( %defaultFileName $= "" ) + %defaultFileName = expandFilename("^game/gui/untitled.gui"); + + %dlg = new OpenFileDialog() + { + Filters = $GUI::FileSpec; + DefaultPath = GuiEditor.LastPath; + DefaultFile = %defaultFileName; + ChangePath = false; + MustExist = true; + }; + + if(%dlg.Execute()) + { + GuiEditor.LastPath = filePath( %dlg.FileName ); + %filename = %dlg.FileName; + %dlg.delete(); + return %filename; + } + + %dlg.delete(); + return ""; +} diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditor.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditor.ed.cs new file mode 100644 index 000000000..61dc8c5e7 --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditor.ed.cs @@ -0,0 +1,1189 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +//============================================================================================= +// Activation. +//============================================================================================= + +$InGuiEditor = false; +$MLAAFxGuiEditorTemp = false; + +function GuiEdit( %val ) +{ + if (Canvas.isFullscreen()) + { + MessageBoxOK("Windowed Mode Required", "Please switch to windowed mode to access the GUI Editor."); + return; + } + + if(%val != 0) + return; + + if (!$InGuiEditor) + { + GuiEditContent(Canvas.getContent()); + + //Temp fix to disable MLAA when in GUI editor + if( isObject(MLAAFx) && MLAAFx.isEnabled==true ) + { + MLAAFx.isEnabled = false; + $MLAAFxGuiEditorTemp = true; + } + + } + else + { + GuiEditCanvas.quit(); + } + +} + +function GuiEditContent( %content ) +{ + if( !isObject( GuiEditCanvas ) ) + new GuiControl( GuiEditCanvas, EditorGuiGroup ); + + GuiEditor.openForEditing( %content ); + + $InGuiEditor = true; +} + +function toggleGuiEditor( %make ) +{ + if( %make ) + { + if( EditorIsActive() && !GuiEditor.toggleIntoEditorGui ) + toggleEditor( true ); + + if( !isObject( GuiEditCanvas ) ) + new GuiControl( GuiEditCanvas, EditorGuiGroup ); + + if( GuiEditorIsActive() ) + { + GuiEditor.close(); + } + else + { + GuiEditor.open(); + + // Cancel the scheduled event to prevent + // the level from cycling after it's duration + // has elapsed. + cancel($Game::Schedule); + } + + // Cancel the scheduled event to prevent + // the level from cycling after it's duration + // has elapsed. + cancel($Game::Schedule); + } +} + +GlobalActionMap.bind( keyboard, "f10", toggleGuiEditor ); + +//============================================================================================= +// Methods. +//============================================================================================= + +package GuiEditor_BlockDialogs +{ + function GuiCanvas::pushDialog() {} + function GuiCanvas::popDialog() {} +}; + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::open(%this) +{ + GuiEditCanvas.onCreateMenu(); + + GuiEditContent(Canvas.getContent()); +} + +function GuiEditor::close(%this) +{ + // prevent the mission editor from opening while the GuiEditor is open. + if(Canvas.getContent() != GuiEditorGui.getId()) + return; + + GuiGroup.add(GuiEditorGui); + + Canvas.setContent(GuiEditor.lastContent); + + GuiEditCanvas.onDestroyMenu(); +} + +function GuiEditor::openForEditing( %this, %content ) +{ + Canvas.setContent( GuiEditorGui ); + while( GuiEditorContent.getCount() ) + GuiGroup.add( GuiEditorContent.getObject( 0 ) ); // get rid of anything being edited + + // Clear the current guide set and add the guides + // from the control. + + %this.clearGuides(); + %this.readGuides( %content ); + + // Enumerate GUIs and put them into the content list. + + GuiEditorContentList.init(); + + GuiEditorScroll.scrollToTop(); + activatePackage( GuiEditor_BlockDialogs ); + GuiEditorContent.add( %content ); + deactivatePackage( GuiEditor_BlockDialogs ); + GuiEditorContentList.sort(); + + if(%content.getName() $= "") + %name = "(unnamed) - " @ %content; + else + %name = %content.getName() @ " - " @ %content; + + GuiEditorContentList.setText(%name); + + %this.setContentControl(%content); + + // Initialize the preview resolution list and select the current + // preview resolution. + + GuiEditorResList.init(); + + %res = %this.previewResolution; + if( %res $= "" ) + %res = "1024 768"; + GuiEditorResList.selectFormat( %res ); + + // Initialize the treeview and expand the first level. + + GuiEditorTreeView.init(); + GuiEditorTreeView.open( %content ); + GuiEditorTreeView.expandItem( 1 ); + + // Initialize profiles tree. + + if( !GuiEditorProfilesTree.isInitialized ) + { + GuiEditorProfilesTree.init(); + GuiEditorProfilesTree.isInitialized = true; + } + + // Create profile change manager if we haven't already. + + if( !isObject( GuiEditorProfileChangeManager ) ) + new SimGroup( GuiEditorProfileChangeManager ); + + // clear the undo manager if we're switching controls. + if( %this.lastContent != %content ) + GuiEditor.getUndoManager().clearAll(); + + GuiEditor.setFirstResponder(); + + %this.updateUndoMenu(); + %this.lastContent = %content; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::switchToWorldEditor( %this ) +{ + %editingWorldEditor = false; + if( GuiEditorContent.getObject( 0 ) == EditorGui.getId() ) + %editingWorldEditor = true; + + GuiEdit(); + + if( !$missionRunning ) + EditorNewLevel(); + else if( !%editingWorldEditor ) + toggleEditor( true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::enableMenuItems(%this, %val) +{ + %menu = GuiEditCanvas.menuBar->EditMenu.getID(); + + %menu.enableItem( 3, %val ); // cut + %menu.enableItem( 4, %val ); // copy + %menu.enableItem( 5, %val ); // paste + //%menu.enableItem( 7, %val ); // selectall + //%menu.enableItem( 8, %val ); // deselectall + %menu.enableItem( 9, %val ); // selectparents + %menu.enableItem( 10, %val ); // selectchildren + %menu.enableItem( 11, %val ); // addselectparents + %menu.enableItem( 12, %val ); // addselectchildren + %menu.enableItem( 15, %val ); // lock + %menu.enableItem( 16, %val ); // hide + %menu.enableItem( 18, %val ); // group + %menu.enableItem( 19, %val ); // ungroup + + GuiEditCanvas.menuBar->LayoutMenu.enableAllItems( %val ); + GuiEditCanvas.menuBar->MoveMenu.enableAllItems( %val ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::showPrefsDialog(%this) +{ + Canvas.pushDialog(GuiEditorPrefsDlg); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::getUndoManager( %this ) +{ + if( !isObject( GuiEditorUndoManager ) ) + new UndoManager( GuiEditorUndoManager ); + + return GuiEditorUndoManager; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::undo(%this) +{ + %action = %this.getUndoManager().getNextUndoName(); + + %this.getUndoManager().undo(); + %this.updateUndoMenu(); + //%this.clearSelection(); + + GuiEditorStatusBar.print( "Undid '" @ %action @ "'" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::redo(%this) +{ + %action = %this.getUndoManager().getNextRedoName(); + + %this.getUndoManager().redo(); + %this.updateUndoMenu(); + //%this.clearSelection(); + + GuiEditorStatusBar.print( "Redid '" @ %action @ "'" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::updateUndoMenu(%this) +{ + %uman = %this.getUndoManager(); + %nextUndo = %uman.getNextUndoName(); + %nextRedo = %uman.getNextRedoName(); + + %editMenu = GuiEditCanvas.menuBar->editMenu; + + %editMenu.setItemName( 0, "Undo " @ %nextUndo ); + %editMenu.setItemName( 1, "Redo " @ %nextRedo ); + + %editMenu.enableItem( 0, %nextUndo !$= "" ); + %editMenu.enableItem( 1, %nextRedo !$= "" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::isFilteredClass( %this, %className ) +{ + // Filter out all the internal GuiInspector classes. + + if( startsWith( %className, "GuiInspector" ) && %className !$= "GuiInspector" ) + return true; + + // Filter out GuiEditor classes. + + if( startsWith( %className, "GuiEditor" ) ) + return true; + + // Filter out specific classes. + + switch$( %className ) + { + case "GuiCanvas": return true; + case "GuiAviBitmapCtrl": return true; // For now. Probably removed altogether. + case "GuiArrayCtrl": return true; // Abstract base class really. + case "GuiScintillaTextCtrl": return true; // Internal class. + case "GuiNoMouseCtrl": return true; // Too odd. + case "GuiEditCtrl": return true; + case "GuiBackgroundCtrl": return true; // Just plain useless. + case "GuiTSCtrl": return true; // Abstract base class. + case "GuiTickCtrl": return true; // Abstract base class. + case "GuiWindowCollapseCtrl": return true; // Legacy. + } + + return false; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::editProfile( %this, %profile ) +{ + GuiEditorTabBook->profilesPage.select(); + GuiEditorProfilesTree.setSelectedProfile( %profile ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::createControl( %this, %className ) +{ + %ctrl = eval( "return new " @ %className @ "();" ); + if( !isObject( %ctrl ) ) + return; + + // Add the control. + + %this.addNewCtrl( %ctrl ); +} + +//--------------------------------------------------------------------------------------------- + +/// Group all GuiControls in the currenct selection set under a new GuiControl. +function GuiEditor::groupSelected( %this ) +{ + %selection = %this.getSelection(); + if( %selection.getCount() < 2 ) + return; + + // Create action. + + %action = GuiEditorGroupAction::create( %selection, GuiEditor.getContentControl() ); + %action.groupControls(); + + // Update editor tree. + + %this.clearSelection(); + %this.addSelection( %action.group[ 0 ].groupObject ); + GuiEditorTreeView.update(); + + // Update undo state. + + %action.addtoManager( %this.getUndoManager() ); + %this.updateUndoMenu(); +} + +//--------------------------------------------------------------------------------------------- + +/// Take all direct GuiControl instances in the selection set and reparent their child controls +/// to each of the group's parents. The GuiControl group objects are deleted. +function GuiEditor::ungroupSelected( %this ) +{ + %action = GuiEditorUngroupAction::create( %this.getSelection() ); + %action.ungroupControls(); + + // Update editor tree. + + %this.clearSelection(); + GuiEditorTreeView.update(); + + // Update undo state. + + %action.addToManager( %this.getUndoManager() ); + %this.updateUndoMenu(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::deleteControl( %this, %ctrl ) +{ + // Unselect. + + GuiEditor.removeSelection( %ctrl ); + + // Record undo. + + %set = new SimSet() { parentGroup = RootGroup; }; + %set.add( %ctrl ); + + %action = UndoActionDeleteObject::create( %set, %this.getTrash(), GuiEditorTreeView ); + %action.addToManager( %this.getUndoManager() ); + %this.updateUndoMenu(); + + GuiEditorTreeView.update(); + %set.delete(); + + // Remove. + + %this.getTrash().add( %ctrl ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::setPreviewResolution( %this, %width, %height ) +{ + GuiEditorRegion.resize( 0, 0, %width, %height ); + GuiEditorContent.getObject( 0 ).resize( 0, 0, %width, %height ); + + GuiEditor.previewResolution = %width SPC %height; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleEdgeSnap( %this ) +{ + %this.snapToEdges = !%this.snapToEdges; + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_EDGESNAP_INDEX, %this.snapToEdges ); + GuiEditorEdgeSnapping_btn.setStateOn( %this.snapToEdges ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleCenterSnap( %this ) +{ + %this.snapToCenters = !%this.snapToCenters; + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CENTERSNAP_INDEX, %this.snapToCenters ); + GuiEditorCenterSnapping_btn.setStateOn( %this.snapToCenters ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleFullBoxSelection( %this ) +{ + %this.fullBoxSelection = !%this.fullBoxSelection; + GuiEditCanvas.menuBar->EditMenu.checkItem( $GUI_EDITOR_MENU_FULLBOXSELECT_INDEX, %this.fullBoxSelection ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleDrawGuides( %this ) +{ + %this.drawGuides= !%this.drawGuides; + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_DRAWGUIDES_INDEX, %this.drawGuides ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleGuideSnap( %this ) +{ + %this.snapToGuides = !%this.snapToGuides; + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_GUIDESNAP_INDEX, %this.snapToGuides ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleControlSnap( %this ) +{ + %this.snapToControls = !%this.snapToControls; + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CONTROLSNAP_INDEX, %this.snapToControls ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleCanvasSnap( %this ) +{ + %this.snapToCanvas = !%this.snapToCanvas; + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CANVASSNAP_INDEX, %this.snapToCanvas ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleGridSnap( %this ) +{ + %this.snap2Grid = !%this.snap2Grid; + if( !%this.snap2Grid ) + %this.setSnapToGrid( 0 ); + else + %this.setSnapToGrid( %this.snap2GridSize ); + + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_GRIDSNAP_INDEX, %this.snap2Grid ); + GuiEditorSnapCheckBox.setStateOn( %this.snap2Grid ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleLockSelection( %this ) +{ + %this.toggleFlagInAllSelectedObjects( "locked" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleHideSelection( %this ) +{ + %this.toggleFlagInAllSelectedObjects( "hidden" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::selectAllControlsInSet( %this, %set, %deselect ) +{ + if( !isObject( %set ) ) + return; + + foreach( %obj in %set ) + { + if( !%obj.isMemberOfClass( "GuiControl" ) ) + continue; + + if( !%deselect ) + %this.addSelection( %obj ); + else + %this.removeSelection( %obj ); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::toggleFlagInAllSelectedObjects( %this, %flagFieldName ) +{ + // Use the inspector's code here to record undo information + // for the field edits. + + GuiEditorInspectFields.onInspectorPreFieldModification( %flagFieldName ); + + %selected = %this.getSelection(); + foreach( %object in %selected ) + %object.setFieldValue( %flagFieldName, !%object.getFieldValue( %flagFieldName ) ); + + GuiEditorInspectFields.onInspectorPostFieldModification(); + GuiEditorInspectFields.refresh(); +} + +//============================================================================================= +// Event Handlers. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onDelete(%this) +{ + GuiEditorTreeView.update(); + // clear out the gui inspector. + GuiEditorInspectFields.update(0); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onSelectionMoved( %this, %ctrl ) +{ + GuiEditorInspectFields.update( %ctrl ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onSelectionResized( %this, %ctrl ) +{ + GuiEditorInspectFields.update( %ctrl ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onSelect(%this, %ctrl) +{ + if( !%this.dontSyncTreeViewSelection ) + { + GuiEditorTreeView.clearSelection(); + GuiEditorTreeView.addSelection( %ctrl ); + } + + GuiEditorInspectFields.update( %ctrl ); + + GuiEditorSelectionStatus.setText( "1 Control Selected" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onAddSelected( %this, %ctrl ) +{ + if( !%this.dontSyncTreeViewSelection ) + { + GuiEditorTreeView.addSelection( %ctrl ); + GuiEditorTreeView.scrollVisibleByObjectId( %ctrl ); + } + + GuiEditorSelectionStatus.setText( %this.getNumSelected() @ " Controls Selected" ); + + // Add to inspection set. + + GuiEditorInspectFields.addInspect( %ctrl ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onRemoveSelected( %this, %ctrl ) +{ + if( !%this.dontSyncTreeViewSelection ) + GuiEditorTreeView.removeSelection( %ctrl ); + + GuiEditorSelectionStatus.setText( %this.getNumSelected() @ " Controls Selected" ); + + // Remove from inspection set. + + GuiEditorInspectFields.removeInspect( %ctrl ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onClearSelected( %this ) +{ + if( !%this.dontSyncTreeViewSelection ) + GuiEditorTreeView.clearSelection(); + + GuiEditorInspectFields.update( 0 ); + GuiEditorSelectionStatus.setText( "" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onControlDragged( %this, %payload, %position ) +{ + // Make sure we have the right kind of D&D. + + if( !%payload.parentGroup.isInNamespaceHierarchy( "GuiDragAndDropControlType_GuiControl" ) ) + return; + + // use the position under the mouse cursor, not the payload position. + %position = VectorSub( %position, GuiEditorContent.getGlobalPosition() ); + %x = getWord( %position, 0 ); + %y = getWord( %position, 1 ); + %target = GuiEditor.getContentControl().findHitControl( %x, %y ); + + // Make sure the target is a valid parent for our payload. + + while( ( !%target.isContainer || !%target.acceptsAsChild( %payload ) ) + && %target != GuiEditor.getContentControl() ) + %target = %target.getParent(); + + if( %target != %this.getCurrentAddSet() ) + %this.setCurrentAddSet( %target ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onControlDropped(%this, %payload, %position) +{ + // Make sure we have the right kind of D&D. + + if( !%payload.parentGroup.isInNamespaceHierarchy( "GuiDragAndDropControlType_GuiControl" ) ) + return; + + %pos = %payload.getGlobalPosition(); + %x = getWord(%pos, 0); + %y = getWord(%pos, 1); + + %this.addNewCtrl(%payload); + + %payload.setPositionGlobal(%x, %y); + %this.setFirstResponder(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onGainFirstResponder(%this) +{ + %this.enableMenuItems(true); + + // JCF: don't just turn them all on! + // Undo/Redo is only enabled if those actions exist. + %this.updateUndoMenu(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onLoseFirstResponder(%this) +{ + %this.enableMenuItems(false); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onHierarchyChanged( %this ) +{ + GuiEditorTreeView.update(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::onMouseModeChange( %this ) +{ + GuiEditorStatusBar.setText( GuiEditorStatusBar.getMouseModeHelp() ); +} + +//============================================================================================= +// Resolution List. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorResList::init( %this ) +{ + %this.clear(); + + // Non-widescreen formats. + + %this.add( "640x480 (VGA, 4:3)", 640 ); + %this.add( "800x600 (SVGA, 4:3)", 800 ); + %this.add( "1024x768 (XGA, 4:3)", 1024 ); + %this.add( "1280x1024 (SXGA, 4:3)", 1280 ); + %this.add( "1600x1200 (UXGA, 4:3)", 1600 ); + + // Widescreen formats. + + %this.add( "1280x720 (WXGA, 16:9)", 720 ); + %this.add( "1600x900 (16:9)", 900 ); + %this.add( "1920x1080 (16:9)", 1080 ); + %this.add( "1440x900 (WXGA+, 16:10)", 900 ); + %this.add( "1680x1050 (WSXGA+, 16:10)", 1050 ); + %this.add( "1920x1200 (WUXGA, 16:10)", 1200 ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorResList::selectFormat( %this, %format ) +{ + %width = getWord( %format, 0 ); + %height = getWord( %format, 1 ); + + switch( %height ) + { + case 720: + %this.setSelected( 720 ); + + case 900: + %this.setSelected( 900 ); + + case 1050: + %this.setSelected( 1050 ); + + case 1080: + %this.setSelected( 1080 ); + + default: + + switch( %width ) + { + case 640: + %this.setSelected( 640 ); + + case 800: + %this.setSelected( 800 ); + + case 1024: + %this.setSelected( 1024 ); + + case 1280: + %this.setSelected( 1280 ); + + case 1600: + %this.setSelected( 1600 ); + + default: + %this.setSelected( 1200 ); + } + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorResList::onSelect( %this, %id ) +{ + switch( %id ) + { + case 640: + GuiEditor.setPreviewResolution( 640, 480 ); + + case 800: + GuiEditor.setPreviewResolution( 800, 600 ); + + case 1024: + GuiEditor.setPreviewResolution( 1024, 768 ); + + case 1280: + GuiEditor.setPreviewResolution( 1280, 1024 ); + + case 1600: + GuiEditor.setPreviewResolution( 1600, 1200 ); + + case 720: + GuiEditor.setPreviewResolution( 1280, 720 ); + + case 900: + GuiEditor.setPreviewResolution( 1440, 900 ); + + case 1050: + GuiEditor.setPreviewResolution( 1680, 1050 ); + + case 1080: + GuiEditor.setPreviewResolution( 1920, 1080 ); + + case 1200: + GuiEditor.setPreviewResolution( 1920, 1200 ); + } +} + +//============================================================================================= +// Sidebar. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTabBook::onWake( %this ) +{ + if( !isObject( "GuiEditorTabBookLibraryPopup" ) ) + new PopupMenu( GuiEditorTabBookLibraryPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Alphabetical View" TAB "" TAB "GuiEditorToolbox.setViewType( \"Alphabetical\" );"; + item[ 1 ] = "Categorized View" TAB "" TAB "GuiEditorToolbox.setViewType( \"Categorized\" );"; + }; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTabBook::onTabSelected( %this, %text, %index ) +{ + %sidebar = GuiEditorSidebar; + %name = %this.getObject( %index ).getInternalName(); + + switch$( %name ) + { + case "guiPage": + + %sidebar-->button1.setVisible( false ); + %sidebar-->button2.setVisible( false ); + %sidebar-->button3.setVisible( true ); + %sidebar-->button4.setVisible( true ); + + %sidebar-->button4.setBitmap( "tools/gui/images/delete" ); + %sidebar-->button4.command = "GuiEditor.deleteSelection();"; + %sidebar-->button4.tooltip = "Delete Selected Control(s)"; + + %sidebar-->button3.setBitmap( "tools/gui/images/visible" ); + %sidebar-->button3.command = "GuiEditor.toggleHideSelection();"; + %sidebar-->button3.tooltip = "Hide Selected Control(s)"; + + case "profilesPage": + + %sidebar-->button1.setVisible( true ); + %sidebar-->button2.setVisible( true ); + %sidebar-->button3.setVisible( true ); + %sidebar-->button4.setVisible( true ); + + %sidebar-->button4.setBitmap( "tools/gui/images/delete" ); + %sidebar-->button4.command = "GuiEditor.showDeleteProfileDialog( GuiEditorProfilesTree.getSelectedProfile() );"; + %sidebar-->button4.tooltip = "Delete Selected Profile"; + + %sidebar-->button3.setBitmap( "tools/gui/images/new" ); + %sidebar-->button3.command = "GuiEditor.createNewProfile( \"Unnamed\" );"; + %sidebar-->button3.tooltip = "Create New Profile with Default Values"; + + %sidebar-->button2.setBitmap( "tools/gui/images/copy-btn" ); + %sidebar-->button2.command = "GuiEditor.createNewProfile( GuiEditorProfilesTree.getSelectedProfile().getName(), GuiEditorProfilesTree.getSelectedProfile() );"; + %sidebar-->button2.tooltip = "Create New Profile by Copying the Selected Profile"; + + %sidebar-->button1.setBitmap( "tools/gui/images/reset-icon" ); + %sidebar-->button1.command = "GuiEditor.revertProfile( GuiEditorProfilesTree.getSelectedProfile() );"; + %sidebar-->button1.tooltip = "Revert Changes to the Selected Profile"; + + case "toolboxPage": + + //TODO + + %sidebar-->button1.setVisible( false ); + %sidebar-->button2.setVisible( false ); + %sidebar-->button3.setVisible( false ); + %sidebar-->button4.setVisible( false ); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTabBook::onTabRightClick( %this, %text, %index ) +{ + %name = %this.getObject( %index ).getInternalName(); + + switch$( %name ) + { + case "toolboxPage": + + // Open toolbox popup. + + %popup = GuiEditorTabBookLibraryPopup; + + %currentViewType = GuiEditorToolbox.getViewType(); + switch$( %currentViewType ) + { + case "Alphabetical": + %popup.checkRadioItem( 0, 1, 0 ); + + case "Categorized": + %popup.checkRadioItem( 0, 1, 1 ); + } + + %popup.showPopup( Canvas ); + } +} + +//============================================================================================= +// Toolbar. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSnapCheckBox::onWake(%this) +{ + %snap = GuiEditor.snap2grid * GuiEditor.snap2gridsize; + %this.setValue( %snap ); + GuiEditor.setSnapToGrid( %snap ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSnapCheckBox::onAction(%this) +{ + %snap = GuiEditor.snap2gridsize * %this.getValue(); + GuiEditor.snap2grid = %this.getValue(); + GuiEditor.setSnapToGrid(%snap); +} + +//============================================================================================= +// GuiEditorGui. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorGui::onWake( %this ) +{ + GHGuiEditor.setStateOn( 1 ); + + if( !isObject( %this->SelectControlsDlg ) ) + { + %this.add( GuiEditorSelectDlg ); + GuiEditorSelectDlg.setVisible( false ); + } + + // Attach our menus. + + if( isObject( %this.menuGroup ) ) + for( %i = 0; %i < %this.menuGroup.getCount(); %i ++ ) + %this.menuGroup.getObject( %i ).attachToMenuBar(); + + // Read settings. + + %this.initSettings(); + %this.readSettings(); + + // Initialize toolbox. + + if( !GuiEditorToolbox.isInitialized ) + GuiEditorToolbox.initialize(); + + // Set up initial menu toggle states. + + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_EDGESNAP_INDEX, GuiEditor.snapToEdges ); + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CENTERSNAP_INDEX, GuiEditor.snapToCenters ); + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_GUIDESNAP_INDEX, GuiEditor.snapToGuides ); + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CONTROLSNAP_INDEX, GuiEditor.snapToControls ); + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_CANVASSNAP_INDEX, GuiEditor.snapToCanvas ); + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_GRIDSNAP_INDEX, GuiEditor.snap2Grid ); + GuiEditCanvas.menuBar->SnapMenu.checkItem( $GUI_EDITOR_MENU_DRAWGUIDES_INDEX, GuiEditor.drawGuides ); + GuiEditCanvas.menuBar->EditMenu.checkItem( $GUI_EDITOR_MENU_FULLBOXSELECT_INDEX, GuiEditor.fullBoxSelection ); + + // Sync toolbar buttons. + + GuiEditorSnapCheckBox.setStateOn( GuiEditor.snap2Grid ); + GuiEditorEdgeSnapping_btn.setStateOn( GuiEditor.snapToEdges ); + GuiEditorCenterSnapping_btn.setStateOn( GuiEditor.snapToCenters ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorGui::onSleep( %this) +{ + // If we are editing a control, store its guide state. + + %content = GuiEditor.getContentControl(); + if( isObject( %content ) ) + GuiEditor.writeGuides( %content ); + + // Remove our menus. + + if( isObject( %this.menuGroup ) ) + for( %i = 0; %i < %this.menuGroup.getCount(); %i ++ ) + %this.menuGroup.getObject( %i ).removeFromMenuBar(); + + // Store our preferences. + + %this.writeSettings(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorGui::initSettings( %this ) +{ + EditorSettings.beginGroup( "GuiEditor", true ); + + EditorSettings.setDefaultValue( "lastPath", "" ); + EditorSettings.setDefaultValue( "previewResolution", "1024 768" ); + + EditorSettings.beginGroup( "EngineDevelopment" ); + EditorSettings.setDefaultValue( "toggleIntoEditor", 0 ); + EditorSettings.setDefaultValue( "showEditorProfiles", 0 ); + EditorSettings.setDefaultValue( "showEditorGuis", 0 ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Library" ); + EditorSettings.setDefaultValue( "viewType", "Categorized" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Snapping" ); + EditorSettings.setDefaultValue( "snapToControls", "1" ); + EditorSettings.setDefaultValue( "snapToGuides", "1" ); + EditorSettings.setDefaultValue( "snapToCanvas", "1" ); + EditorSettings.setDefaultValue( "snapToEdges", "1" ); + EditorSettings.setDefaultValue( "snapToCenters", "1" ); + EditorSettings.setDefaultValue( "sensitivity", "2" ); + EditorSettings.setDefaultValue( "snap2Grid", "0" ); + EditorSettings.setDefaultValue( "snap2GridSize", $GuiEditor::defaultGridSize ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Selection" ); + EditorSettings.setDefaultValue( "fullBox", "0" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Rendering" ); + EditorSettings.setDefaultValue( "drawBorderLines", "1" ); + EditorSettings.setDefaultValue( "drawGuides", "1" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Help" ); + EditorSettings.setDefaultValue( "documentationURL", "http://www.garagegames.com/products/torque-3d/documentation/user" ); //RDTODO: make this point to Gui Editor docs when available + + // Create a path to the local documentation. This is a bit of guesswork here. + // It assumes that the project is located in a folder of the SDK root directory + // (e.g. "Examples/" or "Demos/") and that from there the path to the game + // folder is "<project>/game". + EditorSettings.setDefaultValue("documentationLocal", "../../../Documentation/Official Documentation.html" ); + + EditorSettings.setDefaultValue("documentationReference", "../../../Documentation/Torque 3D - Script Manual.chm" ); + + EditorSettings.endGroup(); + + EditorSettings.endGroup(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorGui::readSettings( %this ) +{ + EditorSettings.read(); + + EditorSettings.beginGroup( "GuiEditor", true ); + + GuiEditor.lastPath = EditorSettings.value( "lastPath" ); + GuiEditor.previewResolution = EditorSettings.value( "previewResolution" ); + + EditorSettings.beginGroup( "EngineDevelopment" ); + GuiEditor.toggleIntoEditor = EditorSettings.value( "toggleIntoEditor" ); + GuiEditor.showEditorProfiles = EditorSettings.value( "showEditorProfiles" ); + GuiEditor.showEditorGuis = EditorSettings.value( "showEditorGuis" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Library" ); + GuiEditorToolbox.currentViewType = EditorSettings.value( "viewType" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Snapping" ); + GuiEditor.snapToGuides = EditorSettings.value( "snapToGuides" ); + GuiEditor.snapToControls = EditorSettings.value( "snapToControls" ); + GuiEditor.snapToCanvas = EditorSettings.value( "snapToCanvas" ); + GuiEditor.snapToEdges = EditorSettings.value( "snapToEdges" ); + GuiEditor.snapToCenters = EditorSettings.value( "snapToCenters" ); + GuiEditor.snapSensitivity = EditorSettings.value( "sensitivity" ); + GuiEditor.snap2Grid = EditorSettings.value( "snap2Grid" ); + GuiEditor.snap2GridSize = EditorSettings.value( "snap2GridSize" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Selection" ); + GuiEditor.fullBoxSelection = EditorSettings.value( "fullBox" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Rendering" ); + GuiEditor.drawBorderLines = EditorSettings.value( "drawBorderLines" ); + GuiEditor.drawGuides = EditorSettings.value( "drawGuides" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Help" ); + GuiEditor.documentationURL = EditorSettings.value( "documentationURL" ); + GuiEditor.documentationLocal = EditorSettings.value( "documentationLocal" ); + GuiEditor.documentationReference = EditorSettings.value( "documentationReference" ); + EditorSettings.endGroup(); + + EditorSettings.endGroup(); + + if( GuiEditor.snap2Grid ) + GuiEditor.setSnapToGrid( GuiEditor.snap2GridSize ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorGui::writeSettings( %this ) +{ + EditorSettings.beginGroup( "GuiEditor", true ); + + EditorSettings.setValue( "lastPath", GuiEditor.lastPath ); + EditorSettings.setValue( "previewResolution", GuiEditor.previewResolution ); + + EditorSettings.beginGroup( "EngineDevelopment" ); + EditorSettings.setValue( "toggleIntoEditor", GuiEditor.toggleIntoEditor ); + EditorSettings.setValue( "showEditorProfiles", GuiEditor.showEditorProfiles ); + EditorSettings.setValue( "showEditorGuis", GuiEditor.showEditorGuis ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Library" ); + EditorSettings.setValue( "viewType", GuiEditorToolbox.currentViewType ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Snapping" ); + EditorSettings.setValue( "snapToControls", GuiEditor.snapToControls ); + EditorSettings.setValue( "snapToGuides", GuiEditor.snapToGuides ); + EditorSettings.setValue( "snapToCanvas", GuiEditor.snapToCanvas ); + EditorSettings.setValue( "snapToEdges", GuiEditor.snapToEdges ); + EditorSettings.setValue( "snapToCenters", GuiEditor.snapToCenters ); + EditorSettings.setValue( "sensitivity", GuiEditor.snapSensitivity ); + EditorSettings.setValue( "snap2Grid", GuiEditor.snap2Grid ); + EditorSettings.setValue( "snap2GridSize", GuiEditor.snap2GridSize ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Selection" ); + EditorSettings.setValue( "fullBox", GuiEditor.fullBoxSelection ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Rendering" ); + EditorSettings.setValue( "drawBorderLines", GuiEditor.drawBorderLines ); + EditorSettings.setValue( "drawGuides", GuiEditor.drawGuides ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Help" ); + EditorSettings.setValue( "documentationURL", GuiEditor.documentationURL ); + EditorSettings.setValue( "documentationLocal", GuiEditor.documentationLocal ); + EditorSettings.setValue( "documentationReference", GuiEditor.documentationReference ); + EditorSettings.endGroup(); + + EditorSettings.endGroup(); + + EditorSettings.write(); +} diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs new file mode 100644 index 000000000..1305ae170 --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorCanvas.ed.cs @@ -0,0 +1,540 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +//============================================================================================= +// Event Handlers. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::onAdd( %this ) +{ + // %this.setWindowTitle("Torque Gui Editor"); + + %this.onCreateMenu(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::onRemove( %this ) +{ + if( isObject( GuiEditorGui.menuGroup ) ) + GuiEditorGui.delete(); + + // cleanup + %this.onDestroyMenu(); +} + +//--------------------------------------------------------------------------------------------- + +/// Create the Gui Editor menu bar. +function GuiEditCanvas::onCreateMenu(%this) +{ + if(isObject(%this.menuBar)) + return; + + //set up %cmdctrl variable so that it matches OS standards + if( $platform $= "macos" ) + { + %cmdCtrl = "cmd"; + %redoShortcut = "Cmd-Shift Z"; + } + else + { + %cmdCtrl = "Ctrl"; + %redoShort = "Ctrl Y"; + } + + // Menu bar + %this.menuBar = new MenuBar() + { + dynamicItemInsertPos = 3; + + new PopupMenu() + { + superClass = "MenuBuilder"; + barTitle = "File"; + internalName = "FileMenu"; + + item[0] = "New Gui..." TAB %cmdCtrl SPC "N" TAB %this @ ".create();"; + item[1] = "Open..." TAB %cmdCtrl SPC "O" TAB %this @ ".open();"; + item[2] = "Save" TAB %cmdCtrl SPC "S" TAB %this @ ".save( false, true );"; + item[3] = "Save As..." TAB %cmdCtrl @ "-Shift S" TAB %this @ ".save( false );"; + item[4] = "Save Selected As..." TAB %cmdCtrl @ "-Alt S" TAB %this @ ".save( true );"; + item[5] = "-"; + item[6] = "Revert Gui" TAB "" TAB %this @ ".revert();"; + item[7] = "Add Gui From File..." TAB "" TAB %this @ ".append();"; + item[8] = "-"; + item[9] = "Open Gui File in Torsion" TAB "" TAB %this @".openInTorsion();"; + item[10] = "-"; + item[11] = "Close Editor" TAB "F10" TAB %this @ ".quit();"; + item[12] = "Quit" TAB %cmdCtrl SPC "Q" TAB "quit();"; + }; + + new PopupMenu() + { + superClass = "MenuBuilder"; + barTitle = "Edit"; + internalName = "EditMenu"; + + item[0] = "Undo" TAB %cmdCtrl SPC "Z" TAB "GuiEditor.undo();"; + item[1] = "Redo" TAB %redoShortcut TAB "GuiEditor.redo();"; + item[2] = "-"; + item[3] = "Cut" TAB %cmdCtrl SPC "X" TAB "GuiEditor.saveSelection(); GuiEditor.deleteSelection();"; + item[4] = "Copy" TAB %cmdCtrl SPC "C" TAB "GuiEditor.saveSelection();"; + item[5] = "Paste" TAB %cmdCtrl SPC "V" TAB "GuiEditor.loadSelection();"; + item[6] = "-"; + item[7] = "Select All" TAB %cmdCtrl SPC "A" TAB "GuiEditor.selectAll();"; + item[8] = "Deselect All" TAB %cmdCtrl SPC "D" TAB "GuiEditor.clearSelection();"; + item[9] = "Select Parent(s)" TAB %cmdCtrl @ "-Alt Up" TAB "GuiEditor.selectParents();"; + item[10] = "Select Children" TAB %cmdCtrl @ "-Alt Down" TAB "GuiEditor.selectChildren();"; + item[11] = "Add Parent(s) to Selection" TAB %cmdCtrl @ "-Alt-Shift Up" TAB "GuiEditor.selectParents( true );"; + item[12] = "Add Children to Selection" TAB %cmdCtrl @ "-Alt-Shift Down" TAB "GuiEditor.selectChildren( true );"; + item[13] = "Select..." TAB "" TAB "GuiEditorSelectDlg.toggleVisibility();"; + item[14] = "-"; + item[15] = "Lock/Unlock Selection" TAB %cmdCtrl SPC "L" TAB "GuiEditor.toggleLockSelection();"; + item[16] = "Hide/Unhide Selection" TAB %cmdCtrl SPC "H" TAB "GuiEditor.toggleHideSelection();"; + item[17] = "-"; + item[18] = "Group Selection" TAB %cmdCtrl SPC "G" TAB "GuiEditor.groupSelected();"; + item[19] = "Ungroup Selection" TAB %cmdCtrl @ "-Shift G" TAB "GuiEditor.ungroupSelected();"; + item[20] = "-"; + item[21] = "Full Box Selection" TAB "" TAB "GuiEditor.toggleFullBoxSelection();"; + item[22] = "-"; + item[23] = "Grid Size" TAB %cmdCtrl SPC "," TAB "GuiEditor.showPrefsDialog();"; + }; + + new PopupMenu() + { + superClass = "MenuBuilder"; + barTitle = "Layout"; + internalName = "LayoutMenu"; + + item[0] = "Align Left" TAB %cmdCtrl SPC "Left" TAB "GuiEditor.Justify(0);"; + item[1] = "Center Horizontally" TAB "" TAB "GuiEditor.Justify(1);"; + item[2] = "Align Right" TAB %cmdCtrl SPC "Right" TAB "GuiEditor.Justify(2);"; + item[3] = "-"; + item[4] = "Align Top" TAB %cmdCtrl SPC "Up" TAB "GuiEditor.Justify(3);"; + item[5] = "Center Vertically" TAB "" TAB "GuiEditor.Justify(7);"; + item[6] = "Align Bottom" TAB %cmdCtrl SPC "Down" TAB "GuiEditor.Justify(4);"; + item[7] = "-"; + item[8] = "Space Vertically" TAB "" TAB "GuiEditor.Justify(5);"; + item[9] = "Space Horizontally" TAB "" TAB "GuiEditor.Justify(6);"; + item[10] = "-"; + item[11] = "Fit into Parent(s)" TAB "" TAB "GuiEditor.fitIntoParents();"; + item[12] = "Fit Width to Parent(s)" TAB "" TAB "GuiEditor.fitIntoParents( true, false );"; + item[13] = "Fit Height to Parent(s)" TAB "" TAB "GuiEditor.fitIntoParents( false, true );"; + item[14] = "-"; + item[15] = "Bring to Front" TAB "" TAB "GuiEditor.BringToFront();"; + item[16] = "Send to Back" TAB "" TAB "GuiEditor.PushToBack();"; + }; + + new PopupMenu() + { + superClass = "MenuBuilder"; + barTitle = "Move"; + internalName = "MoveMenu"; + + item[0] = "Nudge Left" TAB "Left" TAB "GuiEditor.moveSelection( -1, 0);"; + item[1] = "Nudge Right" TAB "Right" TAB "GuiEditor.moveSelection( 1, 0);"; + item[2] = "Nudge Up" TAB "Up" TAB "GuiEditor.moveSelection( 0, -1);"; + item[3] = "Nudge Down" TAB "Down" TAB "GuiEditor.moveSelection( 0, 1 );"; + item[4] = "-"; + item[5] = "Big Nudge Left" TAB "Shift Left" TAB "GuiEditor.moveSelection( - GuiEditor.snap2gridsize, 0 );"; + item[6] = "Big Nudge Right" TAB "Shift Right" TAB "GuiEditor.moveSelection( GuiEditor.snap2gridsize, 0 );"; + item[7] = "Big Nudge Up" TAB "Shift Up" TAB "GuiEditor.moveSelection( 0, - GuiEditor.snap2gridsize );"; + item[8] = "Big Nudge Down" TAB "Shift Down" TAB "GuiEditor.moveSelection( 0, GuiEditor.snap2gridsize );"; + }; + + new PopupMenu() + { + superClass = "MenuBuilder"; + barTitle = "Snap"; + internalName = "SnapMenu"; + + item[0] = "Snap Edges" TAB "Alt-Shift E" TAB "GuiEditor.toggleEdgeSnap();"; + item[1] = "Snap Centers" TAB "Alt-Shift C" TAB "GuiEditor.toggleCenterSnap();"; + item[2] = "-"; + item[3] = "Snap to Guides" TAB "Alt-Shift G" TAB "GuiEditor.toggleGuideSnap();"; + item[4] = "Snap to Controls" TAB "Alt-Shift T" TAB "GuiEditor.toggleControlSnap();"; + item[5] = "Snap to Canvas" TAB "" TAB "GuiEditor.toggleCanvasSnap();"; + item[6] = "Snap to Grid" TAB "" TAB "GuiEditor.toggleGridSnap();"; + item[7] = "-"; + item[8] = "Show Guides" TAB "" TAB "GuiEditor.toggleDrawGuides();"; + item[9] = "Clear Guides" TAB "" TAB "GuiEditor.clearGuides();"; + }; + + new PopupMenu() + { + superClass = "MenuBuilder"; + internalName = "HelpMenu"; + + barTitle = "Help"; + + item[0] = "Online Documentation..." TAB "Alt F1" TAB "gotoWebPage( GuiEditor.documentationURL );"; + item[1] = "Offline User Guid..." TAB "" TAB "gotoWebPage( GuiEditor.documentationLocal );"; + item[2] = "Offline Reference Guide..." TAB "" TAB "shellExecute( GuiEditor.documentationReference );"; + item[3] = "-"; + item[4] = "Torque 3D Public Forums..." TAB "" TAB "gotoWebPage( \"http://www.garagegames.com/community/forums/73\" );"; + item[5] = "Torque 3D Private Forums..." TAB "" TAB "gotoWebPage( \"http://www.garagegames.com/community/forums/63\" );"; + }; + }; + %this.menuBar.attachToCanvas( Canvas, 0 ); +} + +$GUI_EDITOR_MENU_EDGESNAP_INDEX = 0; +$GUI_EDITOR_MENU_CENTERSNAP_INDEX = 1; +$GUI_EDITOR_MENU_GUIDESNAP_INDEX = 3; +$GUI_EDITOR_MENU_CONTROLSNAP_INDEX = 4; +$GUI_EDITOR_MENU_CANVASSNAP_INDEX = 5; +$GUI_EDITOR_MENU_GRIDSNAP_INDEX = 6; +$GUI_EDITOR_MENU_DRAWGUIDES_INDEX = 8; +$GUI_EDITOR_MENU_FULLBOXSELECT_INDEX = 21; + +//--------------------------------------------------------------------------------------------- + +/// Called before onSleep when the canvas content is changed +function GuiEditCanvas::onDestroyMenu(%this) +{ + if( !isObject( %this.menuBar ) ) + return; + + // Destroy menus + while( %this.menuBar.getCount() != 0 ) + %this.menuBar.getObject( 0 ).delete(); + + %this.menuBar.removeFromCanvas(); + %this.menuBar.delete(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::onWindowClose(%this) +{ + %this.quit(); +} + +//============================================================================================= +// Menu Commands. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::create( %this ) +{ + GuiEditorNewGuiDialog.init( "NewGui", "GuiControl" ); + + Canvas.pushDialog( GuiEditorNewGuiDialog ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::load( %this, %filename ) +{ + %newRedefineBehavior = "replaceExisting"; + if( isDefined( "$GuiEditor::loadRedefineBehavior" ) ) + { + // This trick allows to choose different redefineBehaviors when loading + // GUIs. This is useful, for example, when loading GUIs that would lead to + // problems when loading with their correct names because script behavior + // would immediately attach. + // + // This allows to also edit the GUI editor's own GUI inside itself. + + %newRedefineBehavior = $GuiEditor::loadRedefineBehavior; + } + + // Allow stomping objects while exec'ing the GUI file as we want to + // pull the file's objects even if we have another version of the GUI + // already loaded. + + %oldRedefineBehavior = $Con::redefineBehavior; + $Con::redefineBehavior = %newRedefineBehavior; + + // Load up the gui. + exec( %fileName ); + + $Con::redefineBehavior = %oldRedefineBehavior; + + // The GUI file should have contained a GUIControl which should now be in the instant + // group. And, it should be the only thing in the group. + if( !isObject( %guiContent ) ) + { + MessageBox( getEngineName(), + "You have loaded a Gui file that was created before this version. It has been loaded but you must open it manually from the content list dropdown", + "Ok", "Information" ); + return 0; + } + + GuiEditor.openForEditing( %guiContent ); + + GuiEditorStatusBar.print( "Loaded '" @ %filename @ "'" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::openInTorsion( %this ) +{ + if( !GuiEditorContent.getCount() ) + return; + + %guiObject = GuiEditorContent.getObject( 0 ); + EditorOpenDeclarationInTorsion( %guiObject ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::open( %this ) +{ + %openFileName = GuiBuilder::getOpenName(); + if( %openFileName $= "" ) + return; + + // Make sure the file is valid. + if ((!isFile(%openFileName)) && (!isFile(%openFileName @ ".dso"))) + return; + + %this.load( %openFileName ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::save( %this, %selectedOnly, %noPrompt ) +{ + // Get the control we should save. + + if( %selectedOnly ) + { + %selected = GuiEditor.getSelection(); + if( !%selected.getCount() ) + return; + else if( %selected.getCount() > 1 ) + { + MessageBox( "Invalid selection", "Only a single control hierarchy can be saved to a file. Make sure you have selected only one control in the tree view." ); + return; + } + + %currentObject = %selected.getObject( 0 ); + } + else if( GuiEditorContent.getCount() > 0 ) + %currentObject = GuiEditorContent.getObject( 0 ); + else + return; + + // Store the current guide set on the control. + + GuiEditor.writeGuides( %currentObject ); + %currentObject.canSaveDynamicFields = true; // Make sure the guides get saved out. + + // Construct a base filename. + + if( %currentObject.getName() !$= "" ) + %name = %currentObject.getName() @ ".gui"; + else + %name = "Untitled.gui"; + + // Construct a path. + + if( %selectedOnly + && %currentObject != GuiEditorContent.getObject( 0 ) + && %currentObject.getFileName() $= GuiEditorContent.getObject( 0 ).getFileName() ) + { + // Selected child control that hasn't been yet saved to its own file. + + %currentFile = GuiEditor.LastPath @ "/" @ %name; + %currentFile = makeRelativePath( %currentFile, getMainDotCsDir() ); + } + else + { + %currentFile = %currentObject.getFileName(); + if( %currentFile $= "") + { + // No file name set on control. Force a prompt. + %noPrompt = false; + + if( GuiEditor.LastPath !$= "" ) + { + %currentFile = GuiEditor.LastPath @ "/" @ %name; + %currentFile = makeRelativePath( %currentFile, getMainDotCsDir() ); + } + else + %currentFile = expandFileName( %name ); + } + else + %currentFile = expandFileName( %currentFile ); + } + + // Get the filename. + + if( !%noPrompt ) + { + %filename = GuiBuilder::getSaveName( %currentFile ); + if( %filename $= "" ) + return; + } + else + %filename = %currentFile; + + // Save the Gui. + + if( isWriteableFileName( %filename ) ) + { + // + // Extract any existent TorqueScript before writing out to disk + // + %fileObject = new FileObject(); + %fileObject.openForRead( %filename ); + %skipLines = true; + %beforeObject = true; + // %var++ does not post-increment %var, in torquescript, it pre-increments it, + // because ++%var is illegal. + %lines = -1; + %beforeLines = -1; + %skipLines = false; + while( !%fileObject.isEOF() ) + { + %line = %fileObject.readLine(); + if( %line $= "//--- OBJECT WRITE BEGIN ---" ) + %skipLines = true; + else if( %line $= "//--- OBJECT WRITE END ---" ) + { + %skipLines = false; + %beforeObject = false; + } + else if( %skipLines == false ) + { + if(%beforeObject) + %beforeNewFileLines[ %beforeLines++ ] = %line; + else + %newFileLines[ %lines++ ] = %line; + } + } + %fileObject.close(); + %fileObject.delete(); + + %fo = new FileObject(); + %fo.openForWrite(%filename); + + // Write out the captured TorqueScript that was before the object before the object + for( %i = 0; %i <= %beforeLines; %i++) + %fo.writeLine( %beforeNewFileLines[ %i ] ); + + %fo.writeLine("//--- OBJECT WRITE BEGIN ---"); + %fo.writeObject(%currentObject, "%guiContent = "); + %fo.writeLine("//--- OBJECT WRITE END ---"); + + // Write out captured TorqueScript below Gui object + for( %i = 0; %i <= %lines; %i++ ) + %fo.writeLine( %newFileLines[ %i ] ); + + %fo.close(); + %fo.delete(); + + %currentObject.setFileName( makeRelativePath( %filename, getMainDotCsDir() ) ); + + GuiEditorStatusBar.print( "Saved file '" @ %currentObject.getFileName() @ "'" ); + } + else + MessageBox( "Error writing to file", "There was an error writing to file '" @ %currentFile @ "'. The file may be read-only.", "Ok", "Error" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::append( %this ) +{ + // Get filename. + + %openFileName = GuiBuilder::getOpenName(); + if( %openFileName $= "" + || ( !isFile( %openFileName ) + && !isFile( %openFileName @ ".dso" ) ) ) + return; + + // Exec file. + + %oldRedefineBehavior = $Con::redefineBehavior; + $Con::redefineBehavior = "renameNew"; + exec( %openFileName ); + $Con::redefineBehavior = %oldRedefineBehavior; + + // Find guiContent. + + if( !isObject( %guiContent ) ) + { + MessageBox( "Error loading GUI file", "The GUI content controls could not be found. This function can only be used with files saved by the GUI editor.", "Ok", "Error" ); + return; + } + + if( !GuiEditorContent.getCount() ) + GuiEditor.openForEditing( %guiContent ); + else + { + GuiEditor.getCurrentAddSet().add( %guiContent ); + GuiEditor.readGuides( %guiContent ); + GuiEditor.onAddNewCtrl( %guiContent ); + GuiEditor.onHierarchyChanged(); + } + + GuiEditorStatusBar.print( "Appended controls from '" @ %openFileName @ "'" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::revert( %this ) +{ + if( !GuiEditorContent.getCount() ) + return; + + %gui = GuiEditorContent.getObject( 0 ); + %filename = %gui.getFileName(); + if( %filename $= "" ) + return; + + if( MessageBox( "Revert Gui", "Really revert the current Gui? This cannot be undone.", "OkCancel", "Question" ) == $MROk ) + %this.load( %filename ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::close( %this ) +{ +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditCanvas::quit( %this ) +{ + %this.close(); + GuiGroup.add(GuiEditorGui); + // we must not delete a window while in its event handler, or we foul the event dispatch mechanism + %this.schedule(10, delete); + + Canvas.setContent(GuiEditor.lastContent); + $InGuiEditor = false; + + //Temp fix to disable MLAA when in GUI editor + if( isObject(MLAAFx) && $MLAAFxGuiEditorTemp==true ) + { + MLAAFx.isEnabled = true; + $MLAAFxGuiEditorTemp = false; + } +} diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorContentList.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorContentList.ed.cs new file mode 100644 index 000000000..8a946a2a2 --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorContentList.ed.cs @@ -0,0 +1,102 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Code for the drop-down that allows selecting a GUI to edit in the Gui Editor. + + +if( !isDefined( "$GuiEditor::GuiFilterList" ) ) +{ + /// List of named controls that are filtered out from the + /// control list dropdown. + $GuiEditor::GuiFilterList = + "GuiEditorGui" TAB + "AL_ShadowVizOverlayCtrl" TAB + "MessageBoxOKDlg" TAB + "MessageBoxOKCancelDlg" TAB + "MessageBoxOKCancelDetailsDlg" TAB + "MessageBoxYesNoDlg" TAB + "MessageBoxYesNoCancelDlg" TAB + "MessagePopupDlg"; +} + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorContentList::init( %this ) +{ + %this.clear(); + %this.scanGroup( GuiGroup ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorContentList::scanGroup( %this, %group ) +{ + foreach( %obj in %group ) + { + if( %obj.isMemberOfClass( "GuiControl" ) ) + { + if(%obj.getClassName() $= "GuiCanvas") + { + %this.scanGroup( %obj ); + } + else + { + if(%obj.getName() $= "") + %name = "(unnamed) - " @ %obj; + else + %name = %obj.getName() @ " - " @ %obj; + + %skip = false; + + foreach$( %guiEntry in $GuiEditor::GuiFilterList ) + if( %obj.getName() $= %guiEntry ) + { + %skip = true; + break; + } + + if( !%skip ) + %this.add( %name, %obj ); + } + } + else if( %obj.isMemberOfClass( "SimGroup" ) + && ( %obj.internalName !$= "EditorGuiGroup" // Don't put our editor's GUIs in the list + || GuiEditor.showEditorGuis ) ) // except if explicitly requested. + { + // Scan nested SimGroups for GuiControls. + + %this.scanGroup( %obj ); + } + } +} + +//============================================================================================= +// Event Handlers. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorContentList::onSelect( %this, %ctrl ) +{ + GuiEditor.openForEditing( %ctrl ); +} diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorGroup.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorGroup.ed.cs new file mode 100644 index 000000000..558aa7763 --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorGroup.ed.cs @@ -0,0 +1,149 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +// GuiEditorGroups are recorded only for undo/redo. They are ScriptObjects +// containing all the information about a particular GUIControl group. +// +// The properties of GuiEditorGroups are: +// +// int count - Number of controls in group. +// object ctrl[ 0 .. count ] - Controls in group. +// object ctrlParent[ 0 .. count ] - Original parent of each control in group (if missing, controls are moved to parent of group object in ungroup()) +// object groupObject - The GuiControl group object. +// object groupParent - The object to which the group should be parented to. + + +/// Return the combined global bounds of the controls contained in the GuiEditorGroup. +function GuiEditorGroup::getGlobalBounds( %this ) +{ + %minX = 2147483647; + %minY = 2147483647; + %maxX = -2147483647; + %maxY = -2147483647; + + for( %i = 0; %i < %this.count; %i ++ ) + { + %ctrl = %this.ctrl[ %i ]; + + %pos = %ctrl.getGlobalPosition(); + %extent = %ctrl.getExtent(); + + // Min. + + %posX = getWord( %pos, 0 ); + %posY = getWord( %pos, 1 ); + + if( %posX < %minX ) + %minX = %posX; + if( %posY < %minY ) + %minY = %posY; + + // Max. + + %posX += getWord( %extent, 0 ); + %posY += getWord( %extent, 1 ); + + if( %posX > %maxX ) + %maxX = %posX; + if( %posY > %maxY ) + %maxY = %posY; + } + + return ( %minX SPC %minY SPC ( %maxX - %minX ) SPC ( %maxY - %minY ) ); +} + +/// Create a new GuiControl and move all the controls contained in the GuiEditorGroup into it. +function GuiEditorGroup::group( %this ) +{ + %parent = %this.groupParent; + + // Create group. + + %group = new GuiControl(); + %parent.addGuiControl( %group ); + %this.groupObject = %group; + + // Make group fit around selection. + + %bounds = %this.getGlobalBounds(); + %parentGlobalPos = %parent.getGlobalPosition(); + + %x = getWord( %bounds, 0 ) - getWord( %parentGlobalPos, 0 ); + %y = getWord( %bounds, 1 ) - getWord( %parentGlobalPos, 1 ); + + %group.setPosition( %x, %y ); + %group.setExtent( getWord( %bounds, 2 ), getWord( %bounds, 3 ) ); + + // Reparent all objects to group. + + for( %i = 0; %i < %this.count; %i ++ ) + { + %ctrl = %this.ctrl[ %i ]; + + // Save parent for undo. + + %this.ctrlParent[ %i ] = %ctrl.parentGroup; + + // Reparent. + + %group.addGuiControl( %ctrl ); + + // Move into place in new parent. + + %pos = %ctrl.getPosition(); + %ctrl.setPosition( getWord( %pos, 0 ) - %x, getWord( %pos, 1 ) - %y ); + } +} + +/// Move all controls out of group to either former parent or group parent. +function GuiEditorGroup::ungroup( %this ) +{ + %defaultParent = %this.groupParent; + %groupPos = %this.groupObject.getPosition(); + + %x = getWord( %groupPos, 0 ); + %y = getWord( %groupPos, 1 ); + + // Move each control to its former parent (or default parent when + // there is no former parent). + + for( %i = 0; %i < %this.count; %i ++ ) + { + %ctrl = %this.ctrl[ %i ]; + + %parent = %defaultParent; + if( isObject( %this.ctrlParent[ %i ] ) ) + %parent = %this.ctrlParent[ %i ]; + + %parent.addGuiControl( %ctrl ); + + // Move into place in new parent. + + %ctrlPos = %ctrl.getPosition(); + %ctrl.setPosition( getWord( %ctrlPos, 0 ) + %x, getWord( %ctrlPos, 1 ) + %y ); + } + + // Delete old group object. + + %this.groupObject.delete(); +} diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorInspector.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorInspector.ed.cs new file mode 100644 index 000000000..fafc0a7c2 --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorInspector.ed.cs @@ -0,0 +1,172 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Core for the main Gui Editor inspector that shows the properties of +// the currently selected control. + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::update( %this, %inspectTarget ) +{ + %this.inspect( %inspectTarget ); +} + +//============================================================================================= +// Event Handlers. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + // The instant group will try to add our + // UndoAction if we don't disable it. + pushInstantGroup(); + + %nameOrClass = %object.getName(); + if ( %nameOrClass $= "" ) + %nameOrClass = %object.getClassname(); + + %action = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ %fieldName @ " Change"; + + objectId = %object.getId(); + fieldName = %fieldName; + fieldValue = %oldValue; + arrayIndex = %arrayIndex; + + inspectorGui = %this; + }; + + // Restore the instant group. + popInstantGroup(); + + %action.addToManager( GuiEditor.getUndoManager() ); + + GuiEditor.updateUndoMenu(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::onInspectorPreFieldModification( %this, %fieldName, %arrayIndex ) +{ + pushInstantGroup(); + %undoManager = GuiEditor.getUndoManager(); + + %numObjects = %this.getNumInspectObjects(); + if( %numObjects > 1 ) + %action = %undoManager.pushCompound( "Multiple Field Edit" ); + + for( %i = 0; %i < %numObjects; %i ++ ) + { + %object = %this.getInspectObject( %i ); + + %nameOrClass = %object.getName(); + if( %nameOrClass $= "" ) + %nameOrClass = %object.getClassname(); + + %undo = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ %fieldName @ " Change"; + + objectId = %object.getId(); + fieldName = %fieldName; + fieldValue = %object.getFieldValue( %fieldName, %arrayIndex ); + arrayIndex = %arrayIndex; + + inspectorGui = %this; + }; + + if( %numObjects > 1 ) + %undo.addToManager( %undoManager ); + else + { + %action = %undo; + break; + } + } + + %this.currentFieldEditAction = %action; + popInstantGroup(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::onInspectorPostFieldModification( %this ) +{ + if( %this.currentFieldEditAction.isMemberOfClass( "CompoundUndoAction" ) ) + { + // Finish multiple field edit. + GuiEditor.getUndoManager().popCompound(); + } + else + { + // Queue single field undo. + %this.currentFieldEditAction.addToManager( GuiEditor.getUndoManager() ); + } + + %this.currentFieldEditAction = ""; + GuiEditor.updateUndoMenu(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::onInspectorDiscardFieldModification( %this ) +{ + %this.currentFieldEditAction.undo(); + + if( %this.currentFieldEditAction.isMemberOfClass( "CompoundUndoAction" ) ) + { + // Multiple field editor. Pop and discard. + GuiEditor.getUndoManager().popCompound( true ); + } + else + { + // Single field edit. Just kill undo action. + %this.currentFieldEditAction.delete(); + } + + %this.currentFieldEditAction = ""; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + GuiEditorFieldInfo.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::onBeginCompoundEdit( %this ) +{ + GuiEditor.getUndoManager().pushCompound( "Multiple Field Edits" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorInspectFields::onEndCompoundEdit( %this ) +{ + GuiEditor.getUndoManager().popCompound(); +} diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorNewGuiDialog.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorNewGuiDialog.ed.cs new file mode 100644 index 000000000..248c0e97d --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorNewGuiDialog.ed.cs @@ -0,0 +1,107 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Dialog for creating new GUIs. Allows to enter an object name and +// select a GuiControl class to use for the toplevel object. + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorNewGuiDialog::init( %this, %guiName, %guiClass ) +{ + %this-->nameField.setValue( %guiName ); + + // Initialize the class dropdown if we haven't already. + + %classDropdown = %this-->classDropdown; + if( !%classDropdown.size() ) + { + %classes = enumerateConsoleClassesByCategory( "Gui" ); + %count = getFieldCount( %classes ); + + for( %i = 0; %i < %count; %i ++ ) + { + %className = getField( %classes, %i ); + if( GuiEditor.isFilteredClass( %className ) + || !isMemberOfClass( %className, "GuiControl" ) ) + continue; + + %classDropdown.add( %className, 0 ); + } + + %classDropdown.sort(); + } + + %classDropdown.setText( "GuiControl" ); +} + +//============================================================================================= +// Event Handlers. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorNewGuiDialog::onWake( %this ) +{ + // Center the dialog. + + %root = %this.getRoot(); + %this.setPosition( %root.extent.x / 2 - %this.extent.x / 2, %root.extent.y / 2 - %this.extent.y / 2 ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorNewGuiDialog::onOK( %this ) +{ + %name = %this-->nameField.getValue(); + %class = %this-->classDropdown.getText(); + + // Make sure we don't clash with an existing object. + // If there's an existing GUIControl with the name, ask to replace. + // If there's an existing non-GUIControl with the name, or the name is invalid, refuse to create. + + if( isObject( %name ) && %name.isMemberOfClass( "GuiControl" ) ) + { + if( MessageBox( "Warning", "Replace the existing control '" @ %name @ "'?", "OkCancel", "Question" ) == $MROk ) + %name.delete(); + else + return; + } + + if( Editor::validateObjectName( %name, false ) ) + { + %this.getRoot().popDialog( %this ); + %obj = eval("return new " @ %class @ "(" @ %name @ ");"); + + // Make sure we have no association with a filename. + %obj.setFileName( "" ); + + GuiEditContent(%obj); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorNewGuiDialog::onCancel( %this ) +{ + %this.getRoot().popDialog( %this ); +} diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorPrefsDlg.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorPrefsDlg.ed.cs new file mode 100644 index 000000000..c4713fc4e --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorPrefsDlg.ed.cs @@ -0,0 +1,85 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +$GuiEditor::defaultGridSize = 8; +$GuiEditor::minGridSize = 3; + +//----------------------------------------------------------------------------------------- +// Buttons +//----------------------------------------------------------------------------------------- + +function GuiEditorPrefsDlgOkBtn::onAction(%this) +{ + GuiEditor.snap2gridsize = GuiEditorPrefsDlgGridEdit.getValue(); + if( GuiEditor.snap2grid ) + GuiEditor.setSnapToGrid( GuiEditor.snap2gridsize ); + + Canvas.popDialog( GuiEditorPrefsDlg ); +} + +function GuiEditorPrefsDlgCancelBtn::onAction(%this) +{ + Canvas.popDialog( GuiEditorPrefsDlg ); +} + +function GuiEditorPrefsDlgDefaultsBtn::onAction(%this) +{ + GuiEditorPrefsDlgGridSlider.setValue( $GuiEditor::defaultGridSize ); +} + +//----------------------------------------------------------------------------------------- +// Grid +//----------------------------------------------------------------------------------------- + +function GuiEditorPrefsDlgGridEdit::onWake(%this) +{ + %this.setValue( GuiEditor.snap2gridsize ); +} + +function GuiEditorPrefsDlgGridEdit::onAction( %this ) +{ + %value = %this.getValue(); + if( %value < $GuiEditor::minGridSize ) + { + %value = $GuiEditor::minGridSize; + %this.setValue( %value ); + } + + GuiEditorPrefsDlgGridSlider.setValue( %value ); +} + +function GuiEditorPrefsDlgGridSlider::onWake(%this) +{ + %this.setValue( GuiEditor.snap2gridsize ); +} + +function GuiEditorPrefsDlgGridSlider::onAction(%this) +{ + %value = %this.value; + if( %value < $GuiEditor::minGridSize ) + { + %value = $GuiEditor::minGridSize; + %this.setValue( %value ); + } + + GuiEditorPrefsDlgGridEdit.setvalue( mCeil( %value ) ); +} diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorProfiles.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorProfiles.ed.cs new file mode 100644 index 000000000..997512b37 --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorProfiles.ed.cs @@ -0,0 +1,623 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +$GUI_EDITOR_DEFAULT_PROFILE_FILENAME = "art/gui/customProfiles.cs"; +$GUI_EDITOR_DEFAULT_PROFILE_CATEGORY = "Other"; + + + +//============================================================================================= +// GuiEditor. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::createNewProfile( %this, %name, %copySource ) +{ + if( %name $= "" ) + return; + + // Make sure the object name is unique. + + if( isObject( %name ) ) + %name = getUniqueName( %name ); + + // Create the profile. + + if( %copySource !$= "" ) + eval( "new GuiControlProfile( " @ %name @ " : " @ %copySource.getName() @ " );" ); + else + eval( "new GuiControlProfile( " @ %name @ " );" ); + + // Add the item and select it. + + %category = %this.getProfileCategory( %name ); + %group = GuiEditorProfilesTree.findChildItemByName( 0, %category ); + + %id = GuiEditorProfilesTree.insertItem( %group, %name @ " (" @ %name.getId() @ ")", %name.getId(), "" ); + + GuiEditorProfilesTree.sort( 0, true, true, false ); + GuiEditorProfilesTree.clearSelection(); + GuiEditorProfilesTree.selectItem( %id ); + + // Mark it as needing to be saved. + + %this.setProfileDirty( %name, true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::getProfileCategory( %this, %profile ) +{ + if( %this.isDefaultProfile( %name ) ) + return "Default"; + else if( %profile.category !$= "" ) + return %profile.category; + else + return $GUI_EDITOR_DEFAULT_PROFILE_CATEGORY; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::showDeleteProfileDialog( %this, %profile ) +{ + if( %profile $= "" ) + return; + + if( %profile.isInUse() ) + { + MessageBoxOk( "Error", + "The profile '" @ %profile.getName() @ "' is still used by Gui controls." + ); + return; + } + + MessageBoxYesNo( "Delete Profile?", + "Do you really want to delete '" @ %profile.getName() @ "'?", + "GuiEditor.deleteProfile( " @ %profile @ " );" + ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::deleteProfile( %this, %profile ) +{ + if( isObject( "GuiEditorProfilesPM" ) ) + new PersistenceManager( GuiEditorProfilesPM ); + + // Clear dirty state. + + %this.setProfileDirty( %profile, false ); + + // Remove from tree. + + %id = GuiEditorProfilesTree.findItemByValue( %profile.getId() ); + GuiEditorProfilesTree.removeItem( %id ); + + // Remove from file. + + GuiEditorProfilesPM.removeObjectFromFile( %profile ); + + // Delete profile object. + + %profile.delete(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::showSaveProfileDialog( %this, %currentFileName ) +{ + getSaveFileName( "TorqueScript Files|*.cs", %this @ ".doSaveProfile", %currentFileName ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::doSaveProfile( %this, %fileName ) +{ + %path = makeRelativePath( %fileName, getMainDotCsDir() ); + + GuiEditorProfileFileName.setText( %path ); + %this.saveProfile( GuiEditorProfilesTree.getSelectedProfile(), %path ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::saveProfile( %this, %profile, %fileName ) +{ + if( !isObject( "GuiEditorProfilesPM" ) ) + new PersistenceManager( GuiEditorProfilesPM ); + + if( !GuiEditorProfilesPM.isDirty( %profile ) + && ( %fileName $= "" || %fileName $= %profile.getFileName() ) ) + return; + + // Update the filename, if requested. + + if( %fileName !$= "" ) + { + %profile.setFileName( %fileName ); + GuiEditorProfilesPM.setDirty( %profile, %fileName ); + } + + // Save the object. + + GuiEditorProfilesPM.saveDirtyObject( %profile ); + + // Clear its dirty state. + + %this.setProfileDirty( %profile, false, true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::revertProfile( %this, %profile ) +{ + // Revert changes. + + GuiEditorProfileChangeManager.revertEdits( %profile ); + + // Clear its dirty state. + + %this.setProfileDirty( %profile, false ); + + // Refresh inspector. + + if( GuiEditorProfileInspector.getInspectObject() == %profile ) + GuiEditorProfileInspector.refresh(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::isProfileDirty( %this, %profile ) +{ + if( !isObject( "GuiEditorProfilesPM" ) ) + return false; + + return GuiEditorProfilesPM.isDirty( %profile ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::setProfileDirty( %this, %profile, %value, %noCheck ) +{ + if( !isObject( "GuiEditorProfilesPM" ) ) + new PersistenceManager( GuiEditorProfilesPM ); + + if( %value ) + { + if( !GuiEditorProfilesPM.isDirty( %profile ) || %noCheck ) + { + // If the profile hasn't yet been associated with a file, + // put it in the default file. + + if( %profile.getFileName() $= "" ) + %profile.setFileName( $GUI_EDITOR_DEFAULT_PROFILE_FILENAME ); + + // Add the profile to the dirty set. + + GuiEditorProfilesPM.setDirty( %profile ); + + // Show the item as dirty in the tree. + + %id = GuiEditorProfilesTree.findItemByValue( %profile.getId() ); + GuiEditorProfilesTree.editItem( %id, GuiEditorProfilesTree.getItemText( %id ) SPC "*", %profile.getId() ); + + // Count the number of unsaved profiles. If this is + // the first one, indicate in the window title that + // we have unsaved profiles. + + %this.increaseNumDirtyProfiles(); + } + } + else + { + if( GuiEditorProfilesPM.isDirty( %profile ) || %noCheck ) + { + // Remove from dirty list. + + GuiEditorProfilesPM.removeDirty( %profile ); + + // Clear the dirty marker in the tree. + + %id = GuiEditorProfilesTree.findItemByValue( %profile.getId() ); + %text = GuiEditorProfilesTree.getItemText( %id ); + GuiEditorProfilesTree.editItem( %id, getSubStr( %text, 0, strlen( %text ) - 2 ), %profile.getId() ); + + // Count saved profiles. If this was the last unsaved profile, + // remove the unsaved changes indicator from the window title. + + %this.decreaseNumDirtyProfiles(); + + // Remove saved edits from the change manager. + + GuiEditorProfileChangeManager.clearEdits( %profile ); + } + } +} + +//--------------------------------------------------------------------------------------------- + +/// Return true if the given profile name is the default profile for a +/// GuiControl class or if it's the GuiDefaultProfile. +function GuiEditor::isDefaultProfile( %this, %name ) +{ + if( %name $= "GuiDefaultProfile" ) + return true; + + if( !endsWith( %name, "Profile" ) ) + return false; + + %className = getSubStr( %name, 0, strlen( %name ) - 7 ) @ "Ctrl"; + if( !isClass( %className ) ) + return false; + + return true; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::increaseNumDirtyProfiles( %this ) +{ + %this.numDirtyProfiles ++; + if( %this.numDirtyProfiles == 1 ) + { + %tab = GuiEditorTabBook-->profilesPage; + %tab.setText( %tab.text @ " *" ); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditor::decreaseNumDirtyProfiles( %this ) +{ + %this.numDirtyProfiles --; + if( !%this.numDirtyProfiles ) + { + %tab = GuiEditorTabBook-->profilesPage; + %title = %tab.text; + %title = getSubstr( %title, 0, strlen( %title ) - 2 ); + + %tab.setText( %title ); + } +} + +//============================================================================================= +// GuiEditorProfilesTree. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfilesTree::init( %this ) +{ + %this.clear(); + + %defaultGroup = %this.insertItem( 0, "Default", -1 ); + %otherGroup = %this.insertItem( 0, $GUI_EDITOR_DEFAULT_PROFILE_CATEGORY, -1 ); + + foreach( %obj in GuiDataGroup ) + { + if( !%obj.isMemberOfClass( "GuiControlProfile" ) ) + continue; + + // If it's an Editor profile, skip if showing them is not enabled. + + if( %obj.category $= "Editor" && !GuiEditor.showEditorProfiles ) + continue; + + // Create a visible name. + + %name = %obj.getName(); + if( %name $= "" ) + %name = "<Unnamed>"; + %text = %name @ " (" @ %obj.getId() @ ")"; + + // Find which group to put the control in. + + %isDefaultProfile = GuiEditor.isDefaultProfile( %name ); + if( %isDefaultProfile ) + %group = %defaultGroup; + else if( %obj.category !$= "" ) + { + %group = %this.findChildItemByName( 0, %obj.category ); + if( !%group ) + %group = %this.insertItem( 0, %obj.category ); + } + else + %group = %otherGroup; + + // Insert the item. + + %this.insertItem( %group, %text, %obj.getId(), "" ); + } + + %this.sort( 0, true, true, false ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfilesTree::onSelect( %this, %id ) +{ + %obj = %this.getItemValue( %id ); + if( %obj == -1 ) + return; + + GuiEditorProfileInspector.inspect( %obj ); + + %fileName = %obj.getFileName(); + if( %fileName $= "" ) + %fileName = $GUI_EDITOR_DEFAULT_PROFILE_FILENAME; + + GuiEditorProfileFileName.setText( %fileName ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfilesTree::onUnselect( %this, %id ) +{ + GuiEditorProfileInspector.inspect( 0 ); + GuiEditorProfileFileName.setText( "" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfilesTree::onProfileRenamed( %this, %profile, %newName ) +{ + %item = %this.findItemByValue( %profile.getId() ); + if( %item == -1 ) + return; + + %newText = %newName @ " (" @ %profile.getId() @ ")"; + if( GuiEditor.isProfileDirty( %profile ) ) + %newText = %newText @ " *"; + + %this.editItem( %item, %newText, %profile.getId() ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfilesTree::getSelectedProfile( %this ) +{ + return %this.getItemValue( %this.getSelectedItem() ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfilesTree::setSelectedProfile( %this, %profile ) +{ + %id = %this.findItemByValue( %profile.getId() ); + %this.selectItem( %id ); +} + +//============================================================================================= +// GuiEditorProfileInspector. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + GuiEditorProfileFieldInfo.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onFieldAdded( %this, %object, %fieldName ) +{ + GuiEditor.setProfileDirty( %object, true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onFieldRemoved( %this, %object, %fieldName ) +{ + GuiEditor.setProfileDirty( %object, true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onFieldRenamed( %this, %object, %oldFieldName, %newFieldName ) +{ + GuiEditor.setProfileDirty( %object, true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + GuiEditor.setProfileDirty( %object, true ); + + // If it's the name field, make sure to sync up the treeview. + + if( %fieldName $= "name" ) + GuiEditorProfilesTree.onProfileRenamed( %object, %newValue ); + + // Add change record. + + GuiEditorProfileChangeManager.registerEdit( %object, %fieldName, %arrayIndex, %oldValue ); + + // Add undo. + + pushInstantGroup(); + + %nameOrClass = %object.getName(); + if ( %nameOrClass $= "" ) + %nameOrClass = %object.getClassname(); + + %action = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ %fieldName @ " Change"; + + objectId = %object.getId(); + fieldName = %fieldName; + fieldValue = %oldValue; + arrayIndex = %arrayIndex; + + inspectorGui = %this; + }; + + popInstantGroup(); + %action.addToManager( GuiEditor.getUndoManager() ); + GuiEditor.updateUndoMenu(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onInspectorPreFieldModification( %this, %fieldName, %arrayIndex ) +{ + pushInstantGroup(); + %undoManager = GuiEditor.getUndoManager(); + + %object = %this.getInspectObject(); + + %nameOrClass = %object.getName(); + if( %nameOrClass $= "" ) + %nameOrClass = %object.getClassname(); + + %action = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ %fieldName @ " Change"; + + objectId = %object.getId(); + fieldName = %fieldName; + fieldValue = %object.getFieldValue( %fieldName, %arrayIndex ); + arrayIndex = %arrayIndex; + + inspectorGui = %this; + }; + + %this.currentFieldEditAction = %action; + popInstantGroup(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onInspectorPostFieldModification( %this ) +{ + %action = %this.currentFieldEditAction; + %object = %action.objectId; + %fieldName = %action.fieldName; + %arrayIndex = %action.arrayIndex; + %oldValue = %action.fieldValue; + %newValue = %object.getFieldValue( %fieldName, %arrayIndex ); + + // If it's the name field, make sure to sync up the treeview. + + if( %action.fieldName $= "name" ) + GuiEditorProfilesTree.onProfileRenamed( %object, %newValue ); + + // Add change record. + + GuiEditorProfileChangeManager.registerEdit( %object, %fieldName, %arrayIndex, %oldValue ); + + %this.currentFieldEditAction.addToManager( GuiEditor.getUndoManager() ); + %this.currentFieldEditAction = ""; + + GuiEditor.updateUndoMenu(); + GuiEditor.setProfileDirty( %object, true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileInspector::onInspectorDiscardFieldModification( %this ) +{ + %this.currentFieldEditAction.undo(); + %this.currentFieldEditAction.delete(); + %this.currentFieldEditAction = ""; +} + +//============================================================================================= +// GuiEditorProfileChangeManager. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileChangeManager::registerEdit( %this, %profile, %fieldName, %arrayIndex, %oldValue ) +{ + // Early-out if we already have a registered edit on the same field. + + foreach( %obj in %this ) + { + if( %obj.profile != %profile ) + continue; + + if( %obj.fieldName $= %fieldName + && %obj.arrayIndex $= %arrayIndex ) + return; + } + + // Create a new change record. + + new ScriptObject() + { + parentGroup = %this; + profile = %profile; + fieldName = %fieldName; + arrayIndex = %arrayIndex; + oldValue = %oldValue; + }; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileChangeManager::clearEdits( %this, %profile ) +{ + for( %i = 0; %i < %this.getCount(); %i ++ ) + { + %obj = %this.getObject( %i ); + if( %obj.profile != %profile ) + continue; + + %obj.delete(); + %i --; + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileChangeManager::revertEdits( %this, %profile ) +{ + for( %i = 0; %i < %this.getCount(); %i ++ ) + { + %obj = %this.getObject( %i ); + if( %obj.profile != %profile ) + continue; + + %profile.setFieldValue( %obj.fieldName, %obj.oldValue, %obj.arrayIndex ); + + %obj.delete(); + %i --; + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorProfileChangeManager::getEdits( %this, %profile ) +{ + %set = new SimSet(); + + foreach( %obj in %this ) + if( %obj.profile == %profile ) + %set.add( %obj ); + + return %set; +} diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorSelectDlg.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorSelectDlg.ed.cs new file mode 100644 index 000000000..795cef4d3 --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorSelectDlg.ed.cs @@ -0,0 +1,87 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSelectDlg::toggleVisibility( %this ) +{ + if( %this.isVisible() ) + %this.setVisible( false ); + else + %this.setVisible( true ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSelectDlg::getRootGroup( %this ) +{ + return GuiEditor.getContentControl(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSelectDlg::includeClass( %this, %className ) +{ + return ( isMemberOfClass( %className, "GuiControl" ) + && !GuiEditor.isFilteredClass( %className ) ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSelectDlg::selectObject( %this, %object, %val ) +{ + if( %val ) + GuiEditor.addSelection( %object ); + else + GuiEditor.removeSelection( %object ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSelectDlg::clearSelection( %this ) +{ + GuiEditor.clearSelection(); +} + +//============================================================================================= +// Events. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorSelectDlg::onVisible( %this, %visible ) +{ + if( !%visible ) + return; + + if( !%this.isInitialized ) + { + %this.init(); + %this.isInitialized = true; + } + + // Re-initialize the group list on each wake. + + %this.initGroupList(); +} diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorStatusBar.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorStatusBar.ed.cs new file mode 100644 index 000000000..5c8df8f5a --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorStatusBar.ed.cs @@ -0,0 +1,90 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Code for the status bar in the Gui Editor. + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorStatusBar::getMouseModeHelp( %this ) +{ + %isMac = ( $platform $= "macos" ); + if( %isMac ) + %cmdCtrl = "CMD"; + else + %cmdCtrl = "CTRL"; + + %mouseMode = GuiEditor.getMouseMode(); + switch$( %mouseMode ) + { + case "Selecting": + return ""; + + case "DragSelecting": + return %cmdCtrl @ " to add to selection; ALT to exclude parents; CTRL+ALT to exclude children"; + + case "MovingSelection": + return ""; + + case "SizingSelection": + return "CTRL to activate snapping; ALT to move instead of resize"; + + case "DragGuide": + return "Drag into ruler to delete; drop to place"; + } + + return ""; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorStatusBar::print( %this, %message ) +{ + %this.setText( %message ); + + %sequenceNum = %this.sequenceNum + 1; + %this.sequenceNum = %sequenceNum; + + %this.schedule( 4 * 1000, "clearMessage", %sequenceNum ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorStatusBar::clearMessage( %this, %sequenceNum ) +{ + // If we had no newer message in the meantime, clear + // out the current text. + + if( %this.sequenceNum == %sequenceNum ) + %this.setText( %this.getMouseModeHelp() ); +} + +//============================================================================================= +// Event Handlers. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorStatusBar::onWake( %this ) +{ + %this.setText( %this.getMouseModeHelp() ); +} diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorToolbox.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorToolbox.ed.cs new file mode 100644 index 000000000..f8a67f2a9 --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorToolbox.ed.cs @@ -0,0 +1,394 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Code for the toolbox tab of the Gui Editor sidebar. + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::initialize( %this ) +{ + // Set up contents. + + %viewType = %this.currentViewType; + if( %viewType $= "" ) + %viewType = "Categorized"; + + %this.currentViewType = ""; + %this.setViewType( %viewType ); + + %this.isInitialized = true; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::getViewType( %this ) +{ + return %this.currentViewType; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::setViewType( %this, %viewType ) +{ + if( %this.currentViewType $= %viewType + || !%this.isMethod( "setViewType" @ %viewType ) ) + return; + + %this.clear(); + eval( %this @ ".setViewType" @ %viewType @ "();" ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::setViewTypeAlphabetical( %this ) +{ + %controls = enumerateConsoleClassesByCategory( "Gui" ); + %classes = new ArrayObject(); + + // Collect relevant classes. + + foreach$( %className in %controls ) + { + if( GuiEditor.isFilteredClass( %className ) + || !isMemberOfClass( %className, "GuiControl" ) ) + continue; + + %classes.push_back( %className ); + } + + // Sort classes alphabetically. + + %classes.sortk( true ); + + // Add toolbox buttons. + + %numClasses = %classes.count(); + for( %i = 0; %i < %numClasses; %i ++ ) + { + %className = %classes.getKey( %i ); + %ctrl = new GuiIconButtonCtrl() + { + profile = "ToolsGuiIconButtonSmallProfile"; + extent = "128 18"; + text = %className; + iconBitmap = EditorIconRegistry::findIconByClassName( %className ); + buttonMargin = "2 2"; + iconLocation = "left"; + textLocation = "left"; + textMargin = "24"; + AutoSize = true; + + command = "GuiEditor.createControl( " @ %className @ " );"; + useMouseEvents = true; + className = "GuiEditorToolboxButton"; + tooltip = %className NL "\n" @ getDescriptionOfClass( %className ); + tooltipProfile = "ToolsGuiToolTipProfile"; + }; + + %this.add( %ctrl ); + } + + %classes.delete(); + %this.currentViewType = "Alphabetical"; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::setViewTypeCategorized( %this ) +{ + // Create rollouts for each class category we have and + // record the classes in each category in a temporary array + // on the rollout so we can later sort the class names before + // creating the actual controls in the toolbox. + + %controls = enumerateConsoleClassesByCategory( "Gui" ); + foreach$( %className in %controls ) + { + if( GuiEditor.isFilteredClass( %className ) + || !isMemberOfClass( %className, "GuiControl" ) ) + continue; + + // Get the class's next category under Gui. + + %category = getWord( getCategoryOfClass( %className ), 1 ); + if( %category $= "" ) + continue; + + // Find or create the rollout for the category. + + %rollout = %this.getOrCreateRolloutForCategory( %category ); + + // Insert the item. + + if( !%rollout.classes ) + %rollout.classes = new ArrayObject(); + + %rollout.classes.push_back( %className ); + } + + // Go through the rollouts, sort the class names, and + // create the toolbox controls. + + foreach( %rollout in %this ) + { + if( !%rollout.isMemberOfClass( "GuiRolloutCtrl" ) ) + continue; + + // Get the array with the class names and sort it. + // Sort in descending order to counter reversal of order + // when we later add the controls to the stack. + + %classes = %rollout.classes; + %classes.sortk( true ); + + // Add a control for each of the classes to the + // rollout's stack control. + + %stack = %rollout-->array; + %numClasses = %classes.count(); + for( %n = 0; %n < %numClasses; %n ++ ) + { + %className = %classes.getKey( %n ); + %ctrl = new GuiIconButtonCtrl() + { + profile = "ToolsGuiIconButtonSmallProfile"; + extent = "128 18"; + text = %className; + iconBitmap = EditorIconRegistry::findIconByClassName( %className ); + buttonMargin = "2 2"; + iconLocation = "left"; + textLocation = "left"; + textMargin = "24"; + AutoSize = true; + + command = "GuiEditor.createControl( " @ %className @ " );"; + useMouseEvents = true; + className = "GuiEditorToolboxButton"; + tooltip = %className NL "\n" @ getDescriptionOfClass( %className ); + tooltipProfile = "ToolsGuiToolTipProfile"; + }; + + %stack.add( %ctrl ); + } + + // Delete the temporary array. + + %rollout.classes = ""; + %classes.delete(); + } + + %this.currentViewType = "Categorized"; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::getOrCreateRolloutForCategory( %this, %category ) +{ + // Try to find an existing rollout. + + %ctrl = %this.getRolloutForCategory( %category ); + if( %ctrl != 0 ) + return %ctrl; + + // None there. Create a new one. + + %ctrl = new GuiRolloutCtrl() { + Margin = "0 0 0 0"; + DefaultHeight = "40"; + Expanded = "1"; + ClickCollapse = "1"; + HideHeader = "0"; + isContainer = "1"; + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "421 114"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + autoCollapseSiblings = true; + caption = %category; + class = "GuiEditorToolboxRolloutCtrl"; + + new GuiDynamicCtrlArrayControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "421 64"; + MinExtent = "64 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + padding = "6 2 4 0"; + colSpacing = "1"; + rowSpacing = "9"; + dynamicSize = true; + autoCellSize = true; + internalName = "array"; + }; + }; + + %this.add( %ctrl ); + %ctrl.collapse(); + + // Sort the rollouts by their caption. + + %this.sort( "_GuiEditorToolboxSortRollouts" ); + + return %ctrl; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::getRolloutForCategory( %this, %category ) +{ + foreach( %obj in %this ) + { + if( !%obj.isMemberOfClass( "GuiRolloutCtrl" ) ) + continue; + + if( stricmp( %obj.caption, %category ) == 0 ) + return %obj; + } + + return 0; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolbox::startGuiControlDrag( %this, %class ) +{ + // Create a new control of the given class. + + %payload = eval( "return new " @ %class @ "();" ); + if( !isObject( %payload ) ) + return; + + // this offset puts the cursor in the middle of the dragged object. + %xOffset = getWord( %payload.extent, 0 ) / 2; + %yOffset = getWord( %payload.extent, 1 ) / 2; + + // position where the drag will start, to prevent visible jumping. + %cursorpos = Canvas.getCursorPos(); + %xPos = getWord( %cursorpos, 0 ) - %xOffset; + %yPos = getWord( %cursorpos, 1 ) - %yOffset; + + // Create drag&drop control. + + %dragCtrl = new GuiDragAndDropControl() + { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiSolidDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = %xPos SPC %yPos; + extent = %payload.extent; + MinExtent = "32 32"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + deleteOnMouseUp = true; + class = "GuiDragAndDropControlType_GuiControl"; + }; + + %dragCtrl.add( %payload ); + Canvas.getContent().add( %dragCtrl ); + + // Start drag. + + %dragCtrl.startDragging( %xOffset, %yOffset ); +} + +//============================================================================================= +// GuiEditorToolboxRolloutCtrl. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolboxRolloutCtrl::onHeaderRightClick( %this ) +{ + if( !isObject( GuiEditorToolboxRolloutCtrlMenu ) ) + new PopupMenu( GuiEditorToolboxRolloutCtrlMenu ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Expand All" TAB "" TAB %this @ ".expandAll();"; + item[ 1 ] = "Collapse All" TAB "" TAB %this @ ".collapseAll();"; + }; + + GuiEditorToolboxRolloutCtrlMenu.showPopup( %this.getRoot() ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolboxRolloutCtrl::expandAll( %this ) +{ + foreach( %ctrl in %this.parentGroup ) + { + if( %ctrl.isMemberOfClass( "GuiRolloutCtrl" ) ) + %ctrl.instantExpand(); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolboxRolloutCtrl::collapseAll( %this ) +{ + foreach( %ctrl in %this.parentGroup ) + { + if( %ctrl.isMemberOfClass( "GuiRolloutCtrl" ) ) + %ctrl.instantCollapse(); + } +} + +//============================================================================================= +// GuiEditorToolboxButton. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function GuiEditorToolboxButton::onMouseDragged( %this ) +{ + GuiEditorToolbox.startGuiControlDrag( %this.text ); +} + +//============================================================================================= +// Misc. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +/// Utility function to sort rollouts by their caption. +function _GuiEditorToolboxSortRollouts( %a, %b ) +{ + return strinatcmp( %a.caption, %b.caption ); +} diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorTreeView.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorTreeView.ed.cs new file mode 100644 index 000000000..82a14bea0 --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorTreeView.ed.cs @@ -0,0 +1,220 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Code for the main Gui Editor tree view that shows the hierarchy of the +// current GUI being edited. + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::init(%this) +{ + if( !isObject( %this.contextMenu ) ) + %this.contextMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Rename" TAB "" TAB "GuiEditorTreeView.showItemRenameCtrl( GuiEditorTreeView.findItemByObjectId( %this.object ) );"; + item[ 1 ] = "Delete" TAB "" TAB "GuiEditor.deleteControl( %this.object );"; + item[ 2 ] = "-"; + item[ 3 ] = "Locked" TAB "" TAB "%this.object.setLocked( !%this.object.locked ); GuiEditorTreeView.update();"; + item[ 4 ] = "Hidden" TAB "" TAB "%this.object.setVisible( !%this.object.isVisible() ); GuiEditorTreeView.update();"; + item[ 5 ] = "-"; + item[ 6 ] = "Add New Controls Here" TAB "" TAB "GuiEditor.setCurrentAddSet( %this.object );"; + item[ 7 ] = "Add Child Controls to Selection" TAB "" TAB "GuiEditor.selectAllControlsInSet( %this.object, false );"; + item[ 8 ] = "Remove Child Controls from Selection" TAB "" TAB "GuiEditor.selectAllControlsInSet( %this.object, true );"; + + object = -1; + }; + + if( !isObject( %this.contextMenuMultiSel ) ) + %this.contextMenuMultiSel = new PopupMenu() + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Delete" TAB "" TAB "GuiEditor.deleteSelection();"; + }; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::update( %this ) +{ + %obj = GuiEditorContent.getObject( 0 ); + + if( !isObject( %obj ) ) + GuiEditorTreeView.clear(); + else + { + // Open inspector tree. + + GuiEditorTreeView.open( %obj ); + + // Sync selection with GuiEditor. + + GuiEditorTreeView.clearSelection(); + + %selection = GuiEditor.getSelection(); + %count = %selection.getCount(); + + for( %i = 0; %i < %count; %i ++ ) + GuiEditorTreeView.addSelection( %selection.getObject( %i ) ); + } +} + +//============================================================================================= +// Event Handlers. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +/// Defines the icons to be used in the tree view control. +/// Provide the paths to each icon minus the file extension. +/// Seperate them with ':'. +/// The order of the icons must correspond to the bit array defined +/// in the GuiTreeViewCtrl.h. +function GuiEditorTreeView::onDefineIcons(%this) +{ + %icons = ":" @ // Default1 + ":" @ // SimGroup1 + ":" @ // SimGroup2 + ":" @ // SimGroup3 + ":" @ // SimGroup4 + "tools/gui/images/treeview/hidden:" @ + "tools/worldEditor/images/lockedHandle"; + + GuiEditorTreeView.buildIconTable( %icons ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onRightMouseDown( %this, %item, %pts, %obj ) +{ + if( %this.getSelectedItemsCount() > 1 ) + { + %popup = %this.contextMenuMultiSel; + %popup.showPopup( Canvas ); + } + else if( %obj ) + { + %popup = %this.contextMenu; + + %popup.checkItem( 3, %obj.locked ); + %popup.checkItem( 4, !%obj.isVisible() ); + + %popup.enableItem( 6, %obj.isContainer ); + %popup.enableItem( 7, %obj.getCount() > 0 ); + %popup.enableItem( 8, %obj.getCount() > 0 ); + + %popup.object = %obj; + %popup.showPopup( Canvas ); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onAddSelection(%this,%ctrl) +{ + GuiEditor.dontSyncTreeViewSelection = true; + GuiEditor.addSelection( %ctrl ); + GuiEditor.dontSyncTreeViewSelection = false; + GuiEditor.setFirstResponder(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onRemoveSelection( %this, %ctrl ) +{ + GuiEditor.dontSyncTreeViewSelection = true; + GuiEditor.removeSelection( %ctrl ); + GuiEditor.dontSyncTreeViewSelection = false; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onDeleteSelection(%this) +{ + GuiEditor.clearSelection(); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onSelect( %this, %obj ) +{ + if( isObject( %obj ) ) + { + GuiEditor.dontSyncTreeViewSelection = true; + GuiEditor.select( %obj ); + GuiEditor.dontSyncTreeViewSelection = false; + GuiEditorInspectFields.update( %obj ); + } +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::isValidDragTarget( %this, %id, %obj ) +{ + return ( %obj.isContainer || %obj.getCount() > 0 ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onBeginReparenting( %this ) +{ + if( isObject( %this.reparentUndoAction ) ) + %this.reparentUndoAction.delete(); + + %action = UndoActionReparentObjects::create( %this ); + + %this.reparentUndoAction = %action; +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onReparent( %this, %obj, %oldParent, %newParent ) +{ + %this.reparentUndoAction.add( %obj, %oldParent, %newParent ); +} + +//--------------------------------------------------------------------------------------------- + +function GuiEditorTreeView::onEndReparenting( %this ) +{ + %action = %this.reparentUndoAction; + %this.reparentUndoAction = ""; + + if( %action.numObjects > 0 ) + { + if( %action.numObjects == 1 ) + %action.actionName = "Reparent Control"; + else + %action.actionName = "Reparent Controls"; + + %action.addToManager( GuiEditor.getUndoManager() ); + + GuiEditor.updateUndoMenu(); + } + else + %action.delete(); +} diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorUndo.ed.cs b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorUndo.ed.cs new file mode 100644 index 000000000..fad91557e --- /dev/null +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorUndo.ed.cs @@ -0,0 +1,598 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------------------------- + +function GuiEditorUndoManager::onAddUndo( %this ) +{ + GuiEditor.updateUndoMenu(); +} + +//----------------------------------------------------------------------------------------- +// Undo adding an object +function UndoActionAddObject::create( %set, %trash, %treeView ) +{ + %act = UndoActionAddDelete::create( UndoActionAddObject, %set, %trash, %treeView ); + %act.actionName = "Add Objects"; + return %act; +} + +function UndoActionAddObject::undo(%this) +{ + %this.trashObjects(); +} + +function UndoActionAddObject::redo(%this) +{ + %this.restoreObjects(); +} + +//----------------------------------------------------------------------------------------- +// Undo Deleting an object +function UndoActionDeleteObject::create( %set, %trash, %treeView ) +{ + %act = UndoActionAddDelete::create( UndoActionDeleteObject, %set, %trash, %treeView, true ); + %act.designatedDeleter = true; + %act.actionName = "Delete Objects"; + return %act; +} + +function UndoActionDeleteObject::undo( %this ) +{ + %this.restoreObjects(); +} + +function UndoActionDeleteObject::redo( %this ) +{ + %this.trashObjects(); +} + +//----------------------------------------------------------------------------------------- +// Behavior common to Add and Delete UndoActions +function UndoActionAddDelete::create( %class, %set, %trash, %treeView, %clearNames ) +{ + // record objects + // record parents + // record trash + // return new subclass %class of UndoActionAddDelete + + // The instant group will try to add our + // UndoAction if we don't disable it. + pushInstantGroup(); + + %act = new UndoScriptAction() { class = %class; superclass = UndoActionAddDelete; }; + + // Restore the instant group. + popInstantGroup(); + + for(%i = 0; %i < %set.getCount(); %i++) + { + %obj = %set.getObject(%i); + + %act.object[ %i ] = %obj.getId(); + %act.parent[ %i ] = %obj.getParent(); + %act.objectName[ %i ] = %obj.name; + + // Clear object name so we don't get name clashes with the trash. + + if( %clearNames ) + %obj.name = ""; + } + + %act.objCount = %set.getCount(); + %act.trash = %trash; + %act.tree = %treeView; + + return %act; +} + +function UndoActionAddDelete::trashObjects(%this) +{ + // Move objects to trash. + + for( %i = 0; %i < %this.objCount; %i ++ ) + { + %object = %this.object[ %i ]; + + %this.trash.add( %object ); + %object.name = ""; + } + + // Note that we're responsible for deleting those objects we've moved to the trash. + + %this.designatedDeleter = true; + + // Update the tree view. + + if( isObject( %this.tree ) ) + %this.tree.update(); +} + +function UndoActionAddDelete::restoreObjects(%this) +{ + // Move objects to saved parent and restore names. + + for( %i = 0; %i < %this.objCount; %i ++ ) + { + %object = %this.object[ %i ]; + %object.name = %this.objectName[ %i ]; + %this.parent[ %i ].add( %object ); + } + + // Note that we no longer own the objects, and should not delete them when we're deleted. + + %this.designatedDeleter = false; + + // Update the tree view. + + if( isObject( %this.tree ) ) + %this.tree.update(); +} + +function UndoActionAddObject::onRemove(%this) +{ + // if this undoAction owns objects in the trash, delete them. + if( !%this.designatedDeleter) + return; + + for( %i = 0; %i < %this.objCount; %i ++) + %this.object[ %i ].delete(); +} + +//----------------------------------------------------------------------------------------- +// Undo grouping/ungrouping of controls. + +function GuiEditorGroupUngroupAction::groupControls( %this ) +{ + for( %i = 0; %i < %this.count; %i ++ ) + %this.group[ %i ].group(); + + GuiEditorTreeView.update(); +} + +function GuiEditorGroupUngroupAction::ungroupControls( %this ) +{ + for( %i = 0; %i < %this.count; %i ++ ) + %this.group[ %i ].ungroup(); + + GuiEditorTreeView.update(); +} + +function GuiEditorGroupUngroupAction::onRemove( %this ) +{ + for( %i = 0; %i < %this.count; %i ++ ) + if( isObject( %this.group[ %i ] ) ) + %this.group[ %i ].delete(); +} + +function GuiEditorGroupAction::create( %set, %root ) +{ + // Create action object. + + pushInstantGroup(); + %action = new UndoScriptAction() + { + actionName = "Group"; + className = GuiEditorGroupAction; + superClass = GuiEditorGroupUngroupAction; + count = 1; + group[ 0 ] = new ScriptObject() + { + className = GuiEditorGroup; + count = %set.getCount(); + groupParent = GuiEditor.getCurrentAddSet(); + }; + }; + popInstantGroup(); + + // Add objects from set to group. + + %group = %action.group[ 0 ]; + %num = %set.getCount(); + for( %i = 0; %i < %num; %i ++ ) + { + %ctrl = %set.getObject( %i ); + if( %ctrl != %root ) + %group.ctrl[ %i ] = %ctrl; + } + + return %action; +} + +function GuiEditorGroupAction::undo( %this ) +{ + %this.ungroupControls(); +} + +function GuiEditorGroupAction::redo( %this ) +{ + %this.groupControls(); +} + +function GuiEditorUngroupAction::create( %set, %root ) +{ + // Create action object. + + pushInstantGroup(); + %action = new UndoScriptAction() + { + actionName = "Ungroup"; + className = GuiEditorUngroupAction; + superClass = GuiEditorGroupUngroupAction; + }; + + // Add groups from set to action. + + %groupCount = 0; + %numInSet = %set.getCount(); + for( %i = 0; %i < %numInSet; %i ++ ) + { + %obj = %set.getObject( %i ); + if( %obj.getClassName() $= "GuiControl" && %obj != %root ) + { + // Create group object. + + %group = new ScriptObject() + { + className = GuiEditorGroup; + count = %obj.getCount(); + groupParent = %obj.parentGroup; + groupObject = %obj; + }; + %action.group[ %groupCount ] = %group; + %groupCount ++; + + // Add controls. + + %numControls = %obj.getCount(); + for( %j = 0; %j < %numControls; %j ++ ) + %group.ctrl[ %j ] = %obj.getObject( %j ); + } + } + + popInstantGroup(); + + %action.count = %groupCount; + return %action; +} + +function GuiEditorUngroupAction::undo( %this ) +{ + %this.groupControls(); +} + +function GuiEditorUngroupAction::redo( %this ) +{ + %this.ungroupControls(); +} + +//------------------------------------------------------------------------------ +// Undo Any State Change. +function GenericUndoAction::create() +{ + // The instant group will try to add our + // UndoAction if we don't disable it. + pushInstantGroup(); + + %act = new UndoScriptAction() { class = GenericUndoAction; }; + %act.actionName = "Edit Objects"; + + // Restore the instant group. + popInstantGroup(); + + return %act; +} + +function GenericUndoAction::watch(%this, %object) +{ + // make sure we're working with the object id, because it cannot change. + %object = %object.getId(); + + %fieldCount = %object.getFieldCount(); + %dynFieldCount = %object.getDynamicFieldCount(); + + // inspect all the fields on the object, including dyanamic ones. + // record field names and values. + for(%i = 0; %i < %fieldCount; %i++) + { + %field = %object.getField(%i); + %this.fieldNames[%object] = %this.fieldNames[%object] SPC %field; + %this.fieldValues[%object, %field] = %object.getFieldValue(%field); + } + for(%i = 0; %i < %dynFieldCount; %i++) + { + %field = %object.getDynamicField(%i); + %this.fieldNames[%object] = %this.fieldNames[%object] SPC %field; + %this.fieldValues[%object, %field] = %object.getFieldValue(%field); + } + // clean spurious spaces from the field name list + %this.fieldNames[%object] = trim(%this.fieldNames[%object]); + // record that we know this object + %this.objectIds[%object] = 1; + %this.objectIdList = %this.objectIdList SPC %object; +} + +function GenericUndoAction::learn(%this, %object) +{ + // make sure we're working with the object id, because it cannot change. + %object = %object.getId(); + + %fieldCount = %object.getFieldCount(); + %dynFieldCount = %object.getDynamicFieldCount(); + + // inspect all the fields on the object, including dyanamic ones. + // record field names and values. + for(%i = 0; %i < %fieldCount; %i++) + { + %field = %object.getField(%i); + %this.newFieldNames[%object] = %this.newFieldNames[%object] SPC %field; + %this.newFieldValues[%object, %field] = %object.getFieldValue(%field); + } + for(%i = 0; %i < %dynFieldCount; %i++) + { + %field = %object.getDynamicField(%i); + %this.newFieldNames[%object] = %this.newFieldNames[%object] SPC %field; + %this.newFieldValues[%object, %field] = %object.getFieldValue(%field); + } + // trim + %this.newFieldNames[%object] = trim(%this.newFieldNames[%object]); + + // look for differences + //---------------------------------------------------------------------- + %diffs = false; + %newFieldNames = %this.newFieldNames[%object]; + %oldFieldNames = %this.fieldNames[%object]; + %numNewFields = getWordCount(%newFieldNames); + %numOldFields = getWordCount(%oldFieldNames); + // compare the old field list to the new field list. + // if a field is on the old list that isn't on the new list, + // add it to the newNullFields list. + for(%i = 0; %i < %numOldFields; %i++) + { + %field = getWord(%oldFieldNames, %i); + %newVal = %this.newFieldValues[%object, %field]; + %oldVal = %this.fieldValues[%object, %field]; + if(%newVal !$= %oldVal) + { + %diffs = true; + if(%newVal $= "") + { + %newNullFields = %newNullFields SPC %field; + } + } + } + // scan the new field list + // add missing fields to the oldNullFields list + for(%i = 0; %i < %numNewFields; %i++) + { + %field = getWord(%newFieldNames, %i); + %newVal = %this.newFieldValues[%object, %field]; + %oldVal = %this.fieldValues[%object, %field]; + if(%newVal !$= %oldVal) + { + %diffs = true; + if(%oldVal $= "") + { + %oldNullFields = %oldNullFields SPC %field; + } + } + } + %this.newNullFields[%object] = trim(%newNullFields); + %this.oldNullFields[%object] = trim(%oldNullFields); + + return %diffs; +} + +function GenericUndoAction::watchSet(%this, %set) +{ + // scan the set + // this.watch each object. + %setcount = %set.getCount(); + %i = 0; + for(; %i < %setcount; %i++) + { + %object = %set.getObject(%i); + %this.watch(%object); + } +} + +function GenericUndoAction::learnSet(%this, %set) +{ + // scan the set + // this.learn any objects that we have a this.objectIds[] entry for. + %diffs = false; + for(%i = 0; %i < %set.getCount(); %i++) + { + %object = %set.getObject(%i).getId(); + if(%this.objectIds[%object] != 1) + continue; + + if(%this.learn(%object)) + %diffs = true; + } + + return %diffs; +} + +function GenericUndoAction::undo(%this) +{ + // set the objects to the old values + // scan through our objects + %objectList = %this.objectIdList; + for(%i = 0; %i < getWordCount(%objectList); %i++) + { + %object = getWord(%objectList, %i); + // scan through the old extant fields + %fieldNames = %this.fieldNames[%object]; + for(%j = 0; %j < getWordCount(%fieldNames); %j++) + { + %field = getWord(%fieldNames, %j); + %object.setFieldValue(%field, %this.fieldValues[%object, %field]); + } + // null out the fields in the null list + %fieldNames = %this.oldNullFields[%object]; + for(%j = 0; %j < getWordCount(%fieldNames); %j++) + { + %field = getWord(%fieldNames, %j); + %object.setFieldValue(%field, ""); + } + } + + // update the tree view + if(isObject(%this.tree)) + %this.tree.update(); +} + +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; + for(%i = 0; %i < getWordCount(%objectList); %i++) + { + %object = getWord(%objectList, %i); + // scan through the new extant fields + %fieldNames = %this.newFieldNames[%object]; + for(%j = 0; %j < getWordCount(%fieldNames); %j++) + { + %field = getWord(%fieldNames, %j); + %object.setFieldValue(%field, %this.newFieldValues[%object, %field]); + } + // null out the fields in the null list + %fieldNames = %this.newNullFields[%object]; + for(%j = 0; %j < getWordCount(%fieldNames); %j++) + { + %field = getWord(%fieldNames, %j); + %object.setFieldValue(%field, ""); + } + } + + // update the tree view + if(isObject(%this.tree)) + %this.tree.update(); +} + +//----------------------------------------------------------------------------------------- +// Gui Editor Undo hooks from code +function GuiEditor::onPreEdit(%this, %selection) +{ + if ( isObject(%this.pendingGenericUndoAction) ) + { + error("Error: attempting to create two generic undo actions at once in the same editor!"); + return; + } + + //echo("pre edit"); + %act = GenericUndoAction::create(); + %act.watchSet(%selection); + %act.tree = GuiEditorTreeView; + + %this.pendingGenericUndoAction = %act; + + %this.updateUndoMenu(); +} + +function GuiEditor::onPostEdit(%this, %selection) +{ + if(!isObject(%this.pendingGenericUndoAction)) + error("Error: attempting to complete a GenericUndoAction that hasn't been started!"); + + %act = %this.pendingGenericUndoAction; + %this.pendingGenericUndoAction = ""; + + %diffs = %act.learnSet(%selection); + if(%diffs) + { + //echo("adding generic undoaction to undo manager"); + //%act.dump(); + %act.addToManager(%this.getUndoManager()); + } + else + { + //echo("deleting empty generic undoaction"); + %act.delete(); + } + + %this.updateUndoMenu(); +} + +function GuiEditor::onPreSelectionNudged(%this, %selection) +{ + %this.onPreEdit(%selection); + %this.pendingGenericUndoAction.actionName = "Nudge"; +} + +function GuiEditor::onPostSelectionNudged(%this, %selection) +{ + %this.onPostEdit(%selection); +} + +function GuiEditor::onAddNewCtrl(%this, %ctrl) +{ + %set = new SimSet(); + %set.add(%ctrl); + %act = UndoActionAddObject::create(%set, %this.getTrash(), GuiEditorTreeView); + %set.delete(); + %act.addToManager(%this.getUndoManager()); + %this.updateUndoMenu(); + //GuiEditorInspectFields.update(0); +} + +function GuiEditor::onAddNewCtrlSet(%this, %selection) +{ + %act = UndoActionAddObject::create(%selection, %this.getTrash(), GuiEditorTreeView); + %act.addToManager(%this.getUndoManager()); + %this.updateUndoMenu(); +} + +function GuiEditor::onTrashSelection(%this, %selection) +{ + %act = UndoActionDeleteObject::create(%selection, %this.getTrash(), GuiEditorTreeView); + %act.addToManager(%this.getUndoManager()); + %this.updateUndoMenu(); +} + +function GuiEditor::onControlInspectPreApply(%this, %object) +{ + %set = new SimSet(); + %set.add(%object); + %this.onPreEdit(%set); + %this.pendingGenericUndoAction.actionName = "Change Properties"; + %set.delete(); +} + +function GuiEditor::onControlInspectPostApply(%this, %object) +{ + %set = new SimSet(); + %set.add(%object); + %this.onPostEdit(%set); + %set.delete(); + GuiEditorTreeView.update(); +} + +function GuiEditor::onFitIntoParents( %this ) +{ + %selected = %this.getSelection(); + //TODO +} diff --git a/Templates/BaseGame/game/tools/levels/BlankRoom.mis b/Templates/BaseGame/game/tools/levels/BlankRoom.mis new file mode 100644 index 000000000..5ca65ed5a --- /dev/null +++ b/Templates/BaseGame/game/tools/levels/BlankRoom.mis @@ -0,0 +1,94 @@ +//--- OBJECT WRITE BEGIN --- +new SimGroup(MissionGroup) { + canSaveDynamicFields = "1"; + cdTrack = "2"; + CTF_scoreLimit = "5"; + Enabled = "1"; + musicTrack = "lush"; + + new LevelInfo(theLevelInfo) { + visibleDistance = "1000"; + fogColor = "0.6 0.6 0.7 1"; + fogDensity = "0"; + fogDensityOffset = "700"; + fogAtmosphereHeight = "0"; + canvasClearColor = "0 0 0 255"; + canSaveDynamicFields = "1"; + levelName = "Blank Room"; + desc0 = "A blank room ready to be populated with Torque objects.\n\nGuns, anyone?"; + Enabled = "1"; + }; + new SkyBox(theSky) { + canSaveDynamicFields = "1"; + Position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + Material = "BlackSkyMat"; + drawBottom = "0"; + fogBandHeight = "0"; + }; + new Sun(theSun) { + canSaveDynamicFields = "1"; + Position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + azimuth = "230.396"; + elevation = "45"; + color = "0.968628 0.901961 0.901961 1"; + ambient = "0.078431 0.113725 0.156863 1"; + castShadows = "1"; + attenuationRatio = "0 1 1"; + shadowType = "PSSM"; + texSize = "1024"; + overDarkFactor = "3000 1500 750 250"; + shadowDistance = "200"; + shadowSoftness = "0.25"; + numSplits = "4"; + logWeight = "0.9"; + fadeStartDistance = "0"; + lastSplitTerrainOnly = "0"; + splitFadeDistances = "1 1 1 1"; + bias = "0.1"; + Blur = "1"; + Enabled = "1"; + height = "1024"; + lightBleedFactor = "0.8"; + minVariance = "0"; + pointShadowType = "PointShadowType_Paraboloid"; + shadowBox = "-100 -100 -100 100 100 100"; + width = "3072"; + }; + new SimGroup(PlayerDropPoints) { + canSaveDynamicFields = "1"; + Enabled = "1"; + + new SpawnSphere() { + canSaveDynamicFields = "1"; + Position = "0 0 2"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + radius = "5"; + autoSpawn = "false"; + sphereWeight = "1"; + indoorWeight = "1"; + outdoorWeight = "1"; + Enabled = "1"; + homingCount = "0"; + lockCount = "0"; + }; + }; + new GroundPlane() { + canSaveDynamicFields = "1"; + Position = "0 0 0"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + squareSize = "128"; + scaleU = "12"; + scaleV = "12"; + Material = "BlankWhite"; + Enabled = "1"; + }; +}; +//--- OBJECT WRITE END --- + diff --git a/Templates/BaseGame/game/tools/levels/BlankRoom_preview.png b/Templates/BaseGame/game/tools/levels/BlankRoom_preview.png new file mode 100644 index 000000000..1d91f60f7 Binary files /dev/null and b/Templates/BaseGame/game/tools/levels/BlankRoom_preview.png differ diff --git a/Templates/BaseGame/game/tools/main.cs b/Templates/BaseGame/game/tools/main.cs new file mode 100644 index 000000000..d1a0df811 --- /dev/null +++ b/Templates/BaseGame/game/tools/main.cs @@ -0,0 +1,284 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//--------------------------------------------------------------------------------------------- +// Path to the folder that contains the editors we will load. +//--------------------------------------------------------------------------------------------- +$Tools::resourcePath = "tools/"; + +// These must be loaded first, in this order, before anything else is loaded +$Tools::loadFirst = "editorClasses base worldEditor"; + +//--------------------------------------------------------------------------------------------- +// Object that holds the simObject id that the materialEditor uses to interpret its material list +//--------------------------------------------------------------------------------------------- +$Tools::materialEditorList = ""; + +//--------------------------------------------------------------------------------------------- +// Tools Package. +//--------------------------------------------------------------------------------------------- +package Tools +{ + function loadKeybindings() + { + Parent::loadKeybindings(); + } + + // Start-up. + function onStart() + { + //First, we want to ensure we don't inadvertently clean up our editor objects by leaving them in the MissionCleanup group, so lets change that real fast + $instantGroup = ""; + pushInstantGroup(); + + new Settings(EditorSettings) { file = "tools/settings.xml"; }; + EditorSettings.read(); + + echo( " % - Initializing Tools" ); + + // Default file path when saving from the editor (such as prefabs) + if ($Pref::WorldEditor::LastPath $= "") + { + $Pref::WorldEditor::LastPath = getMainDotCsDir(); + } + + // Common GUI stuff. + exec( "./gui/cursors.ed.cs" ); + exec( "./gui/profiles.ed.cs" ); + exec( "./gui/messageBoxes/messageBox.ed.cs" ); + exec( "./editorClasses/gui/panels/navPanelProfiles.ed.cs" ); + + // Make sure we get editor profiles before any GUI's + // BUG: these dialogs are needed earlier in the init sequence, and should be moved to + // common, along with the guiProfiles they depend on. + exec( "./gui/guiDialogs.ed.cs" ); + + //%toggle = $Scripts::ignoreDSOs; + //$Scripts::ignoreDSOs = true; + + $ignoredDatablockSet = new SimSet(); + + // fill the list of editors + $editors[count] = getWordCount( $Tools::loadFirst ); + for ( %i = 0; %i < $editors[count]; %i++ ) + { + $editors[%i] = getWord( $Tools::loadFirst, %i ); + } + + %pattern = $Tools::resourcePath @ "/*/main.cs"; + %folder = findFirstFile( %pattern ); + if ( %folder $= "") + { + // if we have absolutely no matches for main.cs, we look for main.cs.dso + %pattern = $Tools::resourcePath @ "/*/main.cs.dso"; + %folder = findFirstFile( %pattern ); + } + while ( %folder !$= "" ) + { + if( filePath( %folder ) !$= "tools" ) // Skip the actual 'tools' folder...we want the children + { + %folder = filePath( %folder ); + %editor = fileName( %folder ); + if ( IsDirectory( %folder ) ) + { + // Yes, this sucks and should be done better + if ( strstr( $Tools::loadFirst, %editor ) == -1 ) + { + $editors[$editors[count]] = %editor; + $editors[count]++; + } + } + } + %folder = findNextFile( %pattern ); + } + + // initialize every editor + new SimSet( EditorPluginSet ); + %count = $editors[count]; + for ( %i = 0; %i < %count; %i++ ) + { + exec( "./" @ $editors[%i] @ "/main.cs" ); + + %initializeFunction = "initialize" @ $editors[%i]; + if( isFunction( %initializeFunction ) ) + call( %initializeFunction ); + } + + // Popuplate the default SimObject icons that + // are used by the various editors. + EditorIconRegistry::loadFromPath( "tools/classIcons/" ); + + // Load up the tools resources. All the editors are initialized at this point, so + // resources can override, redefine, or add functionality. + Tools::LoadResources( $Tools::resourcePath ); + + //Now that we're done loading, we can set the instant group back + popInstantGroup(); + $instantGroup = MissionCleanup; + pushInstantGroup(); + + } + + function startToolTime(%tool) + { + if($toolDataToolCount $= "") + $toolDataToolCount = 0; + + if($toolDataToolEntry[%tool] !$= "true") + { + $toolDataToolEntry[%tool] = "true"; + $toolDataToolList[$toolDataToolCount] = %tool; + $toolDataToolCount++; + $toolDataClickCount[%tool] = 0; + } + + $toolDataStartTime[%tool] = getSimTime(); + $toolDataClickCount[%tool]++; + } + + function endToolTime(%tool) + { + %startTime = 0; + + if($toolDataStartTime[%tool] !$= "") + %startTime = $toolDataStartTime[%tool]; + + if($toolDataTotalTime[%tool] $= "") + $toolDataTotalTime[%tool] = 0; + + $toolDataTotalTime[%tool] += getSimTime() - %startTime; + } + + function dumpToolData() + { + %count = $toolDataToolCount; + for(%i=0; %i<%count; %i++) + { + %tool = $toolDataToolList[%i]; + %totalTime = $toolDataTotalTime[%tool]; + if(%totalTime $= "") + %totalTime = 0; + %clickCount = $toolDataClickCount[%tool]; + echo("---"); + echo("Tool: " @ %tool); + echo("Time (seconds): " @ %totalTime / 1000); + echo("Activated: " @ %clickCount); + echo("---"); + } + } + + // Shutdown. + function onExit() + { + if( EditorGui.isInitialized ) + EditorGui.shutdown(); + + // Free all the icon images in the registry. + EditorIconRegistry::clear(); + + // Save any Layouts we might be using + //GuiFormManager::SaveLayout(LevelBuilder, Default, User); + + %count = $editors[count]; + for (%i = 0; %i < %count; %i++) + { + %destroyFunction = "destroy" @ $editors[%i]; + if( isFunction( %destroyFunction ) ) + call( %destroyFunction ); + } + + // Call Parent. + Parent::onExit(); + + // write out our settings xml file + EditorSettings.write(); + } +}; + +function fastLoadWorldEdit(%val) +{ + if(%val) + { + if(!$Tools::loaded) + { + onStart(); + } + + if(Canvas.getContent() == MainMenuGui.getId()) + { + //startGame(); + activatePackage( "BootEditor" ); + ChooseLevelDlg.launchInEditor = false; + StartGame("tools/levels/BlankRoom.mis", "SinglePlayer"); + } + else + { + toggleEditor(true); + } + } +} + +function fastLoadGUIEdit(%val) +{ + if(%val) + { + if(!$Tools::loaded) + { + onStart(); + } + + toggleGuiEditor(true); + } +} + +function Tools::LoadResources( %path ) +{ + %resourcesPath = %path @ "resources/"; + %resourcesList = getDirectoryList( %resourcesPath ); + + %wordCount = getFieldCount( %resourcesList ); + for( %i = 0; %i < %wordCount; %i++ ) + { + %resource = GetField( %resourcesList, %i ); + if( isFile( %resourcesPath @ %resource @ "/resourceDatabase.cs") ) + ResourceObject::load( %path, %resource ); + } +} + +//----------------------------------------------------------------------------- +// Activate Package. +//----------------------------------------------------------------------------- +activatePackage(Tools); + +//This lets us fast-load the editor from the menu +GlobalActionMap.bind(keyboard, "F11", fastLoadWorldEdit); +GlobalActionMap.bind(keyboard, "F10", fastLoadGUIEdit); + +function EditorIsActive() +{ + return ( isObject(EditorGui) && Canvas.getContent() == EditorGui.getId() ); +} + +function GuiEditorIsActive() +{ + return ( isObject(GuiEditorGui) && Canvas.getContent() == GuiEditorGui.getId() ); +} diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/MaterialToolbar.ed.gui b/Templates/BaseGame/game/tools/materialEditor/gui/MaterialToolbar.ed.gui new file mode 100644 index 000000000..efc140578 --- /dev/null +++ b/Templates/BaseGame/game/tools/materialEditor/gui/MaterialToolbar.ed.gui @@ -0,0 +1,68 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MaterialEditorToolbar) { + canSaveDynamicFields = "0"; + internalName = "ShapeEditorToolbar"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "672 0"; + Extent = "802" SPC getWord(EditorGuiToolbar.extent, 1); + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + canMove = "0"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + EdgeSnap = "0"; + text =""; + + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 7"; + extent = "76 16"; + minExtent = "8 8"; + visible = "1"; + text = "Material Library"; + maxLength = "255"; + helpTag = "0"; + }; + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "86 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "91 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "materialSelector.showDialog();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Select and Edit an Existing Material"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/materialSelectorIcon"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/Profiles.ed.cs b/Templates/BaseGame/game/tools/materialEditor/gui/Profiles.ed.cs new file mode 100644 index 000000000..fb70def29 --- /dev/null +++ b/Templates/BaseGame/game/tools/materialEditor/gui/Profiles.ed.cs @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Material Editor Written by Dave Calabrese of Gaslight Studios + +singleton GuiControlProfile (GuiMatEdSliderProfile) +{ + bitmap = "./matEdSlider"; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiMatEdRightJustifyProfile) +{ + // font + fontType = "Arial"; + fontSize = 14; + fontCharset = ANSI; + + fontColor = "0 0 0"; + + justify = "right"; + category = "Editor"; +}; + +singleton GuiControlProfile(GuiMatEdPopUpMenuProfile) +{ + opaque = false; + mouseOverSelected = true; + textOffset = "3 3"; + border = 1; + /*borderThickness = 1;*/ + fixedExtent = true; + //bitmap = "./images/scrollbar"; + bitmap = "tools/editorClasses/gui/images/scroll"; + hasBitmapArray = true; + profileForChildren = GuiControlListPopupProfile; + fillColor = "255 0 0 255"; + fontColor = "255 255 255 255"; + fillColorHL = "50 50 50"; + fontColorHL = "220 220 220"; + borderColor = "100 100 108"; + category = "Editor"; +}; + +singleton GuiControlProfile (MatEdCenteredTextProfile) +{ + fontColor = "0 0 0"; + justify = "center"; + category = "Editor"; +}; diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/change-material-btn_d.png b/Templates/BaseGame/game/tools/materialEditor/gui/change-material-btn_d.png new file mode 100644 index 000000000..c8b2106c2 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/change-material-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/change-material-btn_h.png b/Templates/BaseGame/game/tools/materialEditor/gui/change-material-btn_h.png new file mode 100644 index 000000000..d803dc6af Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/change-material-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/change-material-btn_n.png b/Templates/BaseGame/game/tools/materialEditor/gui/change-material-btn_n.png new file mode 100644 index 000000000..4cc985e1c Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/change-material-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cubeMapEd_cubePreview.max b/Templates/BaseGame/game/tools/materialEditor/gui/cubeMapEd_cubePreview.max new file mode 100644 index 000000000..fa6249ee9 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cubeMapEd_cubePreview.max differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cubeMapEd_previewMat.jpg b/Templates/BaseGame/game/tools/materialEditor/gui/cubeMapEd_previewMat.jpg new file mode 100644 index 000000000..b10e74052 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cubeMapEd_previewMat.jpg differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cube_xNeg.jpg b/Templates/BaseGame/game/tools/materialEditor/gui/cube_xNeg.jpg new file mode 100644 index 000000000..6501386c6 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cube_xNeg.jpg differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cube_xPos.jpg b/Templates/BaseGame/game/tools/materialEditor/gui/cube_xPos.jpg new file mode 100644 index 000000000..c01a9c520 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cube_xPos.jpg differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cube_yNeg.jpg b/Templates/BaseGame/game/tools/materialEditor/gui/cube_yNeg.jpg new file mode 100644 index 000000000..d3fdd38db Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cube_yNeg.jpg differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cube_yPos.jpg b/Templates/BaseGame/game/tools/materialEditor/gui/cube_yPos.jpg new file mode 100644 index 000000000..539cf7762 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cube_yPos.jpg differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cube_zNeg.jpg b/Templates/BaseGame/game/tools/materialEditor/gui/cube_zNeg.jpg new file mode 100644 index 000000000..b81b6f920 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cube_zNeg.jpg differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cube_zPos.jpg b/Templates/BaseGame/game/tools/materialEditor/gui/cube_zPos.jpg new file mode 100644 index 000000000..7d7d797b0 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cube_zPos.jpg differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cubemapBtnBorder_d.png b/Templates/BaseGame/game/tools/materialEditor/gui/cubemapBtnBorder_d.png new file mode 100644 index 000000000..0ce0b477b Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cubemapBtnBorder_d.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cubemapBtnBorder_h.png b/Templates/BaseGame/game/tools/materialEditor/gui/cubemapBtnBorder_h.png new file mode 100644 index 000000000..acea03281 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cubemapBtnBorder_h.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cubemapBtnBorder_i.png b/Templates/BaseGame/game/tools/materialEditor/gui/cubemapBtnBorder_i.png new file mode 100644 index 000000000..f2ee385bf Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cubemapBtnBorder_i.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cubemapBtnBorder_n.png b/Templates/BaseGame/game/tools/materialEditor/gui/cubemapBtnBorder_n.png new file mode 100644 index 000000000..717f9b4f8 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cubemapBtnBorder_n.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cubemapEd_spherePreview.max b/Templates/BaseGame/game/tools/materialEditor/gui/cubemapEd_spherePreview.max new file mode 100644 index 000000000..9425d3b4f Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cubemapEd_spherePreview.max differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cubemaped_cubepreview.dts b/Templates/BaseGame/game/tools/materialEditor/gui/cubemaped_cubepreview.dts new file mode 100644 index 000000000..20472c9cf Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cubemaped_cubepreview.dts differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cubemaped_cylinderpreview.dts b/Templates/BaseGame/game/tools/materialEditor/gui/cubemaped_cylinderpreview.dts new file mode 100644 index 000000000..75a359334 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cubemaped_cylinderpreview.dts differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cubemaped_spherepreview.dts b/Templates/BaseGame/game/tools/materialEditor/gui/cubemaped_spherepreview.dts new file mode 100644 index 000000000..ed117d334 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cubemaped_spherepreview.dts differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cubematEd_cylinderPreview.max b/Templates/BaseGame/game/tools/materialEditor/gui/cubematEd_cylinderPreview.max new file mode 100644 index 000000000..2926befd6 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cubematEd_cylinderPreview.max differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cubepreview.dts b/Templates/BaseGame/game/tools/materialEditor/gui/cubepreview.dts new file mode 100644 index 000000000..18724762d Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cubepreview.dts differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/cylinderpreview.dts b/Templates/BaseGame/game/tools/materialEditor/gui/cylinderpreview.dts new file mode 100644 index 000000000..dfe5ec1bc Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/cylinderpreview.dts differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/gridTiny2.PNG b/Templates/BaseGame/game/tools/materialEditor/gui/gridTiny2.PNG new file mode 100644 index 000000000..6ce109308 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/gridTiny2.PNG differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPreviewWindow.ed.gui b/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPreviewWindow.ed.gui new file mode 100644 index 000000000..8110d2c34 --- /dev/null +++ b/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPreviewWindow.ed.gui @@ -0,0 +1,796 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + canSaveDynamicFields = "0"; + internalName = "MatEdPreviewWindowContainer"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(MaterialEditorPreviewWindow) { + canSaveDynamicFields = "0"; + internalName = "MatEdPreviewWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Extent = "210 251 "; + MinExtent = "210 150"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1)-1; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + closeCommand = "MaterialEditorPreviewWindow.setVisible(false);"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Material Preview"; + + /*new GuiContainer(MaterialEditorPreviewPane) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; //1 + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "4 23"; + Extent = "200 221"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0";*/ + + new GuiContainer(matEd_previewPanel) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "4 45"; + Extent = "202 202"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Docking = "Client"; + Margin = "24 1 3 3 "; + + + new GuiSwatchButtonCtrl(matEd_previewBackground) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "-1 -1"; + Extent = "204 204"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + color = "0 0 0 .8"; + //bitmap = "tools/materialEditor/gui/gridTiny2.PNG"; + //wrap = "1"; + }; + new GuiContainer(){ // this is blocking the mouse imput to the swatch imput behind it + HorizSizing = "width"; + VertSizing = "height"; + Position = "-1 -1"; + Extent = "204 204"; + }; + new GuiMaterialPreview(matEd_previewObjectView) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "1 1"; + Extent = "199 199"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + }; + //}; + }; + + new GuiPopUpMenuCtrl(matEd_quickPreview_Popup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 24"; + Extent = "67 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updatePreviewObject();"; + ToolTip = "Changes the Preview Mesh"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Sphere"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiSwatchButtonCtrl(MaterialPreviewBackgroundPicker) { // Background Color + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "189 229"; + Extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF($thisControl.color, \"MaterialEditorGui.updatePreviewBackground\");"; + color = "0 0 0 .8"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + // Ambient light color picker + new GuiSwatchButtonCtrl(matEd_ambientLightColorPicker) { + canSaveDynamicFields = "0"; + Enabled = "1"; + color = "1 1 1 1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "81 28"; + Extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF($ThisControl.color, \"MaterialEditorGui.updateAmbientColor\");"; + hovertime = "1000"; + groupNum = "-1"; + ToolTip ="Change Ambient Light Color"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + // Light color picker + new GuiSwatchButtonCtrl(matEd_lightColorPicker) { + canSaveDynamicFields = "0"; + Enabled = "1"; + color = "1 1 1 1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "75 23"; + Extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF($ThisControl.color, \"MaterialEditorGui.updateLightColor\");"; + hovertime = "1000"; + groupNum = "-1"; + ToolTip ="Change Normal Light Color"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiCheckboxCtrl(){ + position = "108 25"; + Extent = "98 18"; + HorizSizing = "left"; + profile = "ToolsGuiCheckBoxProfile"; + Variable = "MaterialEditorGui.livePreview"; + Command = "MaterialEditorGui.updateLivePreview($ThisControl.getValue());"; + text ="Preview in World"; + }; + }; + new GuiWindowCtrl(matEd_cubemapEditor) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "200 257"; + Extent = "478 248"; + MinExtent = "478 248"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + closeCommand = "MaterialEditorGui.hideCubemapEditor(true);"; + text = "Cubemap Editor"; + + new GuiTextCtrl(){ + Profile = "ToolsGuiTextProfile"; + position = "307 40"; + Extent = "30 16"; + text = "Name"; + }; + new GuiTextEditCtrl(matEd_cubemapEd_activeCubemapNameTxt) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "338 40"; + Extent = "131 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "myCubemap 1"; + maxLength = "1024"; + AltCommand = "MaterialEditorGui.editCubemapName($ThisControl.getText());"; + }; + new GuiButtonCtrl(){ + Profile = "ToolsGuiButtonProfile"; + position = "339 216"; + Extent = "74 24"; + text = "Select"; + command = "MaterialEditorGui.selectCubemap();"; // needs hookup use selected cubemap + }; + new GuiButtonCtrl(){ + Profile = "ToolsGuiButtonProfile"; + position = "417 216"; + Extent = "52 24"; + text = "Cancel"; + command = "MaterialEditorGui.hideCubemapEditor(true);"; // needs hookup Cancel + }; + new GuiScrollCtrl(matEd_cubemapEd_availableCubemapScroller) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 40"; + Extent = "154 203"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiListBoxCtrl(matEd_cubemapEd_availableCubemapList) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiListBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "128 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + AllowMultipleSelections = "0"; + fitParentWidth = "1"; + }; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiTextProfile"; + position = "6 22"; + Extent = "67 16"; + text = "Cubemaps"; + }; + // ------------------------------ Right X Positive ------------------------------------ + new GuiBitmapCtrl(matEd_cubemapEd_XPos) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "299 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl(matEd_cubeMapEd_xPosTxt) { + position = "304 110"; + Extent = "57 10"; + text = "+ X Right"; + }; + new GuiBitmapButtonCtrl(matEd_cubeMapEd_updateXPOSImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "299 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.editCubemapImage(\"0\", $ThisControl.bitmap );"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "When using Static Cubemaps, select your CubeMap by clicking here."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + // ------------------------------ X Negitive ------------------------------------ + new GuiBitmapCtrl(matEd_cubemapEd_XNeg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "167 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl(matEd_cubeMapEd_xNegTxt) { + position = "171 110"; + Extent = "57 10"; + text = "- X Left"; + }; + new GuiBitmapButtonCtrl(matEd_cubeMapEd_updateXNEGImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "167 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.editCubemapImage(\"1\", $ThisControl.bitmap );"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "When using Static Cubemaps, select your CubeMap by clicking here."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + // ------------------------------ Y Positive ------------------------------------ + new GuiBitmapCtrl(matEd_cubemapEd_YPos) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "233 172"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl(matEd_cubeMapEd_yPosTxt) { + position = "237 175"; + Extent = "57 10"; + text = "+ Y Front"; + }; + new GuiBitmapButtonCtrl(matEd_cubeMapEd_updateYPOSImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "233 172"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.editCubemapImage(\"3\", $ThisControl.bitmap );"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "When using Static Cubemaps, select your CubeMap by clicking here."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + // ------------------------------ Y Negitive ------------------------------------ + new GuiBitmapCtrl(matEd_cubemapEd_YNeG) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "233 40"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl(matEd_cubeMapEd_yNegTxt) { + position = "237 44"; + Extent = "57 10"; + text = "- Y Back"; + }; + new GuiBitmapButtonCtrl(matEd_cubeMapEd_updateYNegImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "233 40"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.editCubemapImage(\"2\", $ThisControl.bitmap );"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "When using Static Cubemaps, select your CubeMap by clicking here."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + // ------------------------------ Z Positive ------------------------------------ + new GuiBitmapCtrl(matEd_cubemapEd_ZPos) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "233 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl(matEd_cubeMapEd_zPosTxt) { + position = "237 110"; + Extent = "57 10"; + text = "+ Z Top"; + }; + new GuiBitmapButtonCtrl(matEd_cubeMapEd_updateZPosImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "233 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.editCubemapImage(\"4\", $ThisControl.bitmap );"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "When using Static Cubemaps, select your CubeMap by clicking here."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + // ------------------------------ Z Negitive ------------------------------------ + new GuiBitmapCtrl(matEd_cubemapEd_ZNeg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "365 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl(matEd_cubeMapEd_zNegTxt) { + position = "369 110"; + Extent = "57 10"; + text = "- Z Bottom"; + }; + new GuiBitmapButtonCtrl(matEd_cubeMapEd_updateZNegImg) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "365 106"; + Extent = "64 64"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.editCubemapImage(\"5\", $ThisControl.bitmap );"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "When using Static Cubemaps, select your CubeMap by clicking here."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + + // Create New Cubemap + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "128 23"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "matEd_addCubemapWindow.setVisible(1);"; // -------------- Needs Hookup Create New Cubemap + hovertime = "1000"; + tooltip = "Create New Cubemap"; + bitmap = "tools/gui/images/new"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "143 23"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.showDeleteCubemapDialog();"; // -------------- Needs Hookup Delete Cubemap + hovertime = "1000"; + tooltip = "Delete Cubemap"; + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + internalName = "saveCubemap"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "top"; + position = "106 23"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.showSaveCubemapDialog();"; // -------------- Needs Hookup Save Cubemap + hovertime = "1000"; + tooltip = "Save Cubemap"; + bitmap = "tools/gui/images/save-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + + new GuiWindowCtrl(matEd_addCubemapWindow) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "362 333"; + Extent = "300 99"; + MinExtent = "48 92"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Create Cubemap"; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "cubemapName"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "96 35"; + Extent = "196 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + AltCommand = ""; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "12 36"; + Extent = "77 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + text = "Cubemap Name"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "96 68"; + Extent = "126 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + text = "Create"; + Command = "MaterialEditorGui.addCubemap( matEd_addCubemapWindow-->cubemapName.getText() );matEd_addCubemapWindow.setVisible(0);"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "228 68"; + Extent = "64 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + text = "Cancel"; + Command = "matEd_addCubemapWindow.setVisible(0);"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui b/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui new file mode 100644 index 000000000..328d946b6 --- /dev/null +++ b/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui @@ -0,0 +1,4091 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MaterialEditorGui,EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = "MatEdPropertiesWindowContainer"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(MaterialEditorPropertiesWindow) { + canSaveDynamicFields = "0"; + internalName = "MatEdPropertiesWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Extent = "210 446"; + MinExtent = "210 316"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(MaterialEditorPreviewWindow.extent, 1) - 2; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + closeCommand = "MaterialEditorPropertiesWindow.setVisible(false);"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Material Properties"; + + new GuiContainer(){ // Client group + isContainer = "1"; + Docking = "Client"; + Margin = "3 1 3 3"; + Position = "4 24"; + Extent = "202 668"; + + new GuiContainer(){ // container to prevent transparent collapsing from effecting children. + Position = "0 21"; + Extent = "202 39"; + isContainer = "1"; + HorizSizing = "width"; + Visible = "1"; + + new GuiContainer(MatEdMaterialMode){ // Edit Mode + Position = "0 0"; + Extent = "202 39"; + isContainer = "1"; + HorizSizing = "width"; + Visible = "0"; + + new GuiTextCtrl(){ + Position = "1 1"; + Extent = "39 16"; + Profile = "ToolsGuiTextRightProfile"; + text = "Material"; + }; + new GuiTextEditCtrl(){ + internalName = "selMaterialName"; + Profile = "ToolsGuiTextEditProfile"; + AltCommand = "MaterialEditorGui.setMaterialDirty();MaterialEditorGui.updateActiveMaterialName($ThisControl.getText());"; // needs hookup + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "45 0"; + Extent = "158 18"; + text = ""; + HorizSizing = "width"; + }; + new GuiTextCtrl(){ + Position = "1 21"; + Extent = "39 16"; + Profile = "ToolsGuiTextRightProfile"; + text = "Target"; + }; + new GuiTextCtrl(){ // mesh name should not include the path + internalName = "selMaterialMapTo"; // will use the first child found with that name if called from a previous parent even if it is invisable. + Position = "46 21"; + Extent = "141 16"; + HorizSizing = "width"; + VertSizing = "bottom"; + text = ""; + }; + }; + new GuiContainer(MatEdTargetMode){ // Selection Mode + Position = "0 0"; + Extent = "202 39"; + isContainer = "1"; + HorizSizing = "width"; + Visible = "1"; + + new GuiBitmapButtonCtrl(){ + Profile = "ToolsGuiButtonProfile"; + Position = "186 23"; + Extent = "17 17"; + HorizSizing = "left"; + tooltip = "Swap material on the object with existing"; + bitmap = "tools/materialEditor/gui/change-material-btn"; + command = "materialSelector.showDialog(\"MaterialEditorGui.showMaterialChangeSaveDialog\");"; + }; + + new GuiTextEditCtrl(){ + internalName = "selMaterialName"; + Profile = "ToolsGuiTextEditProfile"; + AltCommand = "MaterialEditorGui.setMaterialDirty();MaterialEditorGui.updateActiveMaterialName($ThisControl.getText());"; // needs hookup + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "76 21"; + Extent = "107 18"; + text = "myMaterial 1"; + HorizSizing = "width"; + }; + new GuiTextCtrl(){ // mesh name should not include the path + internalName = "selMaterialMapTo"; + Profile = "ToolsGuiTextRightProfile"; + Position = "1 1"; + Extent = "70 16"; + HorizSizing = "right"; + VertSizing = "bottom"; + text = ""; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + Position = "1 21"; + Extent = "70 16"; + HorizSizing = "right"; + VertSizing = "bottom"; + text = "Material"; + }; + new GuiPopupMenuCtrlEx(SubMaterialSelector){ // needs hookup will show the name of the current mesh Maped to + Profile = "ToolsGuiPopUpMenuProfile"; + Position = "76 0"; + Extent = "126 17"; + HorizSizing = "width"; + VertSizing = "bottom"; + text = ""; + tooltip = "Target Material"; + Command = "SubMaterialSelector.onSelect();"; + reverseTextList = "0"; + }; + }; + }; + + // make this shorter //////////////////////////////////////////////////////////////////////////// + new GuiScrollCtrl(matEd_scrollControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; //height + position = "0 65"; + Extent = "202 603"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiStackControl(MatEd_scrollContents) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "187 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiPopUpMenuCtrl() { + canSaveDynamicFields = "0"; + internalName = "MaterialLayerCtrl"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuTabProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "112 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.changeLayer( $ThisControl.getText() );"; + ToolTip = "Changes the material layer being edited"; + hovertime = "1000"; + text = "Layer 0"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "185 0"; + Caption = "Basic Texture Maps"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "185 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ // Diffuse Map + profile="ToolsGuiDefaultProfile"; + isContainer = "1"; + position = "6 21"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "diffuseMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"diffuse\", 1);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Change the Active Diffuse Map for this layer"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Diffuse Map"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "diffuseMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "134 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiSwatchButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "colorTintSwatch"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "55 33"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF(materialEd_PreviewMaterial.diffuseColor[MaterialEditorGui.currentLayer], \"MaterialEditorGui.updateColorMultiply\");"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl(){ + profile="ToolsGuiDefaultProfile"; + text = "Color"; + position = "74 34"; + Extent = "30 15"; + }; + new GuiButtonCtrl(){ + profile="ToolsGuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command = "MaterialEditorGui.updateTextureMap(\"diffuse\", 1);"; + + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"diffuse\", 0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + new GuiBitmapCtrl(){ + position="6 75"; + extent ="175 2"; + HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + new GuiContainer(){ // Normal Map + profile="ToolsGuiDefaultProfile"; + isContainer = "1"; + position = "6 79"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "normalMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Normal Map"; + maxLength = "1024"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"normal\", 1);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Change the active Normal Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "normalMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "143 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="ToolsGuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command = "MaterialEditorGui.updateTextureMap(\"normal\", 1);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"normal\", 0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + new GuiBitmapCtrl(){ + position="6 360"; + extent ="175 2"; + HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + new GuiContainer(){ // spec Map + profile="ToolsGuiDefaultProfile"; + isContainer = "1"; + position = "6 364"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "specMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Spec Map"; + maxLength = "1024"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateSpecMap(1);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Change the active Tone Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "specMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "143 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="ToolsGuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command="MaterialEditorGui.updateSpecMap(1);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateSpecMap(0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + }; + }; + new GuiRolloutCtrl(advancedTextureMapsRollout) { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "185 0"; + Caption = "Advanced Texture Maps"; + Expanded = false; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "185 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ // Detail Map + profile="ToolsGuiDefaultProfile"; + isContainer = "1"; + position = "6 193"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "detailMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"detail\", 1);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Change the active Detail Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + + new GuiTextCtrl() { // Detailmap Scale text + profile="ToolsGuiDefaultProfile"; + position = "56 34"; + Extent = "29 16"; + text ="Scale"; + }; + + new GuiTextEditCtrl() { // Detailmap Scale + profile="ToolsGuiNumericTextEditProfile"; + internalName = "detailScaleTextEdit"; + position = "87 33"; + Extent = "28 18"; + text ="0"; + maxLength = "2"; + AltCommand = "MaterialEditorGui.updateDetailScale($ThisControl.getText());"; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Detail Map"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "detailMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "143 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="ToolsGuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command = "MaterialEditorGui.updateTextureMap(\"detail\", 1);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"detail\", 0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + new GuiBitmapCtrl(){ + position="6 246"; + extent ="175 2"; + HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + + new GuiContainer(){ // Detail Normal Map + profile="ToolsGuiDefaultProfile"; + isContainer = "1"; + position = "6 136"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "detailNormalMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"detailNormal\", 1);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Change the active DetailNormal Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + + new GuiTextCtrl() { // Detail Normal Map Strength text + profile="ToolsGuiDefaultProfile"; + position = "56 34"; + Extent = "29 16"; + text ="Strength"; + }; + + new GuiTextEditCtrl() { // Detail Normal Map Strength + profile="ToolsGuiNumericTextEditProfile"; + internalName = "detailNormalStrengthTextEdit"; + position = "87 33"; + Extent = "28 18"; + text ="0"; + maxLength = "3"; + AltCommand = "MaterialEditorGui.updateDetailNormalStrength($ThisControl.getText());"; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Detail Normal Map"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "detailNormalMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "143 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="ToolsGuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command = "MaterialEditorGui.updateTextureMap(\"detailNormal\", 1);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"detailNormal\", 0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + new GuiBitmapCtrl(){ + position="6 189"; + extent ="175 2"; + HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + + new GuiContainer(){ // Overlay Map + profile="ToolsGuiDefaultProfile"; + isContainer = "1"; + position = "6 136"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "overlayMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"overlay\", 1);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Change the active Overlay Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Overlay Map"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "overlayMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "143 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="ToolsGuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command = "MaterialEditorGui.updateTextureMap(\"overlay\", 1);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"overlay\", 0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + new GuiBitmapCtrl(){ + position="6 189"; + extent ="175 2"; + HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + new GuiContainer(){ // light Map + profile="ToolsGuiDefaultProfile"; + isContainer = "1"; + position = "6 250"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "lightMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Light Map"; + maxLength = "1024"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"light\", 1);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Change the active light Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "lightMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "143 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="ToolsGuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command="MaterialEditorGui.updateTextureMap(\"light\", 1);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"light\", 0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + new GuiBitmapCtrl(){ + position="6 303"; + extent ="175 2"; + HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + new GuiContainer(){ // tone Map + profile="ToolsGuiDefaultProfile"; + isContainer = "1"; + position = "6 307"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + internalName = "toneMapDisplayBitmap"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Tone Map"; + maxLength = "1024"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"tone\", 1);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Change the active Tone Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "toneMapNameText"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "143 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="ToolsGuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "134 34"; + Extent = "40 16"; + buttonType = "PushButton"; + command="MaterialEditorGui.updateTextureMap(\"tone\", 1);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "177 34"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateTextureMap(\"tone\", 0);"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "195 0"; + Caption = "Accumulation Properties"; + Expanded = false; + Margin = "-1 0 0 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "195 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ // enable/disable + profile="GuiTransparentProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "195 24"; + HorizSizing = "width"; + + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "accuCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 7"; + Extent = "57 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateAccuCheckbox($ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Enables the use of Pixel Specular for this layer."; + hovertime = "1000"; + text = "Enable"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + + new GuiContainer(){ // scale + profile="GuiTransparentProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "195 24"; + HorizSizing = "width"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 3"; + Extent = "54 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Scale"; + maxLength = "1024"; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "70 3"; + Extent = "96 20"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "accuScaleSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + Extent = "61 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"accuScale[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuScale[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Sets the scale of the accu map."; + hovertime = "1000"; + range = "0.03125 32"; + ticks = "0"; + value = "1"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "accuScaleTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "64 0"; + Extent = "29 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuScale[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + hovertime = "1000"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "1"; + maxLength = "3"; + }; + }; + }; + + new GuiContainer(){ // direction + profile="GuiTransparentProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "195 24"; + HorizSizing = "width"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 3"; + Extent = "54 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Direction"; + maxLength = "1024"; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "70 3"; + Extent = "96 20"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "accuDirectionSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + Extent = "61 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"accuDirection[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuDirection[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Sets the direction of the accu map."; + hovertime = "1000"; + range = "-1 1"; + ticks = "0"; + value = "-1"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "accuDirectionTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "64 0"; + Extent = "29 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuDirection[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + hovertime = "1000"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "-1"; + maxLength = "3"; + }; + }; + }; + new GuiContainer(){ // strength + profile="GuiTransparentProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "195 24"; + HorizSizing = "width"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 3"; + Extent = "54 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Strength"; + maxLength = "1024"; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "70 3"; + Extent = "96 20"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "accuStrengthSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + Extent = "61 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"accuStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Sets the strength of the accu map."; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0.6"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "accuStrengthTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "64 0"; + Extent = "29 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + hovertime = "1000"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "0.6"; + maxLength = "3"; + }; + }; + }; + new GuiContainer(){ // coverage + profile="GuiTransparentProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "195 24"; + HorizSizing = "width"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 3"; + Extent = "54 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Coverage"; + maxLength = "1024"; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "70 3"; + Extent = "96 20"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "accuCoverageSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + Extent = "61 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"accuCoverage[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuCoverage[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Sets the coverage of the accu map."; + hovertime = "1000"; + range = "0 2"; + ticks = "0"; + value = "1"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "accuCoverageTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "64 0"; + Extent = "29 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuCoverage[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + hovertime = "1000"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "1"; + maxLength = "3"; + }; + }; + }; + new GuiContainer(){ // specular + profile="GuiTransparentProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "195 24"; + HorizSizing = "width"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 3"; + Extent = "54 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Specular scale"; + maxLength = "1024"; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "70 3"; + Extent = "96 20"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "accuSpecularSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + Extent = "61 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"accuSpecular[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuSpecular[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);"; + tooltipprofile = "GuiDefaultProfile"; + ToolTip = "Sets the specular scale over the accu map."; + hovertime = "1000"; + range = "0 2"; + ticks = "0"; + value = "1"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "accuSpecularTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "64 0"; + Extent = "29 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"accuSpecular[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + hovertime = "1000"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "1"; + maxLength = "3"; + }; + }; + }; + + }; + }; + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "185 0"; + Caption = "Lighting Properties"; + Expanded = false; + Margin = "-1 0 0 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "185 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ // specular + profile = "ToolsGuiTransparentProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "185 44"; + HorizSizing = "width"; + + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "pixelSpecularCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 4"; + Extent = "57 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateSpecularCheckbox($ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Enables the use of Pixel Specular for this layer."; + hovertime = "1000"; + text = "Specular"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiSwatchButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "specularColorSwatch"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "69 4"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF(materialEd_PreviewMaterial.specular[MaterialEditorGui.currentLayer], \"MaterialEditorGui.updateSpecular\");"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + position = "9 26"; + Extent = "72 16"; + text = "Spec strength"; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "91 4"; + Extent = "96 20"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "specularPowerSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "61 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"specularPower[\" @ MaterialEditorGui.currentLayer @ \"]\", mCeil($ThisControl.getValue()), true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularPower[\" @ MaterialEditorGui.currentLayer @ \"]\", mCeil($ThisControl.getValue()), true, false);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Sets the hardness of the Pixel Specular value."; + hovertime = "1000"; + range = "1 128"; + ticks = "0"; + value = "1"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "specularPowerTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "64 0"; + Extent = "29 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularPower[\" @ MaterialEditorGui.currentLayer @ \"]\", mCeil($ThisControl.getValue()));"; + hovertime = "1000"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "32"; + maxLength = "3"; + }; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "91 26"; + Extent = "96 20"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "specularStrengthSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "61 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"specularStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Sets the strength of the Pixel Specular value."; + hovertime = "1000"; + range = "0 5"; + ticks = "0"; + value = "1"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "specularStrengthTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "64 0"; + Extent = "29 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + hovertime = "1000"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "1"; + maxLength = "3"; + }; + }; + }; + new GuiContainer(){ // glow emissive + profile = "ToolsGuiTransparentProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "185 22"; + HorizSizing = "width"; + + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "glowCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "70 4"; + Extent = "40 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"glow[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Determines if this layer will Glow or not."; + hovertime = "1000"; + text = "Glow"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "emissiveCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 4"; + Extent = "60 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"emissive[\" @ MaterialEditorGui.currentLayer @ \"]\",$ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Emissive causes an object to not be affected by lights. Good for light sources."; + hovertime = "1000"; + text = "Emissive"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + new GuiContainer(){ // parallax + profile = "ToolsGuiTransparentProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "185 24"; + HorizSizing = "width"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 3"; + Extent = "54 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Parallax"; + maxLength = "1024"; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "70 3"; + Extent = "115 20"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "parallaxSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + Extent = "82 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"parallaxScale[\" @ MaterialEditorGui.currentLayer @ \"]\",$ThisControl.getValue(), true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateActiveMaterial(\"parallaxScale[\" @ MaterialEditorGui.currentLayer @ \"]\",$ThisControl.getValue(), true, false);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Parallax Scale"; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "parallaxTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "85 0"; + Extent = "29 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateActiveMaterial(\"parallaxScale[\" @ MaterialEditorGui.currentLayer @ \"]\",$ThisControl.getValue());"; + hovertime = "1000"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "0"; + maxLength = "3"; + }; + }; + }; + new GuiContainer(){ + profile = "ToolsGuiTransparentProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "185 84"; + HorizSizing = "width"; + + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "useAnisoCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 4"; + Extent = "108 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"useAnisotropic[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Enables the use of anisotropic filtering for this layer."; + hovertime = "1000"; + text = "Anisotropic filtering"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "vertLitCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 25"; + Extent = "102 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"vertLit[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Enables the use of vertex lighting for this layer."; + hovertime = "1000"; + text = "Vertex lit"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "vertLitCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "113 25"; + Extent = "102 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"vertColor[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Multiply vertex colors with diffuse colors for this layer."; + hovertime = "1000"; + text = "Vertex colors"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "subSurfaceCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 46"; + Extent = "79 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"subSurface[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Enables the use of subsurface scattering for this layer."; + hovertime = "1000"; + text = "Sub Surface"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + }; + }; + new GuiRolloutCtrl(materialAnimationPropertiesRollout) { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "185 0"; + Caption = "Animation Properties"; + Expanded = false; + Margin = "-1 0 0 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "185 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ // Rotation Animation Properties + profile="inspectorStyleRolloutInnerProfile"; + isContainer = "1"; + position = "-1 96"; + Extent = "185 94"; + HorizSizing = "width"; + + new GuiCheckboxCtrl() { + canSaveDynamicFields = "0"; + internalName = "RotationAnimation"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiInspectorCheckBoxTitleProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 -1"; + Extent = "112 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateAnimationFlags();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Rotation Animation"; + maxLength = "1024"; + }; + + new GuiControl(){ + class = "AggregateControl"; + position = "0 29"; + Extent = "135 20"; + + new GuiTextCtrl(){ // u + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 1"; + Extent = "12 16"; + text = "U"; + }; + + new GuiSliderCtrl() { // u + Profile = "ToolsGuiSliderProfile"; + internalName = "RotationSliderU"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "25 2"; + Extent = "68 15"; + Command = "MaterialEditorGui.updateRotationOffset(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateRotationOffset(true, false);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Change U Scroll Direction"; + hovertime = "1000"; + range = "-1 0"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl(){ // u + internalName = "RotationTextEditU"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "98 0"; + Extent = "34 18"; + text = "0"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl);"; + }; + }; + + + + new GuiControl() { + class = "AggregateControl"; + position = "0 50"; + Extent = "135 20"; + + new GuiTextCtrl(){ // v + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 1"; + Extent = "12 16"; + text = "V"; + }; + + new GuiSliderCtrl() { // v + Profile = "ToolsGuiSliderProfile"; + internalName = "RotationSliderV"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "25 2"; + Extent = "68 15"; + Command = "MaterialEditorGui.updateRotationOffset(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateRotationOffset(true, false);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Change V Scroll Direction"; + hovertime = "1000"; + range = "-1 0"; + ticks = "0"; + value = "0"; + }; + + new GuiTextEditCtrl(){ // v + internalName = "RotationTextEditV"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "98 0"; + Extent = "34 18"; + text = "0"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateRotationOffset();"; + }; + }; + new GuiTextCtrl(){ // Pivot Point + HorizSizing = "right"; + VertSizing = "bottom"; + position = "98 16"; + Extent = "34 16"; + text = "Pivot"; + }; + new GuiBitmapCtrl(){ + HorizSizing = "right"; + VertSizing = "bottom"; + position = "136 20"; + Extent = "48 48"; + isContainer = true; + bitmap=""; + + new GuiBitmapCtrl(){ + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "48 48"; + bitmap="tools/materialEditor/gui/cubemapBtnBorder_n"; + }; + + new GuiBitmapCtrl(){ //horizontal bar + internalName = "RotationCrosshair"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 20"; + Extent = "7 7"; + MinExtent = "0 0"; + bitmap="tools/gui/images/crosshair_blue"; + }; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "0 70"; + Extent = "187 20"; + + new GuiTextCtrl(){ // Speed + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 0"; + Extent = "43 16"; + text = "Speed"; + }; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "RotationSpeedSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "49 3"; + Extent = "95 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateRotationSpeed(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateRotationSpeed(true, false);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Scrolling Speed"; + hovertime = "1000"; + range = "-10 10"; + ticks = "0"; + value = "0"; + }; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "RotationSpeedTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "150 1"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateRotationSpeed();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + }; + }; + new GuiContainer(){ // Scroll Animation Properties + profile="inspectorStyleRolloutInnerProfile"; + isContainer = "1"; + position = "-1 191"; + Extent = "185 94"; + HorizSizing = "width"; + + new GuiCheckboxCtrl() { + canSaveDynamicFields = "0"; + internalName = "ScrollAnimation"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiInspectorCheckBoxTitleProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 -1"; + Extent = "112 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + Command = "MaterialEditorGui.updateAnimationFlags();"; + text = "Scroll Animation"; + maxLength = "1024"; + }; + + + new GuiControl(){ + class = "AggregateControl"; + position = "0 29"; + Extent = "135 20"; + + new GuiTextCtrl(){ // u + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 1"; + Extent = "12 16"; + text = "U"; + }; + + new GuiSliderCtrl() { // u + Profile = "ToolsGuiSliderProfile"; + internalName = "ScrollSliderU"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "25 2"; + Extent = "68 15"; + Command = "MaterialEditorGui.updateScrollOffset(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateScrollOffset(true, false);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Change U Scroll Direction"; + hovertime = "1000"; + range = "-1 1"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl(){ // u + internalName = "ScrollTextEditU"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "98 0"; + Extent = "34 18"; + text = "0"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateScrollOffset();"; + }; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "0 50"; + Extent = "135 20"; + + new GuiTextCtrl(){ // v + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 1"; + Extent = "12 16"; + text = "V"; + }; + + new GuiSliderCtrl() { // v + Profile = "ToolsGuiSliderProfile"; + internalName = "ScrollSliderV"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "25 2"; + Extent = "68 15"; + Command = "MaterialEditorGui.updateScrollOffset(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateScrollOffset(true, false);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Change V Scroll Direction"; + hovertime = "1000"; + range = "-1 1"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl(){ // v + internalName = "ScrollTextEditV"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "98 0"; + Extent = "34 18"; + text = "0"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateScrollOffset();"; + }; + }; + new GuiTextCtrl(){ // Direction Offset + HorizSizing = "right"; + VertSizing = "bottom"; + position = "98 16"; + Extent = "34 16"; + text = "Offset"; + }; + new GuiBitmapCtrl(){ + HorizSizing = "right"; + VertSizing = "bottom"; + position = "136 20"; + Extent = "48 48"; + isContainer = true; + bitmap=""; + + new GuiBitmapCtrl(){ + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "48 48"; + bitmap="tools/materialEditor/gui/cubemapBtnBorder_n"; + }; + new GuiBitmapCtrl(){ //vertical bar + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 20"; + Extent = "7 7"; + MinExtent = "7 7"; + bitmap="tools/gui/images/crosshair"; + }; + new GuiBitmapCtrl(){ //horizontal bar + internalName = "ScrollCrosshair"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 20"; + Extent = "7 7"; + MinExtent = "0 0"; + bitmap="tools/gui/images/crosshair_blue"; + }; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "0 70"; + Extent = "187 20"; + + new GuiTextCtrl(){ // Speed + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 0"; + Extent = "43 16"; + text = "Speed"; + }; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "ScrollSpeedSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "49 3"; + Extent = "95 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateScrollSpeed(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateScrollSpeed(true, false);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Scrolling Speed"; + hovertime = "1000"; + range = "0 10"; + ticks = "0"; + value = "0"; + }; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "ScrollSpeedTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "150 1"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl);MaterialEditorGui.updateScrollSpeed();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + }; + }; + new GuiContainer(){ // Wave Animation Properties + profile="inspectorStyleRolloutInnerProfile"; + isContainer = "1"; + position = "-1 287"; + Extent = "185 85"; + HorizSizing = "width"; + + new GuiCheckboxCtrl() { + Profile = "ToolsGuiInspectorCheckBoxTitleProfile"; + internalName = "WaveAnimation"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 -1"; + Extent = "155 16"; + MinExtent = "8 2"; + text = " Wave Animation"; + Command = "MaterialEditorGui.updateAnimationFlags();"; + groupNum = "-1"; + }; + + new GuiCheckboxCtrl() { + Profile = "ToolsGuiCheckBoxProfile"; + internalName = "ScaleAnimation"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "139 24"; + Extent = "45 16"; + MinExtent = "8 2"; + text = "Scale"; + Command = "MaterialEditorGui.updateAnimationFlags();"; + groupNum = "-1"; + }; + + new GuiTextCtrl() { + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 22"; + Extent = "59 16"; + text = " Wave Type"; + }; + new GuiContainer(){ // Wave Radio Button container + profile = "ToolsGuiDefaultProfile"; + internalName = "WaveButtonContainer"; + position = "72 25"; + Extent = "49 13"; + isContainer = "1"; + + new GuiBitmapButtonCtrl(){ + profile = "ToolsGuiDefaultProfile"; + buttonType = "RadioButton"; + position = "1 0"; + Extent = "13 13"; + bitmap = "tools/materialEditor/gui/wav-sine"; + command = "MaterialEditorGui.updateWaveType();"; + tooltip="Sine Wave"; + hovertime = "1000"; + groupNum = "0"; + waveType = "Sin"; + }; + new GuiBitmapButtonCtrl(){ + profile = "ToolsGuiDefaultProfile"; + buttonType = "RadioButton"; + position = "17 0"; + Extent = "13 13"; + bitmap = "tools/materialEditor/gui/wav-triangle"; + command = "MaterialEditorGui.updateWaveType();"; + tooltip="Triangle Wave"; + hovertime = "1000"; + groupNum = "0"; + waveType = "Triangle"; + }; + new GuiBitmapButtonCtrl(){ + profile = "ToolsGuiDefaultProfile"; + buttonType = "RadioButton"; + position = "33 0"; + Extent = "13 13"; + bitmap = "tools/materialEditor/gui/wav-square"; + command = "MaterialEditorGui.updateWaveType();"; + tooltip="Square Wave"; + hovertime = "1000"; + groupNum = "0"; + waveType = "Square"; + }; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "0 61"; + Extent = "187 20"; + + new GuiTextCtrl() { + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "16 1"; + Extent = "64 16"; + text = "Frequency"; + }; + + new GuiTextEditCtrl() { // frequence + canSaveDynamicFields = "0"; + internalName = "WaveTextEditFreq"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "150 1"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateWaveFreq();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + new GuiSliderCtrl() { // freqency + canSaveDynamicFields = "0"; + internalName = "WaveSliderFreq"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 3"; + Extent = "74 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateWaveFreq(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateWaveFreq(true, false);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Changes Wave Frequency"; + hovertime = "1000"; + range = "0 10"; + ticks = "0"; + value = "0"; + }; + + }; + + new GuiControl() { + class = "AggregateControl"; + position = "0 40"; + Extent = "187 20"; + + new GuiTextCtrl() { + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "21 1"; + Extent = "64 16"; + text = "Amplitude"; + }; + + new GuiTextEditCtrl() { // amplitude + Profile = "ToolsGuiTextEditProfile"; + internalName = "WaveTextEditAmp"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "150 1"; + Extent = "34 18"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateWaveAmp();"; + hovertime = "1000"; + text = "0"; + }; + new GuiSliderCtrl() { // amplitude + canSaveDynamicFields = "0"; + internalName = "WaveSliderAmp"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 3"; + Extent = "74 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateWaveAmp(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateWaveAmp(true, false);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Changes Wave Amplitude"; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0"; + }; + + }; + }; + new GuiContainer(){ // image Sequence Animation Properties + profile="inspectorStyleRolloutInnerProfile"; + isContainer = "1"; + position = "-1 373"; + Extent = "185 66"; + HorizSizing = "width"; + + new GuiCheckboxCtrl() { + Profile = "ToolsGuiInspectorCheckBoxTitleProfile"; + internalName = "SequenceAnimation"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "4 0"; + Extent = "130 16"; + MinExtent = "8 2"; + text = "Image Sequence"; + Command = "MaterialEditorGui.updateAnimationFlags();"; + groupNum = "-1"; + }; + + + new GuiControl() { + class = "AggregateControl"; + position = "0 21"; + Extent = "187 20"; + + new GuiTextCtrl() { + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "64 16"; + text = "Frames / Sec"; + }; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "SequenceTextEditFPS"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "150 1"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateSequenceFPS();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "0"; + maxLength = "1024"; + }; + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "SequenceSliderFPS"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 3"; + Extent = "74 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateSequenceFPS(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateSequenceFPS(true, false);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "How many frames to display per second."; + hovertime = "1000"; + range = "0 30"; + ticks = "0"; + value = "0"; + }; + }; + + new GuiControl() { + class = "AggregateControl"; + position = "0 42"; + Extent = "187 20"; + + new GuiTextCtrl() { + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "33 1"; + Extent = "43 16"; + text = "Frames"; + }; + + new GuiTextEditCtrl() { // size + Profile = "ToolsGuiTextEditProfile"; + internalName = "SequenceTextEditSSS"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "150 1"; + Extent = "34 18"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateSequenceSSS();"; + hovertime = "1000"; + text = "0"; + }; + new GuiSliderCtrl() { //size + canSaveDynamicFields = "0"; + internalName = "SequenceSliderSSS"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 3"; + Extent = "74 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateSequenceSSS(true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateSequenceSSS(true, false);"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "How many frames in the sequence."; + hovertime = "1000"; + range = "0 100"; + ticks = "0"; + value = "0"; + }; + }; + }; + }; + }; + new GuiRolloutCtrl(materialAdvancedPropertiesRollout) { // Advanced Properties Group + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "202 0"; + Caption = "Advanced (all layers)"; + Expanded = false; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "202 16"; + + new GuiContainer(){ // Transparentcy Properties + Profile = "ToolsGuiDefaultProfile"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "210 89"; + + new GuiPopUpMenuCtrl() { + internalName = "blendingTypePopUp"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "3 2"; + Extent = "83 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"translucentBlendOp\",$ThisControl.getValue());"; + ToolTip = "Determines the type of blending to be applied on the transparent object."; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "LerpAlpha"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "alphaTestCheckBox"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "3 39"; + Extent = "106 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"alphaTest\",$ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "When enabled, caused pixels under a specific alpha threshold to get discarded rather than be computed. Only valid for transparent objects."; + hovertime = "1000"; + text = "Alpha Threshold"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + + new GuiControl() { + class = "AggregateControl"; + HorizSizing = "width"; + position = "100 39"; + Extent = "187 20"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "alphaRefSlider"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 3"; + Extent = "45 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"alphaRef\",$ThisControl.getValue(), true, true );"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"alphaRef\",$ThisControl.getValue(), true, false );"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Sets the minimum transparency value that a pixel must have to be calculated. Anything below this value will simply not be rendered at all."; + hovertime = "1000"; + range = "0 255"; + ticks = "0"; + value = "0"; + }; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "alphaRefTextEdit"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "49 0"; + Extent = "27 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"alphaRef\",$ThisControl.getValue());"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "100"; + maxLength = "1024"; + }; + }; + + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "transZWriteCheckBox"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "3 23"; + Extent = "112 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"translucentZWrite\",$ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Can be used to help force a proper Z-Ordering when Z-Ordering issues occur. Only valid for materials with Transparency."; + hovertime = "1000"; + text = "Transparent Z-Write"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "translucentCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "89 3"; + Extent = "107 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"translucent\",$ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Sets material to use transparent blending modes."; + hovertime = "1000"; + text = "Transparency"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "castShadows"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "3 55"; + Extent = "112 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"castShadows\", $ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Object casts shadows."; + hovertime = "1000"; + text = "Cast Shadows"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "castDynamicShadows"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "3 70"; + Extent = "112 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"castDynamicShadows\", $ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Object casts dynamic shadows."; + hovertime = "1000"; + text = "Dynamic Shadows"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "doubleSidedCheckBox"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "105 55"; + Extent = "85 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"doubleSided\",$ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Determines if this material will be rendered from both sides of the polygon, or just the \'front facing\' side. "; + hovertime = "1000"; + text = "Double Sided"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + new GuiContainer(){ // Reflection Properties + Profile = "ToolsGuiDefaultProfile"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 95"; + Extent = "212 25"; + + new GuiBitmapCtrl(){ + position="2 2"; + extent ="192 2"; + HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + // Reflection Properties Text + new GuiTextCtrl(matEd_reflectionPropertiesText) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "91 6"; + Extent = "80 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Reflection"; + maxLength = "1024"; + }; + + new GuiPopUpMenuCtrl() { + canSaveDynamicFields = "0"; + internalName = "reflectionTypePopUp"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "3 6"; + Extent = "84 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateReflectionType($ThisControl.getText());"; + ToolTip = "Determines the type of blending to be applied on the transparent object."; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiButtonCtrl(matEd_cubemapEditBtn){ + internalName = "matEd_cubemapEditBtn"; + profile ="ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "143 6 28"; + Extent = "33 18"; + Command = "MaterialEditorGui.showCubemapEditor();"; + text = "Edit"; + }; + }; + new GuiContainer(){ // Behavior Properties + Profile = "ToolsGuiDefaultProfile"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 122"; + Extent = "212 80"; + + new GuiBitmapCtrl(){ + position="2 2"; + extent ="192 2"; + HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + new GuiTextCtrl() { + text = "Effect Colors[0:1]"; + position = "1 6"; + extent = "86 15"; + profile = "ToolsGuiDefaultProfile"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "89 6"; + extent = "16 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiInspectorSwatchButtonProfile"; + visible = "1"; + active = "1"; + command = "getColorF(materialEd_PreviewMaterial.effectColor[0], \"MaterialEditorGui.updateEffectColor0\");"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "effectColor0Swatch"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "109 6"; + extent = "16 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiInspectorSwatchButtonProfile"; + visible = "1"; + active = "1"; + command = "getColorF(materialEd_PreviewMaterial.effectColor[1], \"MaterialEditorGui.updateEffectColor1\");"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "effectColor1Swatch"; + }; + new GuiCheckBoxCtrl() { + text = "Show Footprints"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "1 24"; + extent = "93 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiCheckBoxProfile"; + visible = "1"; + active = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"showFootprints\", $ThisControl.getValue());"; + tooltipProfile = "ToolsGuiDefaultProfile"; + tooltip = "Enables Player footprints on surfaces that use this Material."; + hovertime = "1000"; + isContainer = "0"; + internalName = "showFootprintsCheckbox"; + }; + new GuiCheckBoxCtrl() { + text = "Show Dust"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "110 24"; + extent = "68 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiCheckBoxProfile"; + visible = "1"; + active = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"showDust\", $ThisControl.getValue());"; + tooltipProfile = "ToolsGuiDefaultProfile"; + tooltip = "Enables dust particles on surfaces that use this Material."; + hovertime = "1000"; + isContainer = "0"; + internalName = "showDustCheckbox"; + }; + new GuiTextCtrl() { + text = "Footstep sound"; + position = "1 43"; + extent = "77 15"; + profile = "ToolsGuiDefaultProfile"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "None"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "80 42"; + extent = "105 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.updateBehaviorSound(\"Footstep\", $ThisControl.getText());"; + tooltipProfile = "ToolsGuiToolTipProfile"; + tooltip = "Determines the footstep sound to use when the Player walks on this Material."; + hovertime = "1000"; + isContainer = "0"; + internalName = "footstepSoundPopUp"; + }; + new GuiTextCtrl() { + text = "Impact sound"; + position = "1 63"; + extent = "64 15"; + profile = "ToolsGuiDefaultProfile"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "None"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "80 62"; + extent = "105 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.updateBehaviorSound(\"Impact\", $ThisControl.getText());"; + tooltipProfile = "ToolsGuiToolTipProfile"; + tooltip = "Determines the impact sound to use when an object collides with this Material."; + hovertime = "1000"; + isContainer = "0"; + internalName = "impactSoundPopUp"; + }; + }; + }; + }; + }; + + }; + new GuiBitmapButtonCtrl(MatEd_phoBreadcrumb) { //Go back to previous editor + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "-1 0"; + Extent = "20 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + //Command = "materialSelector.showDialog(\"MaterialEditorGui.switchMaterial\");"; + hovertime = "1000"; + bitmap = "tools/gui/images/folderUp"; + tooltip = "Go back to previous editor"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(MatEd_editMaterial) { //Select and Edit an Existing Material + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "86 1"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "materialSelector.showDialog(\"MaterialEditorGui.switchMaterial\");"; + hovertime = "1000"; + bitmap = "tools/gui/images/open-file"; + tooltip = "Open Existing Material"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + // New Button + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "106 1"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.createNewMaterial();"; + hovertime = "1000"; + groupNum = "-1"; + text =""; + tooltip = "Create New Material"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/new"; + }; + // Save Button + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "123 1"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.save();"; + hovertime = "1000"; + groupNum = "-1"; + text =""; + tooltip = "Save Material (ALT S)"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/save-icon"; + }; + new GuiBitmapCtrl(){ + position = "147 1"; + Extent = "2 16"; + minExtent = "2 16"; + HorizSizing = "left"; + VertSizing = "bottom"; + bitmap = "tools/gui/images/separator-h"; + }; + // Revert Material + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "151 1"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.refreshMaterial();"; + hovertime = "1000"; + tooltip = "Revert Material to Saved"; + text = ""; + bitmap = "tools/gui/images/reset-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + // Clear Material + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "168 1"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.clearMaterial();"; + hovertime = "1000"; + tooltip = "Clear All Material Properties"; + text = ""; + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + // Delete Material + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "185 1"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + tooltip = "Delete Material from File"; + text = ""; + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + Command = "MaterialEditorGui.deleteMaterial();"; + }; + }; + }; +}; + +// Here are all of the other gui elements that were included in the original gui============================================ +// EDIT: Instead of showing the faded bitmap, were going to just go ahead and push the controls; that way they are sitting +// on top of the editor gui, while being nonmodal +new GuiControl(matEdNonModalGroup, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiOverlayProfile"; + Enabled = "1"; + isContainer = "1"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(matEdSaveDialog) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "197 221"; + Extent = "336 104"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "0"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Material Not Saved!"; + + new GuiButtonCtrl(matEd_notSavedWindow_Save) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 69"; + Extent = "121 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "matEdSaveDialog.dialogSave();"; + hovertime = "1000"; + text = "Save"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl(matEd_materialNotSavedText) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 35"; + Extent = "318 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "This material has unsaved changes. Do you wish to save?"; + maxLength = "1024"; + }; + new GuiButtonCtrl(matEd_notSavedWindow_DontSave) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "157 69"; + Extent = "80 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "matEdSaveDialog.dialogDontSave();"; + hovertime = "1000"; + text = "Don\'t Save"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl(matEd_notSavedWindow_Cancel) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "245 69"; + Extent = "80 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "matEdSaveDialog.dialogCancel();"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + new GuiWindowCtrl(matEd_changeCategoryDialog) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "288 144"; + Extent = "248 133"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "0"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Change Material Category"; + + new GuiPopUpMenuCtrl(matEd_changeCategory_categoryList) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 32"; + Extent = "183 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiButtonCtrl(matEd_changeCategory_okayBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 97"; + Extent = "137 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.okayChangeCategoryDialog();"; + hovertime = "1000"; + text = "Update Category"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl(matEd_changeCategory_cancelBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "159 97"; + Extent = "80 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.cancelChangeCategoryDialog();"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl(matEd_changeCategory_addCatBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "200 60"; + Extent = "39 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.addCategory();"; + hovertime = "1000"; + text = "New"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextEditCtrl(matEd_changeCategory_catNameEntry) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 60"; + Extent = "183 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + new GuiWindowCtrl(matEd_changeCategory_ErrorDialog) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 18"; + Extent = "232 113"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "0"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Category Change Error"; + + new GuiButtonCtrl(matEd_changeCategory_Error_Button) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 81"; + Extent = "80 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.okChangeCategoryErrorDialog();"; + hovertime = "1000"; + text = "Ok"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl(matEd_changeCategory_error_Text) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 31"; + Extent = "215 40"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Text goes here!"; + maxLength = "1024"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/matEd_cubePreview.max b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_cubePreview.max new file mode 100644 index 000000000..6feb85fc4 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_cubePreview.max differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/matEd_cylinderButt_d.jpg b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_cylinderButt_d.jpg new file mode 100644 index 000000000..e61b7543a Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_cylinderButt_d.jpg differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/matEd_cylinderButt_h.jpg b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_cylinderButt_h.jpg new file mode 100644 index 000000000..0dfc3466b Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_cylinderButt_h.jpg differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/matEd_cylinderButt_n.jpg b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_cylinderButt_n.jpg new file mode 100644 index 000000000..f64864a13 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_cylinderButt_n.jpg differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/matEd_cylinderPreview.max b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_cylinderPreview.max new file mode 100644 index 000000000..7259a5df0 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_cylinderPreview.max differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/matEd_mappedMat.jpg b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_mappedMat.jpg new file mode 100644 index 000000000..4328f2a4d Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_mappedMat.jpg differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/matEd_pyramidPreview.max b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_pyramidPreview.max new file mode 100644 index 000000000..06b4b48d1 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_pyramidPreview.max differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/matEd_sphereButt_d.jpg b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_sphereButt_d.jpg new file mode 100644 index 000000000..b693e34d6 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_sphereButt_d.jpg differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/matEd_sphereButt_h.jpg b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_sphereButt_h.jpg new file mode 100644 index 000000000..d3a8ca6ed Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_sphereButt_h.jpg differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/matEd_sphereButt_n.jpg b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_sphereButt_n.jpg new file mode 100644 index 000000000..e2244ab55 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_sphereButt_n.jpg differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/matEd_spherePreview.max b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_spherePreview.max new file mode 100644 index 000000000..71485ac86 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_spherePreview.max differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/matEd_torusKnotPreview.max b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_torusKnotPreview.max new file mode 100644 index 000000000..4e2bfec10 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_torusKnotPreview.max differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/matEd_torusPreview.max b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_torusPreview.max new file mode 100644 index 000000000..4e004500d Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/matEd_torusPreview.max differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/materialSelectorIcon_d.png b/Templates/BaseGame/game/tools/materialEditor/gui/materialSelectorIcon_d.png new file mode 100644 index 000000000..081e06e98 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/materialSelectorIcon_d.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/materialSelectorIcon_h.png b/Templates/BaseGame/game/tools/materialEditor/gui/materialSelectorIcon_h.png new file mode 100644 index 000000000..88795fd44 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/materialSelectorIcon_h.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/materialSelectorIcon_n.png b/Templates/BaseGame/game/tools/materialEditor/gui/materialSelectorIcon_n.png new file mode 100644 index 000000000..a563b88d2 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/materialSelectorIcon_n.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/mesh-selector-btn_d.png b/Templates/BaseGame/game/tools/materialEditor/gui/mesh-selector-btn_d.png new file mode 100644 index 000000000..81aa03f2d Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/mesh-selector-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/mesh-selector-btn_h.png b/Templates/BaseGame/game/tools/materialEditor/gui/mesh-selector-btn_h.png new file mode 100644 index 000000000..5ccbd9835 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/mesh-selector-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/mesh-selector-btn_n.png b/Templates/BaseGame/game/tools/materialEditor/gui/mesh-selector-btn_n.png new file mode 100644 index 000000000..62f65da52 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/mesh-selector-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/new-material_d.png b/Templates/BaseGame/game/tools/materialEditor/gui/new-material_d.png new file mode 100644 index 000000000..681da25dc Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/new-material_d.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/new-material_h.png b/Templates/BaseGame/game/tools/materialEditor/gui/new-material_h.png new file mode 100644 index 000000000..d13a6e4a5 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/new-material_h.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/new-material_n.png b/Templates/BaseGame/game/tools/materialEditor/gui/new-material_n.png new file mode 100644 index 000000000..4c509a909 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/new-material_n.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/pyramidpreview.dts b/Templates/BaseGame/game/tools/materialEditor/gui/pyramidpreview.dts new file mode 100644 index 000000000..285f42ae2 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/pyramidpreview.dts differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/screenFaded.png b/Templates/BaseGame/game/tools/materialEditor/gui/screenFaded.png new file mode 100644 index 000000000..a5125a3ab Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/screenFaded.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/scrollBox.jpg b/Templates/BaseGame/game/tools/materialEditor/gui/scrollBox.jpg new file mode 100644 index 000000000..bd15e5fcd Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/scrollBox.jpg differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/spherepreview.dts b/Templates/BaseGame/game/tools/materialEditor/gui/spherepreview.dts new file mode 100644 index 000000000..e7b208f61 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/spherepreview.dts differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/torusknotpreview.dts b/Templates/BaseGame/game/tools/materialEditor/gui/torusknotpreview.dts new file mode 100644 index 000000000..55208ac35 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/torusknotpreview.dts differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/torusknowpreview.dts b/Templates/BaseGame/game/tools/materialEditor/gui/torusknowpreview.dts new file mode 100644 index 000000000..e69de29bb diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/toruspreview.dts b/Templates/BaseGame/game/tools/materialEditor/gui/toruspreview.dts new file mode 100644 index 000000000..8c3153396 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/toruspreview.dts differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/unknownImage.png b/Templates/BaseGame/game/tools/materialEditor/gui/unknownImage.png new file mode 100644 index 000000000..21d75f311 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/unknownImage.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/unsavedWarn.png b/Templates/BaseGame/game/tools/materialEditor/gui/unsavedWarn.png new file mode 100644 index 000000000..cf7ecda6b Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/unsavedWarn.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-none_d.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-none_d.png new file mode 100644 index 000000000..d7629c669 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-none_d.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-none_h.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-none_h.png new file mode 100644 index 000000000..bf14a5ecd Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-none_h.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-none_i.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-none_i.png new file mode 100644 index 000000000..7fc641c93 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-none_i.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-none_n.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-none_n.png new file mode 100644 index 000000000..e28974ad7 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-none_n.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-sine_d.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-sine_d.png new file mode 100644 index 000000000..eb8e9c684 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-sine_d.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-sine_h.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-sine_h.png new file mode 100644 index 000000000..6570fe142 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-sine_h.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-sine_i.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-sine_i.png new file mode 100644 index 000000000..0008c320e Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-sine_i.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-sine_n.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-sine_n.png new file mode 100644 index 000000000..9595622a6 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-sine_n.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-square_d.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-square_d.png new file mode 100644 index 000000000..f51cbf301 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-square_d.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-square_h.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-square_h.png new file mode 100644 index 000000000..0643cd076 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-square_h.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-square_i.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-square_i.png new file mode 100644 index 000000000..1f6d750f5 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-square_i.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-square_n.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-square_n.png new file mode 100644 index 000000000..3a99a5aac Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-square_n.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-triangle_d.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-triangle_d.png new file mode 100644 index 000000000..2ca098768 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-triangle_d.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-triangle_h.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-triangle_h.png new file mode 100644 index 000000000..42549866f Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-triangle_h.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-triangle_i.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-triangle_i.png new file mode 100644 index 000000000..b63963b77 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-triangle_i.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/wav-triangle_n.png b/Templates/BaseGame/game/tools/materialEditor/gui/wav-triangle_n.png new file mode 100644 index 000000000..6f05c0175 Binary files /dev/null and b/Templates/BaseGame/game/tools/materialEditor/gui/wav-triangle_n.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/main.cs b/Templates/BaseGame/game/tools/materialEditor/main.cs new file mode 100644 index 000000000..4751676fe --- /dev/null +++ b/Templates/BaseGame/game/tools/materialEditor/main.cs @@ -0,0 +1,160 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Material Editor Written by Dave Calabrese and Travis Vroman of Gaslight Studios + +function initializeMaterialEditor() +{ + echo(" % - Initializing Material Editor"); + + // Load Preview Window + exec("~/materialEditor/gui/guiMaterialPreviewWindow.ed.gui"); + + // Load Properties Window + exec("~/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui"); + + // Load Client Scripts. + exec("./scripts/materialEditor.ed.cs"); + exec("./scripts/materialEditorUndo.ed.cs"); + //exec("./gui/profiles.ed.cs"); + + MaterialEditorPreviewWindow.setVisible( false ); + matEd_cubemapEditor.setVisible( false ); + matEd_addCubemapWindow.setVisible( false ); + MaterialEditorPropertiesWindow.setVisible( false ); + + EditorGui.add( MaterialEditorPreviewWindow ); + EditorGui.add( matEd_cubemapEditor ); + EditorGui.add( matEd_addCubemapWindow ); + EditorGui.add( MaterialEditorPropertiesWindow ); +} + +function destroyMaterialEditor() +{ +} + +// Material Editor +function MaterialEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Material Editor", "", MaterialEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Material Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "MaterialEditorPlugin", "MaterialEditorPalette", expandFilename("tools/worldEditor/images/toolbar/matterial-editor"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( MaterialEditorPropertiesWindow, MaterialEditorPreviewWindow); + + %map = new ActionMap(); + %map.bindCmd( keyboard, "1", "EWorldEditorNoneModeBtn.performClick();", "" ); // Select + %map.bindCmd( keyboard, "2", "EWorldEditorMoveModeBtn.performClick();", "" ); // Move + %map.bindCmd( keyboard, "3", "EWorldEditorRotateModeBtn.performClick();", "" ); // Rotate + %map.bindCmd( keyboard, "4", "EWorldEditorScaleModeBtn.performClick();", "" ); // Scale + %map.bindCmd( keyboard, "f", "FitToSelectionBtn.performClick();", "" );// Fit Camera to Selection + %map.bindCmd( keyboard, "z", "EditorGuiStatusBar.setCamera(\"Standard Camera\");", "" );// Free Camera + %map.bindCmd( keyboard, "n", "ToggleNodeBar->renderHandleBtn.performClick();", "" );// Render Node + %map.bindCmd( keyboard, "shift n", "ToggleNodeBar->renderTextBtn.performClick();", "" );// Render Node Text + %map.bindCmd( keyboard, "alt s", "MaterialEditorGui.save();", "" );// Save Material + //%map.bindCmd( keyboard, "delete", "ToggleNodeBar->renderTextBtn.performClick();", "" );// delete Material + %map.bindCmd( keyboard, "g", "ESnapOptions-->GridSnapButton.performClick();" ); // Grid Snappping + %map.bindCmd( keyboard, "t", "SnapToBar->objectSnapDownBtn.performClick();", "" );// Terrain Snapping + %map.bindCmd( keyboard, "b", "SnapToBar-->objectSnapBtn.performClick();" ); // Soft Snappping + %map.bindCmd( keyboard, "v", "EWorldEditorToolbar->boundingBoxColBtn.performClick();", "" );// Bounds Selection + %map.bindCmd( keyboard, "o", "objectCenterDropdown->objectBoxBtn.performClick(); objectCenterDropdown.toggle();", "" );// Object Center + %map.bindCmd( keyboard, "p", "objectCenterDropdown->objectBoundsBtn.performClick(); objectCenterDropdown.toggle();", "" );// Bounds Center + %map.bindCmd( keyboard, "k", "objectTransformDropdown->objectTransformBtn.performClick(); objectTransformDropdown.toggle();", "" );// Object Transform + %map.bindCmd( keyboard, "l", "objectTransformDropdown->worldTransformBtn.performClick(); objectTransformDropdown.toggle();", "" );// World Transform + + MaterialEditorPlugin.map = %map; + + MaterialEditorGui.fileSpec = "Torque Material Files (materials.cs)|materials.cs|All Files (*.*)|*.*|"; + MaterialEditorGui.textureFormats = "Image Files (*.png, *.jpg, *.dds, *.bmp, *.gif, *.jng. *.tga)|*.png;*.jpg;*.dds;*.bmp;*.gif;*.jng;*.tga|All Files (*.*)|*.*|"; + MaterialEditorGui.modelFormats = "DTS Files (*.dts)|*.dts"; + MaterialEditorGui.lastTexturePath = ""; + MaterialEditorGui.lastTextureFile = ""; + MaterialEditorGui.lastModelPath = ""; + MaterialEditorGui.lastModelFile = ""; + MaterialEditorGui.currentMaterial = ""; + MaterialEditorGui.lastMaterial = ""; + MaterialEditorGui.currentCubemap = ""; + MaterialEditorGui.currentObject = ""; + + MaterialEditorGui.livePreview = "1"; + MaterialEditorGui.currentLayer = "0"; + MaterialEditorGui.currentMode = "Material"; + MaterialEditorGui.currentMeshMode = "EditorShape"; + + new ArrayObject(UnlistedCubemaps); + UnlistedCubemaps.add( "unlistedCubemaps", matEdCubeMapPreviewMat ); + UnlistedCubemaps.add( "unlistedCubemaps", WarnMatCubeMap ); + + //MaterialEditor persistence manager + new PersistenceManager(matEd_PersistMan); +} + +function MaterialEditorPlugin::onActivated( %this ) +{ + if($gfx::wireframe){ + $wasInWireFrameMode = true; + $gfx::wireframe = false; + }else{ + $wasInWireFrameMode = false; + } + advancedTextureMapsRollout.Expanded = false; + materialAnimationPropertiesRollout.Expanded = false; + materialAdvancedPropertiesRollout.Expanded = false; + WorldEditorPlugin.onActivated(); + + EditorGui-->MatEdPropertiesWindow.setVisible( true ); + EditorGui-->MatEdPreviewWindow.setVisible( true ); + EditorGui-->WorldEditorToolbar.setVisible( true ); + + MaterialEditorGui.currentObject = $Tools::materialEditorList; + // Execute the back end scripts that actually do the work. + MaterialEditorGui.open(); + %this.map.push(); + + Parent::onActivated(%this); +} + +function MaterialEditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + WorldEditorPlugin.onEditMenuSelect( %editMenu ); +} + +function MaterialEditorPlugin::onDeactivated( %this ) +{ + if($wasInWireFrameMode) + $gfx::wireframe = true; + + WorldEditorPlugin.onDeactivated(); + + MaterialEditorGui.quit(); + + EditorGui-->MatEdPropertiesWindow.setVisible( false ); + EditorGui-->MatEdPreviewWindow.setVisible( false ); + EditorGui-->WorldEditorToolbar.setVisible( false ); + %this.map.pop(); + + Parent::onDeactivated(%this); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.cs b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.cs new file mode 100644 index 000000000..b4e85229f --- /dev/null +++ b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.cs @@ -0,0 +1,2270 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Material Editor originally created by Dave Calabrese and Travis Vroman of Gaslight Studios + +function MaterialEditorGui::establishMaterials(%this) +{ + //Cubemap used to preview other cubemaps in the editor. + singleton CubemapData( matEdCubeMapPreviewMat ) + { + cubeFace[0] = "tools/materialEditor/gui/cube_xNeg"; + cubeFace[1] = "tools/materialEditor/gui/cube_xPos"; + cubeFace[2] = "tools/materialEditor/gui/cube_ZNeg"; + cubeFace[3] = "tools/materialEditor/gui/cube_ZPos"; + cubeFace[4] = "tools/materialEditor/gui/cube_YNeg"; + cubeFace[5] = "tools/materialEditor/gui/cube_YPos"; + parentGroup = "RootGroup"; + }; + + //Material used to preview other materials in the editor. + singleton Material(materialEd_previewMaterial) + { + mapTo = "matEd_mappedMat"; + diffuseMap[0] = "tools/materialEditor/gui/matEd_mappedMat"; + }; + + singleton CustomMaterial( materialEd_justAlphaMaterial ) + { + mapTo = "matEd_mappedMatB"; + texture[0] = materialEd_previewMaterial.diffuseMap[0]; + }; + + //Custom shader to allow the display of just the alpha channel. + singleton ShaderData( materialEd_justAlphaShader ) + { + DXVertexShaderFile = "shaders/alphaOnlyV.hlsl"; + DXPixelShaderFile = "shaders/alphaOnlyP.hlsl"; + pixVersion = 1.0; + }; +} + +function MaterialEditorGui::open(%this) +{ + MaterialEditorGui.establishMaterials(); + + // We hide these specific windows here due too there non-modal nature. + // These guis are also pushed onto Canvas, which means they shouldn't be parented + // by editorgui + materialSelector.setVisible(0); + matEdSaveDialog.setVisible(0); + + MaterialEditorPropertiesWindow-->matEd_cubemapEditBtn.setVisible(0); + + //Setup our dropdown menu contents. + //Blending Modes + MaterialEditorPropertiesWindow-->blendingTypePopUp.clear(); + MaterialEditorPropertiesWindow-->blendingTypePopUp.add(None,0); + MaterialEditorPropertiesWindow-->blendingTypePopUp.add(Mul,1); + MaterialEditorPropertiesWindow-->blendingTypePopUp.add(Add,2); + MaterialEditorPropertiesWindow-->blendingTypePopUp.add(AddAlpha,3); + MaterialEditorPropertiesWindow-->blendingTypePopUp.add(Sub,4); + MaterialEditorPropertiesWindow-->blendingTypePopUp.add(LerpAlpha,5); + MaterialEditorPropertiesWindow-->blendingTypePopUp.setSelected( 0, false ); + + //Reflection Types + MaterialEditorPropertiesWindow-->reflectionTypePopUp.clear(); + MaterialEditorPropertiesWindow-->reflectionTypePopUp.add("None",0); + MaterialEditorPropertiesWindow-->reflectionTypePopUp.add("cubemap",1); + MaterialEditorPropertiesWindow-->reflectionTypePopUp.setSelected( 0, false ); + + //Sounds + MaterialEditorPropertiesWindow-->footstepSoundPopup.clear(); + MaterialEditorPropertiesWindow-->impactSoundPopup.clear(); + + %sounds = "<None>" TAB "<Soft>" TAB "<Hard>" TAB "<Metal>" TAB "<Snow>"; // Default sounds + + // Get custom sound datablocks + foreach (%db in DataBlockSet) + { + if (%db.isMemberOfClass("SFXTrack")) + %sounds = %sounds TAB %db.getName(); + } + + %count = getFieldCount(%sounds); + for (%i = 0; %i < %count; %i++) + { + %name = getField(%sounds, %i); + MaterialEditorPropertiesWindow-->footstepSoundPopup.add(%name); + MaterialEditorPropertiesWindow-->impactSoundPopup.add(%name); + } + + //Preview Models + matEd_quickPreview_Popup.clear(); + matEd_quickPreview_Popup.add("Cube",0); + matEd_quickPreview_Popup.add("Sphere",1); + matEd_quickPreview_Popup.add("Pyramid",2); + matEd_quickPreview_Popup.add("Cylinder",3); + matEd_quickPreview_Popup.add("Torus",4); + matEd_quickPreview_Popup.add("Knot",5); + matEd_quickPreview_Popup.setSelected( 0, false ); + matEd_quickPreview_Popup.selected = matEd_quickPreview_Popup.getText(); + + MaterialEditorPropertiesWindow-->MaterialLayerCtrl.clear(); + MaterialEditorPropertiesWindow-->MaterialLayerCtrl.add("Layer 0",0); + MaterialEditorPropertiesWindow-->MaterialLayerCtrl.add("Layer 1",1); + MaterialEditorPropertiesWindow-->MaterialLayerCtrl.add("Layer 2",2); + MaterialEditorPropertiesWindow-->MaterialLayerCtrl.add("Layer 3",3); + MaterialEditorPropertiesWindow-->MaterialLayerCtrl.setSelected( 0, false ); + + //Sift through the RootGroup and find all loaded material items. + MaterialEditorGui.updateAllFields(); + MaterialEditorGui.updatePreviewObject(); + + // If no selected object; go to material mode. And edit the last selected material + MaterialEditorGui.setMode(); + + MaterialEditorGui.preventUndo = true; + + if( MaterialEditorGui.currentMode $= "Mesh" ) + MaterialEditorGui.prepareActiveObject( true ); + else + MaterialEditorGui.prepareActiveMaterial( "", true ); + + MaterialEditorGui.preventUndo = false; + +} + +function MaterialEditorGui::quit(%this) +{ + // if we quit, restore with notDirty + if(MaterialEditorGui.materialDirty) + { + //keep on doing this + MaterialEditorGui.copyMaterials( notDirtyMaterial, materialEd_previewMaterial ); + MaterialEditorGui.copyMaterials( notDirtyMaterial, MaterialEditorGui.currentMaterial ); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } + + if( isObject(MaterialEditorGui.currentMaterial) ) + { + MaterialEditorGui.lastMaterial = MaterialEditorGui.currentMaterial.getName(); + } + + MaterialEditorGui.setMaterialNotDirty(); + + // First delete the model so that it releases + // material instances that use the preview materials. + matEd_previewObjectView.deleteModel(); + + // Now we can delete the preview materials and shaders + // knowing that there are no matinstances using them. + matEdCubeMapPreviewMat.delete(); + materialEd_previewMaterial.delete(); + materialEd_justAlphaMaterial.delete(); + materialEd_justAlphaShader.delete(); +} + +function MaterialEditorGui::openFile( %this, %fileType ) +{ + switch$(%fileType) + { + case "Texture": %filters = MaterialEditorGui.textureFormats; + + if(MaterialEditorGui.lastTextureFile $= "") + %defaultFileName = "*.*"; + else + %defaultFileName = MaterialEditorGui.lastTextureFile; + + %defaultPath = MaterialEditorGui.lastTexturePath; + + case "Model": %filters = MaterialEditorGui.modelFormats; + %defaultFileName = "*.dts"; + %defaultPath = MaterialEditorGui.lastModelPath; + } + + %dlg = new OpenFileDialog() + { + Filters = %filters; + DefaultPath = %defaultPath; + DefaultFile = %defaultFileName; + ChangePath = false; + MustExist = true; + }; + + %ret = %dlg.Execute(); + if(%ret) + { + switch$(%fileType) + { + case "Texture": + MaterialEditorGui.lastTexturePath = filePath( %dlg.FileName ); + MaterialEditorGui.lastTextureFile = %filename = %dlg.FileName; + + case "Model": + MaterialEditorGui.lastModelPath = filePath( %dlg.FileName ); + MaterialEditorGui.lastModelFile = %filename = %dlg.FileName; + } + } + + %dlg.delete(); + + if(!%ret) + return; + else + return makeRelativePath( %filename, getMainDotCsDir() ); +} + +//============================================================================== +// SubMaterial(Material Target) -- Supports different ways to grab the +// material from the dropdown list. We're here either because- +// 1. We have switched over from another editor with an object locked in the +// $Tools::materialEditorList variable +// 2. We have selected an object using the Object Editor via the Material Editor + +function SubMaterialSelector::onSelect( %this ) +{ + %material = ""; + + if( MaterialEditorGui.currentMeshMode $= "Model" ) + %material = getMapEntry( %this.getText() ); + else + %material = MaterialEditorGui.currentObject.getFieldValue( %this.getText() ); + + %origMat = %material; + if(%material$="") + %origMat = %material = %this.getText(); + // if there is no material attached to that objects material field or the + // object does not have a valid method to grab a material + if( !isObject( %material ) ) + { + // look for a newMaterial name to grab + // addiitonally, convert "." to "_" in case we have something like: "base.texname" as a material name + // at the end we will have generated material name: "base_texname_mat" + %material = getUniqueName( strreplace(%material, ".", "_") @ "_mat" ); + + new Material(%material) + { + diffuseMap[0] = %origMat; + mapTo = %origMat; + parentGroup = RootGroup; + }; + + eval( "MaterialEditorGui.currentObject." @ strreplace(%this.getText(),".","_") @ " = " @ %material @ ";"); + + if( MaterialEditorGui.currentObject.isMethod("postApply") ) + MaterialEditorGui.currentObject.postApply(); + } + + MaterialEditorGui.prepareActiveMaterial( %material.getId() ); +} + +//============================================================================== +// Select object logic (deciding material/target mode) + +function MaterialEditorGui::setMode( %this ) +{ + MatEdMaterialMode.setVisible(0); + MatEdTargetMode.setVisible(0); + + if( isObject(MaterialEditorGui.currentObject) ) + { + MaterialEditorGui.currentMode = "Mesh"; + MatEdTargetMode.setVisible(1); + } + else + { + MaterialEditorGui.currentMode = "Material"; + MatEdMaterialMode.setVisible(1); + EWorldEditor.clearSelection(); + } +} + +function MaterialEditorGui::prepareActiveObject( %this, %override ) +{ + %obj = $Tools::materialEditorList; + if( MaterialEditorGui.currentObject == %obj && !%override) + return; + + // TSStatics and ShapeBase objects should have getModelFile methods + if( %obj.isMethod( "getModelFile" ) ) + { + MaterialEditorGui.currentObject = %obj; + + SubMaterialSelector.clear(); + MaterialEditorGui.currentMeshMode = "Model"; + + MaterialEditorGui.setMode(); + + for(%j = 0; %j < MaterialEditorGui.currentObject.getTargetCount(); %j++) + { + %target = MaterialEditorGui.currentObject.getTargetName(%j); + %count = SubMaterialSelector.getCount(); + SubMaterialSelector.add(%target); + } + } + else // Other classes that support materials if possible + { + %canSupportMaterial = false; + for( %i = 0; %i < %obj.getFieldCount(); %i++ ) + { + %fieldName = %obj.getField(%i); + + if( %obj.getFieldType(%fieldName) !$= "TypeMaterialName" ) + continue; + + if( !%canSupportMaterial ) + { + MaterialEditorGui.currentObject = %obj; + SubMaterialSelector.clear(); + SubMaterialSelector.add(%fieldName, 0); + } + else + { + %count = SubMaterialSelector.getCount(); + SubMaterialSelector.add(%fieldName, %count); + } + %canSupportMaterial = true; + } + + if( !%canSupportMaterial ) // Non-relevant classes get returned + return; + + MaterialEditorGui.currentMeshMode = "EditorShape"; + MaterialEditorGui.setMode(); + } + + %id = SubMaterialSelector.findText( MaterialEditorGui.currentMaterial.mapTo ); + if( %id != -1 ) + SubMaterialSelector.setSelected( %id ); + else + SubMaterialSelector.setSelected(0); +} + +//============================================================================== +// Helper functions to help create categories and manage category lists + +function MaterialEditorGui::updateAllFields(%this) +{ + matEd_cubemapEd_availableCubemapList.clear(); +} + +function MaterialEditorGui::updatePreviewObject(%this) +{ + %newModel = matEd_quickPreview_Popup.getValue(); + + switch$(%newModel) + { + case "sphere": + matEd_quickPreview_Popup.selected = %newModel; + matEd_previewObjectView.setModel("tools/materialEditor/gui/spherePreview.dts"); + matEd_previewObjectView.setOrbitDistance(4); + + case "cube": + matEd_quickPreview_Popup.selected = %newModel; + matEd_previewObjectView.setModel("tools/materialEditor/gui/cubePreview.dts"); + matEd_previewObjectView.setOrbitDistance(5); + + case "pyramid": + matEd_quickPreview_Popup.selected = %newModel; + matEd_previewObjectView.setModel("tools/materialEditor/gui/pyramidPreview.dts"); + matEd_previewObjectView.setOrbitDistance(5); + + case "cylinder": + matEd_quickPreview_Popup.selected = %newModel; + matEd_previewObjectView.setModel("tools/materialEditor/gui/cylinderPreview.dts"); + matEd_previewObjectView.setOrbitDistance(4.2); + + case "torus": + matEd_quickPreview_Popup.selected = %newModel; + matEd_previewObjectView.setModel("tools/materialEditor/gui/torusPreview.dts"); + matEd_previewObjectView.setOrbitDistance(4.2); + + case "knot": + matEd_quickPreview_Popup.selected = %newModel; + matEd_previewObjectView.setModel("tools/materialEditor/gui/torusknotPreview.dts"); + } +} + +//============================================================================== +// Helper functions to help load and update the preview and active material + +// Finds the selected line in the material list, then makes it active in the editor. +function MaterialEditorGui::prepareActiveMaterial(%this, %material, %override) +{ + // If were not valid, grab the first valid material out of the materialSet + if( !isObject(%material) ) + %material = MaterialSet.getObject(0); + + // Check made in order to avoid loading the same material. Overriding + // made in special cases + if(%material $= MaterialEditorGui.lastMaterial && !%override) + { + return; + } + else + { + if(MaterialEditorGui.materialDirty ) + { + MaterialEditorGui.showSaveDialog( %material ); + return; + } + + MaterialEditorGui.setActiveMaterial(%material); + } +} + +// Updates the preview material to use the same properties as the selected material, +// and makes that material active in the editor. +function MaterialEditorGui::setActiveMaterial( %this, %material ) +{ + // Warn if selecting a CustomMaterial (they can't be properly previewed or edited) + if ( isObject( %material ) && %material.isMemberOfClass( "CustomMaterial" ) ) + { + MessageBoxOK( "Warning", "The selected Material (" @ %material.getName() @ + ") is a CustomMaterial, and cannot be edited using the Material Editor." ); + return; + } + + MaterialEditorGui.currentMaterial = %material; + MaterialEditorGui.lastMaterial = %material; + + // we create or recreate a material to hold in a pristine state + singleton Material(notDirtyMaterial) + { + mapTo = "matEd_mappedMat"; + diffuseMap[0] = "tools/materialEditor/gui/matEd_mappedMat"; + }; + + // Converts the texture files into absolute paths. + MaterialEditorGui.convertTextureFields(); + + // If we're allowing for name changes, make sure to save the name seperately + %this.originalName = MaterialEditorGui.currentMaterial.name; + + // Copy materials over to other references + MaterialEditorGui.copyMaterials( MaterialEditorGui.currentMaterial, materialEd_previewMaterial ); + MaterialEditorGui.copyMaterials( MaterialEditorGui.currentMaterial, notDirtyMaterial ); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + + // Necessary functionality in order to render correctly + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + + MaterialEditorGui.setMaterialNotDirty(); +} + +function MaterialEditorGui::isMatEditorMaterial(%this, %material) +{ + return ( %material.getFilename() $= "" || + %material.getFilename() $= "tools/gui/materialSelector.ed.gui" || + %material.getFilename() $= "tools/materialEditor/scripts/materialEditor.ed.cs" ); +} + +function MaterialEditorGui::setMaterialNotDirty(%this) +{ + %propertyText = "Material Properties"; + %previewText = "Material Preview"; + MaterialEditorPropertiesWindow.text = %propertyText; + MaterialEditorPreviewWindow.text = %previewText; + + MaterialEditorGui.materialDirty = false; + matEd_PersistMan.removeDirty(MaterialEditorGui.currentMaterial); +} + +function MaterialEditorGui::setMaterialDirty(%this) +{ + %propertyText = "Material Properties *"; + %previewText = "Material Preview *"; + MaterialEditorPropertiesWindow.text = %propertyText; + MaterialEditorPreviewWindow.text = %previewText; + + MaterialEditorGui.materialDirty = true; + + // materials created in the material selector are given that as its filename, so we run another check + if( MaterialEditorGui.isMatEditorMaterial( MaterialEditorGui.currentMaterial ) ) + { + if( MaterialEditorGui.currentMaterial.isAutoGenerated() ) + { + %obj = MaterialEditorGui.currentObject; + + if( %obj.shapeName !$= "" ) + %shapePath = %obj.shapeName; + else if( %obj.isMethod("getDatablock") ) + { + if( %obj.getDatablock().shapeFile !$= "" ) + %shapePath = %obj.getDatablock().shapeFile; + } + + //creating toPath + %k = 0; + while( strpos( %shapePath, "/", %k ) != -1 ) + { + %pos = strpos( %shapePath, "/", %k ); + %k = %pos + 1; + } + %savePath = getSubStr( %shapePath , 0 , %k ); + %savePath = %savePath @ "materials.cs"; + + matEd_PersistMan.setDirty(MaterialEditorGui.currentMaterial, %savePath); + } + else + { + matEd_PersistMan.setDirty(MaterialEditorGui.currentMaterial, "art/materials.cs"); + } + } + else + matEd_PersistMan.setDirty(MaterialEditorGui.currentMaterial); +} + +function MaterialEditorGui::convertTextureFields(%this) +{ + // Find the absolute paths for the texture filenames so that + // we can properly wire up the preview materials and controls. + + for(%diffuseI = 0; %diffuseI < 4; %diffuseI++) + { + %diffuseMap = MaterialEditorGui.currentMaterial.diffuseMap[%diffuseI]; + %diffuseMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %diffuseMap); + MaterialEditorGui.currentMaterial.diffuseMap[%diffuseI] = %diffuseMap; + } + + for(%normalI = 0; %normalI < 4; %normalI++) + { + %normalMap = MaterialEditorGui.currentMaterial.normalMap[%normalI]; + %normalMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %normalMap); + MaterialEditorGui.currentMaterial.normalMap[%normalI] = %normalMap; + } + + for(%overlayI = 0; %overlayI < 4; %overlayI++) + { + %overlayMap = MaterialEditorGui.currentMaterial.overlayMap[%overlayI]; + %overlayMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %overlayMap); + MaterialEditorGui.currentMaterial.overlayMap[%overlayI] = %overlayMap; + } + + for(%detailI = 0; %detailI < 4; %detailI++) + { + %detailMap = MaterialEditorGui.currentMaterial.detailMap[%detailI]; + %detailMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %detailMap); + MaterialEditorGui.currentMaterial.detailMap[%detailI] = %detailMap; + } + + for(%detailNormalI = 0; %detailNormalI < 4; %detailNormalI++) + { + %detailNormalMap = MaterialEditorGui.currentMaterial.detailNormalMap[%detailNormalI]; + %detailNormalMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %detailNormalMap); + MaterialEditorGui.currentMaterial.detailNormalMap[%detailNormalI] = %detailNormalMap; + } + + for(%lightI = 0; %lightI < 4; %lightI++) + { + %lightMap = MaterialEditorGui.currentMaterial.lightMap[%lightI]; + %lightMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %lightMap); + MaterialEditorGui.currentMaterial.lightMap[%lightI] = %lightMap; + } + + for(%toneI = 0; %toneI < 4; %toneI++) + { + %toneMap = MaterialEditorGui.currentMaterial.toneMap[%toneI]; + %toneMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %toneMap); + MaterialEditorGui.currentMaterial.toneMap[%toneI] = %toneMap; + } + + for(%specI = 0; %specI < 4; %specI++) + { + %specMap = MaterialEditorGui.currentMaterial.specularMap[%specI]; + %specMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %specMap); + MaterialEditorGui.currentMaterial.specularMap[%specI] = %specMap; + } +} + +// still needs to be optimized further +function MaterialEditorGui::searchForTexture(%this,%material, %texture) +{ + if( %texture !$= "" ) + { + // set the find signal as false to start out with + %isFile = false; + // sete the formats we're going to be looping through if need be + %formats = ".png .jpg .dds .bmp .gif .jng .tga"; + + // if the texture contains the correct filepath and name right off the bat, lets use it + if( isFile(%texture) ) + %isFile = true; + else + { + + for( %i = 0; %i < getWordCount(%formats); %i++) + { + %testFileName = %texture @ getWord( %formats, %i ); + if(isFile(%testFileName)) + { + %isFile = true; + break; + } + } + } + + // if we didn't grab a proper name, lets use a string logarithm + if( !%isFile ) + { + %materialDiffuse = %texture; + %materialDiffuse2 = %texture; + + %materialPath = %material.getFilename(); + + if( strchr( %materialDiffuse, "/") $= "" ) + { + %k = 0; + while( strpos( %materialPath, "/", %k ) != -1 ) + { + %count = strpos( %materialPath, "/", %k ); + %k = %count + 1; + } + + %materialsCs = getSubStr( %materialPath , %k , 99 ); + %texture = strreplace( %materialPath, %materialsCs, %texture ); + } + else + %texture = strreplace( %materialPath, %materialPath, %texture ); + + + // lets test the pathing we came up with + if( isFile(%texture) ) + %isFile = true; + else + { + for( %i = 0; %i < getWordCount(%formats); %i++) + { + %testFileName = %texture @ getWord( %formats, %i ); + if(isFile(%testFileName)) + { + %isFile = true; + break; + } + } + } + + // as a last resort to find the proper name + // we have to resolve using find first file functions very very slow + if( !%isFile ) + { + %k = 0; + while( strpos( %materialDiffuse2, "/", %k ) != -1 ) + { + %count = strpos( %materialDiffuse2, "/", %k ); + %k = %count + 1; + } + + %texture = getSubStr( %materialDiffuse2 , %k , 99 ); + for( %i = 0; %i < getWordCount(%formats); %i++) + { + %searchString = "*" @ %texture @ getWord( %formats, %i ); + %testFileName = findFirstFile( %searchString ); + if( isFile(%testFileName) ) + { + %texture = %testFileName; + %isFile = true; + break; + } + } + } + + return %texture; + } + else + return %texture; //Texture exists and can be found - just return the input argument. + } + + return ""; //No texture associated with this property. +} + +function MaterialEditorGui::updateLivePreview(%this,%preview) +{ + // When checkbox is selected, preview the material in real time, if not; then don't + if( %preview ) + MaterialEditorGui.copyMaterials( materialEd_previewMaterial, MaterialEditorGui.currentMaterial ); + else + MaterialEditorGui.copyMaterials( notDirtyMaterial, MaterialEditorGui.currentMaterial ); + + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); +} + +function MaterialEditorGui::copyMaterials( %this, %copyFrom, %copyTo) +{ + // Make sure we copy and restore the map to. + %mapTo = %copyTo.mapTo; + %copyTo.assignFieldsFrom( %copyFrom ); + %copyTo.mapTo = %mapTo; + +} + +function MaterialEditorGui::guiSync( %this, %material ) +{ + %this.preventUndo = true; + //Setup our headers + if( MaterialEditorGui.currentMode $= "material" ) + { + MatEdMaterialMode-->selMaterialName.setText(MaterialEditorGui.currentMaterial.name); + MatEdMaterialMode-->selMaterialMapTo.setText(MaterialEditorGui.currentMaterial.mapTo); + } + else + { + if( MaterialEditorGui.currentObject.isMethod("getModelFile") ) + { + %sourcePath = MaterialEditorGui.currentObject.getModelFile(); + if( %sourcePath !$= "" ) + { + MatEdTargetMode-->selMaterialMapTo.ToolTip = %sourcePath; + %sourceName = fileName(%sourcePath); + MatEdTargetMode-->selMaterialMapTo.setText(%sourceName); + MatEdTargetMode-->selMaterialName.setText(MaterialEditorGui.currentMaterial.name); + } + } + else + { + %info = MaterialEditorGui.currentObject.getClassName(); + MatEdTargetMode-->selMaterialMapTo.ToolTip = %info; + MatEdTargetMode-->selMaterialMapTo.setText(%info); + MatEdTargetMode-->selMaterialName.setText(MaterialEditorGui.currentMaterial.name); + } + } + + MaterialEditorPropertiesWindow-->alphaRefTextEdit.setText((%material).alphaRef); + MaterialEditorPropertiesWindow-->alphaRefSlider.setValue((%material).alphaRef); + MaterialEditorPropertiesWindow-->doubleSidedCheckBox.setValue((%material).doubleSided); + MaterialEditorPropertiesWindow-->transZWriteCheckBox.setValue((%material).translucentZWrite); + MaterialEditorPropertiesWindow-->alphaTestCheckBox.setValue((%material).alphaTest); + MaterialEditorPropertiesWindow-->castShadows.setValue((%material).castShadows); + MaterialEditorPropertiesWindow-->castDynamicShadows.setValue((%material).castDynamicShadows); + MaterialEditorPropertiesWindow-->translucentCheckbox.setValue((%material).translucent); + + switch$((%material).translucentBlendOp) + { + case "None": %selectedNum = 0; + case "Mul": %selectedNum = 1; + case "Add": %selectedNum = 2; + case "AddAlpha": %selectedNum = 3; + case "Sub": %selectedNum = 4; + case "LerpAlpha": %selectedNum = 5; + } + MaterialEditorPropertiesWindow-->blendingTypePopUp.setSelected(%selectedNum); + + if((%material).cubemap !$= "") + { + MaterialEditorPropertiesWindow-->matEd_cubemapEditBtn.setVisible(1); + MaterialEditorPropertiesWindow-->reflectionTypePopUp.setSelected(1); + } + else if((%material).dynamiccubemap) + { + MaterialEditorPropertiesWindow-->matEd_cubemapEditBtn.setVisible(0); + MaterialEditorPropertiesWindow-->reflectionTypePopUp.setSelected(2); + } + else if((%material).planarReflection) + { + MaterialEditorPropertiesWindow-->matEd_cubemapEditBtn.setVisible(0); + MaterialEditorPropertiesWindow-->reflectionTypePopUp.setSelected(3); + } + else + { + MaterialEditorPropertiesWindow-->matEd_cubemapEditBtn.setVisible(0); + MaterialEditorPropertiesWindow-->reflectionTypePopUp.setSelected(0); + } + + MaterialEditorPropertiesWindow-->effectColor0Swatch.color = (%material).effectColor[0]; + MaterialEditorPropertiesWindow-->effectColor1Swatch.color = (%material).effectColor[1]; + MaterialEditorPropertiesWindow-->showFootprintsCheckbox.setValue((%material).showFootprints); + MaterialEditorPropertiesWindow-->showDustCheckbox.setValue((%material).showDust); + MaterialEditorGui.updateSoundPopup("Footstep", (%material).footstepSoundId, (%material).customFootstepSound); + MaterialEditorGui.updateSoundPopup("Impact", (%material).impactSoundId, (%material).customImpactSound); + + //layer specific controls are located here + %layer = MaterialEditorGui.currentLayer; + + if((%material).diffuseMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->diffuseMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->diffuseMapDisplayBitmap.setBitmap( "tools/materialEditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->diffuseMapNameText.setText( (%material).diffuseMap[%layer] ); + MaterialEditorPropertiesWindow-->diffuseMapDisplayBitmap.setBitmap( (%material).diffuseMap[%layer] ); + } + + if((%material).normalMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->normalMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->normalMapDisplayBitmap.setBitmap( "tools/materialEditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->normalMapNameText.setText( (%material).normalMap[%layer] ); + MaterialEditorPropertiesWindow-->normalMapDisplayBitmap.setBitmap( (%material).normalMap[%layer] ); + } + + if((%material).overlayMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->overlayMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->overlayMapDisplayBitmap.setBitmap( "tools/materialEditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->overlayMapNameText.setText( (%material).overlayMap[%layer] ); + MaterialEditorPropertiesWindow-->overlayMapDisplayBitmap.setBitmap( (%material).overlayMap[%layer] ); + } + + if((%material).detailMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->detailMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->detailMapDisplayBitmap.setBitmap( "tools/materialEditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->detailMapNameText.setText( (%material).detailMap[%layer] ); + MaterialEditorPropertiesWindow-->detailMapDisplayBitmap.setBitmap( (%material).detailMap[%layer] ); + } + + if((%material).detailNormalMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->detailNormalMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->detailNormalMapDisplayBitmap.setBitmap( "tools/materialEditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->detailNormalMapNameText.setText( (%material).detailNormalMap[%layer] ); + MaterialEditorPropertiesWindow-->detailNormalMapDisplayBitmap.setBitmap( (%material).detailNormalMap[%layer] ); + } + + if((%material).lightMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->lightMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->lightMapDisplayBitmap.setBitmap( "tools/materialEditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->lightMapNameText.setText( (%material).lightMap[%layer] ); + MaterialEditorPropertiesWindow-->lightMapDisplayBitmap.setBitmap( (%material).lightMap[%layer] ); + } + + if((%material).toneMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->toneMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->toneMapDisplayBitmap.setBitmap( "tools/materialEditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->toneMapNameText.setText( (%material).toneMap[%layer] ); + MaterialEditorPropertiesWindow-->toneMapDisplayBitmap.setBitmap( (%material).toneMap[%layer] ); + } + + if((%material).specularMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->specMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->specMapDisplayBitmap.setBitmap( "tools/materialEditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->specMapNameText.setText( (%material).specularMap[%layer] ); + MaterialEditorPropertiesWindow-->specMapDisplayBitmap.setBitmap( (%material).specularMap[%layer] ); + } + + MaterialEditorPropertiesWindow-->accuScaleTextEdit.setText((%material).accuScale[%layer]); + MaterialEditorPropertiesWindow-->accuScaleTextEdit.setText((%material).accuScale[%layer]); + MaterialEditorPropertiesWindow-->accuDirectionTextEdit.setText((%material).accuDirection[%layer]); + MaterialEditorPropertiesWindow-->accuDirectionTextEdit.setText((%material).accuDirection[%layer]); + MaterialEditorPropertiesWindow-->accuStrengthTextEdit.setText((%material).accuStrength[%layer]); + MaterialEditorPropertiesWindow-->accuStrengthTextEdit.setText((%material).accuStrength[%layer]); + MaterialEditorPropertiesWindow-->accuCoverageTextEdit.setText((%material).accuCoverage[%layer]); + MaterialEditorPropertiesWindow-->accuCoverageTextEdit.setText((%material).accuCoverage[%layer]); + MaterialEditorPropertiesWindow-->accuSpecularTextEdit.setText((%material).accuSpecular[%layer]); + MaterialEditorPropertiesWindow-->accuSpecularTextEdit.setText((%material).accuSpecular[%layer]); + + MaterialEditorPropertiesWindow-->detailScaleTextEdit.setText( getWord((%material).detailScale[%layer], 0) ); + MaterialEditorPropertiesWindow-->detailNormalStrengthTextEdit.setText( getWord((%material).detailNormalMapStrength[%layer], 0) ); + + MaterialEditorPropertiesWindow-->colorTintSwatch.color = (%material).diffuseColor[%layer]; + MaterialEditorPropertiesWindow-->specularColorSwatch.color = (%material).specular[%layer]; + + MaterialEditorPropertiesWindow-->specularPowerTextEdit.setText((%material).specularPower[%layer]); + MaterialEditorPropertiesWindow-->specularPowerSlider.setValue((%material).specularPower[%layer]); + MaterialEditorPropertiesWindow-->specularStrengthTextEdit.setText((%material).specularStrength[%layer]); + MaterialEditorPropertiesWindow-->specularStrengthSlider.setValue((%material).specularStrength[%layer]); + MaterialEditorPropertiesWindow-->pixelSpecularCheckbox.setValue((%material).pixelSpecular[%layer]); + MaterialEditorPropertiesWindow-->glowCheckbox.setValue((%material).glow[%layer]); + MaterialEditorPropertiesWindow-->emissiveCheckbox.setValue((%material).emissive[%layer]); + MaterialEditorPropertiesWindow-->parallaxTextEdit.setText((%material).parallaxScale[%layer]); + MaterialEditorPropertiesWindow-->parallaxSlider.setValue((%material).parallaxScale[%layer]); + + MaterialEditorPropertiesWindow-->useAnisoCheckbox.setValue((%material).useAnisotropic[%layer]); + MaterialEditorPropertiesWindow-->vertLitCheckbox.setValue((%material).vertLit[%layer]); + MaterialEditorPropertiesWindow-->vertColorSwatch.color = (%material).vertColor[%layer]; + MaterialEditorPropertiesWindow-->subSurfaceCheckbox.setValue((%material).subSurface[%layer]); + + // Animation properties + MaterialEditorPropertiesWindow-->RotationAnimation.setValue(0); + MaterialEditorPropertiesWindow-->ScrollAnimation.setValue(0); + MaterialEditorPropertiesWindow-->WaveAnimation.setValue(0); + MaterialEditorPropertiesWindow-->ScaleAnimation.setValue(0); + MaterialEditorPropertiesWindow-->SequenceAnimation.setValue(0); + + %flags = (%material).getAnimFlags(%layer); + %wordCount = getWordCount( %flags ); + for(%i = 0; %i != %wordCount; %i++) + { + switch$(getWord( %flags, %i)) + { + case "$rotate": MaterialEditorPropertiesWindow-->RotationAnimation.setValue(1); + case "$scroll": MaterialEditorPropertiesWindow-->ScrollAnimation.setValue(1); + case "$wave": MaterialEditorPropertiesWindow-->WaveAnimation.setValue(1); + case "$scale": MaterialEditorPropertiesWindow-->ScaleAnimation.setValue(1); + case "$sequence": MaterialEditorPropertiesWindow-->SequenceAnimation.setValue(1); + } + } + + MaterialEditorPropertiesWindow-->RotationTextEditU.setText( getWord((%material).rotPivotOffset[%layer], 0) ); + MaterialEditorPropertiesWindow-->RotationTextEditV.setText( getWord((%material).rotPivotOffset[%layer], 1) ); + MaterialEditorPropertiesWindow-->RotationSpeedTextEdit.setText( (%material).rotSpeed[%layer] ); + MaterialEditorPropertiesWindow-->RotationSliderU.setValue( getWord((%material).rotPivotOffset[%layer], 0) ); + MaterialEditorPropertiesWindow-->RotationSliderV.setValue( getWord((%material).rotPivotOffset[%layer], 1) ); + MaterialEditorPropertiesWindow-->RotationSpeedSlider.setValue( (%material).rotSpeed[%layer] ); + MaterialEditorPropertiesWindow-->RotationCrosshair.setPosition( 45*mAbs(getWord((%material).rotPivotOffset[%layer], 0))-2, 45*mAbs(getWord((%material).rotPivotOffset[%layer], 1))-2 ); + + MaterialEditorPropertiesWindow-->ScrollTextEditU.setText( getWord((%material).scrollDir[%layer], 0) ); + MaterialEditorPropertiesWindow-->ScrollTextEditV.setText( getWord((%material).scrollDir[%layer], 1) ); + MaterialEditorPropertiesWindow-->ScrollSpeedTextEdit.setText( (%material).scrollSpeed[%layer] ); + MaterialEditorPropertiesWindow-->ScrollSliderU.setValue( getWord((%material).scrollDir[%layer], 0) ); + MaterialEditorPropertiesWindow-->ScrollSliderV.setValue( getWord((%material).scrollDir[%layer], 1) ); + MaterialEditorPropertiesWindow-->ScrollSpeedSlider.setValue( (%material).scrollSpeed[%layer] ); + MaterialEditorPropertiesWindow-->ScrollCrosshair.setPosition( -(23 * getWord((%material).scrollDir[%layer], 0))+20, -(23 * getWord((%material).scrollDir[%layer], 1))+20); + + %waveType = (%material).waveType[%layer]; + for( %radioButton = 0; %radioButton < MaterialEditorPropertiesWindow-->WaveButtonContainer.getCount(); %radioButton++ ) + { + if( %waveType $= MaterialEditorPropertiesWindow-->WaveButtonContainer.getObject(%radioButton).waveType ) + MaterialEditorPropertiesWindow-->WaveButtonContainer.getObject(%radioButton).setStateOn(1); + } + + MaterialEditorPropertiesWindow-->WaveTextEditAmp.setText( (%material).waveAmp[%layer] ); + MaterialEditorPropertiesWindow-->WaveTextEditFreq.setText( (%material).waveFreq[%layer] ); + MaterialEditorPropertiesWindow-->WaveSliderAmp.setValue( (%material).waveAmp[%layer] ); + MaterialEditorPropertiesWindow-->WaveSliderFreq.setValue( (%material).waveFreq[%layer] ); + + %numFrames = mRound( 1 / (%material).sequenceSegmentSize[%layer] ); + + MaterialEditorPropertiesWindow-->SequenceTextEditFPS.setText( (%material).sequenceFramePerSec[%layer] ); + MaterialEditorPropertiesWindow-->SequenceTextEditSSS.setText( %numFrames ); + MaterialEditorPropertiesWindow-->SequenceSliderFPS.setValue( (%material).sequenceFramePerSec[%layer] ); + MaterialEditorPropertiesWindow-->SequenceSliderSSS.setValue( %numFrames ); + + // Accumulation + MaterialEditorPropertiesWindow-->accuCheckbox.setValue((%material).accuEnabled[%layer]); + + %this.preventUndo = false; +} + +//======================================= +// Material Update Functionality + +function MaterialEditorGui::changeLayer( %this, %layer ) +{ + if( MaterialEditorGui.currentLayer == getWord(%layer, 1) ) + return; + + MaterialEditorGui.currentLayer = getWord(%layer, 1); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); +} + +function MaterialEditorGui::updateActiveMaterial(%this, %propertyField, %value, %isSlider, %onMouseUp) +{ + MaterialEditorGui.setMaterialDirty(); + + if(%value $= "") + %value = "\"\""; + + // Here is where we handle undo actions with slider controls. We want to be able to + // undo every onMouseUp; so we overrite the same undo action when necessary in order + // to achieve this desired effect. + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if((%last != -1) && (%last.isSlider) && (!%last.onMouseUp)) + { + %last.field = %propertyField; + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValue = %value; + } + else + { + %action = %this.createUndo(ActionUpdateActiveMaterial, "Update Active Material"); + %action.material = MaterialEditorGui.currentMaterial; + %action.object = MaterialEditorGui.currentObject; + %action.field = %propertyField; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + %action.newValue = %value; + eval( "%action.oldValue = " @ MaterialEditorGui.currentMaterial @ "." @ %propertyField @ ";"); + %action.oldValue = "\"" @ %action.oldValue @ "\""; + MaterialEditorGui.submitUndo( %action ); + } + + eval("materialEd_previewMaterial." @ %propertyField @ " = " @ %value @ ";"); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + eval("MaterialEditorGui.currentMaterial." @ %propertyField @ " = " @ %value @ ";"); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } +} + +function MaterialEditorGui::updateActiveMaterialName(%this, %name) +{ + %action = %this.createUndo(ActionUpdateActiveMaterialName, "Update Active Material Name"); + %action.material = MaterialEditorGui.currentMaterial; + %action.object = MaterialEditorGui.currentObject; + %action.oldName = MaterialEditorGui.currentMaterial.getName(); + %action.newName = %name; + MaterialEditorGui.submitUndo( %action ); + + MaterialEditorGui.currentMaterial.setName(%name); + + // Some objects (ConvexShape, DecalRoad etc) reference Materials by name => need + // to find and update all these references so they don't break when we rename the + // Material. + MaterialEditorGui.updateMaterialReferences( MissionGroup, %action.oldName, %action.newName ); +} + +function MaterialEditorGui::updateMaterialReferences( %this, %obj, %oldName, %newName ) +{ + if ( %obj.isMemberOfClass( "SimSet" ) ) + { + // invoke on children + %count = %obj.getCount(); + for ( %i = 0; %i < %count; %i++ ) + %this.updateMaterialReferences( %obj.getObject( %i ), %oldName, %newName ); + } + else + { + %objChanged = false; + + // Change all material fields that use the old material name + %count = %obj.getFieldCount(); + for( %i = 0; %i < %count; %i++ ) + { + %fieldName = %obj.getField( %i ); + if ( ( %obj.getFieldType( %fieldName ) $= "TypeMaterialName" ) && ( %obj.getFieldValue( %fieldName ) $= %oldName ) ) + { + eval( %obj @ "." @ %fieldName @ " = " @ %newName @ ";" ); + %objChanged = true; + } + } + + EWorldEditor.isDirty |= %objChanged; + if ( %objChanged && %obj.isMethod( "postApply" ) ) + %obj.postApply(); + } +} + +// Global Material Options + +function MaterialEditorGui::updateReflectionType( %this, %type ) +{ + if( %type $= "None" ) + { + MaterialEditorPropertiesWindow-->matEd_cubemapEditBtn.setVisible(0); + //Reset material reflection settings on the preview materials + MaterialEditorGui.updateActiveMaterial( "cubeMap", "" ); + MaterialEditorGui.updateActiveMaterial( "dynamicCubemap" , false ); + MaterialEditorGui.updateActiveMaterial( "planarReflection", false ); + } + else + { + if(%type $= "cubeMap") + { + MaterialEditorPropertiesWindow-->matEd_cubemapEditBtn.setVisible(1); + MaterialEditorGui.updateActiveMaterial( %type, materialEd_previewMaterial.cubemap ); + } + else + { + MaterialEditorGui.updateActiveMaterial( %type, true ); + } + } +} + +// Per-Layer Material Options + +// For update maps +// %action : 1 = change map +// %action : 0 = remove map + +function MaterialEditorGui::updateTextureMap( %this, %type, %action ) +{ + %layer = MaterialEditorGui.currentLayer; + + %bitmapCtrl = MaterialEditorPropertiesWindow.findObjectByInternalName( %type @ "MapDisplayBitmap", true ); + %textCtrl = MaterialEditorPropertiesWindow.findObjectByInternalName( %type @ "MapNameText", true ); + + if( %action ) + { + %texture = MaterialEditorGui.openFile("texture"); + if( %texture !$= "" ) + { + %bitmapCtrl.setBitmap(%texture); + + %bitmap = %bitmapCtrl.bitmap; + %bitmap = strreplace(%bitmap,"tools/materialEditor/scripts/",""); + %bitmapCtrl.setBitmap(%bitmap); + %textCtrl.setText(%bitmap); + MaterialEditorGui.updateActiveMaterial(%type @ "Map[" @ %layer @ "]","\"" @ %bitmap @ "\""); + } + } + else + { + %textCtrl.setText("None"); + %bitmapCtrl.setBitmap("tools/materialEditor/gui/unknownImage"); + MaterialEditorGui.updateActiveMaterial(%type @ "Map[" @ %layer @ "]",""); + } +} + +function MaterialEditorGui::updateDetailScale(%this,%newScale) +{ + %layer = MaterialEditorGui.currentLayer; + + %detailScale = "\"" @ %newScale SPC %newScale @ "\""; + MaterialEditorGui.updateActiveMaterial("detailScale[" @ %layer @ "]", %detailScale); +} + +function MaterialEditorGui::updateDetailNormalStrength(%this,%newStrength) +{ + %layer = MaterialEditorGui.currentLayer; + + %detailStrength = "\"" @ %newStrength @ "\""; + MaterialEditorGui.updateActiveMaterial("detailNormalMapStrength[" @ %layer @ "]", %detailStrength); +} + +function MaterialEditorGui::updateSpecMap(%this,%action) +{ + %layer = MaterialEditorGui.currentLayer; + + if( %action ) + { + %texture = MaterialEditorGui.openFile("texture"); + if( %texture !$= "" ) + { + MaterialEditorGui.updateActiveMaterial("pixelSpecular[" @ MaterialEditorGui.currentLayer @ "]", 0); + + MaterialEditorPropertiesWindow-->specMapDisplayBitmap.setBitmap(%texture); + + %bitmap = MaterialEditorPropertiesWindow-->specMapDisplayBitmap.bitmap; + %bitmap = strreplace(%bitmap,"tools/materialEditor/scripts/",""); + MaterialEditorPropertiesWindow-->specMapDisplayBitmap.setBitmap(%bitmap); + MaterialEditorPropertiesWindow-->specMapNameText.setText(%bitmap); + MaterialEditorGui.updateActiveMaterial("specularMap[" @ %layer @ "]","\"" @ %bitmap @ "\""); + } + } + else + { + MaterialEditorPropertiesWindow-->specMapNameText.setText("None"); + MaterialEditorPropertiesWindow-->specMapDisplayBitmap.setBitmap("tools/materialEditor/gui/unknownImage"); + MaterialEditorGui.updateActiveMaterial("specularMap[" @ %layer @ "]",""); + } + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); +} + +function MaterialEditorGui::updateRotationOffset(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %X = MaterialEditorPropertiesWindow-->RotationTextEditU.getText(); + %Y = MaterialEditorPropertiesWindow-->RotationTextEditV.getText(); + MaterialEditorPropertiesWindow-->RotationCrosshair.setPosition(45*mAbs(%X)-2, 45*mAbs(%Y)-2); + + MaterialEditorGui.updateActiveMaterial("rotPivotOffset[" @ %layer @ "]","\"" @ %X SPC %Y @ "\"",%isSlider,%onMouseUp); +} + +function MaterialEditorGui::updateRotationSpeed(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %speed = MaterialEditorPropertiesWindow-->RotationSpeedTextEdit.getText(); + MaterialEditorGui.updateActiveMaterial("rotSpeed[" @ %layer @ "]",%speed,%isSlider,%onMouseUp); +} + +function MaterialEditorGui::updateScrollOffset(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %X = MaterialEditorPropertiesWindow-->ScrollTextEditU.getText(); + %Y = MaterialEditorPropertiesWindow-->ScrollTextEditV.getText(); + MaterialEditorPropertiesWindow-->ScrollCrosshair.setPosition( -(23 * %X)+20, -(23 * %Y)+20); + + MaterialEditorGui.updateActiveMaterial("scrollDir[" @ %layer @ "]","\"" @ %X SPC %Y @ "\"",%isSlider,%onMouseUp); +} + +function MaterialEditorGui::updateScrollSpeed(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %speed = MaterialEditorPropertiesWindow-->ScrollSpeedTextEdit.getText(); + MaterialEditorGui.updateActiveMaterial("scrollSpeed[" @ %layer @ "]",%speed,%isSlider,%onMouseUp); +} + +function MaterialEditorGui::updateWaveType(%this) +{ + for( %radioButton = 0; %radioButton < MaterialEditorPropertiesWindow-->WaveButtonContainer.getCount(); %radioButton++ ) + { + if( MaterialEditorPropertiesWindow-->WaveButtonContainer.getObject(%radioButton).getValue() == 1 ) + %type = MaterialEditorPropertiesWindow-->WaveButtonContainer.getObject(%radioButton).waveType; + } + + %layer = MaterialEditorGui.currentLayer; + MaterialEditorGui.updateActiveMaterial("waveType[" @ %layer @ "]", %type); +} + +function MaterialEditorGui::updateWaveAmp(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %amp = MaterialEditorPropertiesWindow-->WaveTextEditAmp.getText(); + MaterialEditorGui.updateActiveMaterial("waveAmp[" @ %layer @ "]", %amp, %isSlider, %onMouseUp); +} + +function MaterialEditorGui::updateWaveFreq(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %freq = MaterialEditorPropertiesWindow-->WaveTextEditFreq.getText(); + MaterialEditorGui.updateActiveMaterial("waveFreq[" @ %layer @ "]", %freq, %isSlider, %onMouseUp); +} + +function MaterialEditorGui::updateSequenceFPS(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %fps = MaterialEditorPropertiesWindow-->SequenceTextEditFPS.getText(); + MaterialEditorGui.updateActiveMaterial("sequenceFramePerSec[" @ %layer @ "]", %fps, %isSlider, %onMouseUp); +} + +function MaterialEditorGui::updateSequenceSSS(%this, %isSlider, %onMouseUp) +{ + %layer = MaterialEditorGui.currentLayer; + %sss = 1 / MaterialEditorPropertiesWindow-->SequenceTextEditSSS.getText(); + MaterialEditorGui.updateActiveMaterial("sequenceSegmentSize[" @ %layer @ "]", %sss, %isSlider, %onMouseUp); +} + +function MaterialEditorGui::updateAnimationFlags(%this) +{ + MaterialEditorGui.setMaterialDirty(); + %single = true; + + if(MaterialEditorPropertiesWindow-->RotationAnimation.getValue() == true) + { + if(%single == true) + %flags = %flags @ "$Rotate"; + else + %flags = %flags @ " | $Rotate"; + + %single = false; + } + if(MaterialEditorPropertiesWindow-->ScrollAnimation.getValue() == true) + { + if(%single == true) + %flags = %flags @ "$Scroll"; + else + %flags = %flags @ " | $Scroll"; + + %single = false; + } + if(MaterialEditorPropertiesWindow-->WaveAnimation.getValue() == true) + { + if(%single == true) + %flags = %flags @ "$Wave"; + else + %flags = %flags @ " | $Wave"; + + %single = false; + } + if(MaterialEditorPropertiesWindow-->ScaleAnimation.getValue() == true) + { + if(%single == true) + %flags = %flags @ "$Scale"; + else + %flags = %flags @ " | $Scale"; + + %single = false; + } + if(MaterialEditorPropertiesWindow-->SequenceAnimation.getValue() == true) + { + if(%single == true) + %flags = %flags @ "$Sequence"; + else + %flags = %flags @ " | $Sequence"; + + %single = false; + } + + if(%flags $= "") + %flags = "\"\""; + + %action = %this.createUndo(ActionUpdateActiveMaterialAnimationFlags, "Update Active Material"); + %action.material = MaterialEditorGui.currentMaterial; + %action.object = MaterialEditorGui.currentObject; + %action.layer = MaterialEditorGui.currentLayer; + + %action.newValue = %flags; + + %oldFlags = MaterialEditorGui.currentMaterial.getAnimFlags(MaterialEditorGui.currentLayer); + if(%oldFlags $= "") + %oldFlags = "\"\""; + + %action.oldValue = %oldFlags; + MaterialEditorGui.submitUndo( %action ); + + eval("materialEd_previewMaterial.animFlags[" @ MaterialEditorGui.currentLayer @ "] = " @ %flags @ ";"); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + eval("MaterialEditorGui.currentMaterial.animFlags[" @ MaterialEditorGui.currentLayer @ "] = " @ %flags @ ";"); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } +} + +//============================================================================== +// Color Picker Helpers - They are all using colorPicker.ed.gui in order to function +// These functions are mainly passed callbacks from getColorI/getColorF callbacks + +function MaterialEditorGui::syncGuiColor(%this, %guiCtrl, %propname, %color) +{ + %layer = MaterialEditorGui.currentLayer; + + %r = getWord(%color,0); + %g = getWord(%color,1); + %b = getWord(%color,2); + %a = getWord(%color,3); + + %colorSwatch = (%r SPC %g SPC %b SPC %a); + %color = "\"" @ %r SPC %g SPC %b SPC %a @ "\""; + + %guiCtrl.color = %colorSwatch; + MaterialEditorGui.updateActiveMaterial(%propName, %color); +} + +//These two functions are focused on object/layer specific functionality +function MaterialEditorGui::updateColorMultiply(%this,%color) +{ + %propName = "diffuseColor[" @ MaterialEditorGui.currentLayer @ "]"; + %this.syncGuiColor(MaterialEditorPropertiesWindow-->colorTintSwatch, %propName, %color); +} + +function MaterialEditorGui::updateSpecularCheckbox(%this,%value) +{ + MaterialEditorGui.updateActiveMaterial("pixelSpecular[" @ MaterialEditorGui.currentLayer @ "]", %value); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); +} + +function MaterialEditorGui::updateSpecular(%this, %color) +{ + %propName = "specular[" @ MaterialEditorGui.currentLayer @ "]"; + %this.syncGuiColor(MaterialEditorPropertiesWindow-->specularColorSwatch, %propName, %color); +} + +function MaterialEditorGui::updateSubSurfaceColor(%this, %color) +{ + %propName = "subSurfaceColor[" @ MaterialEditorGui.currentLayer @ "]"; + %this.syncGuiColor(MaterialEditorPropertiesWindow-->subSurfaceColorSwatch, %propName, %color); +} + +function MaterialEditorGui::updateEffectColor0(%this, %color) +{ + %this.syncGuiColor(MaterialEditorPropertiesWindow-->effectColor0Swatch, "effectColor[0]", %color); +} + +function MaterialEditorGui::updateEffectColor1(%this, %color) +{ + %this.syncGuiColor(MaterialEditorPropertiesWindow-->effectColor1Swatch, "effectColor[1]", %color); +} + +function MaterialEditorGui::updateBehaviorSound(%this, %type, %sound) +{ + %defaultId = -1; + %customName = ""; + + switch$ (%sound) + { + case "<Soft>": %defaultId = 0; + case "<Hard>": %defaultId = 1; + case "<Metal>": %defaultId = 2; + case "<Snow>": %defaultId = 3; + default: %customName = %sound; + } + + %this.updateActiveMaterial(%type @ "SoundId", %defaultId); + %this.updateActiveMaterial("custom" @ %type @ "Sound", %customName); +} + +function MaterialEditorGui::updateSoundPopup(%this, %type, %defaultId, %customName) +{ + %ctrl = MaterialEditorPropertiesWindow.findObjectByInternalName( %type @ "SoundPopup", true ); + + switch (%defaultId) + { + case 0: %name = "<Soft>"; + case 1: %name = "<Hard>"; + case 2: %name = "<Metal>"; + case 3: %name = "<Snow>"; + default: + if (%customName $= "") + %name = "<None>"; + else + %name = %customName; + } + + %r = %ctrl.findText(%name); + if (%r != -1) + %ctrl.setSelected(%r, false); + else + %ctrl.setText(%name); +} + +//These two functions are focused on environment specific functionality +function MaterialEditorGui::updateLightColor(%this, %color) +{ + matEd_previewObjectView.setLightColor(%color); + matEd_lightColorPicker.color = %color; +} + +function MaterialEditorGui::updatePreviewBackground(%this,%color) +{ + matEd_previewBackground.color = %color; + MaterialPreviewBackgroundPicker.color = %color; +} + +function MaterialEditorGui::updateAmbientColor(%this,%color) +{ + matEd_previewObjectView.setAmbientLightColor(%color); + matEd_ambientLightColorPicker.color = %color; +} + +//============================================================================== +// Commands for the Cubemap Editor + +function MaterialEditorGui::selectCubemap(%this) +{ + %cubemap = MaterialEditorGui.currentCubemap; + if(!isObject(%cubemap)) + return; + + MaterialEditorGui.updateActiveMaterial( "cubemap", %cubemap.name ); + MaterialEditorGui.hideCubemapEditor(); +} + +function MaterialEditorGui::cancelCubemap(%this) +{ + %cubemap = MaterialEditorGui.currentCubemap; + + %idx = matEd_cubemapEd_availableCubemapList.findItemText( %cubemap.getName() ); + matEd_cubemapEd_availableCubemapList.setItemText( %idx, notDirtyCubemap.originalName ); + %cubemap.setName( notDirtyCubemap.originalName ); + + MaterialEditorGui.copyCubemaps( notDirtyCubemap, %cubemap ); + MaterialEditorGui.copyCubemaps( notDirtyCubemap, matEdCubeMapPreviewMat); + + %cubemap.updateFaces(); + matEdCubeMapPreviewMat.updateFaces(); +} + +function MaterialEditorGui::showCubemapEditor(%this) +{ + if (matEd_cubemapEditor.isVisible()) + return; + + MaterialEditorGui.currentCubemap = ""; + + matEd_cubemapEditor.setVisible(1); + new PersistenceManager(matEd_cubemapEdPerMan); + MaterialEditorGui.setCubemapNotDirty(); + + for( %i = 0; %i < RootGroup.getCount(); %i++ ) + { + if( RootGroup.getObject(%i).getClassName()!$= "CubemapData" ) + continue; + + for( %k = 0; %k < UnlistedCubemaps.count(); %k++ ) + { + %unlistedFound = 0; + if( UnlistedCubemaps.getValue(%k) $= RootGroup.getObject(%i).name ) + { + %unlistedFound = 1; + break; + } + } + + if( %unlistedFound ) + continue; + + matEd_cubemapEd_availableCubemapList.addItem( RootGroup.getObject(%i).name ); + } + + singleton CubemapData(notDirtyCubemap); + + // if there was no cubemap, pick the first, select, and bail, these are going to take + // care of themselves in the selected function + if( !isObject( MaterialEditorGui.currentMaterial.cubemap ) ) + { + if( matEd_cubemapEd_availableCubemapList.getItemCount() > 0 ) + { + matEd_cubemapEd_availableCubemapList.setSelected(0, true); + return; + } + else + { + // if there are no cubemaps, then create one, select, and bail + %cubemap = MaterialEditorGui.createNewCubemap(); + matEd_cubemapEd_availableCubemapList.addItem( %cubemap.name ); + matEd_cubemapEd_availableCubemapList.setSelected(0, true); + return; + } + } + + // do not directly change activeMat! + MaterialEditorGui.currentCubemap = MaterialEditorGui.currentMaterial.cubemap.getId(); + %cubemap = MaterialEditorGui.currentCubemap; + + notDirtyCubemap.originalName = %cubemap.getName(); + MaterialEditorGui.copyCubemaps( %cubemap, notDirtyCubemap); + MaterialEditorGui.copyCubemaps( %cubemap, matEdCubeMapPreviewMat); + MaterialEditorGui.syncCubemap( %cubemap ); +} + +function MaterialEditorGui::hideCubemapEditor(%this,%cancel) +{ + if(%cancel) + MaterialEditorGui.cancelCubemap(); + + matEd_cubemapEd_availableCubemapList.clearItems(); + matEd_cubemapEdPerMan.delete(); + matEd_cubemapEditor.setVisible(0); +} + +// create category and update current material if there is one +function MaterialEditorGui::addCubemap( %this,%cubemapName ) +{ + if( %cubemapName $= "" ) + { + MessageBoxOK( "Error", "Can not create a cubemap without a valid name."); + return; + } + + for(%i = 0; %i < RootGroup.getCount(); %i++) + { + if( %cubemapName $= RootGroup.getObject(%i).getName() ) + { + MessageBoxOK( "Error", "There is already an object with the same name."); + return; + } + } + + // Create and select a new cubemap + %cubemap = MaterialEditorGui.createNewCubemap( %cubemapName ); + %idx = matEd_cubemapEd_availableCubemapList.addItem( %cubemap.name ); + matEd_cubemapEd_availableCubemapList.setSelected( %idx, true ); + + // material category text field to blank + matEd_addCubemapWindow-->cubemapName.setText(""); +} + +function MaterialEditorGui::createNewCubemap( %this, %cubemap ) +{ + if( %cubemap $= "" ) + { + for(%i = 0; ; %i++) + { + %cubemap = "newCubemap_" @ %i; + if( !isObject(%cubemap) ) + break; + } + } + + new CubemapData(%cubemap) + { + cubeFace[0] = "tools/materialEditor/gui/cube_xNeg"; + cubeFace[1] = "tools/materialEditor/gui/cube_xPos"; + cubeFace[2] = "tools/materialEditor/gui/cube_ZNeg"; + cubeFace[3] = "tools/materialEditor/gui/cube_ZPos"; + cubeFace[4] = "tools/materialEditor/gui/cube_YNeg"; + cubeFace[5] = "tools/materialEditor/gui/cube_YPos"; + + parentGroup = RootGroup; + }; + + matEd_cubemapEdPerMan.setDirty( %cubemap, "art/materials.cs" ); + matEd_cubemapEdPerMan.saveDirty(); + + return %cubemap; +} + +function MaterialEditorGui::setCubemapDirty(%this) +{ + %propertyText = "Create Cubemap *"; + matEd_cubemapEditor.text = %propertyText; + matEd_cubemapEditor.dirty = true; + matEd_cubemapEditor-->saveCubemap.setActive(true); + + %cubemap = MaterialEditorGui.currentCubemap; + + // materials created in the materail selector are given that as its filename, so we run another check + if( MaterialEditorGui.isMatEditorMaterial( %cubemap ) ) + matEd_cubemapEdPerMan.setDirty(%cubemap, "art/materials.cs"); + else + matEd_cubemapEdPerMan.setDirty(%cubemap); +} + +function MaterialEditorGui::setCubemapNotDirty(%this) +{ + %propertyText= strreplace("Create Cubemap" , "*" , ""); + matEd_cubemapEditor.text = %propertyText; + matEd_cubemapEditor.dirty = false; + matEd_cubemapEditor-->saveCubemap.setActive(false); + + %cubemap = MaterialEditorGui.currentCubemap; + matEd_cubemapEdPerMan.removeDirty(%cubemap); +} + +function MaterialEditorGui::showDeleteCubemapDialog(%this) +{ + %idx = matEd_cubemapEd_availableCubemapList.getSelectedItem(); + %cubemap = matEd_cubemapEd_availableCubemapList.getItemText( %idx ); + %cubemap = %cubemap.getId(); + + if( %cubemap == -1 || !isObject(%cubemap) ) + return; + + if( isObject( %cubemap ) ) + { + MessageBoxYesNoCancel("Delete Cubemap?", + "Are you sure you want to delete<br><br>" @ %cubemap.getName() @ "<br><br> Cubemap deletion won't take affect until the engine is quit.", + "MaterialEditorGui.deleteCubemap( " @ %cubemap @ ", " @ %idx @ " );", + "", + "" ); + } +} + +function MaterialEditorGui::deleteCubemap( %this, %cubemap, %idx ) +{ + matEd_cubemapEd_availableCubemapList.deleteItem( %idx ); + + UnlistedCubemaps.add( "unlistedCubemaps", %cubemap.getName() ); + + if( !MaterialEditorGui.isMatEditorMaterial( %cubemap ) ) + { + matEd_cubemapEdPerMan.removeDirty( %cubemap ); + matEd_cubemapEdPerMan.removeObjectFromFile( %cubemap ); + } + + if( matEd_cubemapEd_availableCubemapList.getItemCount() > 0 ) + { + matEd_cubemapEd_availableCubemapList.setSelected(0, true); + } + else + { + // if there are no cubemaps, then create one, select, and bail + %cubemap = MaterialEditorGui.createNewCubemap(); + matEd_cubemapEd_availableCubemapList.addItem( %cubemap.getName() ); + matEd_cubemapEd_availableCubemapList.setSelected(0, true); + } +} + +function matEd_cubemapEd_availableCubemapList::onSelect( %this, %id, %cubemap ) +{ + %cubemap = %cubemap.getId(); + if( MaterialEditorGui.currentCubemap $= %cubemap ) + return; + + if( matEd_cubemapEditor.dirty ) + { + %savedCubemap = MaterialEditorGui.currentCubemap; + MessageBoxYesNoCancel("Save Existing Cubemap?", + "Do you want to save changes to <br><br>" @ %savedCubemap.getName(), + "MaterialEditorGui.saveCubemap(" @ true @ ");", + "MaterialEditorGui.saveCubemapDialogDontSave(" @ %cubemap @ ");", + "MaterialEditorGui.saveCubemapDialogCancel();" ); + } + else + MaterialEditorGui.changeCubemap( %cubemap ); +} + +function MaterialEditorGui::showSaveCubemapDialog( %this ) +{ + %cubemap = MaterialEditorGui.currentCubemap; + if( !isObject(%cubemap) ) + return; + + MessageBoxYesNoCancel("Save Cubemap?", + "Do you want to save changes to <br><br>" @ %cubemap.getName(), + "MaterialEditorGui.saveCubemap( " @ %cubemap @ " );", + "", + "" ); +} + +function MaterialEditorGui::saveCubemap( %this, %cubemap ) +{ + notDirtyCubemap.originalName = %cubemap.getName(); + MaterialEditorGui.copyCubemaps( %cubemap, notDirtyCubemap ); + MaterialEditorGui.copyCubemaps( %cubemap, matEdCubeMapPreviewMat); + + matEd_cubemapEdPerMan.saveDirty(); + + MaterialEditorGui.setCubemapNotDirty(); +} + +function MaterialEditorGui::saveCubemapDialogDontSave( %this, %newCubemap) +{ + //deal with old cubemap first + %oldCubemap = MaterialEditorGui.currentCubemap; + + %idx = matEd_cubemapEd_availableCubemapList.findItemText( %oldCubemap.getName() ); + matEd_cubemapEd_availableCubemapList.setItemText( %idx, notDirtyCubemap.originalName ); + %oldCubemap.setName( notDirtyCubemap.originalName ); + + MaterialEditorGui.copyCubemaps( notDirtyCubemap, %oldCubemap); + MaterialEditorGui.copyCubemaps( notDirtyCubemap, matEdCubeMapPreviewMat); + MaterialEditorGui.syncCubemap( %oldCubemap ); + + MaterialEditorGui.changeCubemap( %newCubemap ); +} + +function MaterialEditorGui::saveCubemapDialogCancel( %this ) +{ + %cubemap = MaterialEditorGui.currentCubemap; + %idx = matEd_cubemapEd_availableCubemapList.findItemText( %cubemap.getName() ); + matEd_cubemapEd_availableCubemapList.clearSelection(); + matEd_cubemapEd_availableCubemapList.setSelected( %idx, true ); +} + +function MaterialEditorGui::changeCubemap( %this, %cubemap ) +{ + MaterialEditorGui.setCubemapNotDirty(); + MaterialEditorGui.currentCubemap = %cubemap; + + notDirtyCubemap.originalName = %cubemap.getName(); + MaterialEditorGui.copyCubemaps( %cubemap, notDirtyCubemap); + MaterialEditorGui.copyCubemaps( %cubemap, matEdCubeMapPreviewMat); + MaterialEditorGui.syncCubemap( %cubemap ); +} + +function MaterialEditorGui::editCubemapImage( %this, %face ) +{ + MaterialEditorGui.setCubemapDirty(); + + %cubemap = MaterialEditorGui.currentCubemap; + %bitmap = MaterialEditorGui.openFile("texture"); + if( %bitmap !$= "" && %bitmap !$= "tools/materialEditor/gui/cubemapBtnBorder" ) + { + %cubemap.cubeFace[%face] = %bitmap; + MaterialEditorGui.copyCubemaps( %cubemap, matEdCubeMapPreviewMat); + MaterialEditorGui.syncCubemap( %cubemap ); + } +} + +function MaterialEditorGui::editCubemapName( %this, %newName ) +{ + MaterialEditorGui.setCubemapDirty(); + + %cubemap = MaterialEditorGui.currentCubemap; + + %idx = matEd_cubemapEd_availableCubemapList.findItemText( %cubemap.getName() ); + matEd_cubemapEd_availableCubemapList.setItemText( %idx, %newName ); + %cubemap.setName(%newName); + + MaterialEditorGui.syncCubemap( %cubemap ); +} + +function MaterialEditorGui::syncCubemap( %this, %cubemap ) +{ + %xpos = MaterialEditorGui.searchForTexture(%cubemap.getName(), %cubemap.cubeFace[0]); + if( %xpos !$= "" ) + matEd_cubemapEd_XPos.setBitmap( %xpos ); + + %xneg = MaterialEditorGui.searchForTexture(%cubemap.getName(), %cubemap.cubeFace[1]); + if( %xneg !$= "" ) + matEd_cubemapEd_XNeg.setBitmap( %xneg ); + + %yneg = MaterialEditorGui.searchForTexture(%cubemap.getName(), %cubemap.cubeFace[2]); + if( %yneg !$= "" ) + matEd_cubemapEd_YNeG.setBitmap( %yneg ); + + %ypos = MaterialEditorGui.searchForTexture(%cubemap.getName(), %cubemap.cubeFace[3]); + if( %ypos !$= "" ) + matEd_cubemapEd_YPos.setBitmap( %ypos ); + + %zpos = MaterialEditorGui.searchForTexture(%cubemap.getName(), %cubemap.cubeFace[4]); + if( %zpos !$= "" ) + matEd_cubemapEd_ZPos.setBitmap( %zpos ); + + %zneg = MaterialEditorGui.searchForTexture(%cubemap.getName(), %cubemap.cubeFace[5]); + if( %zneg !$= "" ) + matEd_cubemapEd_ZNeg.setBitmap( %zneg ); + + matEd_cubemapEd_activeCubemapNameTxt.setText(%cubemap.getName()); + + %cubemap.updateFaces(); + matEdCubeMapPreviewMat.updateFaces(); +} + +function MaterialEditorGui::copyCubemaps( %this, %copyFrom, %copyTo) +{ + %copyTo.cubeFace[0] = %copyFrom.cubeFace[0]; + %copyTo.cubeFace[1] = %copyFrom.cubeFace[1]; + %copyTo.cubeFace[2] = %copyFrom.cubeFace[2]; + %copyTo.cubeFace[3] = %copyFrom.cubeFace[3]; + %copyTo.cubeFace[4] = %copyFrom.cubeFace[4]; + %copyTo.cubeFace[5] = %copyFrom.cubeFace[5]; +} + + +//============================================================================== +// showSaveDialog logic + +function MaterialEditorGui::showSaveDialog( %this, %toMaterial ) +{ + MessageBoxYesNoCancel("Save Material?", + "The material " @ MaterialEditorGui.currentMaterial.getName() @ " has unsaved changes. <br>Do you want to save?", + "MaterialEditorGui.saveDialogSave(" @ %toMaterial @ ");", + "MaterialEditorGui.saveDialogDontSave(" @ %toMaterial @ ");", + "MaterialEditorGui.saveDialogCancel();" ); +} + +function MaterialEditorGui::showMaterialChangeSaveDialog( %this, %toMaterial ) +{ + %fromMaterial = MaterialEditorGui.currentMaterial; + + MessageBoxYesNoCancel("Save Material?", + "The material " @ %fromMaterial.getName() @ " has unsaved changes. <br>Do you want to save before changing the material?", + "MaterialEditorGui.saveDialogSave(" @ %toMaterial @ "); MaterialEditorGui.changeMaterial(" @ %fromMaterial @ ", " @ %toMaterial @ ");", + "MaterialEditorGui.saveDialogDontSave(" @ %toMaterial @ "); MaterialEditorGui.changeMaterial(" @ %fromMaterial @ ", " @ %toMaterial @ ");", + "MaterialEditorGui.saveDialogCancel();" ); +} + +/* +function MaterialEditorGui::showCreateNewMaterialSaveDialog( %this, %toMaterial ) +{ + MessageBoxYesNoCancel("Save Material?", + "The material " @ MaterialEditorGui.currentMaterial.getName() @ " has unsaved changes. <br>Do you want to save before changing the material?", + "MaterialEditorGui.save(); MaterialEditorGui.createNewMaterial(" @ %toMaterial @ ");", + "MaterialEditorGui.saveDialogDontSave(" @ %toMaterial @ "); MaterialEditorGui.changeMaterial(" @ %toMaterial @ ");", + "MaterialEditorGui.saveDialogCancel();" ); +} +*/ + +function MaterialEditorGui::saveDialogCancel( %this ) +{ + MaterialEditorGui.guiSync( materialEd_previewMaterial ); +} + +function MaterialEditorGui::saveDialogDontSave( %this, %material ) +{ + MaterialEditorGui.currentMaterial.setName( %this.originalName ); + + //restore to defaults + MaterialEditorGui.copyMaterials( notDirtyMaterial, MaterialEditorGui.currentMaterial ); + MaterialEditorGui.copyMaterials( notDirtyMaterial, materialEd_previewMaterial ); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + + MaterialEditorGui.setMaterialNotDirty(); + + MaterialEditorGui.setActiveMaterial( %material ); +} + +function MaterialEditorGui::saveDialogSave( %this, %material ) +{ + MaterialEditorGui.save(); + MaterialEditorGui.setActiveMaterial( %material ); +} + +function MaterialEditorGui::save( %this ) +{ + if( MaterialEditorGui.currentMaterial.getName() $= "" ) + { + MessageBoxOK("Cannot perform operation", "Saved materials cannot be named \"\". A name must be given before operation is performed" ); + return; + } + + // Update the live object regardless in this case + MaterialEditorGui.updateLivePreview(true); + + %currentMaterial = MaterialEditorGui.currentMaterial; + if( %currentMaterial == -1 ) + { + MessageBoxOK("Cannot perform operation", "Could not locate material" ); + return; + } + + // Specifically for materials autogenerated from shapes. + if( %currentMaterial.isAutoGenerated() ) + %currentMaterial.setAutoGenerated( false ); + + // Save the material using the persistence manager + matEd_PersistMan.saveDirty(); + + // Clean up the Material Editor + MaterialEditorGui.copyMaterials( materialEd_previewMaterial, notDirtyMaterial ); + MaterialEditorGui.setMaterialNotDirty(); +} + +//============================================================================== +// Create New and Delete Material + +function MaterialEditorGui::createNewMaterial( %this ) +{ + %action = %this.createUndo(ActionCreateNewMaterial, "Create New Material"); + %action.object = ""; + + %material = getUniqueName( "newMaterial" ); + new Material(%material) + { + diffuseMap[0] = "core/art/warnmat"; + mapTo = "unmapped_mat"; + parentGroup = RootGroup; + }; + + %action.newMaterial = %material.getId(); + %action.oldMaterial = MaterialEditorGui.currentMaterial; + + MaterialEditorGui.submitUndo( %action ); + + MaterialEditorGui.currentObject = ""; + MaterialEditorGui.setMode(); + MaterialEditorGui.prepareActiveMaterial( %material.getId(), true ); +} + +function MaterialEditorGui::deleteMaterial( %this ) +{ + %action = %this.createUndo(ActionDeleteMaterial, "Delete Material"); + %action.object = MaterialEditorGui.currentObject; + %action.currentMode = MaterialEditorGui.currentMode; + + /* + if( MaterialEditorGui.currentMode $= "Mesh" ) + { + %materialTarget = SubMaterialSelector.text; + %action.materialTarget = %materialTarget; + + //create the stub material + %toMaterial = getUniqueName( "newMaterial" ); + new Material(%toMaterial) + { + diffuseMap[0] = "core/art/warnmat"; + mapTo = "unmapped_mat"; + parentGroup = RootGroup; + }; + + %action.toMaterial = %toMaterial.getId(); + %action.fromMaterial = MaterialEditorGui.currentMaterial; + %action.fromMaterialOldFname = MaterialEditorGui.currentMaterial.getFilename(); + } + else + { + // Grab first material we see; if theres not one, create one + %toMaterial = MaterialSet.getObject(0); + if( !isObject( %toMaterial ) ) + { + %toMaterial = getUniqueName( "newMaterial" ); + new Material(%toMaterial) + { + diffuseMap[0] = "core/art/warnmat"; + mapTo = "unmapped_mat"; + parentGroup = RootGroup; + }; + } + + %action.toMaterial = %toMaterial.getId(); + %action.fromMaterial = MaterialEditorGui.currentMaterial; + } + */ + + // Grab first material we see; if theres not one, create one + %newMaterial = getUniqueName( "newMaterial" ); + new Material(%newMaterial) + { + diffuseMap[0] = "core/art/warnmat"; + mapTo = "unmapped_mat"; + parentGroup = RootGroup; + }; + + // Setup vars + %action.newMaterial = %newMaterial.getId(); + %action.oldMaterial = MaterialEditorGui.currentMaterial; + %action.oldMaterialFname = MaterialEditorGui.currentMaterial.getFilename(); + + // Submit undo + MaterialEditorGui.submitUndo( %action ); + + // Delete the material from file + if( !MaterialEditorGui.isMatEditorMaterial( MaterialEditorGui.currentMaterial ) ) + { + matEd_PersistMan.removeObjectFromFile(MaterialEditorGui.currentMaterial); + matEd_PersistMan.removeDirty(MaterialEditorGui.currentMaterial); + } + + // Delete the material as seen through the material selector. + UnlistedMaterials.add( "unlistedMaterials", MaterialEditorGui.currentMaterial.getName() ); + + // Loadup another material + MaterialEditorGui.currentObject = ""; + MaterialEditorGui.setMode(); + MaterialEditorGui.prepareActiveMaterial( %newMaterial.getId(), true ); +} + +//============================================================================== +// Clear and Refresh Material + +function MaterialEditorGui::clearMaterial(%this) +{ + %action = %this.createUndo(ActionClearMaterial, "Clear Material"); + %action.material = MaterialEditorGui.currentMaterial; + %action.object = MaterialEditorGui.currentObject; + + pushInstantGroup(); + %action.oldMaterial = new Material(); + %action.newMaterial = new Material(); + popInstantGroup(); + + MaterialEditorGui.submitUndo( %action ); + + MaterialEditorGui.copyMaterials( MaterialEditorGui.currentMaterial, %action.oldMaterial ); + + %tempMat = new Material() + { + name = "tempMaterial"; + mapTo = "unmapped_mat"; + parentGroup = RootGroup; + }; + + MaterialEditorGui.copyMaterials( %tempMat, materialEd_previewMaterial ); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + MaterialEditorGui.copyMaterials( %tempMat, MaterialEditorGui.currentMaterial ); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } + + MaterialEditorGui.setMaterialDirty(); + + %tempMat.delete(); +} + +function MaterialEditorGui::refreshMaterial(%this) +{ + %action = %this.createUndo(ActionRefreshMaterial, "Refresh Material"); + %action.material = MaterialEditorGui.currentMaterial; + %action.object = MaterialEditorGui.currentObject; + + pushInstantGroup(); + %action.oldMaterial = new Material(); + %action.newMaterial = new Material(); + popInstantGroup(); + + MaterialEditorGui.copyMaterials( MaterialEditorGui.currentMaterial, %action.oldMaterial ); + MaterialEditorGui.copyMaterials( notDirtyMaterial, %action.newMaterial ); + + %action.oldName = MaterialEditorGui.currentMaterial.getName(); + %action.newName = %this.originalName; + + MaterialEditorGui.submitUndo( %action ); + + MaterialEditorGui.currentMaterial.setName( %this.originalName ); + MaterialEditorGui.copyMaterials( notDirtyMaterial, materialEd_previewMaterial ); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + MaterialEditorGui.copyMaterials( notDirtyMaterial, MaterialEditorGui.currentMaterial ); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } + + MaterialEditorGui.setMaterialNotDirty(); +} + +//============================================================================== +// Switching and Changing Materials + +function MaterialEditorGui::switchMaterial( %this, %material ) +{ + //MaterialEditorGui.currentMaterial = %material.getId(); + MaterialEditorGui.currentObject = ""; + MaterialEditorGui.setMode(); + MaterialEditorGui.prepareActiveMaterial( %material.getId(), true ); +} + +/*------------------------------------------------------------------------------ + This changes the map to's of possibly two materials (%fromMaterial, %toMaterial) + and updates the engines libraries accordingly in order to make this change per + object/per objects instances/per target. Before this functionality is enacted, + there is a popup beforehand that will ask if you are sure if you want to make + this change. Making this change will physically alter possibly two materials.cs + files in order to move the (%fromMaterial, %toMaterial), replacing the + (%fromMaterials)'s mapTo to "unmapped_mat". +-------------------------------------------------------------------------------*/ + +function MaterialEditorGui::changeMaterial(%this, %fromMaterial, %toMaterial) +{ + %action = %this.createUndo(ActionChangeMaterial, "Change Material"); + %action.object = MaterialEditorGui.currentObject; + + %materialTarget = SubMaterialSelector.text; + %action.materialTarget = %materialTarget; + + %action.fromMaterial = %fromMaterial; + %action.toMaterial = %toMaterial; + %action.toMaterialOldFname = %toMaterial.getFilename(); + %action.object = MaterialEditorGui.currentObject; + + if( MaterialEditorGui.currentMeshMode $= "Model" ) // Models + { + %action.mode = "model"; + + MaterialEditorGui.currentObject.changeMaterial( %materialTarget, %fromMaterial.getName(), %toMaterial.getName() ); + + if( MaterialEditorGui.currentObject.shapeName !$= "" ) + %sourcePath = MaterialEditorGui.currentObject.shapeName; + else if( MaterialEditorGui.currentObject.isMethod("getDatablock") ) + { + if( MaterialEditorGui.currentObject.getDatablock().shapeFile !$= "" ) + %sourcePath = MaterialEditorGui.currentObject.getDatablock().shapeFile; + } + + // Creating "to" path + %k = 0; + while( strpos( %sourcePath, "/", %k ) != -1 ) + { + %count = strpos( %sourcePath, "/", %k ); + %k = %count + 1; + } + %fileName = getSubStr( %sourcePath , 0 , %k ); + %fileName = %fileName @ "materials.cs"; + + %action.toMaterialNewFname = %fileName; + + MaterialEditorGui.prepareActiveMaterial( %toMaterial, true ); + if( !MaterialEditorGui.isMatEditorMaterial( %toMaterial ) ) + { + matEd_PersistMan.removeObjectFromFile(%toMaterial); + } + + matEd_PersistMan.setDirty(%fromMaterial); + matEd_PersistMan.setDirty(%toMaterial, %fileName); + matEd_PersistMan.saveDirty(); + + matEd_PersistMan.removeDirty(%fromMaterial); + matEd_PersistMan.removeDirty(%toMaterial); + } + else // EditorShapes + { + %action.mode = "editorShapes"; + + eval("MaterialEditorGui.currentObject." @ SubMaterialSelector.getText() @ " = " @ %toMaterial.getName() @ ";"); + if( MaterialEditorGui.currentObject.isMethod("postApply") ) + MaterialEditorGui.currentObject.postApply(); + + MaterialEditorGui.prepareActiveMaterial( %toMaterial, true ); + } + + MaterialEditorGui.submitUndo( %action ); +} + +//============================================================================== +// Image thumbnail right-clicks. + +// not yet functional +function MaterialEditorMapThumbnail::onRightClick( %this ) +{ + if( !isObject( "MaterialEditorMapThumbnailPopup" ) ) + new PopupMenu( MaterialEditorMapThumbnailPopup ) + { + superClass = "MenuBuilder"; + isPopup = true; + + item[ 0 ] = "Open File" TAB "" TAB "openFile( %this.filePath );"; + item[ 1 ] = "Open Folder" TAB "" TAB "openFolder( filePath( %this.filePath ) );"; + + filePath = ""; + }; + + // Find the text control containing the filename. + + %textCtrl = %this.parentGroup.findObjectByInternalName( %this.fileNameTextCtrl, true ); + if( !%textCtrl ) + return; + + %fileName = %textCtrl.getText(); + %fullPath = makeFullPath( %fileName, getMainDotCsDir() ); + + // Construct a full path. + + %isValid = isFile( %fullPath ); + if( !%isValid ) + { + if( isFile( %fileName ) ) + { + %fullPath = %fileName; + %isValid = true; + } + else + { + // Try material-relative path. + + %material = MaterialEditorGui.currentMaterial; + if( isObject( %material ) ) + { + %materialPath = filePath( makeFullPath( %material.getFilename(), getMainDotCsDir() ) ); + %fullPath = makeFullPath( %fileName, %materialPath ); + %isValid = isFile( %fullPath ); + } + } + } + + %popup = MaterialEditorMapThumbnailPopup; + %popup.enableItem( 0, %isValid ); + %popup.enableItem( 1, %isValid ); + %popup.filePath = %fullPath; + + %popup.showPopup( Canvas ); +} + +// Accumulation +function MaterialEditorGui::updateAccuCheckbox(%this, %value) +{ + MaterialEditorGui.updateActiveMaterial("accuEnabled[" @ MaterialEditorGui.currentLayer @ "]", %value); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); +} diff --git a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditorUndo.ed.cs b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditorUndo.ed.cs new file mode 100644 index 000000000..184f02ce4 --- /dev/null +++ b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditorUndo.ed.cs @@ -0,0 +1,477 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function MaterialEditorGui::createUndo(%this, %class, %desc) +{ + pushInstantGroup(); + %action = new UndoScriptAction() + { + class = %class; + superClass = BaseMaterialEdAction; + actionName = %desc; + }; + popInstantGroup(); + return %action; +} + +function MaterialEditorGui::submitUndo(%this, %action) +{ + if(!%this.preventUndo) + %action.addToManager(Editor.getUndoManager()); +} + +function BaseMaterialEdAction::redo(%this) +{ + %this.redo(); +} + +function BaseMaterialEdAction::undo(%this) +{ +} + +// Generic updateActiveMaterial redo/undo + +function ActionUpdateActiveMaterial::redo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + /* + if( MaterialEditorGui.currentMaterial != %this.material ) + { + MaterialEditorGui.currentObject = %this.object; + MaterialEditorGui.setMode(); + MaterialEditorGui.setActiveMaterial(%this.material); + } + */ + eval("materialEd_previewMaterial." @ %this.field @ " = " @ %this.newValue @ ";"); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + eval("%this.material." @ %this.field @ " = " @ %this.newValue @ ";"); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } + + MaterialEditorGui.preventUndo = true; + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + MaterialEditorGui.preventUndo = false; + } + else + { + eval("%this.material." @ %this.field @ " = " @ %this.newValue @ ";"); + %this.material.flush(); + %this.material.reload(); + } +} + +function ActionUpdateActiveMaterial::undo(%this) +{ + MaterialEditorGui.preventUndo = true; + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + /* + if( MaterialEditorGui.currentMaterial != %this.material ) + { + MaterialEditorGui.currentObject = %this.object; + MaterialEditorGui.setMode(); + MaterialEditorGui.setActiveMaterial(%this.material); + } + */ + + eval("materialEd_previewMaterial." @ %this.field @ " = " @ %this.oldValue @ ";"); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + eval("%this.material." @ %this.field @ " = " @ %this.oldValue @ ";"); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } + else + { + eval("%this.material." @ %this.field @ " = " @ %this.oldValue @ ";"); + %this.material.flush(); + %this.material.reload(); + } + + MaterialEditorGui.preventUndo = false; +} + +// Special case updateActiveMaterial redo/undo + +function ActionUpdateActiveMaterialAnimationFlags::redo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + /* + if( MaterialEditorGui.currentMaterial != %this.material ) + { + MaterialEditorGui.currentObject = %this.object; + MaterialEditorGui.setMode(); + MaterialEditorGui.setActiveMaterial(%this.material); + } + */ + + eval("materialEd_previewMaterial.animFlags[" @ %this.layer @ "] = " @ %this.newValue @ ";"); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + eval("%this.material.animFlags[" @ %this.layer @ "] = " @ %this.newValue @ ";"); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } + else + { + eval("%this.material.animFlags[" @ %this.layer @ "] = " @ %this.newValue @ ";"); + %this.material.flush(); + %this.material.reload(); + } +} + +function ActionUpdateActiveMaterialAnimationFlags::undo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + eval("materialEd_previewMaterial.animFlags[" @ %this.layer @ "] = " @ %this.oldValue @ ";"); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + eval("%this.material.animFlags[" @ %this.layer @ "] = " @ %this.oldValue @ ";"); + MaterialEditorGui.currentMaterial.flush(); + MaterialEditorGui.currentMaterial.reload(); + } + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } + else + { + eval("%this.material.animFlags[" @ %this.layer @ "] = " @ %this.oldValue @ ";"); + %this.material.flush(); + %this.material.reload(); + } +} + +function ActionUpdateActiveMaterialName::redo(%this) +{ + %this.material.setName(%this.newName); + MaterialEditorGui.updateMaterialReferences( MissionGroup, %this.oldName, %this.newName ); + + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } +} + +function ActionUpdateActiveMaterialName::undo(%this) +{ + %this.material.setName(%this.oldName); + MaterialEditorGui.updateMaterialReferences( MissionGroup, %this.newName, %this.oldName ); + + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } +} + +function ActionRefreshMaterial::redo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + %this.material.setName( %this.newName ); + + MaterialEditorGui.copyMaterials( %this.newMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + MaterialEditorGui.copyMaterials( %this.newMaterial , %this.material ); + %this.material.flush(); + %this.material.reload(); + } + + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialNotDirty(); + } + else + { + MaterialEditorGui.copyMaterials( %this.newMaterial, %this.material ); + %this.material.flush(); + %this.material.reload(); + } +} + +function ActionRefreshMaterial::undo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + %this.material.setName( %this.oldName ); + + MaterialEditorGui.copyMaterials( %this.oldMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + MaterialEditorGui.copyMaterials( %this.oldMaterial, %this.material ); + %this.material.flush(); + %this.material.reload(); + } + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } + else + { + MaterialEditorGui.copyMaterials( %this.oldMaterial, %this.material ); + %this.material.flush(); + %this.material.reload(); + } +} + +function ActionClearMaterial::redo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + MaterialEditorGui.copyMaterials( %this.newMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + MaterialEditorGui.copyMaterials( %this.newMaterial, %this.material ); + %this.material.flush(); + %this.material.reload(); + } + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } + else + { + MaterialEditorGui.copyMaterials( %this.newMaterial, %this.material ); + %this.material.flush(); + %this.material.reload(); + } +} + +function ActionClearMaterial::undo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() && MaterialEditorGui.currentMaterial == %this.material ) + { + MaterialEditorGui.copyMaterials( %this.oldMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + if (MaterialEditorGui.livePreview == true) + { + MaterialEditorGui.copyMaterials( %this.oldMaterial, %this.material ); + %this.material.flush(); + %this.material.reload(); + } + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + MaterialEditorGui.setMaterialDirty(); + } + else + { + MaterialEditorGui.copyMaterials( %this.oldMaterial, %this.material ); + %this.material.flush(); + %this.material.reload(); + } +} + +function ActionChangeMaterial::redo(%this) +{ + if( %this.mode $= "model" ) + { + %this.object.changeMaterial( %this.materialTarget, %this.fromMaterial.getName(), %this.toMaterial.getName() ); + + MaterialEditorGui.currentObject = %this.object; + + if( %this.toMaterial.getFilename() !$= "tools/gui/materialSelector.ed.gui" || + %this.toMaterial.getFilename() !$= "tools/materialEditor/scripts/materialEditor.ed.cs") + { + matEd_PersistMan.removeObjectFromFile(%this.toMaterial); + } + + matEd_PersistMan.setDirty(%this.fromMaterial); + matEd_PersistMan.setDirty(%this.toMaterial, %this.toMaterialNewFname); + matEd_PersistMan.saveDirty(); + + matEd_PersistMan.removeDirty(%this.fromMaterial); + matEd_PersistMan.removeDirty(%this.toMaterial); + } + else + { + eval("%this.object." @ %this.materialTarget @ " = " @ %this.toMaterial.getName() @ ";"); + MaterialEditorGui.currentObject.postApply(); + } + + if( MaterialEditorPreviewWindow.isVisible() ) + MaterialEditorGui.setActiveMaterial( %this.toMaterial ); +} + +function ActionChangeMaterial::undo(%this) +{ + if( %this.mode $= "model" ) + { + %this.object.changeMaterial( %this.materialTarget, %this.toMaterial.getName(), %this.fromMaterial.getName() ); + + MaterialEditorGui.currentObject = %this.object; + + if( %this.toMaterial.getFilename() !$= "tools/gui/materialSelector.ed.gui" || + %this.toMaterial.getFilename() !$= "tools/materialEditor/scripts/materialEditor.ed.cs") + { + matEd_PersistMan.removeObjectFromFile(%this.toMaterial); + } + + + matEd_PersistMan.setDirty(%this.fromMaterial); + matEd_PersistMan.setDirty(%this.toMaterial, %this.toMaterialOldFname); + matEd_PersistMan.saveDirty(); + + matEd_PersistMan.removeDirty(%this.fromMaterial); + matEd_PersistMan.removeDirty(%this.toMaterial); + } + else + { + eval("%this.object." @ %this.materialTarget @ " = " @ %this.fromMaterial.getName() @ ";"); + MaterialEditorGui.currentObject.postApply(); + } + + if( MaterialEditorPreviewWindow.isVisible() ) + MaterialEditorGui.setActiveMaterial( %this.fromMaterial ); +} + +function ActionCreateNewMaterial::redo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() ) + { + if( MaterialEditorGui.currentMaterial != %this.newMaterial ) + { + MaterialEditorGui.currentObject = ""; + MaterialEditorGui.setMode(); + MaterialEditorGui.setActiveMaterial(%this.newMaterial); + } + + MaterialEditorGui.copyMaterials( %this.newMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + } + + %idx = UnlistedMaterials.getIndexFromValue( %this.newMaterial.getName() ); + UnlistedMaterials.erase( %idx ); +} + +function ActionCreateNewMaterial::undo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() ) + { + if( MaterialEditorGui.currentMaterial != %this.oldMaterial ) + { + MaterialEditorGui.currentObject = ""; + MaterialEditorGui.setMode(); + MaterialEditorGui.setActiveMaterial(%this.oldMaterial); + } + + MaterialEditorGui.copyMaterials( %this.oldMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + } + + UnlistedMaterials.add( "unlistedMaterials", %this.newMaterial.getName() ); +} + +function ActionDeleteMaterial::redo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() ) + { + if( MaterialEditorGui.currentMaterial != %this.newMaterial ) + { + MaterialEditorGui.currentObject = ""; + MaterialEditorGui.setMode(); + MaterialEditorGui.setActiveMaterial(%this.newMaterial); + } + + MaterialEditorGui.copyMaterials( %this.newMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + } + + if( %this.oldMaterial.getFilename() !$= "tools/gui/materialSelector.ed.gui" || + %this.oldMaterial.getFilename() !$= "tools/materialEditor/scripts/materialEditor.ed.cs") + { + matEd_PersistMan.removeObjectFromFile(%this.oldMaterial); + } + + UnlistedMaterials.add( "unlistedMaterials", %this.oldMaterial.getName() ); +} + +function ActionDeleteMaterial::undo(%this) +{ + if( MaterialEditorPreviewWindow.isVisible() ) + { + if( MaterialEditorGui.currentMaterial != %this.oldMaterial ) + { + MaterialEditorGui.currentObject = ""; + MaterialEditorGui.setMode(); + MaterialEditorGui.setActiveMaterial(%this.oldMaterial); + } + + MaterialEditorGui.copyMaterials( %this.oldMaterial, materialEd_previewMaterial ); + materialEd_previewMaterial.flush(); + materialEd_previewMaterial.reload(); + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); + } + + matEd_PersistMan.setDirty(%this.oldMaterial, %this.oldMaterialFname); + matEd_PersistMan.saveDirty(); + matEd_PersistMan.removeDirty(%this.oldMaterial); + + %idx = UnlistedMaterials.getIndexFromValue( %this.oldMaterial.getName() ); + UnlistedMaterials.erase( %idx ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/meshRoadEditor/main.cs b/Templates/BaseGame/game/tools/meshRoadEditor/main.cs new file mode 100644 index 000000000..d101e50b0 --- /dev/null +++ b/Templates/BaseGame/game/tools/meshRoadEditor/main.cs @@ -0,0 +1,225 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function initializeMeshRoadEditor() +{ + echo(" % - Initializing Mesh Road Editor"); + + exec( "./meshRoadEditor.cs" ); + exec( "./meshRoadEditorGui.gui" ); + exec( "./meshRoadEditorToolbar.gui"); + exec( "./meshRoadEditorGui.cs" ); + + MeshRoadEditorGui.setVisible( false ); + MeshRoadEditorOptionsWindow.setVisible( false ); + MeshRoadEditorToolbar.setVisible( false ); + MeshRoadEditorTreeWindow.setVisible( false ); + + EditorGui.add( MeshRoadEditorGui ); + EditorGui.add( MeshRoadEditorOptionsWindow ); + EditorGui.add( MeshRoadEditorToolbar ); + EditorGui.add( MeshRoadEditorTreeWindow ); + + new ScriptObject( MeshRoadEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = MeshRoadEditorGui; + }; + + %map = new ActionMap(); + %map.bindCmd( keyboard, "backspace", "MeshRoadEditorGui.deleteNode();", "" ); + %map.bindCmd( keyboard, "1", "MeshRoadEditorGui.prepSelectionMode();", "" ); + %map.bindCmd( keyboard, "2", "ToolsPaletteArray->MeshRoadEditorMoveMode.performClick();", "" ); + %map.bindCmd( keyboard, "3", "ToolsPaletteArray->MeshRoadEditorRotateMode.performClick();", "" ); + %map.bindCmd( keyboard, "4", "ToolsPaletteArray->MeshRoadEditorScaleMode.performClick();", "" ); + %map.bindCmd( keyboard, "5", "ToolsPaletteArray->MeshRoadEditorAddRoadMode.performClick();", "" ); + %map.bindCmd( keyboard, "=", "ToolsPaletteArray->MeshRoadEditorInsertPointMode.performClick();", "" ); + %map.bindCmd( keyboard, "numpadadd", "ToolsPaletteArray->MeshRoadEditorInsertPointMode.performClick();", "" ); + %map.bindCmd( keyboard, "-", "ToolsPaletteArray->MeshRoadEditorRemovePointMode.performClick();", "" ); + %map.bindCmd( keyboard, "numpadminus", "ToolsPaletteArray->MeshRoadEditorRemovePointMode.performClick();", "" ); + %map.bindCmd( keyboard, "z", "MeshRoadEditorShowSplineBtn.performClick();", "" ); + %map.bindCmd( keyboard, "x", "MeshRoadEditorWireframeBtn.performClick();", "" ); + %map.bindCmd( keyboard, "v", "MeshRoadEditorShowRoadBtn.performClick();", "" ); + MeshRoadEditorPlugin.map = %map; + + MeshRoadEditorPlugin.initSettings(); +} + +function destroyMeshRoadEditor() +{ +} + +function MeshRoadEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Mesh Road Editor", "", MeshRoadEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Mesh Road Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "MeshRoadEditorPlugin", "MeshRoadEditorPalette", expandFilename("tools/worldEditor/images/toolbar/mesh-road-editor"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( MeshRoadEditorOptionsWindow, MeshRoadEditorTreeWindow); + + // Add ourselves to the Editor Settings window + exec( "./meshRoadEditorSettingsTab.gui" ); + ESettingsWindow.addTabPage( EMeshRoadEditorSettingsPage ); +} + +function MeshRoadEditorPlugin::onActivated( %this ) +{ + %this.readSettings(); + + ToolsPaletteArray->MeshRoadEditorAddRoadMode.performClick(); + EditorGui.bringToFront( MeshRoadEditorGui ); + MeshRoadEditorGui.setVisible( true ); + MeshRoadEditorGui.makeFirstResponder( true ); + MeshRoadEditorOptionsWindow.setVisible( true ); + MeshRoadEditorToolbar.setVisible( true ); + MeshRoadEditorTreeWindow.setVisible( true ); + MeshRoadTreeView.open(ServerMeshRoadSet,true); + %this.map.push(); + + // Store this on a dynamic field + // in order to restore whatever setting + // the user had before. + %this.prevGizmoAlignment = GlobalGizmoProfile.alignment; + + // The DecalEditor always uses Object alignment. + GlobalGizmoProfile.alignment = "Object"; + + // Set the status bar here until all tool have been hooked up + EditorGuiStatusBar.setInfo("Mesh road editor."); + EditorGuiStatusBar.setSelection(""); + + Parent::onActivated(%this); +} + +function MeshRoadEditorPlugin::onDeactivated( %this ) +{ + %this.writeSettings(); + + MeshRoadEditorGui.setVisible( false ); + MeshRoadEditorOptionsWindow.setVisible( false ); + MeshRoadEditorToolbar.setVisible( false ); + MeshRoadEditorTreeWindow.setVisible( false ); + %this.map.pop(); + + // Restore the previous Gizmo + // alignment settings. + GlobalGizmoProfile.alignment = %this.prevGizmoAlignment; + + Parent::onDeactivated(%this); +} + +function MeshRoadEditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %hasSelection = false; + + if( isObject( MeshRoadEditorGui.road ) ) + %hasSelection = true; + + %editMenu.enableItem( 3, false ); // Cut + %editMenu.enableItem( 4, false ); // Copy + %editMenu.enableItem( 5, false ); // Paste + %editMenu.enableItem( 6, %hasSelection ); // Delete + %editMenu.enableItem( 8, false ); // Deselect +} + +function MeshRoadEditorPlugin::handleDelete( %this ) +{ + MeshRoadEditorGui.deleteNode(); +} + +function MeshRoadEditorPlugin::handleEscape( %this ) +{ + return MeshRoadEditorGui.onEscapePressed(); +} + +function MeshRoadEditorPlugin::isDirty( %this ) +{ + return MeshRoadEditorGui.isDirty; +} + +function MeshRoadEditorPlugin::onSaveMission( %this, %missionFile ) +{ + if( MeshRoadEditorGui.isDirty ) + { + MissionGroup.save( %missionFile ); + MeshRoadEditorGui.isDirty = false; + } +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +function MeshRoadEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup( "MeshRoadEditor", true ); + + EditorSettings.setDefaultValue( "DefaultWidth", "10" ); + EditorSettings.setDefaultValue( "DefaultDepth", "5" ); + EditorSettings.setDefaultValue( "DefaultNormal", "0 0 1" ); + EditorSettings.setDefaultValue( "HoverSplineColor", "255 0 0 255" ); + EditorSettings.setDefaultValue( "SelectedSplineColor", "0 255 0 255" ); + EditorSettings.setDefaultValue( "HoverNodeColor", "255 255 255 255" ); //<-- Not currently used + EditorSettings.setDefaultValue( "TopMaterialName", "DefaultRoadMaterialTop" ); + EditorSettings.setDefaultValue( "BottomMaterialName", "DefaultRoadMaterialOther" ); + EditorSettings.setDefaultValue( "SideMaterialName", "DefaultRoadMaterialOther" ); + + EditorSettings.endGroup(); +} + +function MeshRoadEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup( "MeshRoadEditor", true ); + + MeshRoadEditorGui.DefaultWidth = EditorSettings.value("DefaultWidth"); + MeshRoadEditorGui.DefaultDepth = EditorSettings.value("DefaultDepth"); + MeshRoadEditorGui.DefaultNormal = EditorSettings.value("DefaultNormal"); + MeshRoadEditorGui.HoverSplineColor = EditorSettings.value("HoverSplineColor"); + MeshRoadEditorGui.SelectedSplineColor = EditorSettings.value("SelectedSplineColor"); + MeshRoadEditorGui.HoverNodeColor = EditorSettings.value("HoverNodeColor"); + MeshRoadEditorGui.topMaterialName = EditorSettings.value("TopMaterialName"); + MeshRoadEditorGui.bottomMaterialName = EditorSettings.value("BottomMaterialName"); + MeshRoadEditorGui.sideMaterialName = EditorSettings.value("SideMaterialName"); + + EditorSettings.endGroup(); +} + +function MeshRoadEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "MeshRoadEditor", true ); + + EditorSettings.setValue( "DefaultWidth", MeshRoadEditorGui.DefaultWidth ); + EditorSettings.setValue( "DefaultDepth", MeshRoadEditorGui.DefaultDepth ); + EditorSettings.setValue( "DefaultNormal", MeshRoadEditorGui.DefaultNormal ); + EditorSettings.setValue( "HoverSplineColor", MeshRoadEditorGui.HoverSplineColor ); + EditorSettings.setValue( "SelectedSplineColor", MeshRoadEditorGui.SelectedSplineColor ); + EditorSettings.setValue( "HoverNodeColor", MeshRoadEditorGui.HoverNodeColor ); + EditorSettings.setValue( "TopMaterialName", MeshRoadEditorGui.topMaterialName ); + EditorSettings.setValue( "BottomMaterialName", MeshRoadEditorGui.bottomMaterialName ); + EditorSettings.setValue( "SideMaterialName", MeshRoadEditorGui.sideMaterialName ); + + EditorSettings.endGroup(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditor.cs b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditor.cs new file mode 100644 index 000000000..112562d82 --- /dev/null +++ b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditor.cs @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( MeshRoadEditorProfile ) +{ + canKeyFocus = true; + opaque = true; + fillColor = "192 192 192 192"; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiDisabledTextEditProfile) +{ + opaque = false; + border = 0; + bitmap = "./textEdit"; + borderColor = "255 255 255 200"; + fontColor = "0 0 0"; + fontColorHL = "255 255 255"; + fontColorNA = "128 128 128"; + textOffset = "4 2"; + autoSizeWidth = false; + autoSizeHeight = false; + tab = false; + canKeyFocus = false; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiSimpleBorderProfile) +{ + opaque = false; + border = 1; + category = "Editor"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorGui.cs b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorGui.cs new file mode 100644 index 000000000..9d2985e25 --- /dev/null +++ b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorGui.cs @@ -0,0 +1,256 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +$MeshRoad::wireframe = true; +$MeshRoad::showSpline = true; +$MeshRoad::showReflectPlane = false; +$MeshRoad::showRoad = true; +$MeshRoad::breakAngle = 3.0; + +function MeshRoadEditorGui::onWake( %this ) +{ + $MeshRoad::EditorOpen = true; + + %count = EWorldEditor.getSelectionSize(); + for ( %i = 0; %i < %count; %i++ ) + { + %obj = EWorldEditor.getSelectedObject(%i); + if ( %obj.getClassName() !$= "MeshRoad" ) + EWorldEditor.unselectObject(); + else + %this.setSelectedRoad( %obj ); + } + + //%this-->TabBook.selectPage(0); + + %this.onNodeSelected(-1); +} + +function MeshRoadEditorGui::onSleep( %this ) +{ + $MeshRoad::EditorOpen = false; +} + +function MeshRoadEditorGui::paletteSync( %this, %mode ) +{ + %evalShortcut = "ToolsPaletteArray-->" @ %mode @ ".setStateOn(1);"; + eval(%evalShortcut); +} +function MeshRoadEditorGui::onEscapePressed( %this ) +{ + if( %this.getMode() $= "MeshRoadEditorAddNodeMode" ) + { + %this.prepSelectionMode(); + return true; + } + return false; +} +function MeshRoadEditorGui::onRoadSelected( %this, %road ) +{ + %this.road = %road; + + // Update the materialEditorList + if( isObject( %road ) ) + $Tools::materialEditorList = %road.getId(); + + MeshRoadInspector.inspect( %road ); + MeshRoadTreeView.buildVisibleTree(true); + if( MeshRoadTreeView.getSelectedObject() != %road ) + { + MeshRoadTreeView.clearSelection(); + %treeId = MeshRoadTreeView.findItemByObjectId( %road ); + MeshRoadTreeView.selectItem( %treeId ); + } +} + +function MeshRoadEditorGui::onNodeSelected( %this, %nodeIdx ) +{ + if ( %nodeIdx == -1 ) + { + MeshRoadEditorOptionsWindow-->position.setActive( false ); + MeshRoadEditorOptionsWindow-->position.setValue( "" ); + + MeshRoadEditorOptionsWindow-->rotation.setActive( false ); + MeshRoadEditorOptionsWindow-->rotation.setValue( "" ); + + MeshRoadEditorOptionsWindow-->width.setActive( false ); + MeshRoadEditorOptionsWindow-->width.setValue( "" ); + + MeshRoadEditorOptionsWindow-->depth.setActive( false ); + MeshRoadEditorOptionsWindow-->depth.setValue( "" ); + } + else + { + MeshRoadEditorOptionsWindow-->position.setActive( true ); + MeshRoadEditorOptionsWindow-->position.setValue( %this.getNodePosition() ); + + MeshRoadEditorOptionsWindow-->rotation.setActive( true ); + MeshRoadEditorOptionsWindow-->rotation.setValue( %this.getNodeNormal() ); + + MeshRoadEditorOptionsWindow-->width.setActive( true ); + MeshRoadEditorOptionsWindow-->width.setValue( %this.getNodeWidth() ); + + MeshRoadEditorOptionsWindow-->depth.setActive( true ); + MeshRoadEditorOptionsWindow-->depth.setValue( %this.getNodeDepth() ); + } +} + + +function MeshRoadEditorGui::onNodeModified( %this, %nodeIdx ) +{ + MeshRoadEditorOptionsWindow-->position.setValue( %this.getNodePosition() ); + MeshRoadEditorOptionsWindow-->rotation.setValue( %this.getNodeNormal() ); + MeshRoadEditorOptionsWindow-->width.setValue( %this.getNodeWidth() ); + MeshRoadEditorOptionsWindow-->depth.setValue( %this.getNodeDepth() ); +} + +function MeshRoadEditorGui::editNodeDetails( %this ) +{ + + %this.setNodePosition( MeshRoadEditorOptionsWindow-->position.getText() ); + %this.setNodeNormal( MeshRoadEditorOptionsWindow-->rotation.getText() ); + %this.setNodeWidth( MeshRoadEditorOptionsWindow-->width.getText() ); + %this.setNodeDepth( MeshRoadEditorOptionsWindow-->depth.getText() ); +} + +function MeshRoadEditorGui::onBrowseClicked( %this ) +{ + //%filename = RETextureFileCtrl.getText(); + + %dlg = new OpenFileDialog() + { + Filters = "All Files (*.*)|*.*|"; + DefaultPath = MeshRoadEditorGui.lastPath; + DefaultFile = %filename; + ChangePath = false; + MustExist = true; + }; + + %ret = %dlg.Execute(); + if(%ret) + { + MeshRoadEditorGui.lastPath = filePath( %dlg.FileName ); + %filename = %dlg.FileName; + MeshRoadEditorGui.setTextureFile( %filename ); + MeshRoadEditorTextureFileCtrl.setText( %filename ); + } + + %dlg.delete(); +} + +function MeshRoadInspector::inspect( %this, %obj ) +{ + %name = ""; + if ( isObject( %obj ) ) + %name = %obj.getName(); + else + MeshFieldInfoControl.setText( "" ); + + //RiverInspectorNameEdit.setValue( %name ); + Parent::inspect( %this, %obj ); +} + +function MeshRoadInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + // Same work to do as for the regular WorldEditor Inspector. + Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ); +} + +function MeshRoadInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + MeshFieldInfoControl.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} + +function MeshRoadTreeView::onInspect(%this, %obj) +{ + MeshRoadInspector.inspect(%obj); +} + +function MeshRoadTreeView::onSelect(%this, %obj) +{ + MeshRoadEditorGui.road = %obj; + MeshRoadInspector.inspect( %obj ); + if(%obj != MeshRoadEditorGui.getSelectedRoad()) + { + MeshRoadEditorGui.setSelectedRoad( %obj ); + } +} + +function MeshRoadEditorGui::prepSelectionMode( %this ) +{ + %mode = %this.getMode(); + + if ( %mode $= "MeshRoadEditorAddNodeMode" ) + { + if ( isObject( %this.getSelectedRoad() ) ) + %this.deleteNode(); + } + + %this.setMode( "MeshRoadEditorSelectMode" ); + ToolsPaletteArray-->MeshRoadEditorSelectMode.setStateOn(1); +} + +//------------------------------------------------------------------------------ +function EMeshRoadEditorSelectModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function EMeshRoadEditorAddModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function EMeshRoadEditorMoveModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function EMeshRoadEditorRotateModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function EMeshRoadEditorScaleModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function EMeshRoadEditorInsertModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function EMeshRoadEditorRemoveModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function MeshRoadDefaultWidthSliderCtrlContainer::onWake(%this) +{ + MeshRoadDefaultWidthSliderCtrlContainer-->slider.setValue(MeshRoadDefaultWidthTextEditContainer-->textEdit.getText()); +} + +function MeshRoadDefaultDepthSliderCtrlContainer::onWake(%this) +{ + MeshRoadDefaultDepthSliderCtrlContainer-->slider.setValue(MeshRoadDefaultDepthTextEditContainer-->textEdit.getText()); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorGui.gui b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorGui.gui new file mode 100644 index 000000000..14bc92d2a --- /dev/null +++ b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorGui.gui @@ -0,0 +1,361 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiMeshRoadEditorCtrl(MeshRoadEditorGui,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "MeshRoadEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + DefaultWidth = "10"; + HoverSplineColor = "0 255 0 255"; + SelectedSplineColor = "255 0 255 255"; + HoverNodeColor = "255 255 255 255"; + + new GuiWindowCollapseCtrl(MeshRoadEditorTreeWindow) { + internalName = ""; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 167"; + MinExtent = "210 100"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EditorGui.setEditor( WorldEditorInspectorPlugin );"; + EdgeSnap = "1"; + text = "Mesh Roads"; + + new GuiContainer(){ + profile = "ToolsGuiDefaultProfile"; + Position = "5 25"; + Extent = "200 120"; + Docking = "Client"; + Margin = "3 1 3 3 "; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "200 118"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl(MeshRoadTreeView) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "193 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "0"; + internalNamesOnly = "0"; + }; + }; + }; + }; + new GuiWindowCollapseCtrl(MeshRoadEditorOptionsWindow) { + internalName = "Window"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(MeshRoadEditorTreeWindow.extent, 1) - 2; + Extent = "210 530"; + MinExtent = "210 298"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EditorGui.setEditor( WorldEditorPlugin );"; + EdgeSnap = "1"; + text = "Properties"; + + new GuiContainer(){ //Node Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 24"; + Extent = "202 85"; + Docking = "Top"; + Margin = "3 3 3 3"; + + new GuiTextCtrl(){ + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "86 18"; + text = "Node Properties"; + }; + + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 21"; + Extent = "46 18"; + text = "Position"; + }; + new GuiTextEditCtrl(){ + internalName = "position"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 21"; + Extent = "141 18"; + text = ""; + AltCommand = "MeshRoadEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 42"; + Extent = "46 18"; + text = "Rotation"; + }; + new GuiTextEditCtrl(){ + internalName = "rotation"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 42"; + Extent = "141 18"; + text = ""; + AltCommand = "MeshRoadEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 63"; + Extent = "46 18"; + text = "Width"; + }; + new GuiTextEditCtrl(){ + internalName = "width"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "57 63"; + Extent = "52 18"; + text = ""; + AltCommand = "MeshRoadEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "110 63"; + Extent = "32 18"; + text = "Depth"; + }; + new GuiTextEditCtrl(){ + internalName = "depth"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "146 63"; + Extent = "52 18"; + text = ""; + AltCommand = "MeshRoadEditorGui.editNodeDetails();"; + }; + }; + new GuiContainer(){ //Mesh Road Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 112"; + Extent = "202 31"; + Docking = "Top"; + Margin = "0 0 3 3"; + + new GuiTextCtrl(){ + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "121 18"; + text = "Mesh Road Properties"; + }; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 129"; + Extent = "202 357"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "-14 41 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(MeshRoadInspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + name = "MeshRoadInspector"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "179 16"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + }; + }; + new GuiMLTextCtrl(MeshFieldInfoControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "1 485"; + Extent = "202 42"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; + +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorSettingsTab.gui b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorSettingsTab.gui new file mode 100644 index 000000000..81485d307 --- /dev/null +++ b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorSettingsTab.gui @@ -0,0 +1,697 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(MeshRoadEditorSettingsTab,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(EMeshRoadEditorSettingsPage) { + fitBook = "1"; + text = "Mesh Road Editor"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Defaults"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Width:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/DefaultWidth"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Depth:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/DefaultDepth"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Normal:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/DefaultNormal"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Top Material:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/TopMaterialName"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Bottom Material:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/BottomMaterialName"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Side Material:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/SideMaterialName"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Colors"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/HoverSplineColor"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Hover Spline:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 2"; + extent = "70 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "MeshRoadEditorPlugin.readSettings();"; + editorSettingsValue = "MeshRoadEditor/SelectedSplineColor"; + editorSettingsWrite = "MeshRoadEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Sel. Spline:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "4 2"; + extent = "70 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorToolbar.gui b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorToolbar.gui new file mode 100644 index 000000000..e0bf56309 --- /dev/null +++ b/Templates/BaseGame/game/tools/meshRoadEditor/meshRoadEditorToolbar.gui @@ -0,0 +1,322 @@ +%guiContent = new GuiControl(MeshRoadEditorToolbar,EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorToolbar"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "306 0"; + Extent = "800 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "6 6"; + extent = "100 20"; + minExtent = "8 8"; + visible = "1"; + text = "Mesh Road Settings"; + maxLength = "255"; + helpTag = "0"; + }; + new GuiDynamicCtrlArrayControl(){ + Position = "116 3"; + extent = "111 32"; + colCount = "31"; + colSize = "29"; + rowCount = "1"; + RowSize = "27"; + rowSpacing = "2"; + colspacing = "4"; + + new GuiBitmapButtonCtrl(MeshRoadEditorShowSplineBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "167 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$MeshRoad::showSpline"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Spline (Z)"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-spline"; + groupNum = "7"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiBitmapButtonCtrl(MeshRoadEditorWireframeBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "253 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$MeshRoad::wireframe"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Wireframe (X)"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-wireframe"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiBitmapButtonCtrl(MeshRoadEditorShowRoadBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefalutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "89 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$MeshRoad::showRoad"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Road Texture (V)"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-texture"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + new GuiControl(MeshRoadDefaultWidthTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "230 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 6"; + Extent = "68 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Default Width"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="ToolsGuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "67 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.DefaultWidth = $ThisControl.getValue();"; + hovertime = "1000"; + text = "10"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "101 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(MeshRoadDefaultWidthSliderCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes Default Road Width"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/dropslider"; + }; + }; + new GuiControl(MeshRoadDefaultDepthTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "360 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 6"; + Extent = "68 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Default Depth"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="ToolsGuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "67 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.DefaultDepth = $ThisControl.getValue();"; + hovertime = "1000"; + text = "10"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "101 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(MeshRoadDefaultDepthSliderCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes Default Road Depth"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/dropslider"; + }; + }; +}; +new GuiMouseEventCtrl(MeshRoadDefaultWidthSliderCtrlContainer, EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(MeshRoadDefaultWidthTextEditContainer.position) + firstWord(MeshRoadEditorToolbar.position) + 10 SPC + (getWord(MeshRoadDefaultWidthTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "MeshRoadDefaultWidthTextEditContainer-->textEdit.setValue( mFloatLength($ThisControl.getValue(), 2)); MeshRoadEditorGui.DefaultWidth = $ThisControl.getValue();"; + range = "0 100"; + ticks = "0"; + value = "10"; + }; +}; +new GuiMouseEventCtrl(MeshRoadDefaultDepthSliderCtrlContainer, EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(MeshRoadDefaultDepthTextEditContainer.position) + firstWord(MeshRoadEditorToolbar.position) + 10 SPC + (getWord(MeshRoadDefaultDepthTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "MeshRoadDefaultDepthTextEditContainer-->textEdit.setValue( mFloatLength($ThisControl.getValue(), 2)); MeshRoadEditorGui.DefaultDepth = $ThisControl.getValue();"; + range = "0 100"; + ticks = "0"; + value = "10"; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/missionAreaEditor/images/DefaultHandle.png b/Templates/BaseGame/game/tools/missionAreaEditor/images/DefaultHandle.png new file mode 100644 index 000000000..c32ed3fb8 Binary files /dev/null and b/Templates/BaseGame/game/tools/missionAreaEditor/images/DefaultHandle.png differ diff --git a/Templates/BaseGame/game/tools/missionAreaEditor/images/mission-area_d.png b/Templates/BaseGame/game/tools/missionAreaEditor/images/mission-area_d.png new file mode 100644 index 000000000..356cf1f41 Binary files /dev/null and b/Templates/BaseGame/game/tools/missionAreaEditor/images/mission-area_d.png differ diff --git a/Templates/BaseGame/game/tools/missionAreaEditor/images/mission-area_h.png b/Templates/BaseGame/game/tools/missionAreaEditor/images/mission-area_h.png new file mode 100644 index 000000000..b96012a60 Binary files /dev/null and b/Templates/BaseGame/game/tools/missionAreaEditor/images/mission-area_h.png differ diff --git a/Templates/BaseGame/game/tools/missionAreaEditor/images/mission-area_n.png b/Templates/BaseGame/game/tools/missionAreaEditor/images/mission-area_n.png new file mode 100644 index 000000000..5612871e7 Binary files /dev/null and b/Templates/BaseGame/game/tools/missionAreaEditor/images/mission-area_n.png differ diff --git a/Templates/BaseGame/game/tools/missionAreaEditor/main.cs b/Templates/BaseGame/game/tools/missionAreaEditor/main.cs new file mode 100644 index 000000000..000197bc6 --- /dev/null +++ b/Templates/BaseGame/game/tools/missionAreaEditor/main.cs @@ -0,0 +1,152 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function initializeMissionAreaEditor() +{ + echo(" % - Initializing Mission Area Editor"); + + exec( "./missionAreaEditor.ed.cs" ); + exec( "./missionAreaEditorGui.ed.gui" ); + exec( "./missionAreaEditorGui.ed.cs" ); + + // Add ourselves to EditorGui, where all the other tools reside + MissionAreaEditorGui.setVisible( false ); + MissionAreaEditorTerrainWindow.setVisible( false ); + MissionAreaEditorPropertiesWindow.setVisible( false ); + + EditorGui.add( MissionAreaEditorGui ); + EditorGui.add( MissionAreaEditorTerrainWindow ); + EditorGui.add( MissionAreaEditorPropertiesWindow ); + + new ScriptObject( MissionAreaEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = MissionAreaEditorGui; + }; + + MissionAreaEditorPlugin.initSettings(); +} + +function destroyMissionAreaEditor() +{ +} + +function MissionAreaEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Mission Area Editor", "", MissionAreaEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Mission Area Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "MissionAreaEditorPlugin", "MissionAreaEditorPalette", expandFilename("tools/missionAreaEditor/images/mission-area"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( MissionAreaEditorPropertiesWindow, MissionAreaEditorTerrainWindow); +} + +function MissionAreaEditorPlugin::onActivated( %this ) +{ + %this.readSettings(); + + EditorGui.bringToFront( MissionAreaEditorGui ); + + MissionAreaEditorGui.setVisible(true); + MissionAreaEditorGui.makeFirstResponder( true ); + + MissionAreaEditorTerrainWindow.setVisible( true ); + MissionAreaEditorPropertiesWindow.setVisible( true ); + + // Set the status bar here until all tool have been hooked up + EditorGuiStatusBar.setInfo("Mission Area Editor."); + EditorGuiStatusBar.setSelection(""); + + // Allow the Gui to setup. + MissionAreaEditorGui.onEditorActivated(); + + Parent::onActivated(%this); +} + +function MissionAreaEditorPlugin::onDeactivated( %this ) +{ + %this.writeSettings(); + + MissionAreaEditorGui.setVisible(false); + MissionAreaEditorTerrainWindow.setVisible( false ); + MissionAreaEditorPropertiesWindow.setVisible( false ); + + // Allow the Gui to cleanup. + MissionAreaEditorGui.onEditorDeactivated(); + + Parent::onDeactivated(%this); +} + +function MissionAreaEditorPlugin::setEditorFunction( %this ) +{ + %missionAreaExists = isObject(getMissionAreaServerObject()); + + if( %missionAreaExists == false ) + MessageBoxYesNoCancel("No Mission Area","Would you like to create a New Mission Area?", "MissionAreaEditorPlugin.createNewMissionArea();"); + + return %missionAreaExists; +} + +function MissionAreaEditorPlugin::createNewMissionArea(%this) +{ + %newMissionArea = new MissionArea(); + %newMissionArea.area = "-256 -256 512 512"; + + MissionGroup.add(%newMissionArea); + + EditorGui.setEditor(MissionAreaEditorPlugin); + + EWorldEditor.isDirty = true; +} +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +function MissionAreaEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup( "MissionAreaEditor", true ); + + EditorSettings.setDefaultValue( "MissionBoundsColor", "255 255 255" ); + + EditorSettings.endGroup(); +} + +function MissionAreaEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup( "MissionAreaEditor", true ); + + MissionAreaEditorTerrainEditor.missionBoundsColor = EditorSettings.value("MissionBoundsColor"); + + EditorSettings.endGroup(); +} + +function MissionAreaEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "MissionAreaEditor", true ); + + EditorSettings.setValue( "MissionBoundsColor", MissionAreaEditorTerrainEditor.missionBoundsColor ); + + EditorSettings.endGroup(); +} diff --git a/Templates/BaseGame/game/tools/missionAreaEditor/missionAreaEditor.ed.cs b/Templates/BaseGame/game/tools/missionAreaEditor/missionAreaEditor.ed.cs new file mode 100644 index 000000000..dfdeaf970 --- /dev/null +++ b/Templates/BaseGame/game/tools/missionAreaEditor/missionAreaEditor.ed.cs @@ -0,0 +1,29 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( MissionAreaEditorProfile ) +{ + canKeyFocus = true; + opaque = true; + fillColor = "192 192 192"; + category = "Editor"; +}; diff --git a/Templates/BaseGame/game/tools/missionAreaEditor/missionAreaEditorGui.ed.cs b/Templates/BaseGame/game/tools/missionAreaEditor/missionAreaEditorGui.ed.cs new file mode 100644 index 000000000..7d8e79225 --- /dev/null +++ b/Templates/BaseGame/game/tools/missionAreaEditor/missionAreaEditorGui.ed.cs @@ -0,0 +1,84 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function MissionAreaEditorGui::onEditorActivated( %this ) +{ + EWorldEditor.clearSelection(); + + %ma = getMissionAreaServerObject(); + if( isObject( %ma ) ) + { + EWorldEditor.selectObject( %ma ); + EWorldEditor.syncGui(); + MissionAreaEditorTerrainEditor.updateTerrain(); + %this.setSelectedMissionArea( %ma ); + %this.onMissionAreaSelected( %this.getSelectedMissionArea() ); + } +} + +function MissionAreaEditorGui::onEditorDeactivated( %this ) +{ +} + +function MissionAreaEditorGui::onMissionAreaSelected( %this, %missionArea ) +{ + %this.missionArea = %missionArea; + MissionAreaEditorTerrainEditor.setMissionArea( %missionArea ); + MissionAreaInspector.inspect( %missionArea ); +} + +//----------------------------------------------------------------------------- + +function MissionAreaEditorTerrainEditor::onMissionAreaModified( %this ) +{ + MissionAreaInspector.refresh(); +} + +function MissionAreaEditorTerrainEditor::onUndo( %this ) +{ + MissionAreaInspector.refresh(); +} + +//----------------------------------------------------------------------------- + +function MissionAreaInspector::inspect( %this, %obj ) +{ + %name = ""; + if ( isObject( %obj ) ) + %name = %obj.getName(); + else + MissionAreaFieldInfoControl.setText( "" ); + + //RiverInspectorNameEdit.setValue( %name ); + Parent::inspect( %this, %obj ); +} + +function MissionAreaInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + // Same work to do as for the regular WorldEditor Inspector. + Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ); +} + +function MissionAreaInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + MissionAreaFieldInfoControl.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} diff --git a/Templates/BaseGame/game/tools/missionAreaEditor/missionAreaEditorGui.ed.gui b/Templates/BaseGame/game/tools/missionAreaEditor/missionAreaEditorGui.ed.gui new file mode 100644 index 000000000..03e8fdfe5 --- /dev/null +++ b/Templates/BaseGame/game/tools/missionAreaEditor/missionAreaEditorGui.ed.gui @@ -0,0 +1,245 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiMissionAreaEditorCtrl(MissionAreaEditorGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "MissionAreaEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + + new GuiWindowCollapseCtrl(MissionAreaEditorTerrainWindow) { + internalName = ""; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 230"; + MinExtent = "210 100"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Mission Area"; + + new GuiContainer(){ + profile = "ToolsGuiDefaultProfile"; + Position = "5 25"; + Extent = "200 200"; + Docking = "Client"; + Margin = "3 1 3 3 "; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + + new GuiMissionAreaCtrl(MissionAreaEditorTerrainEditor) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "EditorDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "200 200"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + wrap = "0"; + enableMirroring = "0"; + mirrorIndex = "0"; + mirrorLineColor = "255 0 255 255"; + mirrorArrowColor = "255 0 255 128"; + handleFrameColor = "255 255 255 255"; + handleFillColor = "0 0 0 255"; + defaultObjectColor = "0 255 0 100"; + waterObjectColor = "0 0 255 100"; + missionBoundsColor = "255 0 0 255"; + cameraColor = "255 0 0 255"; + squareBitmap = "1"; + enableEditing = "0"; + renderCamera = "1"; + handleBitmap = "tools/missionAreaEditor/images/DefaultHandle.png"; + }; + }; + }; + new GuiWindowCollapseCtrl(MissionAreaEditorPropertiesWindow) { + internalName = "Window"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(MissionAreaEditorTerrainWindow.extent, 1) - 2; + Extent = "210 466"; + MinExtent = "210 300"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Properties"; + + new GuiContainer(){ //Mission Area Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 112"; + Extent = "202 31"; + Docking = "Top"; + Margin = "0 0 3 3"; + + new GuiTextCtrl(){ + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "121 18"; + text = "Mission Area Properties"; + }; + }; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 129"; + Extent = "202 357"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "-14 0 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(MissionAreaInspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + name = "MissionAreaInspector"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "1 1"; + Extent = "178 16"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + }; + }; + new GuiContainer(){ //Mission Area Properties + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 0"; + Extent = "202 42"; + Docking = "Bottom"; + Margin = "0 0 3 3"; + + new GuiMLTextCtrl(MissionAreaFieldInfoControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "0 0"; + Extent = "202 42"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; + }; +}; diff --git a/Templates/BaseGame/game/tools/navEditor/CreateNewNavMeshDlg.gui b/Templates/BaseGame/game/tools/navEditor/CreateNewNavMeshDlg.gui new file mode 100644 index 000000000..755bce30a --- /dev/null +++ b/Templates/BaseGame/game/tools/navEditor/CreateNewNavMeshDlg.gui @@ -0,0 +1,392 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(CreateNewNavMeshDlg) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl() { + text = "New NavMesh"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(CreateNewNavMeshDlg);"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "283 240"; + extent = "200 176"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Name:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 29"; + extent = "39 21"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextRightProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "Nav"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "59 30"; + extent = "129 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "MeshName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Position:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 51"; + extent = "39 21"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextRightProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "0 0 0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "59 52"; + extent = "129 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "MeshPosition"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Scale:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "12 73"; + extent = "39 21"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextRightProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "50 50 20"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "59 74"; + extent = "129 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "MeshScale"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(MeshMissionBounds) { + text = " Fit NavMesh to mission area"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "1"; + position = "22 99"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Positions and scales the NavMesh so it includes all your mission objects."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl(MeshTerrainBounds) { + text = " Include terrain"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "22 121"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "0"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Consider terrain when calculating NavMesh bounds."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Create!"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "12 146"; + extent = "87 19"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "CreateNewNavMeshDlg.create();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "104 146"; + extent = "84 19"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "Canvas.popDialog(CreateNewNavMeshDlg);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function CreateNewNavMeshDlg::onWake(%this) +{ + %this-->MeshName.setText("Nav"); + %this-->MeshPosition.setText("0 0 0"); + %this-->MeshScale.setText("50 50 20"); + MeshMissionBounds.setStateOn(false); + MeshTerrainBounds.setStateOn(true); +} + +function MissionBoundsExtents(%group) +{ + %box = "0 0 0 0 0 0"; + foreach(%obj in %group) + { + %cls = %obj.getClassName(); + if(%cls $= "SimGroup" || %cls $= "SimSet" || %cls $= "Path") + { + // Need to recursively check grouped objects. + %wbox = MissionBoundsExtents(%obj); + } + else + { + // Skip objects that are too big and shouldn't really be considered + // part of the scene, or are global bounds and we therefore can't get + // any sensible information out of them. + if(%cls $= "LevelInfo") + continue; + if(!MeshTerrainBounds.isStateOn() && %cls $= "TerrainBlock") + continue; + + if(!(%obj.getType() & $TypeMasks::StaticObjectType) || + %obj.getType() & $TypeMasks::EnvironmentObjectType) + continue; + + if(%obj.isGlobalBounds()) + continue; + + %wbox = %obj.getWorldBox(); + } + + // Update min point. + for(%j = 0; %j < 3; %j++) + { + if(GetWord(%box, %j) > GetWord(%wbox, %j)) + %box = SetWord(%box, %j, GetWord(%wbox, %j)); + } + // Update max point. + for(%j = 3; %j < 6; %j++) + { + if(GetWord(%box, %j) < GetWord(%wbox, %j)) + %box = SetWord(%box, %j, GetWord(%wbox, %j)); + } + } + return %box; +} + +function CreateNewNavMeshDlg::create(%this) +{ + %name = %this-->MeshName.getText(); + if(%name $= "" || nameToID(%name) != -1) + { + MessageBoxOk("Error", "A NavMesh must have a unique name!"); + return; + } + + %mesh = 0; + + if(MeshMissionBounds.isStateOn()) + { + if(!isObject(MissionGroup)) + { + MessageBoxOk("Error", "You must have a MissionGroup to use the mission bounds function."); + return; + } + // Get maximum extents of all objects. + %box = MissionBoundsExtents(MissionGroup); + %pos = GetBoxCenter(%box); + %scale = (GetWord(%box, 3) - GetWord(%box, 0)) / 2 + 5 + SPC (GetWord(%box, 4) - GetWord(%box, 1)) / 2 + 5 + SPC (GetWord(%box, 5) - GetWord(%box, 2)) / 2 + 5; + + %mesh = new NavMesh(%name) + { + position = %pos; + scale = %scale; + }; + } + else + { + %mesh = new NavMesh(%name) + { + position = %this-->MeshPosition.getText(); + scale = %this-->MeshScale.getText(); + }; + } + MissionGroup.add(%mesh); + NavEditorGui.selectObject(%mesh); + + Canvas.popDialog(CreateNewNavMeshDlg); +} + +function MeshMissionBounds::onClick(%this) +{ + MeshTerrainBounds.setActive(%this.isStateOn()); +} diff --git a/Templates/BaseGame/game/tools/navEditor/NavEditorConsoleDlg.gui b/Templates/BaseGame/game/tools/navEditor/NavEditorConsoleDlg.gui new file mode 100644 index 000000000..3f59069a3 --- /dev/null +++ b/Templates/BaseGame/game/tools/navEditor/NavEditorConsoleDlg.gui @@ -0,0 +1,169 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiWindowCtrl(NavEditorConsoleDlg) { + text = "Nav Console"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "1"; + canMaximize = "1"; + canCollapse = "0"; + closeCommand = "NavEditorConsoleDlg.setVisible(false);"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "238 170"; + extent = "320 240"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiTextCtrl() { + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "3 222"; + extent = "149 13"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "top"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "StatusLeft"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "-14 41 3 3"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "3 23"; + extent = "314 194"; + minExtent = "8 2"; + horizSizing = "relative"; + vertSizing = "relative"; + profile = "GuiEditorScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "OutputScroll"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiListBoxCtrl() { + allowMultipleSelections = "0"; + fitParentWidth = "1"; + colorBullet = "1"; + position = "1 1"; + extent = "312 16"; + minExtent = "8 2"; + horizSizing = "relative"; + vertSizing = "relative"; + profile = "GuiListBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "Output"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +new ScriptMsgListener(NavEditorConsoleListener); +getNavMeshEventManager().subscribe(NavEditorConsoleListener, "NavMeshCreated"); +getNavMeshEventManager().subscribe(NavEditorConsoleListener, "NavMeshRemoved"); +getNavMeshEventManager().subscribe(NavEditorConsoleListener, "NavMeshStartUpdate"); +getNavMeshEventManager().subscribe(NavEditorConsoleListener, "NavMeshUpdate"); +getNavMeshEventManager().subscribe(NavEditorConsoleListener, "NavMeshTileUpdate"); + +function NavEditorConsoleListener::onNavMeshCreated(%this, %data) +{ +} + +function NavEditorConsoleListener::onNavMeshRemoved(%this, %data) +{ +} + +function NavEditorConsoleListener::onNavMeshStartUpdate(%this, %data) +{ + NavEditorConsoleDlg-->Output.clearItems(); + NavEditorConsoleDlg-->Output.addItem("Build starting for NavMesh" SPC %data, "0 0.6 0"); + NavEditorConsoleDlg-->OutputScroll.scrollToBottom(); +} + +function NavEditorConsoleListener::onNavMeshUpdate(%this, %data) +{ + %message = ""; + if(getWordCount(%data) == 2) + { + %seconds = getWord(%data, 1); + %minutes = mFloor(%seconds / 60); + %seconds -= %minutes * 60; + %message = "Built NavMesh" SPC getWord(%data, 0) SPC "in" SPC %minutes @ "m" SPC mRound(%seconds) @ "s"; + if(NavEditorGui.playSoundWhenDone) + { + sfxPlayOnce(Audio2D, "tools/navEditor/done.wav"); + } + } + else + { + %message = "Loaded NavMesh" SPC %data; + } + NavEditorConsoleDlg-->Output.addItem(%message, "0 0.6 0"); + NavEditorConsoleDlg-->OutputScroll.scrollToBottom(); + NavEditorConsoleDlg->StatusLeft.setText(""); +} + +function NavEditorConsoleListener::onNavMeshTileUpdate(%this, %data) +{ + %mesh = getWord(%data, 0); + %index = getWord(%data, 1); + %total = getWord(%data, 2); + %tile = getWords(%data, 3, 4); + %success = getWord(%data, 5) == "1"; + if(!%success) + { + %message = "NavMesh" SPC %mesh SPC "tile" SPC %tile SPC "build failed!"; + NavEditorConsoleDlg-->Output.addItem(%message, "1 0 0"); + NavEditorConsoleDlg-->OutputScroll.scrollToBottom(); + } + %percent = %index / %total * 100; + NavEditorConsoleDlg->StatusLeft.setText("Build progress:" SPC mRound(%percent) @ "%"); +} diff --git a/Templates/BaseGame/game/tools/navEditor/NavEditorGui.gui b/Templates/BaseGame/game/tools/navEditor/NavEditorGui.gui new file mode 100644 index 000000000..de78d5ee7 --- /dev/null +++ b/Templates/BaseGame/game/tools/navEditor/NavEditorGui.gui @@ -0,0 +1,854 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiNavEditorCtrl(NavEditorGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "NavEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + + new GuiWindowCollapseCtrl(NavEditorTreeWindow) { + internalName = ""; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 167"; + MinExtent = "210 100"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Navigation"; + + new GuiButtonCtrl() { + Profile = "GuiButtonProfile"; + buttonType = "PushButton"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "115 2"; + extent = "90 18"; + text = "New NavMesh"; + command = "Canvas.pushDialog(CreateNewNavMeshDlg);"; + }; + + new GuiContainer(){ + profile = GuiDefaultProfile; + Position = "5 25"; + Extent = "200 120"; + Docking = "Client"; + Margin = "3 1 3 3 "; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "200 118"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl(NavTreeView) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "193 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "0"; + internalNamesOnly = "0"; + }; + }; + }; + }; + new GuiWindowCollapseCtrl(NavEditorOptionsWindow) { + internalName = "Window"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(NavEditorTreeWindow.extent, 1) - 2; + Extent = "210 530"; + MinExtent = "210 300"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Properties"; + + new GuiContainer(){ //Actions + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 24"; + Extent = "202 85"; + Docking = "Top"; + Margin = "3 3 3 3"; + internalName = "ActionsBox"; + + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "86 18"; + text = "Actions"; + }; + new GuiStackControl() + { + internalName = "SelectActions"; + position = "7 21"; + extent = "190 64"; + + new GuiButtonCtrl() { + Profile = "GuiButtonProfile"; + buttonType = "PushButton"; + HorizSizing = "right"; + VertSizing = "bottom"; + Extent = "182 18"; + text = "Build NavMesh"; + command = "NavEditorGui.buildSelectedMeshes();"; + }; + new GuiControl() { + profile = "GuiDefaultProfile"; + Extent = "182 20"; + position = "0 20"; + + new GuiCheckboxCtrl() { + internalName = "BackgroundBuildButton"; + text = "Background"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "75 20"; + minExtent = "8 2"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + variable = "NavEditorGui.backgroundBuild"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckboxCtrl() { + position = "75 0"; + internalName = "SaveIntermediatesButton"; + text = "Keep intermediates"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "105 20"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + variable = "NavEditorGui.saveIntermediates"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiCheckboxCtrl() { + internalName = "BuildSoundButton"; + text = "Play sound when done"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "150 20"; + minExtent = "8 2"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + variable = "NavEditorGui.playSoundWhenDone"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiStackControl() + { + internalName = "LinkActions"; + position = "7 21"; + extent = "190 64"; + + new GuiButtonCtrl() { + Profile = "GuiButtonProfile"; + buttonType = "PushButton"; + HorizSizing = "right"; + VertSizing = "bottom"; + Extent = "182 18"; + text = "Rebuild links"; + command = "NavEditorGui.buildLinks();"; + }; + }; + new GuiStackControl() + { + internalName = "CoverActions"; + position = "7 21"; + extent = "190 64"; + + new GuiButtonCtrl() { + Profile = "GuiButtonProfile"; + buttonType = "PushButton"; + HorizSizing = "right"; + VertSizing = "bottom"; + Extent = "182 18"; + text = "Create Cover"; + command = "NavEditorGui.createCoverPoints();"; + }; + new GuiButtonCtrl() { + Profile = "GuiButtonProfile"; + buttonType = "PushButton"; + HorizSizing = "right"; + VertSizing = "bottom"; + Extent = "182 18"; + text = "Delete Cover"; + command = "NavEditorGui.deleteCoverPoints();"; + }; + }; + new GuiStackControl() + { + internalName = "TileActions"; + position = "7 21"; + extent = "190 64"; + + new GuiButtonCtrl() { + Profile = "GuiButtonProfile"; + buttonType = "PushButton"; + HorizSizing = "right"; + VertSizing = "bottom"; + Extent = "182 18"; + text = "Rebuild tile"; + command = "NavEditorGui.buildTile();"; + }; + }; + new GuiStackControl() + { + internalName = "TestActions"; + position = "7 21"; + extent = "190 64"; + + new GuiButtonCtrl() { + Profile = "GuiButtonProfile"; + buttonType = "PushButton"; + HorizSizing = "right"; + VertSizing = "bottom"; + Extent = "180 18"; + text = "Spawn"; + command = "NavEditorGui.spawnPlayer();"; + }; + new GuiControl() { + profile = "GuiDefaultProfile"; + Extent = "190 18"; + + new GuiButtonCtrl() { + Profile = "GuiButtonProfile"; + buttonType = "PushButton"; + HorizSizing = "right"; + VertSizing = "bottom"; + Extent = "90 18"; + text = "Delete"; + command = "NavEditorGui.getPlayer().delete();"; + }; + new GuiButtonCtrl() { + position = "100 0"; + Profile = "GuiButtonProfile"; + buttonType = "PushButton"; + HorizSizing = "right"; + VertSizing = "bottom"; + Extent = "90 18"; + text = "Find cover"; + command = "NavEditorGui.findCover();"; + }; + }; + new GuiControl() { + profile = "GuiDefaultProfile"; + Extent = "190 18"; + + new GuiButtonCtrl() { + Profile = "GuiButtonProfile"; + buttonType = "PushButton"; + HorizSizing = "right"; + VertSizing = "bottom"; + Extent = "90 18"; + text = "Follow"; + command = "NavEditorGui.followObject();"; + }; + new GuiButtonCtrl() { + position = "100 0"; + Profile = "GuiButtonProfile"; + buttonType = "PushButton"; + HorizSizing = "right"; + VertSizing = "bottom"; + Extent = "90 18"; + text = "Stop"; + command = "NavEditorGui.getPlayer().stop();"; + }; + }; + }; + }; + new GuiContainer(){ + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 112"; + Extent = "202 31"; + Docking = "Top"; + Margin = "0 0 3 3"; + + new GuiTextCtrl(){ + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "121 18"; + text = "Properties"; + }; + }; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 129"; + Extent = "202 357"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "-14 41 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + internalName = "PropertiesBox"; + + new GuiInspector(NavInspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + name = "NavInspector"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "1 1"; + Extent = "178 16"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + }; + + new GuiStackControl() { + internalName = "LinkProperties"; + position = "7 21"; + extent = "186 64"; + padding = "2 2 2 2"; + + new GuiCheckBoxCtrl() { + internalName = "LinkWalkFlag"; + class = "NavMeshLinkFlagButton"; + text = " Walk"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "0"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "This link is just ordinary flat ground."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + internalName = "LinkJumpFlag"; + class = "NavMeshLinkFlagButton"; + text = " Jump"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "0"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "Does this link require a jump?"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + internalName = "LinkDropFlag"; + class = "NavMeshLinkFlagButton"; + text = " Drop"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "0"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "Does this link involve a significant drop?"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + internalName = "LinkLedgeFlag"; + class = "NavMeshLinkFlagButton"; + text = " Ledge"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "0"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "Should the character jump at the next ledge?"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + internalName = "LinkClimbFlag"; + class = "NavMeshLinkFlagButton"; + text = " Climb"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "0"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "Does this link involve climbing?"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + internalName = "LinkTeleportFlag"; + class = "NavMeshLinkFlagButton"; + text = " Teleport"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "0"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "Is this link a teleporter?"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiStackControl() { + internalName = "TileProperties"; + position = "7 21"; + extent = "186 64"; + padding = "2 2 2 2"; + + new GuiCheckBoxCtrl() { + text = " Display input geometry"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + variable = "$Nav::Editor::renderInput"; + }; + new GuiCheckBoxCtrl() { + text = " Display voxels"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + variable = "$Nav::Editor::renderVoxels"; + }; + }; + new GuiStackControl() { + internalName = "TestProperties"; + position = "7 21"; + extent = "186 64"; + padding = "2 2 2 2"; + + new GuiTextCtrl() { + text = "Cover"; + profile = "GuiTextProfile"; + extent = "180 20"; + minExtent = "8 2"; + visible = "1"; + }; + new GuiTextEditCtrl() { + internalName = "CoverRadius"; + text = "10"; + profile = "GuiTextEditProfile"; + extent = "40 20"; + minExtent = "8 2"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "Radius for cover-finding."; + }; + new GuiTextEditCtrl() { + internalName = "CoverPosition"; + text = "LocalClientConnection.getControlObject().getPosition();"; + profile = "GuiTextEditProfile"; + extent = "140 20"; + minExtent = "8 2"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "Position to find cover from."; + }; + new GuiTextCtrl() { + text = "Follow"; + profile = "GuiTextProfile"; + extent = "180 20"; + minExtent = "8 2"; + visible = "1"; + }; + new GuiTextEditCtrl() { + internalName = "FollowRadius"; + text = "1"; + profile = "GuiTextEditProfile"; + extent = "40 20"; + minExtent = "8 2"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "Radius for following."; + }; + new GuiTextEditCtrl() { + internalName = "FollowObject"; + text = "LocalClientConnection.player"; + profile = "GuiTextEditProfile"; + extent = "140 20"; + minExtent = "8 2"; + visible = "1"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "Object to follow."; + }; + new GuiTextCtrl() { + text = "Movement"; + profile = "GuiTextProfile"; + extent = "180 20"; + minExtent = "8 2"; + visible = "1"; + }; + new GuiCheckBoxCtrl() { + internalName = "LinkWalkFlag"; + class = "NavMeshTestFlagButton"; + text = " Walk"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "0"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "Can this character walk on ground?"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + internalName = "LinkJumpFlag"; + class = "NavMeshTestFlagButton"; + text = " Jump"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "0"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "Can this character jump?"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + internalName = "LinkDropFlag"; + class = "NavMeshTestFlagButton"; + text = " Drop"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "0"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "Can this character drop over edges?"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + internalName = "LinkLedgeFlag"; + class = "NavMeshTestFlagButton"; + text = " Ledge"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "0"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "Can this character jump from ledges?"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + internalName = "LinkClimbFlag"; + class = "NavMeshTestFlagButton"; + text = " Climb"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "0"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "Can this character climb?"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + internalName = "LinkTeleportFlag"; + class = "NavMeshTestFlagButton"; + text = " Teleport"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + extent = "159 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "0"; + tooltipProfile = "GuiToolTipProfile"; + toolTip = "Can this character teleport?"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiMLTextCtrl(NavFieldInfoControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "1 485"; + Extent = "202 42"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "GuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; + +}; + +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/navEditor/NavEditorSettingsTab.gui b/Templates/BaseGame/game/tools/navEditor/NavEditorSettingsTab.gui new file mode 100644 index 000000000..8611ca3d1 --- /dev/null +++ b/Templates/BaseGame/game/tools/navEditor/NavEditorSettingsTab.gui @@ -0,0 +1,506 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiTabPageCtrl(ENavEditorSettingsPage) { + fitBook = "1"; + text = "Navigation Editor"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "208 292"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiSolidDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "208 292"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "0"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "206 124"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiRolloutCtrl() { + caption = "Test spawn"; + margin = "0 3 0 0"; + defaultHeight = "40"; + expanded = "1"; + clickCollapse = "1"; + hideHeader = "0"; + autoCollapseSiblings = "0"; + position = "0 0"; + extent = "206 62"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRolloutProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "3"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "0 20"; + extent = "206 39"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { + position = "0 0"; + extent = "206 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Spawn class:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 1"; + extent = "70 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextRightProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrlEx() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + hotTrackCallback = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "81 0"; + extent = "121 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "SpawnClassOptions"; + class = "ESettingsWindowPopup"; + canSave = "1"; + canSaveDynamicFields = "1"; + editorSettingsRead = "NavEditorPlugin.readSettings();"; + editorSettingsValue = "NavEditor/SpawnClass"; + editorSettingsWrite = "NavEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + position = "0 21"; + extent = "206 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Datablock:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 1"; + extent = "70 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextRightProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "DefaultPlayerData"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "81 0"; + extent = "121 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + class = "ESettingsWindowTextEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + editorSettingsRead = "NavEditorPlugin.readSettings();"; + editorSettingsValue = "NavEditor/SpawnDatablock"; + editorSettingsWrite = "NavEditorPlugin.writeSettings();"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + caption = "Colors"; + margin = "0 3 0 0"; + defaultHeight = "40"; + expanded = "1"; + clickCollapse = "1"; + hideHeader = "0"; + autoCollapseSiblings = "0"; + position = "0 62"; + extent = "206 62"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRolloutProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "3"; + dynamicSize = "1"; + dynamicNonStackExtent = "0"; + dynamicPos = "0"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "0 20"; + extent = "206 39"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { + position = "0 0"; + extent = "206 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "ESettingsWindowColor"; + canSave = "1"; + canSaveDynamicFields = "1"; + editorSettingsRead = "NavEditorPlugin.readSettings();"; + editorSettingsValue = "NavEditor/HoverSplineColor"; + editorSettingsWrite = "NavEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Hover Spline:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextRightProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "80 0"; + extent = "104 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "ColorEdit"; + class = "ESettingsWindowColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiSwatchButtonCtrl() { + color = "0 0 0 0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "188 2"; + extent = "14 14"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "ColorButton"; + class = "ESettingsWindowColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + }; + new GuiControl() { + position = "0 21"; + extent = "206 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + class = "ESettingsWindowColor"; + canSave = "1"; + canSaveDynamicFields = "1"; + editorSettingsRead = "NavEditorPlugin.readSettings();"; + editorSettingsValue = "NavEditor/SelectedSplineColor"; + editorSettingsWrite = "NavEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Sel. Spline:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextRightProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "80 0"; + extent = "104 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "ColorEdit"; + class = "ESettingsWindowColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiSwatchButtonCtrl() { + color = "0 0 0 0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "188 2"; + extent = "14 14"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "ColorButton"; + class = "ESettingsWindowColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/navEditor/NavEditorToolbar.gui b/Templates/BaseGame/game/tools/navEditor/NavEditorToolbar.gui new file mode 100644 index 000000000..832324475 --- /dev/null +++ b/Templates/BaseGame/game/tools/navEditor/NavEditorToolbar.gui @@ -0,0 +1,144 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(NavEditorToolbar,EditorGuiGroup) { + position = "306 0"; + extent = "800 32"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "NavEditorToolbar"; + canSave = "1"; + canSaveDynamicFields = "1"; + enabled = "1"; + + new GuiTextCtrl() { + text = "Navigation Editor"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 6"; + extent = "150 20"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl() { + bitmap = "core/art/gui/images/separator-h.png"; + wrap = "0"; + position = "90 3"; + extent = "2 26"; + minExtent = "1 1"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(NavEditorAboutBtn) { + text = "Console"; + groupNum = "7"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "100 6"; + extent = "54 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "NavEditorConsoleDlg.setVisible(!NavEditorConsoleDlg.isVisible());"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Show Console"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + text = "Mesh"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "167 1"; + extent = "50 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + variable = "$Nav::Editor::renderMesh"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "MeshButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + text = "Portals"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "224 1"; + extent = "54 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + variable = "$Nav::Editor::renderPortals"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "PortalButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + text = "BV tree"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "286 1"; + extent = "140 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + variable = "$Nav::Editor::renderBVTree"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "BVTreeButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/navEditor/done.wav b/Templates/BaseGame/game/tools/navEditor/done.wav new file mode 100644 index 000000000..826250ddd Binary files /dev/null and b/Templates/BaseGame/game/tools/navEditor/done.wav differ diff --git a/Templates/BaseGame/game/tools/navEditor/images/nav-cover_d.png b/Templates/BaseGame/game/tools/navEditor/images/nav-cover_d.png new file mode 100644 index 000000000..973f360eb Binary files /dev/null and b/Templates/BaseGame/game/tools/navEditor/images/nav-cover_d.png differ diff --git a/Templates/BaseGame/game/tools/navEditor/images/nav-cover_h.png b/Templates/BaseGame/game/tools/navEditor/images/nav-cover_h.png new file mode 100644 index 000000000..91ce9fbdb Binary files /dev/null and b/Templates/BaseGame/game/tools/navEditor/images/nav-cover_h.png differ diff --git a/Templates/BaseGame/game/tools/navEditor/images/nav-cover_n.png b/Templates/BaseGame/game/tools/navEditor/images/nav-cover_n.png new file mode 100644 index 000000000..4080a20cc Binary files /dev/null and b/Templates/BaseGame/game/tools/navEditor/images/nav-cover_n.png differ diff --git a/Templates/BaseGame/game/tools/navEditor/images/nav-editor_d.png b/Templates/BaseGame/game/tools/navEditor/images/nav-editor_d.png new file mode 100644 index 000000000..066ce2367 Binary files /dev/null and b/Templates/BaseGame/game/tools/navEditor/images/nav-editor_d.png differ diff --git a/Templates/BaseGame/game/tools/navEditor/images/nav-editor_h.png b/Templates/BaseGame/game/tools/navEditor/images/nav-editor_h.png new file mode 100644 index 000000000..dde52710a Binary files /dev/null and b/Templates/BaseGame/game/tools/navEditor/images/nav-editor_h.png differ diff --git a/Templates/BaseGame/game/tools/navEditor/images/nav-editor_n.png b/Templates/BaseGame/game/tools/navEditor/images/nav-editor_n.png new file mode 100644 index 000000000..6b7778bea Binary files /dev/null and b/Templates/BaseGame/game/tools/navEditor/images/nav-editor_n.png differ diff --git a/Templates/BaseGame/game/tools/navEditor/images/nav-link_d.png b/Templates/BaseGame/game/tools/navEditor/images/nav-link_d.png new file mode 100644 index 000000000..77f1499b3 Binary files /dev/null and b/Templates/BaseGame/game/tools/navEditor/images/nav-link_d.png differ diff --git a/Templates/BaseGame/game/tools/navEditor/images/nav-link_h.png b/Templates/BaseGame/game/tools/navEditor/images/nav-link_h.png new file mode 100644 index 000000000..4fa204f63 Binary files /dev/null and b/Templates/BaseGame/game/tools/navEditor/images/nav-link_h.png differ diff --git a/Templates/BaseGame/game/tools/navEditor/images/nav-link_n.png b/Templates/BaseGame/game/tools/navEditor/images/nav-link_n.png new file mode 100644 index 000000000..05ef3d748 Binary files /dev/null and b/Templates/BaseGame/game/tools/navEditor/images/nav-link_n.png differ diff --git a/Templates/BaseGame/game/tools/navEditor/main.cs b/Templates/BaseGame/game/tools/navEditor/main.cs new file mode 100644 index 000000000..bcc9cac59 --- /dev/null +++ b/Templates/BaseGame/game/tools/navEditor/main.cs @@ -0,0 +1,274 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2014 Daniel Buckmaster +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// These values should align with enum PolyFlags in walkabout/nav.h +$Nav::WalkFlag = 1 << 0; +$Nav::SwimFlag = 1 << 1; +$Nav::JumpFlag = 1 << 2; +$Nav::LedgeFlag = 1 << 3; +$Nav::DropFlag = 1 << 4; +$Nav::ClimbFlag = 1 << 5; +$Nav::TeleportFlag = 1 << 6; + +function initializeNavEditor() +{ + echo(" % - Initializing Navigation Editor"); + + // Execute all relevant scripts and GUIs. + exec("./navEditor.cs"); + exec("./NavEditorGui.gui"); + exec("./NavEditorToolbar.gui"); + exec("./NavEditorConsoleDlg.gui"); + exec("./CreateNewNavMeshDlg.gui"); + + // Add ourselves to EditorGui, where all the other tools reside + NavEditorGui.setVisible(false); + NavEditorToolbar.setVisible(false); + NavEditorOptionsWindow.setVisible(false); + NavEditorTreeWindow.setVisible(false); + NavEditorConsoleDlg.setVisible(false); + + EditorGui.add(NavEditorGui); + EditorGui.add(NavEditorToolbar); + EditorGui.add(NavEditorOptionsWindow); + EditorGui.add(NavEditorTreeWindow); + EditorGui.add(NavEditorConsoleDlg); + + new ScriptObject(NavEditorPlugin) + { + superClass = "EditorPlugin"; + editorGui = NavEditorGui; + }; + + // Bind shortcuts for the nav editor. + %map = new ActionMap(); + %map.bindCmd(keyboard, "1", "ENavEditorSelectModeBtn.performClick();", ""); + %map.bindCmd(keyboard, "2", "ENavEditorLinkModeBtn.performClick();", ""); + %map.bindCmd(keyboard, "3", "ENavEditorCoverModeBtn.performClick();", ""); + %map.bindCmd(keyboard, "4", "ENavEditorTileModeBtn.performClick();", ""); + %map.bindCmd(keyboard, "5", "ENavEditorTestModeBtn.performClick();", ""); + %map.bindCmd(keyboard, "c", "NavEditorConsoleBtn.performClick();", ""); + NavEditorPlugin.map = %map; + + NavEditorPlugin.initSettings(); +} + +function destroyNavEditor() +{ +} + +function NavEditorPlugin::onWorldEditorStartup(%this) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu("Navigation Editor", "", NavEditorPlugin); + + // Add ourselves to the ToolsToolbar. + %tooltip = "Navigation Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar("NavEditorPlugin", "NavEditorPalette", expandFilename("tools/navEditor/images/nav-editor"), %tooltip); + + GuiWindowCtrl::attach(NavEditorOptionsWindow, NavEditorTreeWindow); + + // Add ourselves to the Editor Settings window. + exec("./NavEditorSettingsTab.gui"); + ESettingsWindow.addTabPage(ENavEditorSettingsPage); + ENavEditorSettingsPage.init(); + + // Add items to World Editor Creator + EWCreatorWindow.beginGroup("Navigation"); + + EWCreatorWindow.registerMissionObject("CoverPoint", "Cover point"); + + EWCreatorWindow.endGroup(); +} + +function ENavEditorSettingsPage::init(%this) +{ + // Initialises the settings controls in the settings dialog box. + %this-->SpawnClassOptions.clear(); + %this-->SpawnClassOptions.add("AIPlayer"); + %this-->SpawnClassOptions.setFirstSelected(); +} + +function NavEditorPlugin::onActivated(%this) +{ + %this.readSettings(); + + // Set a global variable so everyone knows we're editing! + $Nav::EditorOpen = true; + + // Start off in Select mode. + ToolsPaletteArray->NavEditorSelectMode.performClick(); + EditorGui.bringToFront(NavEditorGui); + + NavEditorGui.setVisible(true); + NavEditorGui.makeFirstResponder(true); + NavEditorToolbar.setVisible(true); + + NavEditorOptionsWindow.setVisible(true); + NavEditorTreeWindow.setVisible(true); + + // Inspect the ServerNavMeshSet, which contains all the NavMesh objects + // in the mission. + if(!isObject(ServerNavMeshSet)) + new SimSet(ServerNavMeshSet); + if(ServerNavMeshSet.getCount() == 0) + MessageBoxYesNo("No NavMesh", "There is no NavMesh in this level. Would you like to create one?" SPC + "If not, please use the Nav Editor to create a new NavMesh.", + "Canvas.pushDialog(CreateNewNavMeshDlg);"); + NavTreeView.open(ServerNavMeshSet, true); + + // Push our keybindings to the top. (See initializeNavEditor for where this + // map was created.) + %this.map.push(); + + // Store this on a dynamic field + // in order to restore whatever setting + // the user had before. + %this.prevGizmoAlignment = GlobalGizmoProfile.alignment; + + // Always use Object alignment. + GlobalGizmoProfile.alignment = "Object"; + + // Set the status until some other editing mode adds useful information. + EditorGuiStatusBar.setInfo("Navigation editor."); + EditorGuiStatusBar.setSelection(""); + + // Allow the Gui to setup. + NavEditorGui.onEditorActivated(); + + Parent::onActivated(%this); +} + +function NavEditorPlugin::onDeactivated(%this) +{ + %this.writeSettings(); + + $Nav::EditorOpen = false; + + NavEditorGui.setVisible(false); + NavEditorToolbar.setVisible(false); + NavEditorOptionsWindow.setVisible(false); + NavEditorTreeWindow.setVisible(false); + %this.map.pop(); + + // Restore the previous Gizmo alignment settings. + GlobalGizmoProfile.alignment = %this.prevGizmoAlignment; + + // Allow the Gui to cleanup. + NavEditorGui.onEditorDeactivated(); + + Parent::onDeactivated(%this); +} + +function NavEditorPlugin::onEditMenuSelect(%this, %editMenu) +{ + %hasSelection = false; +} + +function NavEditorPlugin::handleDelete(%this) +{ + // Event happens when the user hits 'delete'. + NavEditorGui.deleteSelected(); +} + +function NavEditorPlugin::handleEscape(%this) +{ + return NavEditorGui.onEscapePressed(); +} + +function NavEditorPlugin::isDirty(%this) +{ + return NavEditorGui.isDirty; +} + +function NavEditorPlugin::onSaveMission(%this, %missionFile) +{ + if(NavEditorGui.isDirty) + { + MissionGroup.save(%missionFile); + NavEditorGui.isDirty = false; + } +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +function NavEditorPlugin::initSettings(%this) +{ + EditorSettings.beginGroup("NavEditor", true); + + EditorSettings.setDefaultValue("SpawnClass", "AIPlayer"); + EditorSettings.setDefaultValue("SpawnDatablock", "DefaultPlayerData"); + + EditorSettings.endGroup(); +} + +function NavEditorPlugin::readSettings(%this) +{ + EditorSettings.beginGroup("NavEditor", true); + + // Currently these are globals because of the way they are accessed in navMesh.cpp. + $Nav::Editor::renderMesh = EditorSettings.value("RenderMesh"); + $Nav::Editor::renderPortals = EditorSettings.value("RenderPortals"); + $Nav::Editor::renderBVTree = EditorSettings.value("RenderBVTree"); + NavEditorGui.spawnClass = EditorSettings.value("SpawnClass"); + NavEditorGui.spawnDatablock = EditorSettings.value("SpawnDatablock"); + NavEditorGui.backgroundBuild = EditorSettings.value("BackgroundBuild"); + NavEditorGui.saveIntermediates = EditorSettings.value("SaveIntermediates"); + NavEditorGui.playSoundWhenDone = EditorSettings.value("PlaySoundWhenDone"); + + // Build in the background by default, unless a preference has been saved. + if (NavEditorGui.backgroundBuild $= "") + { + NavEditorGui.backgroundBuild = true; + } + + EditorSettings.endGroup(); +} + +function NavEditorPlugin::writeSettings(%this) +{ + EditorSettings.beginGroup("NavEditor", true); + + EditorSettings.setValue("RenderMesh", $Nav::Editor::renderMesh); + EditorSettings.setValue("RenderPortals", $Nav::Editor::renderPortals); + EditorSettings.setValue("RenderBVTree", $Nav::Editor::renderBVTree); + EditorSettings.setValue("SpawnClass", NavEditorGui.spawnClass); + EditorSettings.setValue("SpawnDatablock", NavEditorGui.spawnDatablock); + EditorSettings.setValue("BackgroundBuild", NavEditorGui.backgroundBuild); + EditorSettings.setValue("SaveIntermediates", NavEditorGui.saveIntermediates); + EditorSettings.setValue("PlaySoundWhenDone", NavEditorGui.playSoundWhenDone); + + EditorSettings.endGroup(); +} + +function ESettingsWindowPopup::onWake(%this) +{ + %this.setSelected(%this.findText(EditorSettings.value(%this.editorSettingsValue))); +} + +function ESettingsWindowPopup::onSelect(%this) +{ + EditorSettings.setValue(%this.editorSettingsValue, %this.getText()); + eval(%this.editorSettingsRead); +} diff --git a/Templates/BaseGame/game/tools/navEditor/navEditor.cs b/Templates/BaseGame/game/tools/navEditor/navEditor.cs new file mode 100644 index 000000000..b3d5956c0 --- /dev/null +++ b/Templates/BaseGame/game/tools/navEditor/navEditor.cs @@ -0,0 +1,360 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2014 Daniel Buckmaster +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +$Nav::EditorOpen = false; + +function NavEditorGui::onEditorActivated(%this) +{ + if(%this.selectedObject) + %this.selectObject(%this.selectedObject); + %this.prepSelectionMode(); +} + +function NavEditorGui::onEditorDeactivated(%this) +{ + if(%this.getMesh()) + %this.deselect(); +} + +function NavEditorGui::onModeSet(%this, %mode) +{ + // Callback when the nav editor changes mode. Set the appropriate dynamic + // GUI contents in the properties/actions boxes. + NavInspector.setVisible(false); + + %actions = NavEditorOptionsWindow->ActionsBox; + %actions->SelectActions.setVisible(false); + %actions->LinkActions.setVisible(false); + %actions->CoverActions.setVisible(false); + %actions->TileActions.setVisible(false); + %actions->TestActions.setVisible(false); + + %properties = NavEditorOptionsWindow->PropertiesBox; + %properties->LinkProperties.setVisible(false); + %properties->TileProperties.setVisible(false); + %properties->TestProperties.setVisible(false); + + switch$(%mode) + { + case "SelectMode": + NavInspector.setVisible(true); + %actions->SelectActions.setVisible(true); + case "LinkMode": + %actions->LinkActions.setVisible(true); + %properties->LinkProperties.setVisible(true); + case "CoverMode": + // + %actions->CoverActions.setVisible(true); + case "TileMode": + %actions->TileActions.setVisible(true); + %properties->TileProperties.setVisible(true); + case "TestMode": + %actions->TestActions.setVisible(true); + %properties->TestProperties.setVisible(true); + } +} + +function NavEditorGui::paletteSync(%this, %mode) +{ + // Synchronise the palette (small buttons on the left) with the actual mode + // the nav editor is in. + %evalShortcut = "ToolsPaletteArray-->" @ %mode @ ".setStateOn(1);"; + eval(%evalShortcut); +} + +function NavEditorGui::onEscapePressed(%this) +{ + return false; +} + +function NavEditorGui::selectObject(%this, %obj) +{ + NavTreeView.clearSelection(); + if(isObject(%obj)) + NavTreeView.selectItem(%obj); + %this.onObjectSelected(%obj); +} + +function NavEditorGui::onObjectSelected(%this, %obj) +{ + if(isObject(%this.selectedObject)) + %this.deselect(); + %this.selectedObject = %obj; + if(isObject(%obj)) + { + %this.selectMesh(%obj); + NavInspector.inspect(%obj); + } +} + +function NavEditorGui::deleteMesh(%this) +{ + if(isObject(%this.selectedObject)) + { + %this.selectedObject.delete(); + %this.selectObject(-1); + } +} + +function NavEditorGui::deleteSelected(%this) +{ + switch$(%this.getMode()) + { + case "SelectMode": + // Try to delete the selected NavMesh. + if(isObject(NavEditorGui.selectedObject)) + MessageBoxYesNo("Warning", + "Are you sure you want to delete" SPC NavEditorGui.selectedObject.getName(), + "NavEditorGui.deleteMesh();"); + case "TestMode": + %this.getPlayer().delete(); + %this.onPlayerDeselected(); + case "LinkMode": + %this.deleteLink(); + %this.isDirty = true; + } +} + +function NavEditorGui::buildSelectedMeshes(%this) +{ + if(isObject(%this.getMesh())) + { + %this.getMesh().build(NavEditorGui.backgroundBuild, NavEditorGui.saveIntermediates); + %this.isDirty = true; + } +} + +function NavEditorGui::buildLinks(%this) +{ + if(isObject(%this.getMesh())) + { + %this.getMesh().buildLinks(); + %this.isDirty = true; + } +} + +function updateLinkData(%control, %flags) +{ + %control->LinkWalkFlag.setActive(true); + %control->LinkJumpFlag.setActive(true); + %control->LinkDropFlag.setActive(true); + %control->LinkLedgeFlag.setActive(true); + %control->LinkClimbFlag.setActive(true); + %control->LinkTeleportFlag.setActive(true); + + %control->LinkWalkFlag.setStateOn(%flags & $Nav::WalkFlag); + %control->LinkJumpFlag.setStateOn(%flags & $Nav::JumpFlag); + %control->LinkDropFlag.setStateOn(%flags & $Nav::DropFlag); + %control->LinkLedgeFlag.setStateOn(%flags & $Nav::LedgeFlag); + %control->LinkClimbFlag.setStateOn(%flags & $Nav::ClimbFlag); + %control->LinkTeleportFlag.setStateOn(%flags & $Nav::TeleportFlag); +} + +function getLinkFlags(%control) +{ + return (%control->LinkWalkFlag.isStateOn() ? $Nav::WalkFlag : 0) | + (%control->LinkJumpFlag.isStateOn() ? $Nav::JumpFlag : 0) | + (%control->LinkDropFlag.isStateOn() ? $Nav::DropFlag : 0) | + (%control->LinkLedgeFlag.isStateOn() ? $Nav::LedgeFlag : 0) | + (%control->LinkClimbFlag.isStateOn() ? $Nav::ClimbFlag : 0) | + (%control->LinkTeleportFlag.isStateOn() ? $Nav::TeleportFlag : 0); +} + +function disableLinkData(%control) +{ + %control->LinkWalkFlag.setActive(false); + %control->LinkJumpFlag.setActive(false); + %control->LinkDropFlag.setActive(false); + %control->LinkLedgeFlag.setActive(false); + %control->LinkClimbFlag.setActive(false); + %control->LinkTeleportFlag.setActive(false); +} + +function NavEditorGui::onLinkSelected(%this, %flags) +{ + updateLinkData(NavEditorOptionsWindow-->LinkProperties, %flags); +} + +function NavEditorGui::onPlayerSelected(%this, %flags) +{ + updateLinkData(NavEditorOptionsWindow-->TestProperties, %flags); +} + +function NavEditorGui::updateLinkFlags(%this) +{ + if(isObject(%this.getMesh())) + { + %properties = NavEditorOptionsWindow-->LinkProperties; + %this.setLinkFlags(getLinkFlags(%properties)); + %this.isDirty = true; + } +} + +function NavEditorGui::updateTestFlags(%this) +{ + if(isObject(%this.getPlayer())) + { + %properties = NavEditorOptionsWindow-->TestProperties; + %player = %this.getPlayer(); + + %player.allowWwalk = %properties->LinkWalkFlag.isStateOn(); + %player.allowJump = %properties->LinkJumpFlag.isStateOn(); + %player.allowDrop = %properties->LinkDropFlag.isStateOn(); + %player.allowLedge = %properties->LinkLedgeFlag.isStateOn(); + %player.allowClimb = %properties->LinkClimbFlag.isStateOn(); + %player.allowTeleport = %properties->LinkTeleportFlag.isStateOn(); + + %this.isDirty = true; + } +} + +function NavEditorGui::onLinkDeselected(%this) +{ + disableLinkData(NavEditorOptionsWindow-->LinkProperties); +} + +function NavEditorGui::onPlayerDeselected(%this) +{ + disableLinkData(NavEditorOptionsWindow-->TestProperties); +} + +function NavEditorGui::createCoverPoints(%this) +{ + if(isObject(%this.getMesh())) + { + %this.getMesh().createCoverPoints(); + %this.isDirty = true; + } +} + +function NavEditorGui::deleteCoverPoints(%this) +{ + if(isObject(%this.getMesh())) + { + %this.getMesh().deleteCoverPoints(); + %this.isDirty = true; + } +} + +function NavEditorGui::findCover(%this) +{ + if(%this.getMode() $= "TestMode" && isObject(%this.getPlayer())) + { + %pos = LocalClientConnection.getControlObject().getPosition(); + %text = NavEditorOptionsWindow-->TestProperties->CoverPosition.getText(); + if(%text !$= "") + %pos = eval(%text); + %this.getPlayer().findCover(%pos, NavEditorOptionsWindow-->TestProperties->CoverRadius.getText()); + } +} + +function NavEditorGui::followObject(%this) +{ + if(%this.getMode() $= "TestMode" && isObject(%this.getPlayer())) + { + %obj = LocalClientConnection.player; + %text = NavEditorOptionsWindow-->TestProperties->FollowObject.getText(); + if(%text !$= "") + { + eval("%obj = " @ %text); + if(!isObject(%obj)) + MessageBoxOk("Error", "Cannot find object" SPC %text); + } + if(isObject(%obj)) + %this.getPlayer().followObject(%obj, NavEditorOptionsWindow-->TestProperties->FollowRadius.getText()); + } +} + +function NavInspector::inspect(%this, %obj) +{ + %name = ""; + if(isObject(%obj)) + %name = %obj.getName(); + else + NavFieldInfoControl.setText(""); + + Parent::inspect(%this, %obj); +} + +function NavInspector::onInspectorFieldModified(%this, %object, %fieldName, %arrayIndex, %oldValue, %newValue) +{ + // Same work to do as for the regular WorldEditor Inspector. + Inspector::onInspectorFieldModified(%this, %object, %fieldName, %arrayIndex, %oldValue, %newValue); +} + +function NavInspector::onFieldSelected(%this, %fieldName, %fieldTypeStr, %fieldDoc) +{ + NavFieldInfoControl.setText("<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc); +} + +function NavTreeView::onInspect(%this, %obj) +{ + NavInspector.inspect(%obj); +} + +function NavTreeView::onSelect(%this, %obj) +{ + NavInspector.inspect(%obj); + NavEditorGui.onObjectSelected(%obj); +} + +function NavEditorGui::prepSelectionMode(%this) +{ + %this.setMode("SelectMode"); + ToolsPaletteArray-->NavEditorSelectMode.setStateOn(1); +} + +//----------------------------------------------------------------------------- + +function ENavEditorPaletteButton::onClick(%this) +{ + // When clicking on a pelette button, add its description to the bottom of + // the editor window. + EditorGuiStatusBar.setInfo(%this.DetailedDesc); +} + +//----------------------------------------------------------------------------- + +function NavMeshLinkFlagButton::onClick(%this) +{ + NavEditorGui.updateLinkFlags(); +} + +function NavMeshTestFlagButton::onClick(%this) +{ + NavEditorGui.updateTestFlags(); +} + +singleton GuiControlProfile(NavEditorProfile) +{ + canKeyFocus = true; + opaque = true; + fillColor = "192 192 192 192"; + category = "Editor"; +}; + +singleton GuiControlProfile(GuiSimpleBorderProfile) +{ + opaque = false; + border = 1; + category = "Editor"; +}; diff --git a/Templates/BaseGame/game/tools/particleEditor/ParticleEditor.ed.gui b/Templates/BaseGame/game/tools/particleEditor/ParticleEditor.ed.gui new file mode 100644 index 000000000..a2c87457e --- /dev/null +++ b/Templates/BaseGame/game/tools/particleEditor/ParticleEditor.ed.gui @@ -0,0 +1,3324 @@ +//----------------------------------------------------------------------------- +// Torque +// Copyright GarageGames, LLC 2011 +//----------------------------------------------------------------------------- + +$PE_guielement_pos_single_container = "0 0"; +$PE_guielement_ext_single_container = "184 20"; +$PE_guielement_pos_name = "1 0"; +$PE_guielement_ext_name = "70 18"; +$PE_guielement_pos_slider = "74 2"; +$PE_guielement_ext_slider = "58 12"; +$PE_guielement_pos_value = "138 0"; +$PE_guielement_ext_value = "36 18"; +$PE_guielement_pos_textedit = "74 0"; +$PE_guielement_ext_textedit = "100 18"; +$PE_guielement_ext_checkbox_name = "156 18"; +$PE_guielement_pos_checkbox = "161 0"; +$PE_guielement_ext_checkbox = "15 18"; +$PE_guielement_pos_colorpicker = "158 0"; +$PE_guielement_ext_colorpicker = "18 18"; + +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiWindowCollapseCtrl(PE_Window) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + Position = firstWord($pref::Video::mode) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) -1; + Extent = "210 696"; + MinExtent = "210 140"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = ""; + EdgeSnap = "0"; + text = "Particle Editor"; + + new GuiTabBookCtrl(PE_TabBook) { + canSaveDynamicFields = "0"; + isContainer = "1"; + internalName = "EditorTabBook"; + Profile = "ToolsGuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "6 27"; + Extent = "197 289"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "3 2 3 3"; + Docking = "client"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "0"; + MinTabWidth = "64"; + + new GuiTabPageCtrl(PE_EmitterEditor) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiEditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "197 271"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Emitter"; + maxLength = "1024"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "197 271"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(PEE_EmitterSelector_Control){ // PEE_EmitterSelector + class = "QuickEditDropDownTextEditCtrl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = "197 26" ; + + new GuiPopUpMenuCtrl(PEE_EmitterSelector) { + internalName = "PopUpMenu"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "4 4"; + Extent = "123 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor::onNewEmitter();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiTextEditCtrl() { + internalName = "TextEdit"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDropdownTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "4 4"; + Extent = "107 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl);"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "131 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.showNewDialog();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/new"; + tooltip = "Create New Emitter"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "147 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/save-icon"; + command = "PE_EmitterEditor.saveEmitter( " @ PE_EmitterEditor.currEmitter @ " ); PE_ParticleEditor.saveParticle( PE_ParticleEditor.currParticle );"; + tooltip = "Save Current Emitter"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "164 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.showDeleteDialog();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + tooltip = "Delete Current Emitter"; + }; + }; + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Basic"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(){ // Emitter PEE_lifetimeMS + isContainer = "1"; + class = "AggregateControl"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Life"; + maxLength = "255"; + }; + new GuiSliderCtrl(PEE_lifetimeMS) { + internalName = "PEE_lifetimeMS_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateLifeFields( false, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateLifeFields( false, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 1000"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_lifetimeMS_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateLifeFields( false, $ThisControl.getValue() );"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + }; + }; + + new GuiControl(){ // Emitter PEE_lifetimeVarianceMS + isContainer = "1"; + class = "AggregateControl"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Life Random"; + maxLength = "255"; + }; + new GuiSliderCtrl(PEE_lifetimeVarianceMS) { + internalName = "PEE_lifetimeVarianceMS_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateLifeFields( true, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateLifeFields( true, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 1000"; + ticks = "0"; + value = ""; + }; + new GuiTextEditCtrl() { + internalName = "PEE_lifetimeVarianceMS_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateLifeFields( true, $ThisControl.getValue() );"; + }; + }; + + new GuiControl(){ // Emitter Infinite Loop + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_checkbox_name; + text = "Infinite Loop"; + }; + new GuiCheckBoxCtrl() { + internalName = "PEE_infiniteLoop"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_checkbox; + Extent = $PE_guielement_ext_checkbox; + Command = "PE_EmitterEditor.updateLifeFieldsInfiniteLoop();"; + text = ""; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Emitter Amount + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Amount"; + }; + new GuiSliderCtrl(PEE_ejectionPeriodMS) { + internalName = "PEE_ejectionPeriodMS_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateAmountFields( false, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateAmountFields( false, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "1 1000"; + ticks = "0"; + value = "1"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_ejectionPeriodMS_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateAmountFields( false, $ThisControl.getValue() );"; + }; + }; + new GuiControl(){ // Emitter Amount Random + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Amount Random"; + }; + new GuiSliderCtrl(PEE_periodVarianceMS) { + internalName = "PEE_periodVarianceMS_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateAmountFields( true, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateAmountFields( true, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 999"; + ticks = "0"; + value = "1"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_periodVarianceMS_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateAmountFields( true, $ThisControl.getValue() );"; + }; + }; + + new GuiControl(){ // Particle glow + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_checkbox_name; + text = "Glow"; + }; + new GuiCheckBoxCtrl() { + internalName = "PEE_glow"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_checkbox; + Extent = $PE_guielement_ext_checkbox; + Command = "PE_EmitterEditor.updateEmitter( \"glow\", $ThisControl.getValue());"; + text = ""; + }; + }; + };// end stack + }; // end "basic" rollout + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Motion"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(){ // Emitter speed + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Speed"; + }; + new GuiSliderCtrl(PEE_ejectionVelocity) { + internalName = "PEE_ejectionVelocity_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateSpeedFields( false, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateSpeedFields( false, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 100"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_ejectionVelocity_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateSpeedFields( false, $ThisControl.getValue() );"; + }; + }; + new GuiControl(){ // Emitter speed random + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Speed Random"; + }; + new GuiSliderCtrl(PEE_velocityVariance) { + internalName = "PEE_velocityVariance_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateSpeedFields( true, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateSpeedFields( true, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 100"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_velocityVariance_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateSpeedFields( true, $ThisControl.getValue() );"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Emitter Orient to Movment Direction + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_checkbox_name; + text = "Orient to Movment Direction"; + }; + new GuiCheckBoxCtrl() { + internalName = "PEE_orientParticles"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_checkbox; + Extent = $PE_guielement_ext_checkbox; + text = ""; + command = "PE_EmitterEditor.updateEmitter( \"orientParticles\", $ThisControl.getValue());"; + }; + }; + new GuiControl(){ // Emitter Align to a Direction + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_checkbox_name; + text = "Align to a Direction"; + }; + new GuiCheckBoxCtrl() { + internalName = "PEE_alignParticles"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_checkbox; + Extent = $PE_guielement_ext_checkbox; + text = ""; + command = "PE_EmitterEditor.updateEmitter( \"alignParticles\", $ThisControl.getValue());"; + }; + }; + new GuiControl(){ // Emitter Align Direction + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Align Direction"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_alignDirection"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_textedit; + Extent = $PE_guielement_ext_textedit; + text = "0 0 0"; + altCommand = "PE_EmitterEditor.updateEmitter( \"alignDirection\", $ThisControl.getText());"; + }; + }; + }; // end stack + }; // end "motion" rollout + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Spread"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(){ // Emitter Angle Min + isContainer = "1"; + class = "AggregateControl"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiBitmapCtrl(){ // 0 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+4 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "tools/gui/images/separator-h"; + tooltip = "0 Degrees ( Up )"; + }; + new GuiBitmapCtrl(){ // 90 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/4)+1 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "tools/gui/images/separator-h"; + tooltip = "90 Degrees ( Left )"; + }; + new GuiBitmapCtrl(){ // 180 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "tools/gui/images/separator-h"; + tooltip = "180 Degrees ( Down )"; + }; + new GuiBitmapCtrl(){ // 270 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2+mCeil(getWord($PE_guielement_ext_slider,0)/4))-4 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "tools/gui/images/separator-h"; + tooltip = "270 Degrees ( Right )"; + }; + new GuiBitmapCtrl(){ // 360 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0))-5 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "tools/gui/images/separator-h"; + tooltip = "360 Degrees ( Up )"; + }; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Angle Min"; + }; + new GuiSliderCtrl(PEE_thetaMin) { + internalName = "PEE_thetaMin_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateEmitter( \"thetaMin\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"thetaMin\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 180"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalname = "PEE_thetaMin_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"thetaMin\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Emitter Angle Max + isContainer = "1"; + class = "AggregateControl"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiBitmapCtrl(){ // 0 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+4 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "tools/gui/images/separator-h"; + tooltip = "0 Degrees ( Up )"; + }; + new GuiBitmapCtrl(){ // 90 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/4)+1 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "tools/gui/images/separator-h"; + tooltip = "90 Degrees ( Left )"; + }; + new GuiBitmapCtrl(){ // 180 Degrees + HorizSizing = "left"; + minExtent = "0 0"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0"; + Extent = "2 18"; + bitmap = "tools/gui/images/separator-h"; + tooltip = "180 Degrees ( Down )"; + }; + new GuiBitmapCtrl(){ // 270 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2+mCeil(getWord($PE_guielement_ext_slider,0)/4))-4 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "tools/gui/images/separator-h"; + tooltip = "270 Degrees ( Right )"; + }; + new GuiBitmapCtrl(){ // 360 Degrees + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0))-5 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "tools/gui/images/separator-h"; + tooltip = "360 Degrees ( Up )"; + }; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Angle Max"; + }; + new GuiSliderCtrl(PEE_thetaMax) { + internalName = "PEE_thetaMax_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateEmitter( \"thetaMax\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"thetaMax\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 180"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_thetaMax_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"thetaMax\", $ThisControl.getText());"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Emitter Depth + isContainer = "1"; + class = "AggregateControl"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Depth"; + }; + new GuiSliderCtrl(PEE_phiVariance) { + internalName = "PEE_phiVariance_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateEmitter( \"phiVariance\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"phiVariance\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 360"; + ticks = "0"; + value = "360"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_phiVariance_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"phiVariance\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Emitter Offset + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Offset"; + }; + new GuiSliderCtrl(PEE_ejectionOffset) { + internalName = "PEE_ejectionOffset_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateEmitter( \"ejectionOffset\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffset\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 10"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_ejectionOffset_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffset\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Emitter Offset Variance + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "OffsetVariance"; + }; + new GuiSliderCtrl(PEE_ejectionOffsetVariance) { + internalName = "PEE_ejectionOffsetVariance_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_EmitterEditor.updateEmitter( \"ejectionOffsetVariance\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffsetVariance\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 25"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_ejectionOffsetVariance_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ejectionOffsetVariance\", $ThisControl.getText());"; + }; + }; + }; // end stack + }; // end "spread" rollout + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Particles"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(PEE_EmitterParticle1){ // emmiter particle 1 + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Particle 1"; + }; + new GuiPopUpMenuCtrl(PEE_EmitterParticleSelector1) { + internalName = "PopUpMenu"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_textedit; + Extent = $PE_guielement_ext_textedit; + text = ""; + command = "PE_EmitterEditor.updateParticlesFields($ThisControl);"; + }; + }; + new GuiControl(PEE_EmitterParticle2){ // emmiter particle 2 + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Particle 2"; + }; + new GuiPopUpMenuCtrl(PEE_EmitterParticleSelector2) { + internalName = "PopUpMenu"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_textedit; + Extent = $PE_guielement_ext_textedit; + text = "None"; + command = "PE_EmitterEditor.updateParticlesFields();"; + }; + // Clear particle 2 + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "56 1"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "%particleId = PEE_EmitterParticle2-->PopUpMenu.findText( \"None\" ); PEE_EmitterParticle2-->PopUpMenu.setSelected( %particleId );PE_EmitterEditor.updateParticlesFields();"; + hovertime = "1000"; + tooltip = "Clear Particle 2 from Emitter"; + text = ""; + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + new GuiControl(PEE_EmitterParticle3){ // emmiter particle 3 + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Particle 3"; + }; + new GuiPopUpMenuCtrl(PEE_EmitterParticleSelector3) { + internalName = "PopUpMenu"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_textedit; + Extent = $PE_guielement_ext_textedit; + text = "None"; + command = "PE_EmitterEditor.updateParticlesFields();"; + }; + // Clear particle 3 + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "56 1"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "%particleId = PEE_EmitterParticle3-->PopUpMenu.findText( \"None\" ); PEE_EmitterParticle3-->PopUpMenu.setSelected( %particleId );PE_EmitterEditor.updateParticlesFields();"; + hovertime = "1000"; + tooltip = "Clear Particle 3 from Emitter"; + text = ""; + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + new GuiControl(PEE_EmitterParticle4){ // emmiter particle 4 + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Particle 4"; + }; + new GuiPopUpMenuCtrl(PEE_EmitterParticleSelector4) { + internalName = "PopUpMenu"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_textedit; + Extent = $PE_guielement_ext_textedit; + text = "None"; + command = "PE_EmitterEditor.updateParticlesFields();"; + }; + // Clear particle 4 + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "56 1"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "%particleId = PEE_EmitterParticle4-->PopUpMenu.findText( \"None\" ); PEE_EmitterParticle4-->PopUpMenu.setSelected( %particleId );PE_EmitterEditor.updateParticlesFields();"; + hovertime = "1000"; + tooltip = "Clear Particle 4 from Emitter"; + text = ""; + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + }; // end stack + }; // end "particles" rollout + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Blending"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(){ // Blend type + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Blend Type"; + }; + new GuiPopUpMenuCtrl() { + internalName = "PEE_blendType"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_textedit; + Extent = $PE_guielement_ext_textedit; + command = "PE_EmitterEditor.updateEmitter( \"blendStyle\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // softness Distance + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Softness Distance "; + }; + new GuiSliderCtrl() { + internalName = "PEE_softnessDistance_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 1000"; + ticks = "0"; + value = "0"; + Command = "PE_EmitterEditor.updateEmitter( \"softnessDistance\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"softnessDistance\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_softnessDistance_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"softnessDistance\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Ambient Factor + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Ambient Factor"; + }; + new GuiSliderCtrl() { + internalName = "PEE_ambientFactor_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 10"; + ticks = "0"; + value = "0"; + Command = "PE_EmitterEditor.updateEmitter( \"ambientFactor\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ambientFactor\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEE_ambientFactor_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_EmitterEditor.updateEmitter( \"ambientFactor\", $ThisControl.getText));"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Sort Particles + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_checkbox_name; + text = "Sort Particles"; + }; + new GuiCheckBoxCtrl() { + internalName = "PEE_softParticles"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_checkbox; + Extent = $PE_guielement_ext_checkbox; + text = ""; + command = "PE_EmitterEditor.updateEmitter( \"softParticles\", $ThisControl.getValue());"; + }; + }; + new GuiControl(){ // Emitter Reverse Order + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_checkbox_name; + text = "Reverse Order"; + }; + new GuiCheckBoxCtrl() { + internalName = "PEE_reverseOrder"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_checkbox; + Extent = $PE_guielement_ext_checkbox; + text = ""; + command = "PE_EmitterEditor.updateEmitter( \"reverseOrder\", $ThisControl.getValue());"; + }; + }; + new GuiControl(){ // Emitter Use Emitter Size + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_checkbox_name; + text = "Use Emitter Size"; + }; + new GuiCheckBoxCtrl(PEE_useEmitterSizes) { + internalName = "PEE_useEmitterSizes"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_checkbox; + Extent = $PE_guielement_ext_checkbox; + text = ""; + command = "PE_EmitterEditor.updateEmitter( \"useEmitterSizes\", $ThisControl.getValue());"; + }; + }; + new GuiControl(){ // Emitter use Material Effect Color + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_checkbox_name; + text = "Use Material Effect Color"; + }; + new GuiCheckBoxCtrl(PEE_useEmitterColors) { + internalName = "PEE_useEmitterColors"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_checkbox; + Extent = $PE_guielement_ext_checkbox; + text = ""; + command = "PE_EmitterEditor.updateEmitter( \"useEmitterColors\", $ThisControl.getValue());"; + }; + }; + }; // end stack + }; // end "Blending" rollout + };// end stack "Emitter" + };// end scroll "Emitter" + };// end tab page "Emitter" + new GuiTabPageCtrl(PE_ParticleEditor) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiEditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "197 271"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Particle"; + maxLength = "1024"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "197 271"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(PEP_ParticleSelector_Control){ // PEP_ParticleSelector + isContainer = "1"; + class = "QuickEditDropDownTextEditCtrl"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = "197 26" ; + + new GuiPopUpMenuCtrl(PEP_ParticleSelector) { + internalName = "PopUpMenu"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "4 4"; + Extent = "123 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.onNewParticle();"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "255"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiTextEditCtrl() { + internalName = "TextEdit"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDropdownTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "4 4"; + Extent = "107 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl);"; + }; + new GuiBitmapButtonCtrl( PEP_NewParticleButton ) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "131 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/new"; + tooltip = "Add New Particle To Current Emitter"; + useModifiers = "1"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "147 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/save-icon"; + command = "PE_ParticleEditor.saveParticle( PE_ParticleEditor.currParticle );"; + tooltip = "Save Current Particle"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "164 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.showDeleteDialog();"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + tooltip = "Delete Current Particle"; + }; + }; + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Basic"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ // particle texture map + profile="ToolsGuiDefaultProfile"; + isContainer = "1"; + position = "0 0"; + Extent = "185 52"; + HorizSizing = "width"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -2"; + Extent = "72 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Texture Map"; + maxLength = "1024"; + }; + new GuiBitmapButtonCtrl() { + internalName = "PEP_previewImage"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Edit Selected Particle."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Edit Selected Particle."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + Command = "PE_ParticleEditor.updateParticleTexture(1);"; + }; + new GuiCheckBoxCtrl() { + internalName = "PEP_inverseAlpha"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "55 14"; + Extent = "84 18"; + MinExtent = "8 2"; + text = "Inverse Alpha"; + command = "PE_ParticleEditor.updateParticle( \"useInvAlpha\", $ThisControl.getValue());"; + }; + new GuiTextEditCtrl(PEP_textureName) { + internalName = "PEP_previewImageName"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "55 31"; + Extent = "120 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl(){ + profile="ToolsGuiButtonProfile"; + text ="Edit"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "138 0"; + Extent = "36 18" ; + buttonType = "PushButton"; + Command = "PE_ParticleEditor.updateParticleTexture(1);"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + //visible = false; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // particle life + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Life"; + maxLength = "255"; + }; + new GuiSliderCtrl(PEP_lifetimeMS) { + internalName = "PEP_lifetimeMS_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateLifeFields( false, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateLifeFields( false, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "1 9000"; + ticks = "0"; + value = "3000"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_lifetimeMS_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateLifeFields( false, $ThisControl.getText() );"; + }; + }; + new GuiControl(){ // particle life Random + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Life Random"; + maxLength = "255"; + }; + new GuiSliderCtrl(PEP_lifetimeVarianceMS) { + internalName = "PEP_lifetimeVarianceMS_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateLifeFields( true, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateLifeFields( true, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 8999"; + ticks = "0"; + value = "3000"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_lifetimeVarianceMS_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateLifeFields( true, $ThisControl.getText() );"; + }; + }; + }; // end stack + }; // end "Particles Basic" rollout + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Motion"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(){ // Particle Initial speed + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Initial Speed"; + }; + new GuiSliderCtrl(PEP_inheritedVelFactor) { + internalName = "PEP_inheritedVelFactor_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateParticle( \"inheritedVelFactor\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"inheritedVelFactor\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 10"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_inheritedVelFactor_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"inheritedVelFactor\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Acceleration + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Acceleration"; + }; + new GuiSliderCtrl(PEP_constantAcceleration) { + internalName = "PEP_constantAcceleration_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateParticle( \"constantAcceleration\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"constantAcceleration\", $ThisControl.getValue(), true, false);"; + hovertime = "1000"; + range = "-10 10"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_constantAcceleration_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"constantAcceleration\", $ThisControl.getText());"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Particle Gravity + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiBitmapCtrl(){ // 0 Gravity + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "tools/gui/images/separator-h"; + tooltip = "0 Gravity"; + }; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Gravity"; + }; + new GuiSliderCtrl(PEP_gravityCoefficient) { + internalName = "PEP_gravityCoefficient_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateParticle( \"gravityCoefficient\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"gravityCoefficient\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "-1 1"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_gravityCoefficient_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"gravityCoefficient\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Drag + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Drag"; + }; + new GuiSliderCtrl(PEP_dragCoefficient) { + internalName = "PEP_dragCoefficient_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateParticle( \"dragCoefficient\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"dragCoefficient\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0.298143"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_dragCoefficient_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"dragCoefficient\", $ThisControl.getText());"; + }; + }; //End Particle Drag + new GuiControl(){ // Particle Wind + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Wind Coeff"; + }; + new GuiSliderCtrl(PEP_windCoefficient) { + internalName = "PEP_windCoefficient_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateParticle( \"windCoefficient\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"windCoefficient\", $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0.298143"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_windCoefficient_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"windCoefficient\", $ThisControl.getText());"; + }; + }; + }; // end stack + }; // end "motion" rollout + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Spin"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(){ // Particle spin Min + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiBitmapCtrl(){ // No Spin + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "tools/gui/images/separator-h"; + tooltip = "No Spin"; + }; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Spin Min"; + }; + new GuiSliderCtrl(PEP_spinRandomMin) { + internalName = "PEP_spinRandomMin_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateSpinFields( true, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateSpinFields( true, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "-1000 999"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_spinRandomMin_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateSpinFields( true, $ThisControl.getText() );"; + }; + }; + new GuiControl(){ // Particle Spin Max + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiBitmapCtrl(){ // No Spin + HorizSizing = "left"; + position = getWord($PE_guielement_pos_slider,0)+mCeil(getWord($PE_guielement_ext_slider,0)/2)-1 SPC "0"; + Extent = "2 18"; + minExtent = "0 0"; + bitmap = "tools/gui/images/separator-h"; + tooltip = "No Spin"; + }; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Spin Max"; + }; + new GuiSliderCtrl(PEP_spinRandomMax) { + internalName = "PEP_spinRandomMax_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PE_ParticleEditor.updateSpinFields( false, $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateSpinFields( false, $ThisControl.getValue(), true, false );"; + hovertime = "1000"; + range = "-999 1000"; + ticks = "0"; + value = "0"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_spinRandomMax_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateSpinFields( false, $ThisControl.getText() );"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Particle spin Speed + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Spin Speed"; + }; + new GuiSliderCtrl(PEP_spinSpeed) { + internalName = "PEP_spinSpeed_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"spinSpeed\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"spinSpeed\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_spinSpeed_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"spinSpeed\", $ThisControl.getText());"; + }; + }; + }; // end stack + }; // end "Spin" rollout + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Animation"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiCheckBoxCtrl() { + internalName = "PEP_animateTexture"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "55 14"; + Extent = "84 18"; + MinExtent = "8 2"; + text = "Animate Texture"; + command = "PE_ParticleEditor.updateParticle( \"animateTexture\", $ThisControl.getValue());"; + }; + new GuiControl(){ // Particle framesPerSec + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "framesPerSec"; + }; + new GuiSliderCtrl(PEP_framesPerSec) { + internalName = "PEP_framesPerSec_slider"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + range = "0 60"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"framesPerSec\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"framesPerSec\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_framesPerSec_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"framesPerSec\", $ThisControl.getText());"; + }; + }; // end framesPerSec + new GuiControl(){ // Particle animTexFramesList + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container; + Extent = $PE_guielement_ext_single_container; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "animTexFrames"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_animTexFramesList_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_textedit; + Extent = $PE_guielement_ext_textedit; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"animTexFrames\", $ThisControl.getText());"; + }; + }; // end animTexFramesList + new GuiControl(){ // Particle animTileCount + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container; + Extent = $PE_guielement_ext_single_container; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "TileCount (X Y)"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_animTileCount_textEdit"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"animTexTiling\", $ThisControl.getText());"; + }; + }; // end animTileCount + }; // end stack + }; // end "Anim" rollout + new GuiRolloutCtrl() { + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "197 0"; + Caption = "Overtime"; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "197 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl(){ // Particle Point Colors + class = ""; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Colors"; + }; + new GuiSwatchButtonCtrl(PE_ColorTintSwatch0) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "75 0"; + Extent = $PE_guielement_ext_colorpicker; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF( PE_ParticleEditor.currParticle.colors[0], \"PE_ColorTintSwatch0.updateParticleColor\");"; + altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + arrayNum = "0"; + class = "PE_ColorTintSwatch"; + }; + new GuiSwatchButtonCtrl(PE_ColorTintSwatch1) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "102 0"; + Extent = $PE_guielement_ext_colorpicker; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF( PE_ParticleEditor.currParticle.colors[1], \"PE_ColorTintSwatch1.updateParticleColor\");"; + altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + arrayNum = "1"; + class = "PE_ColorTintSwatch"; + }; + new GuiSwatchButtonCtrl(PE_ColorTintSwatch2) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "129 0"; + Extent = $PE_guielement_ext_colorpicker; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF( PE_ParticleEditor.currParticle.colors[2], \"PE_ColorTintSwatch2.updateParticleColor\");"; + altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + arrayNum = "2"; + class = "PE_ColorTintSwatch"; + }; + new GuiSwatchButtonCtrl(PE_ColorTintSwatch3) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "156 0"; + Extent = $PE_guielement_ext_colorpicker; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "getColorF( PE_ParticleEditor.currParticle.colors[3], \"PE_ColorTintSwatch3.updateParticleColor\");"; + altCommand = "$ThisControl.updateParticleColor( $ThisControl.color );"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + arrayNum = "3"; + class = "PE_ColorTintSwatch"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Particle Point Size + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Size 1"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointSize_slider0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 50"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"sizes[0]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[0]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointSize_textEdit0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[0]\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Point Size + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Size 2"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointSize_slider1"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 50"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"sizes[1]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[1]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointSize_textEdit1"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[1]\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Point Size + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Size 3"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointSize_slider2"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 50"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"sizes[2]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[2]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointSize_textEdit2"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[2]\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Point Size + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Size 4"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointSize_slider3"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 50"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"sizes[3]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[3]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointSize_textEdit3"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"sizes[3]\", $ThisControl.getText());"; + }; + }; + + new GuiControl(){ // Spacer ---------------------------- + isContainer = "1"; HorizSizing = "width"; Position = "0 0"; Extent = "194 8"; + new GuiBitmapCtrl(){ + position="0 3"; extent ="188 2"; HorizSizing = "width"; + bitmap ="tools/gui/images/separator-v"; + }; + };// end spacer ---------------------------------------- + + new GuiControl(){ // Particle Point Time + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Time 1"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointTime_slider0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"times[0]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[0]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointTime_textEdit0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[0]\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Point Time + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Time 2"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointTime_slider1"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"times[1]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[1]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointTime_textEdit1"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[1]\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Point Time + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Time 3"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointTime_slider2"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"times[2]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[2]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointTime_textEdit2"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[2]\", $ThisControl.getText());"; + }; + }; + new GuiControl(){ // Particle Point Time + class = "AggregateControl"; + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = $PE_guielement_pos_single_container ; + Extent = $PE_guielement_ext_single_container ; + + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = $PE_guielement_pos_name; + Extent = $PE_guielement_ext_name; + text = "Time 4"; + }; + new GuiSliderCtrl() { + internalName = "PEP_pointTime_slider3"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_slider; + Extent = $PE_guielement_ext_slider; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + hovertime = "1000"; + range = "0 1"; + ticks = "0"; + value = "0"; + Command = "PE_ParticleEditor.updateParticle( \"times[3]\", $ThisControl.getValue(), true, true );"; + altCommand = "$ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[3]\", $ThisControl.getValue(), true, false );"; + }; + new GuiTextEditCtrl() { + internalName = "PEP_pointTime_textEdit3"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = $PE_guielement_pos_value; + Extent = $PE_guielement_ext_value; + altCommand = "$ThisControl.setText(mClamp( $ThisControl.getValue(), 0.0, 1.0)); $ThisControl.getParent().updateFromChild($ThisControl); PE_ParticleEditor.updateParticle( \"times[3]\", $ThisControl.getText());"; + }; + }; + }; // end stack + }; // end "Overtime" rollout + };// end stack "Particles" + };// end scroll "Particles" + };// end tab page "Particles" + };// end tab book + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "169 25"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ParticleEditor.updateEmitterNode();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Play Particle Effect from Start"; + hovertime = "1000"; + bitmap = "tools/particleEditor/images/play_btn"; + buttonType = "PushButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "189 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ParticleEditor.resetEmitterNode();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Drops Particle Effect in front of the Camera"; + hovertime = "1000"; + bitmap = "tools/classIcons/camera"; + buttonType = "PushButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; +};// end window +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/particleEditor/images/play_btn_d.png b/Templates/BaseGame/game/tools/particleEditor/images/play_btn_d.png new file mode 100644 index 000000000..518a15685 Binary files /dev/null and b/Templates/BaseGame/game/tools/particleEditor/images/play_btn_d.png differ diff --git a/Templates/BaseGame/game/tools/particleEditor/images/play_btn_h.png b/Templates/BaseGame/game/tools/particleEditor/images/play_btn_h.png new file mode 100644 index 000000000..87543b362 Binary files /dev/null and b/Templates/BaseGame/game/tools/particleEditor/images/play_btn_h.png differ diff --git a/Templates/BaseGame/game/tools/particleEditor/images/play_btn_n.png b/Templates/BaseGame/game/tools/particleEditor/images/play_btn_n.png new file mode 100644 index 000000000..7fadf843d Binary files /dev/null and b/Templates/BaseGame/game/tools/particleEditor/images/play_btn_n.png differ diff --git a/Templates/BaseGame/game/tools/particleEditor/main.cs b/Templates/BaseGame/game/tools/particleEditor/main.cs new file mode 100644 index 000000000..0283b35c3 --- /dev/null +++ b/Templates/BaseGame/game/tools/particleEditor/main.cs @@ -0,0 +1,178 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Initialization and shutdown code for particle editor plugin. + + +//--------------------------------------------------------------------------------------------- + +function initializeParticleEditor() +{ + echo( " % - Initializing Particle Editor" ); + + exec( "./ParticleEditor.ed.gui" ); + exec( "./particleEditor.ed.cs" ); + exec( "./particleEditorUndo.ed.cs" ); + exec( "./particleEmitterEditor.ed.cs" ); + exec( "./particleParticleEditor.ed.cs" ); + + PE_Window.setVisible( false ); + EditorGui.add( PE_Window ); + + new ScriptObject( ParticleEditorPlugin ) + { + superClass = "WorldEditorPlugin"; + editorGui = EWorldEditor; + }; + + %map = new ActionMap(); + %map.bindCmd( keyboard, "1", "EWorldEditorNoneModeBtn.performClick();", "" ); // Select + %map.bindCmd( keyboard, "2", "EWorldEditorMoveModeBtn.performClick();", "" ); // Move + %map.bindCmd( keyboard, "3", "EWorldEditorRotateModeBtn.performClick();", "" ); // Rotate + %map.bindCmd( keyboard, "4", "EWorldEditorScaleModeBtn.performClick();", "" ); // Scale + + ParticleEditorPlugin.map = %map; + + new ScriptObject( ParticleEditor ); + + new PersistenceManager( PE_EmitterSaver ); + new PersistenceManager( PE_ParticleSaver ); + + new SimSet( PE_UnlistedParticles ); + new SimSet( PE_UnlistedEmitters ); +} + +//--------------------------------------------------------------------------------------------- + +function destroyParticleEditor() +{ +} + +//============================================================================================= +// ParticleEditorPlugin. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ParticleEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Particle Editor", "", ParticleEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Particle Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "ParticleEditorPlugin", "ParticleEditorPalette", expandFilename("tools/worldEditor/images/toolbar/particleeditor"), %tooltip ); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditorPlugin::onActivated( %this ) +{ + if( !ParticleEditor.isInitialized ) + { + ParticleEditor.initEditor(); + ParticleEditor.isInitialized = true; + } + + EditorGui-->WorldEditorToolbar.setVisible( true ); + EditorGui.bringToFront( PE_Window); + PE_Window.setVisible( true ); + PE_Window.makeFirstResponder( true ); + + %this.map.push(); + + ParticleEditor.resetEmitterNode(); + + // Set the status bar here + EditorGuiStatusBar.setInfo( "Particle editor." ); + EditorGuiStatusBar.setSelection( "" ); + + Parent::onActivated( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditorPlugin::onDeactivated( %this ) +{ + EditorGui-->WorldEditorToolbar.setVisible( false ); + PE_Window.setVisible( false ); + + if( isObject( $ParticleEditor::emitterNode) ) + $ParticleEditor::emitterNode.delete(); + + %this.map.pop(); + + Parent::onDeactivated( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditorPlugin::onExitMission( %this ) +{ + // Force Particle Editor to re-initialize. + ParticleEditor.isInitialized = false; + + Parent::onExitMission( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup( "ParticleEditor", true ); + + EditorSettings.setDefaultValue( "selectedTab", 0 ); + + EditorSettings.endGroup(); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup( "ParticleEditor", true ); + + %selectedEmitter = EditorSettings.value( "selectedEmitter" ); + if( isObject( %selectedEmitter ) ) + PEE_EmitterSelector.setSelected( %selectedEmitter.getId() ); + + %selectedParticle = EditorSettings.value( "selectedParticle" ); + if( isObject( %selectedParticle ) ) + PEP_ParticleSelector.setSelected( %selectedParticle.getId() ); + + PE_TabBook.selectPage( EditorSettings.value( "selectedPage" ) ); + + EditorSettings.endGroup(); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "ParticleEditor", true ); + + EditorSettings.setValue( "selectedEmitter", PEE_EmitterSelector.getText() ); + EditorSettings.setValue( "selectedParticle", PEP_ParticleSelector.getText() ); + EditorSettings.setValue( "selectedTab", PE_TabBook.getSelectedPage() ); + + EditorSettings.endGroup(); +} diff --git a/Templates/BaseGame/game/tools/particleEditor/particleEditor.ed.cs b/Templates/BaseGame/game/tools/particleEditor/particleEditor.ed.cs new file mode 100644 index 000000000..4156e38d6 --- /dev/null +++ b/Templates/BaseGame/game/tools/particleEditor/particleEditor.ed.cs @@ -0,0 +1,255 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +// Open the particle editor to spawn a test emitter in front of the player. +// Edit the sliders, check boxes, and text fields and see the results in +// realtime. Switch between emitters and particles with the buttons in the +// top left corner. When in particle mode, the only particles available will +// be those assigned to the current emitter to avoid confusion. In the top +// right corner, there is a button marked "Drop Emitter", which will spawn the +// test emitter in front of the player again, and a button marked "Restart +// Emitter", which will play the particle animation again. + + +//============================================================================================= +// ParticleEditor. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ParticleEditor::initEditor( %this ) +{ + echo( "Initializing ParticleEmitterData and ParticleData DataBlocks..." ); + + datablock ParticleEmitterData(PE_EmitterEditor_NotDirtyEmitter) + { + particles = "DefaultParticle"; + }; + datablock ParticleData(PE_ParticleEditor_NotDirtyParticle) + { + textureName = "art/particles/defaultParticle"; + }; + + PE_UnlistedEmitters.add( PE_EmitterEditor_NotDirtyEmitter ); + PE_UnlistedEmitters.add( PE_ParticleEditor_NotDirtyParticle ); + + PEE_EmitterSelector.clear(); + PEE_EmitterParticleSelector1.clear(); + PEE_EmitterParticleSelector2.clear(); + PEE_EmitterParticleSelector3.clear(); + PEE_EmitterParticleSelector4.clear(); + + PEP_ParticleSelector.clear(); + + ParticleEditor.createParticleList(); + + PEE_EmitterParticleSelector2.add( "None", 0 ); + PEE_EmitterParticleSelector3.add( "None", 0 ); + PEE_EmitterParticleSelector4.add( "None", 0 ); + + PEE_EmitterParticleSelector1.sort(); + PEE_EmitterParticleSelector2.sort(); + PEE_EmitterParticleSelector3.sort(); + PEE_EmitterParticleSelector4.sort(); + + PE_EmitterEditor-->PEE_blendType.clear(); + PE_EmitterEditor-->PEE_blendType.add( "NORMAL", 0 ); + PE_EmitterEditor-->PEE_blendType.add( "ADDITIVE", 1 ); + PE_EmitterEditor-->PEE_blendType.add( "SUBTRACTIVE", 2 ); + PE_EmitterEditor-->PEE_blendType.add( "PREMULTALPHA", 3 ); + + + PEE_EmitterSelector.setFirstSelected(); + + PE_Window-->EditorTabBook.selectPage( 0 ); +} + +function ParticleEditor::createParticleList( %this ) +{ + // This function creates the list of all particles and particle emitters + + %emitterCount = 0; + %particleCount = 0; + + foreach( %obj in DatablockGroup ) + { + if( %obj.isMemberOfClass( "ParticleEmitterData" ) ) + { + // Filter out emitters on the PE_UnlistedEmitters list. + + %unlistedFound = false; + foreach( %unlisted in PE_UnlistedEmitters ) + if( %unlisted.getId() == %obj.getId() ) + { + %unlistedFound = true; + break; + } + + if( %unlistedFound ) + continue; + + // To prevent our default emitters from getting changed, + // prevent them from populating the list. Default emitters + // should only be used as a template for creating new ones. + if ( %obj.getName() $= "DefaultEmitter") + continue; + + PEE_EmitterSelector.add( %obj.getName(), %obj.getId() ); + %emitterCount ++; + } + else if( %obj.isMemberOfClass( "ParticleData" ) ) + { + %unlistedFound = false; + foreach( %unlisted in PE_UnlistedParticles ) + if( %unlisted.getId() == %obj.getId() ) + { + %unlistedFound = true; + break; + } + + if( %unlistedFound ) + continue; + + %name = %obj.getName(); + %id = %obj.getId(); + + if ( %name $= "DefaultParticle") + continue; + + // Add to particle dropdown selectors. + + PEE_EmitterParticleSelector1.add( %name, %id ); + PEE_EmitterParticleSelector2.add( %name, %id ); + PEE_EmitterParticleSelector3.add( %name, %id ); + PEE_EmitterParticleSelector4.add( %name, %id ); + + %particleCount ++; + } + } + + PEE_EmitterSelector.sort(); + PEE_EmitterParticleSelector1.sort(); + PEE_EmitterParticleSelector2.sort(); + PEE_EmitterParticleSelector3.sort(); + PEE_EmitterParticleSelector4.sort(); + + echo( "Found" SPC %emitterCount SPC "emitters and" SPC %particleCount SPC "particles." ); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditor::openEmitterPane( %this ) +{ + PE_Window.text = "Particle Editor - Emitters"; + PE_EmitterEditor.guiSync(); + ParticleEditor.activeEditor = PE_EmitterEditor; + + if( !PE_EmitterEditor.dirty ) + PE_EmitterEditor.setEmitterNotDirty(); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditor::openParticlePane( %this ) +{ + PE_Window.text = "Particle Editor - Particles"; + + PE_ParticleEditor.guiSync(); + ParticleEditor.activeEditor = PE_ParticleEditor; + + if( !PE_ParticleEditor.dirty ) + PE_ParticleEditor.setParticleNotDirty(); +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditor::resetEmitterNode( %this ) +{ + %tform = ServerConnection.getControlObject().getEyeTransform(); + %vec = VectorNormalize( ServerConnection.getControlObject().getForwardVector() ); + %vec = VectorScale( %vec, 4 ); + %tform = setWord( %tform, 0, getWord( %tform, 0 ) + getWord( %vec, 0 ) ); + %tform = setWord( %tform, 1, getWord( %tform, 1 ) + getWord( %vec, 1 ) ); + %tform = setWord( %tform, 2, getWord( %tform, 2 ) + getWord( %vec, 2 ) ); + + if( !isObject( $ParticleEditor::emitterNode ) ) + { + if( !isObject( TestEmitterNodeData ) ) + { + datablock ParticleEmitterNodeData( TestEmitterNodeData ) + { + timeMultiple = 1; + }; + } + + $ParticleEditor::emitterNode = new ParticleEmitterNode() + { + emitter = PEE_EmitterSelector.getText(); + velocity = 1; + position = getWords( %tform, 0, 2 ); + rotation = getWords( %tform, 3, 6 ); + datablock = TestEmitterNodeData; + parentGroup = MissionCleanup; + }; + } + else + { + $ParticleEditor::emitterNode.setTransform( %tform ); + + %clientObject = $ParticleEditor::emitterNode.getClientObject(); + if( isObject( %clientObject ) ) + %clientObject.setTransform( %tform ); + + ParticleEditor.updateEmitterNode(); + } +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditor::updateEmitterNode( %this ) +{ + if( isObject( $ParticleEditor::emitterNode ) ) + { + %id = PEE_EmitterSelector_Control-->PopUpMenu.getSelected(); + + %clientObject = $ParticleEditor::emitterNode.getClientObject(); + if( isObject( %clientObject ) ) + %clientObject.setEmitterDataBlock( %id ); + } + else + %this.resetEmitterNode(); +} + +//============================================================================================= +// PE_TabBook. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function PE_TabBook::onTabSelected( %this, %text, %idx ) +{ + if( %idx == 0 ) + ParticleEditor.openEmitterPane(); + else + ParticleEditor.openParticlePane(); +} diff --git a/Templates/BaseGame/game/tools/particleEditor/particleEditorUndo.ed.cs b/Templates/BaseGame/game/tools/particleEditor/particleEditorUndo.ed.cs new file mode 100644 index 000000000..f1e753d5e --- /dev/null +++ b/Templates/BaseGame/game/tools/particleEditor/particleEditorUndo.ed.cs @@ -0,0 +1,606 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +//============================================================================================= +// ParticleEditor. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ParticleEditor::createUndo( %this, %class, %desc ) +{ + pushInstantGroup(); + %action = new UndoScriptAction() + { + class = %class; + superClass = BaseParticleEdAction; + actionName = %desc; + }; + popInstantGroup(); + return %action; +} + +//--------------------------------------------------------------------------------------------- + +function ParticleEditor::submitUndo( %this, %action ) +{ + %action.addToManager( Editor.getUndoManager() ); +} + +//============================================================================================= +// BaseParticleEdAction. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function BaseParticleEdAction::sync( %this ) +{ + // Sync particle state. + + if( isObject( %this.particle ) ) + { + %this.particle.reload(); + PE_ParticleEditor.guiSync(); + + if( %this.particle.getId() == PE_ParticleEditor.currParticle.getId() ) + PE_ParticleEditor.setParticleDirty(); + } + + // Sync emitter state. + + if( isObject( %this.emitter ) ) + { + %this.emitter.reload(); + + PE_EmitterEditor.guiSync(); + + if( %this.emitter.getId() == PE_EmitterEditor.currEmitter.getId() ) + PE_EmitterEditor.setEmitterDirty(); + } +} + +//--------------------------------------------------------------------------------------------- + +function BaseParticleEdAction::redo( %this ) +{ + %this.sync(); +} + +//--------------------------------------------------------------------------------------------- + +function BaseParticleEdAction::undo( %this ) +{ + %this.sync(); +} + +//============================================================================================= +// ActionRenameEmitter. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +//TODO + +//============================================================================================= +// ActionCreateNewEmitter. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionCreateNewEmitter::redo( %this ) +{ + %emitter = %this.emitter; + + // Assign name. + + %emitter.name = %this.emitterName; + + // Remove from unlisted. + + PE_UnlistedEmitters.remove( %emitter ); + + // Drop it in the dropdown and select it. + + %popup = PEE_EmitterSelector; + + %popup.add( %emitter.getName(), %emitter.getId() ); + %popup.sort(); + %popup.setSelected( %emitter.getId() ); + + // Sync up. + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionCreateNewEmitter::undo( %this ) +{ + %emitter = %this.emitter; + + // Prevent a save dialog coming up on the emitter. + + if( %emitter == PE_EmitterEditor.currEmitter ) + PE_EmitterEditor.setEmitterNotDirty(); + + // Add to unlisted. + + PE_UnlistedEmitters.add( %emitter ); + + // Remove it from in the dropdown and select prev emitter. + + %popup = PEE_EmitterSelector; + + if( isObject( %this.prevEmitter ) ) + %popup.setSelected( %this.prevEmitter.getId() ); + else + %popup.setFirstSelected(); + + %popup.clearEntry( %emitter.getId() ); + + // Unassign name. + + %this.emitterName = %emitter.name; + %emitter.name = ""; + + // Sync up. + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionDeleteEmitter. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionDeleteEmitter::redo( %this ) +{ + %emitter = %this.emitter; + + // Unassign name. + + %this.emitterName = %emitter.name; + %emitter.name = ""; + + // Add to unlisted. + + PE_UnlistedEmitters.add( %emitter ); + + // Remove from file. + + if( %emitter.getFileName() !$= "" + && %emitter.getFilename() !$= "tools/particleEditor/particleEmitterEditor.ed.cs" ) + PE_EmitterSaver.removeObjectFromFile( %emitter ); + + // Select DefaultEmitter or first in list. + + %popup = PEE_EmitterSelector_Control-->PopUpMenu; + + %popup.setFirstSelected(); + + // Remove from dropdown. + + %popup.clearEntry( %emitter ); + + // Sync up. + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionDeleteEmitter::undo( %this ) +{ + %emitter = %this.emitter; + + // Re-assign name. + + %emitter.name = %this.emitterName; + + // Remove from unlisted. + + PE_UnlistedEmitters.remove( %emitter ); + + // Resave to file. + + if( %this.emitterFname !$= "" + && %this.emitterFname !$= "tools/particleEditor/particleEmitterEditor.ed.gui" ) + { + PE_EmitterSaver.setDirty( %emitter, %this.emitterFname ); + PE_EmitterSaver.saveDirty(); + } + + // Add it to the dropdown and selet it. + + %popup = PEE_EmitterSelector_Control-->PopUpMenu; + %popup.add( %emitter.getName(), %emitter.getId() ); + %popup.sort(); + %popup.setSelected( %emitter.getId() ); + + // Sync up. + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionUpdateActiveEmitter. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitter::redo( %this ) +{ + %emitter = %this.emitter; + %emitter.setFieldValue( %this.field, %this.newValue ); + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitter::undo( %this ) +{ + %emitter = %this.emitter; + %emitter.setFieldValue( %this.field, %this.oldValue ); + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionUpdateActiveEmitterLifeFields. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitterLifeFields::redo( %this ) +{ + %emitter = %this.emitter; + + %emitter.lifetimeMS = %this.newValueLifetimeMS; + %emitter.lifetimeVarianceMS = %this.newValueLifetimeVarianceMS; + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitterLifeFields::undo( %this ) +{ + %emitter = %this.emitter; + + %emitter.lifetimeMS = %this.oldValueLifetimeMS; + %emitter.lifetimeVarianceMS = %this.oldValueLifetimeVarianceMS; + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionUpdateActiveEmitterAmountFields. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitterAmountFields::redo( %this ) +{ + %emitter = %this.emitter; + + %emitter.ejectionPeriodMS = %this.newValueEjectionPeriodMS; + %emitter.periodVarianceMS = %this.newValuePeriodVarianceMS; + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitterAmountFields::undo( %this ) +{ + %emitter = %this.emitter; + + %emitter.ejectionPeriodMS = %this.oldValueEjectionPeriodMS; + %emitter.periodVarianceMS = %this.oldValuePeriodVarianceMS; + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionUpdateActiveEmitterSpeedFields. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitterSpeedFields::redo( %this ) +{ + %emitter = %this.emitter; + + %emitter.ejectionVelocity = %this.newValueEjectionVelocity; + %emitter.velocityVariance = %this.newValueVelocityVariance; + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveEmitterSpeedFields::undo( %this ) +{ + %emitter = %this.emitter; + + %emitter.ejectionVelocity = %this.oldValueEjectionVelocity; + %emitter.velocityVariance = %this.oldValueVelocityVariance; + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionCreateNewParticle. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionCreateNewParticle::redo( %this ) +{ + %particle = %this.particle.getName(); + %particleId = %this.particle.getId(); + %particleIndex = %this.particleIndex; + %emitter = %this.emitter; + + // Remove from unlisted. + + PE_UnlistedParticles.remove( %particleId ); + + // Add it to the dropdown. + + PEP_ParticleSelector.add( %particle, %particleId ); + PEP_ParticleSelector.sort(); + PEP_ParticleSelector.setSelected( %particleId, false ); + + // Add particle to dropdowns in the emitter editor. + + for( %i = 1; %i < 5; %i ++ ) + { + %emitterParticle = "PEE_EmitterParticle" @ %i; + %popup = %emitterParticle-->PopupMenu; + + %popup.add( %particle, %particleId ); + %popup.sort(); + + if( %i == %particleIndex + 1 ) + %popup.setSelected( %particleId ); + } + + // Sync up. + + PE_ParticleEditor.loadNewParticle(); + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionCreateNewParticle::undo( %this ) +{ + %particle = %this.particle.getName(); + %particleId = %this.particle.getId(); + %emitter = %this.emitter; + + // Add to unlisted. + + PE_UnlistedParticles.add( %particleId ); + + // Remove from dropdown. + + PEP_ParticleSelector.clearEntry( %particleId ); + PEP_ParticleSelector.setFirstSelected( false ); + + // Remove from particle dropdowns in emitter editor. + + for( %i = 1; %i < 5; %i ++ ) + { + %emitterParticle = "PEE_EmitterParticle" @ %i; + %popup = %emitterParticle-->PopUpMenu; + + if( %popup.getSelected() == %particleId ) + %popup.setSelected( %this.prevParticle ); + + %popup.clearEntry( %particleId ); + } + + // Sync up. + + PE_ParticleEditor.loadNewParticle(); + Parent::undo( %this ); +} + +//============================================================================================= +// ActionDeleteParticle. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionDeleteParticle::redo( %this ) +{ + %particle = %this.particle.getName(); + %particleId = %this.particle.getId(); + %emitter = %this.emitter; + + // Add to unlisted. + + PE_UnlistedParticles.add( %particleId ); + + // Remove from file. + + if( %particle.getFileName() !$= "" + && %particle.getFilename() !$= "tools/particleEditor/particleParticleEditor.ed.cs" ) + PE_ParticleSaver.removeObjectFromFile( %particleId ); + + // Remove from dropdown. + + PEP_ParticleSelector.clearEntry( %particleId ); + PEP_ParticleSelector.setFirstSelected(); + + // Remove from particle selectors in emitter. + + for( %i = 1; %i < 5; %i ++ ) + { + %emitterParticle = "PEE_EmitterParticle" @ %i; + %popup = %emitterParticle-->PopUpMenu; + + if( %popup.getSelected() == %particleId ) + { + %this.particleIndex = %i - 1; + %popup.setSelected( 0 ); // Select "None". + } + + %popup.clearEntry( %particleId ); + } + + // Sync up. + + PE_ParticleEditor.loadNewParticle(); + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionDeleteParticle::undo( %this ) +{ + %particle = %this.particle.getName(); + %particleId = %this.particle.getId(); + %particleIndex = %this.particleIndex; + %emitter = %this.emitter; + + // Remove from unlisted. + + PE_UnlistedParticles.remove( %particleId ); + + // Resave to file. + + if( %particle.getFilename() !$= "" + && %particle.getFilename() !$= "tools/particleEditor/particleParticleEditor.ed.gui" ) + { + PE_ParticleSaver.setDirty( %particle ); + PE_ParticleSaver.saveDirty(); + } + + // Add to dropdown. + + PEP_ParticleSelector.add( %particle, %particleId ); + PEP_ParticleSelector.sort(); + PEP_ParticleSelector.setSelected( %particleId ); + + // Add particle to dropdowns in the emitter editor. + + for( %i = 1; %i < 5; %i ++ ) + { + %emitterParticle = "PEE_EmitterParticle" @ %i; + %popup = %emitterParticle-->PopUpMenu; + + %popup.add( %particle, %particleId ); + %popup.sort(); + + if( %i == %particleIndex + 1 ) + %popup.setSelected( %particleId ); + } + + // Sync up. + + PE_ParticleEditor.loadNewParticle(); + Parent::undo( %This ); +} + +//============================================================================================= +// ActionUpdateActiveParticle. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveParticle::redo( %this ) +{ + %particle = %this.particle; + %particle.setFieldValue( %this.field, %this.newValue ); + + Parent::redo( %this ); +} + +function ActionUpdateActiveParticle::undo( %this ) +{ + %particle = %this.particle; + %particle.setFieldValue( %this.field, %this.oldValue ); + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionUpdateActiveParticleLifeFields. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveParticleLifeFields::redo( %this ) +{ + %particle = %this.particle; + + %particle.lifetimeMS = %this.newValueLifetimeMS; + %particle.lifetimeVarianceMS = %this.newValueLifetimeVarianceMS; + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveParticleLifeFields::undo( %this ) +{ + %particle = %this.particle; + + %particle.lifetimeMS = %this.oldValueLifetimeMS; + %particle.lifetimeVarianceMS = %this.oldValueLifetimeVarianceMS; + + Parent::undo( %this ); +} + +//============================================================================================= +// ActionUpdateActiveParticleSpinFields. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveParticleSpinFields::redo( %this ) +{ + %particle = %this.particle; + + %particle.spinRandomMax = %this.newValueSpinRandomMax; + %particle.spinRandomMin = %this.newValueSpinRandomMin; + + Parent::redo( %this ); +} + +//--------------------------------------------------------------------------------------------- + +function ActionUpdateActiveParticleSpinFields::undo( %this ) +{ + %particle = %this.particle; + + %particle.spinRandomMax = %this.oldValueSpinRandomMax; + %particle.spinRandomMin = %this.oldValueSpinRandomMin; + + Parent::undo( %this ); +} diff --git a/Templates/BaseGame/game/tools/particleEditor/particleEmitterEditor.ed.cs b/Templates/BaseGame/game/tools/particleEditor/particleEmitterEditor.ed.cs new file mode 100644 index 000000000..4e3a571e7 --- /dev/null +++ b/Templates/BaseGame/game/tools/particleEditor/particleEmitterEditor.ed.cs @@ -0,0 +1,659 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +$PE_EMITTEREDITOR_DEFAULT_FILENAME = "art/particles/managedParticleEmitterData.cs"; + + +//============================================================================================= +// PE_EmitterEditor. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::guiSync( %this ) +{ + %data = PE_EmitterEditor.currEmitter; + + // Sync up sliders and number boxes. + + if( PE_EmitterEditor-->PEE_infiniteLoop.isStateOn() ) + { + PE_EmitterEditor-->PEE_lifetimeMS_slider.setActive( false ); + PE_EmitterEditor-->PEE_lifetimeMS_textEdit.setActive( false ); + PE_EmitterEditor-->PEE_lifetimeVarianceMS_slider.setActive( false ); + PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.setActive( false ); + } + else + { + PE_EmitterEditor-->PEE_lifetimeMS_slider.setActive( true ); + PE_EmitterEditor-->PEE_lifetimeMS_textEdit.setActive( true ); + PE_EmitterEditor-->PEE_lifetimeVarianceMS_slider.setActive( true ); + PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.setActive( true ); + + PE_EmitterEditor-->PEE_lifetimeMS_slider.setValue( %data.lifetimeMS ); + PE_EmitterEditor-->PEE_lifetimeMS_textEdit.setText( %data.lifetimeMS ); + PE_EmitterEditor-->PEE_lifetimeVarianceMS_slider.setValue( %data.lifetimeVarianceMS ); + PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.setText( %data.lifetimeVarianceMS ); + } + + PE_EmitterEditor-->PEE_ejectionPeriodMS_slider.setValue( %data.ejectionPeriodMS ); + PE_EmitterEditor-->PEE_ejectionPeriodMS_textEdit.setText( %data.ejectionPeriodMS ); + + PE_EmitterEditor-->PEE_periodVarianceMS_slider.setValue( %data.periodVarianceMS ); + PE_EmitterEditor-->PEE_periodVarianceMS_textEdit.setText( %data.periodVarianceMS ); + + PE_EmitterEditor-->PEE_ejectionVelocity_slider.setValue( %data.ejectionVelocity ); + PE_EmitterEditor-->PEE_ejectionVelocity_textEdit.setText( %data.ejectionVelocity ); + + PE_EmitterEditor-->PEE_velocityVariance_slider.setValue( %data.velocityVariance ); + PE_EmitterEditor-->PEE_velocityVariance_textEdit.setText( %data.velocityVariance ); + + PE_EmitterEditor-->PEE_orientParticles.setValue( %data.orientParticles ); + PE_EmitterEditor-->PEE_alignParticles.setValue( %data.alignParticles ); + PE_EmitterEditor-->PEE_alignDirection.setText( %data.alignDirection ); + + PE_EmitterEditor-->PEE_thetaMin_slider.setValue( %data.thetaMin ); + PE_EmitterEditor-->PEE_thetaMin_textEdit.setText( %data.thetaMin ); + + PE_EmitterEditor-->PEE_thetaMax_slider.setValue( %data.thetaMax ); + PE_EmitterEditor-->PEE_thetaMax_textEdit.setText( %data.thetaMax ); + + PE_EmitterEditor-->PEE_phiVariance_slider.setValue( %data.phiVariance ); + PE_EmitterEditor-->PEE_phiVariance_textEdit.setText( %data.phiVariance ); + + PE_EmitterEditor-->PEE_ejectionOffset_slider.setValue( %data.ejectionOffset ); + PE_EmitterEditor-->PEE_ejectionOffset_textEdit.setText( %data.ejectionOffset ); + + PE_EmitterEditor-->PEE_ejectionOffsetVariance_slider.setValue( %data.ejectionOffsetVariance ); + PE_EmitterEditor-->PEE_ejectionOffsetVariance_textEdit.setText( %data.ejectionOffsetVariance ); + + %blendTypeId = PE_EmitterEditor-->PEE_blendType.findText( %data.blendStyle ); + PE_EmitterEditor-->PEE_blendType.setSelected( %blendTypeId, false ); + + PE_EmitterEditor-->PEE_softnessDistance_slider.setValue( %data.softnessDistance ); + PE_EmitterEditor-->PEE_softnessDistance_textEdit.setText( %data.softnessDistance ); + + PE_EmitterEditor-->PEE_ambientFactor_slider.setValue( %data.ambientFactor ); + PE_EmitterEditor-->PEE_ambientFactor_textEdit.setText( %data.ambientFactor ); + + PE_EmitterEditor-->PEE_softParticles.setValue( %data.softParticles ); + PE_EmitterEditor-->PEE_reverseOrder.setValue( %data.reverseOrder ); + PE_EmitterEditor-->PEE_useEmitterSizes.setValue( %data.useEmitterSizes ); + PE_EmitterEditor-->PEE_useEmitterColors.setValue( %data.useEmitterColors ); + + PE_EmitterEditor-->PEE_glow.setValue( %data.glow ); + + // Sync up particle selectors. + + for( %index = 0; %index < 4; %index ++ ) + { + %ctrl = "PEE_EmitterParticle" @ ( %index + 1 ); + %popup = %ctrl-->PopUpMenu; + + %particle = getWord( %data.particles, %index ); + if( isObject( %particle ) ) + %popup.setSelected( %particle.getId(), false ); + else + %popup.setSelected( 0, false ); // Select "None". + } +} + +//--------------------------------------------------------------------------------------------- + +// Generic updateEmitter method +function PE_EmitterEditor::updateEmitter( %this, %propertyField, %value, %isSlider, %onMouseUp ) +{ + PE_EmitterEditor.setEmitterDirty(); + + %emitter = PE_EmitterEditor.currEmitter; + + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) ) + { + %last.field = %propertyField; + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValue = %value; + } + else + { + %action = ParticleEditor.createUndo(ActionUpdateActiveEmitter, "Update Active Emitter"); + %action.emitter = %emitter; + %action.field = %propertyField; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + %action.newValue = %value; + %action.oldValue = %emitter.getFieldValue( %propertyField ); + + ParticleEditor.submitUndo( %action ); + } + + %emitter.setFieldValue( %propertyField, %value ); + %emitter.reload(); +} + +//--------------------------------------------------------------------------------------------- + +// Special case updateEmitter methods +function PE_EmitterEditor::updateLifeFields( %this, %isRandom, %value, %isSlider, %onMouseUp ) +{ + PE_EmitterEditor.setEmitterDirty(); + + %emitter = PE_EmitterEditor.currEmitter; + + // Transfer values over to gui controls. + + if( %isRandom ) + { + if( %value > 0 ) + %value++; + + if( %value > PE_EmitterEditor-->PEE_lifetimeMS_slider.getValue() ) + { + PE_EmitterEditor-->PEE_lifetimeMS_textEdit.setText( %value ); + PE_EmitterEditor-->PEE_lifetimeMS_slider.setValue( %value ); + } + } + else + { + if( %value > 0 ) + %value --; + + if( %value < PE_EmitterEditor-->PEE_lifetimeVarianceMS_slider.getValue() ) + { + PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.setText( %value ); + PE_EmitterEditor-->PEE_lifetimeVarianceMS_slider.setValue( %value ); + } + } + + // Submit undo. + + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) ) + { + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValueLifetimeMS = PE_EmitterEditor-->PEE_lifetimeMS_textEdit.getText(); + %last.newValueLifetimeVarianceMS = PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.getText(); + } + else + { + %action = ParticleEditor.createUndo(ActionUpdateActiveEmitterLifeFields, "Update Active Emitter"); + %action.emitter = %emitter; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + + %action.newValueLifetimeMS = PE_EmitterEditor-->PEE_lifetimeMS_textEdit.getText(); + %action.oldValueLifetimeMS = %emitter.lifetimeMS; + + %action.newValueLifetimeVarianceMS = PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.getText(); + %action.oldValueLifetimeVarianceMS = %emitter.lifetimeVarianceMS; + + ParticleEditor.submitUndo( %action ); + } + + // Set the values on the current emitter. + + %emitter.lifetimeMS = PE_EmitterEditor-->PEE_lifetimeMS_textEdit.getText(); + %emitter.lifetimeVarianceMS = PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.getText(); + %emitter.reload(); + + // Keep the infiniteLoop checkbox up to date. + + PE_EmitterEditor-->PEE_infiniteLoop.setStateOn( + %emitter.lifetimeMS == 0 + ); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::updateLifeFieldsInfiniteLoop( %this ) +{ + %emitter = PE_EmitterEditor.currEmitter; + %isEnabled = PE_EmitterEditor-->PEE_infiniteLoop.isStateOn(); + + // Submit undo. + + %action = ParticleEditor.createUndo( ActionUpdateActiveEmitterLifeFields, "Update Active Emitter" ); + %action.emitter = %emitter; + + if( %isEnabled ) + { + %action.newValueLifetimeMS = 0; + %action.newvalueLifetimeVarianceMS = 0; + %action.oldValueLifetimeMS = PE_EmitterEditor-->PEE_lifetimeMS_textEdit.getText(); + %action.oldValueLifetimeVarianceMS = PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.getText(); + } + else + { + %action.newValueLifetimeMS = PE_EmitterEditor-->PEE_lifetimeMS_textEdit.getText(); + %action.newvalueLifetimeVarianceMS = PE_EmitterEditor-->PEE_lifetimeVarianceMS_textEdit.getText(); + %action.oldValueLifetimeMS = 0; + %action.oldValueLifetimeVarianceMS = 0; + } + + ParticleEditor.submitUndo( %action ); + + // Execute action. + + %action.redo(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::updateAmountFields( %this, %isRandom, %value, %isSlider, %onMouseUp ) +{ + PE_EmitterEditor.setEmitterDirty(); + %emitter = PE_EmitterEditor.currEmitter; + + // Transfer values over to gui controls. + + if( %isRandom ) + { + %value ++; + if( %value > PE_EmitterEditor-->PEE_ejectionPeriodMS_slider.getValue() ) + { + PE_EmitterEditor-->PEE_ejectionPeriodMS_textEdit.setText( %value ); + PE_EmitterEditor-->PEE_ejectionPeriodMS_slider.setValue( %value ); + } + } + else + { + %value --; + if( %value < PE_EmitterEditor-->PEE_periodVarianceMS_slider.getValue() ) + { + PE_EmitterEditor-->PEE_periodVarianceMS_textEdit.setText( %value ); + PE_EmitterEditor-->PEE_periodVarianceMS_slider.setValue( %value ); + } + } + + // Submit undo. + + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) ) + { + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValueEjectionPeriodMS = PE_EmitterEditor-->PEE_ejectionPeriodMS_textEdit.getText(); + %last.newValuePeriodVarianceMS = PE_EmitterEditor-->PEE_periodVarianceMS_textEdit.getText(); + } + else + { + %action = ParticleEditor.createUndo(ActionUpdateActiveEmitterAmountFields, "Update Active Emitter"); + %action.emitter = %emitter; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + + %action.newValueEjectionPeriodMS = PE_EmitterEditor-->PEE_ejectionPeriodMS_textEdit.getText(); + %action.oldValueEjectionPeriodMS = %emitter.ejectionPeriodMS; + + %action.newValuePeriodVarianceMS = PE_EmitterEditor-->PEE_periodVarianceMS_textEdit.getText(); + %action.oldValuePeriodVarianceMS = %emitter.periodVarianceMS; + + ParticleEditor.submitUndo( %action ); + } + + // Set the values on the current emitter. + + %emitter.ejectionPeriodMS = PE_EmitterEditor-->PEE_ejectionPeriodMS_textEdit.getText(); + %emitter.periodVarianceMS = PE_EmitterEditor-->PEE_periodVarianceMS_textEdit.getText(); + %emitter.reload(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::updateSpeedFields( %this, %isRandom, %value, %isSlider, %onMouseUp ) +{ + PE_EmitterEditor.setEmitterDirty(); + %emitter = PE_EmitterEditor.currEmitter; + + // Transfer values over to gui controls. + + if( %isRandom ) + { + if( %value > PE_EmitterEditor-->PEE_ejectionVelocity_slider.getValue() ) + { + PE_EmitterEditor-->PEE_ejectionVelocity_textEdit.setText( %value ); + PE_EmitterEditor-->PEE_ejectionVelocity_slider.setValue( %value ); + } + } + else + { + if( %value < PE_EmitterEditor-->PEE_velocityVariance_slider.getValue() ) + { + PE_EmitterEditor-->PEE_velocityVariance_textEdit.setText( %value ); + PE_EmitterEditor-->PEE_velocityVariance_slider.setValue( %value ); + } + } + + // Submit undo. + + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) ) + { + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValueEjectionVelocity = PE_EmitterEditor-->PEE_ejectionVelocity_textEdit.getText(); + %last.newValueVelocityVariance = PE_EmitterEditor-->PEE_velocityVariance_textEdit.getText(); + } + else + { + %action = ParticleEditor.createUndo(ActionUpdateActiveEmitterSpeedFields, "Update Active Emitter"); + %action.emitter = %emitter; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + + %action.newValueEjectionVelocity = PE_EmitterEditor-->PEE_ejectionVelocity_textEdit.getText(); + %action.oldValueEjectionVelocity = %emitter.ejectionVelocity; + + %action.newValueVelocityVariance = PE_EmitterEditor-->PEE_velocityVariance_textEdit.getText(); + %action.oldValueVelocityVariance = %emitter.velocityVariance; + + ParticleEditor.submitUndo( %action ); + } + + // Set the values on the current emitter. + + %emitter.ejectionVelocity = PE_EmitterEditor-->PEE_ejectionVelocity_textEdit.getText(); + %emitter.velocityVariance = PE_EmitterEditor-->PEE_velocityVariance_textEdit.getText(); + %emitter.reload(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::updateParticlesFields( %this ) +{ + %particles = ""; + for( %i = 1; %i < 5; %i ++ ) + { + %emitterParticle = "PEE_EmitterParticle" @ %i; + %popup = %emitterParticle-->PopUpMenu; + %text = %popup.getText(); + + if( %text $= "" || %text $= "None" ) + continue; + + if( %particles $= "" ) + %particles = %text; + else + %particles = %particles SPC %text; + } + + %changedEditParticle = 1; + %currParticle = PE_ParticleEditor.currParticle.getName(); + + foreach$( %particleName in %particles ) + { + if( %particleName $= %currParticle ) + { + %changedEditParticle = 0; + break; + } + } + + // True only if the currently edited particle has not been found and the + // ParticleEditor is dirty. + + if( %changedEditParticle && PE_ParticleEditor.dirty ) + { + MessageBoxYesNoCancel("Save Particle Changes?", + "Do you wish to save the changes made to the <br>current particle before changing the particle?", + "PE_ParticleEditor.saveParticle( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_EmitterEditor.updateEmitter( \"particles\"," @ %particles @ ");", + "PE_ParticleEditor.saveParticleDialogDontSave( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_EmitterEditor.updateEmitter( \"particles\"," @ %particles @ ");", + "PE_EmitterEditor.guiSync();" ); + } + else + { + PE_EmitterEditor.updateEmitter( "particles", %particles ); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::onNewEmitter( %this ) +{ + if( isObject( PE_EmitterEditor.currEmitter ) + && PE_EmitterEditor.currEmitter $= PEE_EmitterSelector.getSelected() ) + return; + + //FIXME: disregards particle tab dirty state + + if( PE_EmitterEditor.dirty ) + { + + if( PE_ParticleEditor.dirty ) + { + MessageBoxYesNo("Save Existing Particle?", + "Do you want to save changes to <br><br>" @ PE_ParticleEditor.currParticle.getName(), + "PE_ParticleEditor.saveParticle(" @ PE_ParticleEditor.currParticle @ ");" + ); + } + + %savedEmitter = PE_EmitterEditor.currEmitter; + MessageBoxYesNoCancel("Save Existing Emitter?", + "Do you want to save changes to <br><br>" @ %savedEmitter.getName(), + "PE_EmitterEditor.saveEmitter(" @ %savedEmitter@ "); PE_EmitterEditor.loadNewEmitter();", + "PE_EmitterEditor.saveEmitterDialogDontSave(" @ %savedEmitter @ "); PE_EmitterEditor.loadNewEmitter();" + ); + + + } + else + { + PE_EmitterEditor.loadNewEmitter(); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::loadNewEmitter( %this, %emitter ) +{ + if( isObject( %emitter ) ) + %current = %emitter.getId(); + else + %current = PEE_EmitterSelector.getSelected(); + + PE_EmitterEditor.currEmitter = %current; + PE_EmitterEditor_NotDirtyEmitter.assignFieldsFrom( %current ); + PE_EmitterEditor_NotDirtyEmitter.originalName = %current.name; + + PE_EmitterEditor.guiSync(); + PE_EmitterEditor.setEmitterNotDirty(); + + PE_ParticleEditor.loadNewParticle( getWord( %current.particles, 0 ) ); + + ParticleEditor.updateEmitterNode(); + + PE_EmitterEditor-->PEE_infiniteLoop.setStateOn( %current.lifetimeMS == 0 ); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::setEmitterDirty( %this ) +{ + PE_EmitterEditor.text = "Emitter *"; + PE_EmitterEditor.dirty = true; + + %emitter = PE_EmitterEditor.currEmitter; + + if( %emitter.getFilename() $= "" || %emitter.getFilename() $= "tools/particleEditor/particleEmitterEditor.ed.cs" ) + PE_EmitterSaver.setDirty( %emitter, $PE_EMITTEREDITOR_DEFAULT_FILENAME ); + else + PE_EmitterSaver.setDirty( %emitter ); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::setEmitterNotDirty( %this ) +{ + PE_EmitterEditor.text = "Emitter"; + PE_EmitterEditor.dirty = false; + + PE_EmitterSaver.clearAll(); +} + +//--------------------------------------------------------------------------------------------- + +// Create Functionality +function PE_EmitterEditor::showNewDialog( %this ) +{ + //FIXME: disregards particle tab dirty state + + // Open a dialog if the current emitter is dirty. + + if( PE_ParticleEditor.dirty ) + { + MessageBoxYesNo("Save Existing Particle?", + "Do you want to save changes to <br><br>" @ PE_ParticleEditor.currParticle.getName(), + "PE_ParticleEditor.saveParticle(" @ PE_ParticleEditor.currParticle @ ");" + ); + } + + if( PE_EmitterEditor.dirty ) + { + MessageBoxYesNoCancel("Save Emitter Changes?", + "Do you wish to save the changes made to the <br>current emitter before changing the emitter?", + "PE_EmitterEditor.saveEmitter( " @ PE_EmitterEditor.currEmitter.getName() @ " ); PE_EmitterEditor.createEmitter();", + "PE_EmitterEditor.saveEmitterDialogDontSave( " @ PE_EmitterEditor.currEmitter.getName() @ " ); PE_EmitterEditor.createEmitter();" + ); + } + else + { + PE_EmitterEditor.createEmitter(); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::createEmitter( %this ) +{ + // Create a new emitter. + %emitter = getUniqueName( "newEmitter" ); + datablock ParticleEmitterData( %emitter : DefaultEmitter ) + { + }; + + // Submit undo. + + %action = ParticleEditor.createUndo( ActionCreateNewEmitter, "Create New Emitter" ); + %action.prevEmitter = PE_EmitterEditor.currEmitter; + %action.emitter = %emitter.getId(); + %action.emitterName = %emitter; + + ParticleEditor.submitUndo( %action ); + + // Execute action. + + %action.redo(); + + PE_ParticleEditor.createParticle(false); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::showDeleteDialog( %this ) +{ + if( PE_EmitterEditor.currEmitter.getName() $= "DefaultEmitter" ) + { + MessageBoxOK( "Error", "Cannot delete DefaultEmitter"); + return; + } + + if( isObject( PE_EmitterEditor.currEmitter ) ) + { + MessageBoxYesNoCancel("Delete Emitter?", + "Are you sure you want to delete<br><br>" @ PE_EmitterEditor.currEmitter.getName() @ "<br><br> Emitter deletion won't take affect until the level is exited.", + "PE_EmitterEditor.saveEmitterDialogDontSave( " @ PE_EmitterEditor.currEmitter.getName() @ " ); PE_EmitterEditor.deleteEmitter();" + ); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::deleteEmitter( %this ) +{ + %emitter = PE_EmitterEditor.currEmitter; + + // Create undo. + + %action = ParticleEditor.createUndo( ActionDeleteEmitter, "Delete Emitter" ); + %action.emitter = %emitter; + %action.emitterFname = %emitter.getFilename(); + + ParticleEditor.submitUndo( %action ); + + // Execute action. + + %action.redo(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::saveEmitter( %this, %emitter ) +{ + + + if ( %emitter $= "" ) + %newName = PEE_EmitterSelector_Control->TextEdit.getText(); + else + %newName = %emitter.getName(); + + PE_EmitterEditor.currEmitter.setName( %newName ); + PE_EmitterEditor_NotDirtyEmitter.assignFieldsFrom( %emitter ); + PE_EmitterEditor_NotDirtyEmitter.originalName = %newName; + + PE_EmitterSaver.saveDirty(); + + PE_EmitterEditor.currEmitter = %newName.getId(); + PE_EmitterEditor.setEmitterNotDirty(); + + ParticleEditor.createParticleList(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_EmitterEditor::saveEmitterDialogDontSave( %this, %emitter) +{ + %emitter.setName( PE_EmitterEditor_NotDirtyEmitter.originalName ); + %emitter.assignFieldsFrom( PE_EmitterEditor_NotDirtyEmitter ); + PE_EmitterEditor.setEmitterNotDirty(); +} + +//============================================================================================= +// PEE_EmitterSelector_Control. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function PEE_EmitterSelector_Control::onRenameItem( %this ) +{ + Parent::onRenameItem( %this ); + + //FIXME: need to check for validity of name and name clashes + + PE_EmitterEditor.setEmitterDirty(); + + // Resort menu. + + %this-->PopupMenu.sort(); +} diff --git a/Templates/BaseGame/game/tools/particleEditor/particleParticleEditor.ed.cs b/Templates/BaseGame/game/tools/particleEditor/particleParticleEditor.ed.cs new file mode 100644 index 000000000..00a27e5d4 --- /dev/null +++ b/Templates/BaseGame/game/tools/particleEditor/particleParticleEditor.ed.cs @@ -0,0 +1,603 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +$PE_PARTICLEEDITOR_DEFAULT_FILENAME = "art/particles/managedParticleData.cs"; + + +//============================================================================================= +// PE_ParticleEditor. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::guiSync( %this ) +{ + // Populate the selector with the particles assigned + // to the current emitter. + + %containsCurrParticle = false; + %popup = PEP_ParticleSelector; + %popup.clear(); + + foreach$( %particle in PE_EmitterEditor.currEmitter.particles ) + { + if( %particle.getId() == PE_ParticleEditor.currParticle ) + %containsCurrParticle = true; + + %popup.add( %particle, %particle.getId() ); + } + + // Just in case the particle doesn't exist, fallback gracefully + + if( !%containsCurrParticle ) + PE_ParticleEditor.currParticle = getWord( PE_EmitterEditor.currEmitter.particles, 0 ).getId(); + + %data = PE_ParticleEditor.currParticle; + + %popup.sort(); + %popup.setSelected( %data ); + + %bitmap = MaterialEditorGui.searchForTexture( %data.getName(), %data.textureName ); + if( %bitmap !$= "" ) + { + PE_ParticleEditor-->PEP_previewImage.setBitmap( %bitmap ); + PE_ParticleEditor-->PEP_previewImageName.setText( %bitmap ); + PE_ParticleEditor-->PEP_previewImageName.tooltip = %bitmap; + } + else + { + PE_ParticleEditor-->PEP_previewImage.setBitmap( "" ); + PE_ParticleEditor-->PEP_previewImageName.setText( "None" ); + PE_ParticleEditor-->PEP_previewImageName.tooltip = "None"; + } + + PE_ParticleEditor-->PEP_inverseAlpha.setValue( %data.useInvAlpha ); + + PE_ParticleEditor-->PEP_lifetimeMS_slider.setValue( %data.lifetimeMS ); + PE_ParticleEditor-->PEP_lifetimeMS_textEdit.setText( %data.lifetimeMS ); + + PE_ParticleEditor-->PEP_lifetimeVarianceMS_slider.setValue( %data.lifetimeVarianceMS ); + PE_ParticleEditor-->PEP_lifetimeVarianceMS_textEdit.setText( %data.lifetimeVarianceMS ); + + PE_ParticleEditor-->PEP_inheritedVelFactor_slider.setValue( %data.inheritedVelFactor ); + PE_ParticleEditor-->PEP_inheritedVelFactor_textEdit.setText( %data.inheritedVelFactor ); + + PE_ParticleEditor-->PEP_constantAcceleration_slider.setValue( %data.constantAcceleration ); + PE_ParticleEditor-->PEP_constantAcceleration_textEdit.setText( %data.constantAcceleration ); + + PE_ParticleEditor-->PEP_gravityCoefficient_slider.setValue( %data.gravityCoefficient ); + PE_ParticleEditor-->PEP_gravityCoefficient_textEdit.setText( %data.gravityCoefficient ); + + PE_ParticleEditor-->PEP_dragCoefficient_slider.setValue( %data.dragCoefficient ); + PE_ParticleEditor-->PEP_dragCoefficient_textEdit.setText( %data.dragCoefficient ); + + PE_ParticleEditor-->PEP_windCoefficient_slider.setValue( %data.windCoefficient ); + PE_ParticleEditor-->PEP_windCoefficient_textEdit.setText( %data.windCoefficient ); + + PE_ParticleEditor-->PEP_spinRandomMin_slider.setValue( %data.spinRandomMin ); + PE_ParticleEditor-->PEP_spinRandomMin_textEdit.setText( %data.spinRandomMin ); + + PE_ParticleEditor-->PEP_spinRandomMax_slider.setValue( %data.spinRandomMax ); + PE_ParticleEditor-->PEP_spinRandomMax_textEdit.setText( %data.spinRandomMax ); + + PE_ParticleEditor-->PEP_spinRandomMax_slider.setValue( %data.spinRandomMax ); + PE_ParticleEditor-->PEP_spinRandomMax_textEdit.setText( %data.spinRandomMax ); + + PE_ParticleEditor-->PEP_spinSpeed_slider.setValue( %data.spinSpeed ); + PE_ParticleEditor-->PEP_spinSpeed_textEdit.setText( %data.spinSpeed ); + + PE_ColorTintSwatch0.color = %data.colors[ 0 ]; + PE_ColorTintSwatch1.color = %data.colors[ 1 ]; + PE_ColorTintSwatch2.color = %data.colors[ 2 ]; + PE_ColorTintSwatch3.color = %data.colors[ 3 ]; + + PE_ParticleEditor-->PEP_pointSize_slider0.setValue( %data.sizes[ 0 ] ); + PE_ParticleEditor-->PEP_pointSize_textEdit0.setText( %data.sizes[ 0 ] ); + + PE_ParticleEditor-->PEP_pointSize_slider1.setValue( %data.sizes[ 1 ] ); + PE_ParticleEditor-->PEP_pointSize_textEdit1.setText( %data.sizes[ 1 ] ); + + PE_ParticleEditor-->PEP_pointSize_slider2.setValue( %data.sizes[ 2 ] ); + PE_ParticleEditor-->PEP_pointSize_textEdit2.setText( %data.sizes[ 2 ] ); + + PE_ParticleEditor-->PEP_pointSize_slider3.setValue( %data.sizes[ 3 ] ); + PE_ParticleEditor-->PEP_pointSize_textEdit3.setText( %data.sizes[ 3 ] ); + + PE_ParticleEditor-->PEP_pointTime_slider0.setValue( %data.times[ 0 ] ); + PE_ParticleEditor-->PEP_pointTime_textEdit0.setText( %data.times[ 0 ] ); + + PE_ParticleEditor-->PEP_pointTime_slider1.setValue( %data.times[ 1 ] ); + PE_ParticleEditor-->PEP_pointTime_textEdit1.setText( %data.times[ 1 ] ); + + PE_ParticleEditor-->PEP_pointTime_slider2.setValue( %data.times[ 2 ] ); + PE_ParticleEditor-->PEP_pointTime_textEdit2.setText( %data.times[ 2 ] ); + + PE_ParticleEditor-->PEP_pointTime_slider3.setValue( %data.times[ 3 ] ); + PE_ParticleEditor-->PEP_pointTime_textEdit3.setText( %data.times[ 3 ] ); + + //particle animation + PE_ParticleEditor-->PEP_animateTexture.setValue( %data.animateTexture ); + + PE_ParticleEditor-->PEP_framesPerSec_slider.setValue( %data.framesPerSec ); + PE_ParticleEditor-->PEP_framesPerSec_textEdit.setText( %data.framesPerSec ); + + PE_ParticleEditor-->PEP_animTexFramesList_textEdit.setText( %data.animTexFrames ); + + PE_ParticleEditor-->PEP_animTileCount_textEdit.setText( %data.animTexTiling ); + +} + +//--------------------------------------------------------------------------------------------- + +// Generic updateParticle method +function PE_ParticleEditor::updateParticle(%this, %propertyField, %value, %isSlider, %onMouseUp) +{ + PE_ParticleEditor.setParticleDirty(); + %particle = PE_ParticleEditor.currParticle; + + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) ) + { + %last.field = %propertyField; + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValue = %value; + } + else + { + %action = ParticleEditor.createUndo(ActionUpdateActiveParticle, "Update Active Particle"); + %action.particle = %particle; + %action.field = %propertyField; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + %action.newValue = %value; + %action.oldValue = %particle.getFieldValue( %propertyField ); + + ParticleEditor.submitUndo( %action ); + } + + %particle.setFieldValue( %propertyField, %value ); + %particle.reload(); +} + +//--------------------------------------------------------------------------------------------- + +// Special case updateEmitter methods +function PE_ParticleEditor::updateParticleTexture( %this, %action ) +{ + if( %action ) + { + %texture = MaterialEditorGui.openFile("texture"); + if( %texture !$= "" ) + { + PE_ParticleEditor-->PEP_previewImage.setBitmap(%texture); + PE_ParticleEditor-->PEP_previewImageName.setText(%texture); + PE_ParticleEditor-->PEP_previewImageName.tooltip = %texture; + + PE_ParticleEditor.updateParticle( "textureName", %texture ); + } + } + else + { + PE_ParticleEditor-->PEP_previewImage.setBitmap(""); + PE_ParticleEditor-->PEP_previewImageName.setText(""); + PE_ParticleEditor-->PEP_previewImageName.tooltip = ""; + + PE_ParticleEditor.updateParticle( "textureName", "" ); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::updateLifeFields( %this, %isRandom, %value, %isSlider, %onMouseUp ) +{ + PE_ParticleEditor.setParticleDirty(); + %particle = PE_ParticleEditor.currParticle; + + //Transfer values over to gui controls. + + if( %isRandom ) + { + %value ++; + if( %value > PE_ParticleEditor-->PEP_lifetimeMS_slider.getValue() ) + { + PE_ParticleEditor-->PEP_lifetimeMS_textEdit.setText( %value ); + PE_ParticleEditor-->PEP_lifetimeMS_slider.setValue( %value ); + } + } + else + { + %value --; + if( %value < PE_ParticleEditor-->PEP_lifetimeVarianceMS_slider.getValue() ) + { + PE_ParticleEditor-->PEP_lifetimeVarianceMS_textEdit.setText( %value ); + PE_ParticleEditor-->PEP_lifetimeVarianceMS_slider.setValue( %value ); + } + } + + // Submit undo. + + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) ) + { + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValueLifetimeMS = PE_ParticleEditor-->PEP_lifetimeMS_textEdit.getText(); + %last.newValueLifetimeVarianceMS = PE_ParticleEditor-->PEP_lifetimeVarianceMS_textEdit.getText(); + } + else + { + %action = ParticleEditor.createUndo(ActionUpdateActiveParticleLifeFields, "Update Active Particle"); + %action.particle = %particle; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + + %action.newValueLifetimeMS = PE_ParticleEditor-->PEP_lifetimeMS_textEdit.getText(); + %action.oldValueLifetimeMS = %particle.lifetimeMS; + + %action.newValueLifetimeVarianceMS = PE_ParticleEditor-->PEP_lifetimeVarianceMS_textEdit.getText(); + %action.oldValueLifetimeVarianceMS = %particle.lifetimeVarianceMS; + + ParticleEditor.submitUndo( %action ); + } + + %particle.lifetimeMS = PE_ParticleEditor-->PEP_lifetimeMS_textEdit.getText(); + %particle.lifetimeVarianceMS = PE_ParticleEditor-->PEP_lifetimeVarianceMS_textEdit.getText(); + %particle.reload(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::updateSpinFields( %this, %isMax, %value, %isSlider, %onMouseUp ) +{ + PE_ParticleEditor.setParticleDirty(); + %particle = PE_ParticleEditor.currParticle; + + // Transfer values over to gui controls. + if( %isMax ) + { + %value ++; + if( %value > PE_ParticleEditor-->PEP_spinRandomMax_slider.getValue() ) + { + PE_ParticleEditor-->PEP_spinRandomMax_textEdit.setText( %value ); + PE_ParticleEditor-->PEP_spinRandomMax_slider.setValue( %value ); + } + } + else + { + %value --; + if( %value < PE_ParticleEditor-->PEP_spinRandomMin_slider.getValue() ) + { + PE_ParticleEditor-->PEP_spinRandomMin_textEdit.setText( %value ); + PE_ParticleEditor-->PEP_spinRandomMin_slider.setValue( %value ); + } + } + + // Submit undo. + + %last = Editor.getUndoManager().getUndoAction(Editor.getUndoManager().getUndoCount() - 1); + if( (%isSlider) && (%last.isSlider) && (!%last.onMouseUp) ) + { + %last.isSlider = %isSlider; + %last.onMouseUp = %onMouseUp; + %last.newValueSpinRandomMax = PE_ParticleEditor-->PEP_spinRandomMax_textEdit.getText(); + %last.newValueSpinRandomMin = PE_ParticleEditor-->PEP_spinRandomMin_textEdit.getText(); + } + else + { + %action = ParticleEditor.createUndo(ActionUpdateActiveParticleSpinFields, "Update Active Particle"); + %action.particle = %particle; + %action.isSlider = %isSlider; + %action.onMouseUp = %onMouseUp; + + %action.newValueSpinRandomMax = PE_ParticleEditor-->PEP_spinRandomMax_textEdit.getText(); + %action.oldValueSpinRandomMax = %particle.spinRandomMax; + + %action.newValueSpinRandomMin = PE_ParticleEditor-->PEP_spinRandomMin_textEdit.getText(); + %action.oldValueSpinRandomMin = %particle.spinRandomMin; + + ParticleEditor.submitUndo( %action ); + } + + %particle.spinRandomMax = PE_ParticleEditor-->PEP_spinRandomMax_textEdit.getText(); + %particle.spinRandomMin = PE_ParticleEditor-->PEP_spinRandomMin_textEdit.getText(); + + %particle.reload(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::onNewParticle( %this ) +{ + // Bail if the user selected the same particle. + + %id = PEP_ParticleSelector.getSelected(); + if( %id == PE_ParticleEditor.currParticle ) + return; + + // Load new particle if we're not in a dirty state + if( PE_ParticleEditor.dirty ) + { + MessageBoxYesNoCancel("Save Existing Particle?", + "Do you want to save changes to <br><br>" @ PE_ParticleEditor.currParticle.getName(), + "PE_ParticleEditor.saveParticle(" @ PE_ParticleEditor.currParticle @ ");", + "PE_ParticleEditor.saveParticleDialogDontSave(" @ PE_ParticleEditor.currParticle @ "); PE_ParticleEditor.loadNewParticle();" + ); + } + else + { + PE_ParticleEditor.loadNewParticle(); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::loadNewParticle( %this, %particle ) +{ + if( isObject( %particle ) ) + %particle = %particle.getId(); + else + %particle = PEP_ParticleSelector.getSelected(); + + PE_ParticleEditor.currParticle = %particle; + + %particle.reload(); + + PE_ParticleEditor_NotDirtyParticle.assignFieldsFrom( %particle ); + PE_ParticleEditor_NotDirtyParticle.originalName = %particle.getName(); + + PE_ParticleEditor.guiSync(); + PE_ParticleEditor.setParticleNotDirty(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::setParticleDirty( %this ) +{ + PE_ParticleEditor.text = "Particle *"; + PE_ParticleEditor.dirty = true; + + %particle = PE_ParticleEditor.currParticle; + + if( %particle.getFilename() $= "" || %particle.getFilename() $= "tools/particleEditor/particleParticleEditor.ed.cs" ) + PE_ParticleSaver.setDirty( %particle, $PE_PARTICLEEDITOR_DEFAULT_FILENAME ); + else + PE_ParticleSaver.setDirty( %particle ); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::setParticleNotDirty( %this ) +{ + PE_ParticleEditor.text = "Particle"; + PE_ParticleEditor.dirty = false; + + PE_ParticleSaver.clearAll(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::showNewDialog( %this, %replaceSlot ) +{ + // Open a dialog if the current Particle is dirty + if( PE_ParticleEditor.dirty ) + { + MessageBoxYesNoCancel("Save Particle Changes?", + "Do you wish to save the changes made to the <br>current particle before changing the particle?", + "PE_ParticleEditor.saveParticle( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_ParticleEditor.createParticle( " @ %replaceSlot @ " );", + "PE_ParticleEditor.saveParticleDialogDontSave( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_ParticleEditor.createParticle( " @ %replaceSlot @ " );" + ); + } + else + { + PE_ParticleEditor.createParticle( %replaceSlot ); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::createParticle( %this, %replaceSlot ) +{ + // Make sure we have a spare slot on the current emitter. + + if( !%replaceSlot ) + { + %numExistingParticles = getWordCount( PE_EmitterEditor.currEmitter.particles ); + if( %numExistingParticles > 3 ) + { + MessageBoxOK( "Error", "An emitter cannot have more than 4 particles assigned to it." ); + return; + } + + %particleIndex = %numExistingParticles; + } + else + %particleIndex = %replaceSlot - 1; + + // Create the particle datablock and add to the emitter. + + %newParticle = getUniqueName( "newParticle" ); + + datablock ParticleData( %newParticle : DefaultParticle ) + { + }; + + // Submit undo. + + %action = ParticleEditor.createUndo( ActionCreateNewParticle, "Create New Particle" ); + %action.particle = %newParticle.getId(); + %action.particleIndex = %particleIndex; + %action.prevParticle = ( "PEE_EmitterParticleSelector" @ ( %particleIndex + 1 ) ).getSelected(); + %action.emitter = PE_EmitterEditor.currEmitter; + + ParticleEditor.submitUndo( %action ); + + // Execute action. + + %action.redo(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::showDeleteDialog( %this ) +{ + // Don't allow deleting DefaultParticle. + + if( PE_ParticleEditor.currParticle.getName() $= "DefaultParticle" ) + { + MessageBoxOK( "Error", "Cannot delete DefaultParticle"); + return; + } + + // Check to see if the particle emitter has more than 1 particle on it. + + if( getWordCount( PE_EmitterEditor.currEmitter.particles ) == 1 ) + { + MessageBoxOK( "Error", "At least one particle must remain on the particle emitter."); + return; + } + + // Bring up requester for confirmation. + + if( isObject( PE_ParticleEditor.currParticle ) ) + { + MessageBoxYesNoCancel( "Delete Particle?", + "Are you sure you want to delete<br><br>" @ PE_ParticleEditor.currParticle.getName() @ "<br><br> Particle deletion won't take affect until the engine is quit.", + "PE_ParticleEditor.saveParticleDialogDontSave( " @ PE_ParticleEditor.currParticle.getName() @ " ); PE_ParticleEditor.deleteParticle();", + "", + "" + ); + } +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::deleteParticle( %this ) +{ + %particle = PE_ParticleEditor.currParticle; + + // Submit undo. + + %action = ParticleEditor.createUndo( ActionDeleteParticle, "Delete Particle" ); + %action.particle = %particle; + %action.emitter = PE_EmitterEditor.currEmitter; + + ParticleEditor.submitUndo( %action ); + + // Execute action. + + %action.redo(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::saveParticle( %this, %particle ) +{ + %particle.setName( PEP_ParticleSelector.getText() ); + + PE_ParticleEditor_NotDirtyParticle.assignFieldsFrom( %particle ); + PE_ParticleEditor_NotDirtyParticle.originalName = %particle.getName(); + + PE_ParticleSaver.saveDirty(); + PE_ParticleEditor.setParticleNotDirty(); + + ParticleEditor.createParticleList(); +} + +//--------------------------------------------------------------------------------------------- + +function PE_ParticleEditor::saveParticleDialogDontSave( %this, %particle ) +{ + %particle.setName( PE_ParticleEditor_NotDirtyParticle.originalName ); + %particle.assignFieldsFrom( PE_ParticleEditor_NotDirtyParticle ); + + PE_ParticleEditor.setParticleNotDirty(); +} + +//============================================================================================= +// PE_ColorTintSwatch. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function PE_ColorTintSwatch::updateParticleColor( %this, %color ) +{ + %arrayNum = %this.arrayNum; + + %r = getWord( %color, 0 ); + %g = getWord( %color, 1 ); + %b = getWord( %color, 2 ); + %a = getWord( %color, 3 ); + + %color = %r SPC %g SPC %b SPC %a; + %this.color = %color; + + PE_ParticleEditor.updateParticle( "colors[" @ %arrayNum @ "]", %color ); +} + +//============================================================================================= +// PEP_ParticleSelector_Control. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function PEP_ParticleSelector_Control::onRenameItem( %this ) +{ + Parent::onRenameItem( %this ); + + //FIXME: need to check for validity of name and name clashes + + PE_ParticleEditor.setParticleDirty(); + + // Resort menu. + + %this-->PopupMenu.sort(); +} + +//============================================================================================= +// PEP_NewParticleButton. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function PEP_NewParticleButton::onDefaultClick( %this ) +{ + PE_ParticleEditor.showNewDialog(); +} + +//--------------------------------------------------------------------------------------------- + +function PEP_NewParticleButton::onCtrlClick( %this ) +{ + for( %i = 1; %i < 5; %i ++ ) + { + %popup = "PEE_EmitterParticleSelector" @ %i; + if( %popup.getSelected() == PEP_ParticleSelector.getSelected() ) + { + %replaceSlot = %i; + break; + } + } + + PE_ParticleEditor.showNewDialog( %replaceSlot ); +} diff --git a/Templates/BaseGame/game/tools/physicsTools/main.cs b/Templates/BaseGame/game/tools/physicsTools/main.cs new file mode 100644 index 000000000..8da40844e --- /dev/null +++ b/Templates/BaseGame/game/tools/physicsTools/main.cs @@ -0,0 +1,122 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +function physicsToggleSimulation() +{ + %isEnabled = physicsSimulationEnabled(); + if ( %isEnabled ) + { + physicsStateText.setText( "Simulation is paused." ); + physicsStopSimulation( "client" ); + physicsStopSimulation( "server" ); + } + else + { + physicsStateText.setText( "Simulation is unpaused." ); + physicsStartSimulation( "client" ); + physicsStartSimulation( "server" ); + } +} + +function initializePhysicsTools() +{ + echo( " % - Initializing Physics Tools" ); + + if ( !physicsPluginPresent() ) + { + echo( "No physics plugin exists." ); + return; + } + + globalactionmap.bindCmd( keyboard, "alt t", "physicsToggleSimulation();", "" ); + globalactionmap.bindCmd( keyboard, "alt r", "physicsRestoreState();", "" ); + + new ScriptObject( PhysicsEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = EWorldEditor; + }; +} + +function destroyPhysicsTools() +{ +} + +function PhysicsEditorPlugin::onWorldEditorStartup( %this ) +{ + new PopupMenu( PhysicsToolsMenu ) + { + superClass = "MenuBuilder"; + //class = "PhysXToolsMenu"; + + barTitle = "Physics"; + + item[0] = "Start Simulation" TAB "Ctrl-Alt P" TAB "physicsStartSimulation( \"client\" );physicsStartSimulation( \"server\" );"; + //item[1] = "Stop Simulation" TAB "" TAB "physicsSetTimeScale( 0 );"; + item[1] = "-"; + item[2] = "Speed 25%" TAB "" TAB "physicsSetTimeScale( 0.25 );"; + item[3] = "Speed 50%" TAB "" TAB "physicsSetTimeScale( 0.5 );"; + item[4] = "Speed 100%" TAB "" TAB "physicsSetTimeScale( 1.0 );"; + item[5] = "-"; + item[6] = "Reload NXBs" TAB "" TAB ""; + }; + + // Add our menu. + EditorGui.menuBar.insert( PhysicsToolsMenu, EditorGui.menuBar.dynamicItemInsertPos ); + + // Add ourselves to the window menu. + //EditorGui.addToWindowMenu( "Road and Path Editor", "", "RoadEditor" ); +} + +function PhysicsToolsMenu::onMenuSelect(%this) +{ + %isEnabled = physicsSimulationEnabled(); + + %itemText = !%isEnabled ? "Start Simulation" : "Pause Simulation"; + %itemCommand = !%isEnabled ? "physicsStartSimulation( \"client\" );physicsStartSimulation( \"server\" );" : "physicsStopSimulation( \"client\" );physicsStopSimulation( \"server\" );"; + + %this.setItemName( 0, %itemText ); + %this.setItemCommand( 0, %itemCommand ); +} + +function PhysicsEditorPlugin::onEditorWake( %this ) +{ + // Disable physics when entering + // the editor. Will be re-enabled + // when the editor is closed. + physicsStopSimulation( "client" ); + physicsStopSimulation( "server" ); + physicsRestoreState(); +} + +function PhysicsEditorPlugin::onEditorSleep( %this ) +{ + physicsStoreState(); + + %currentTimeScale = physicsGetTimeScale(); + if ( %currentTimeScale == 0.0 ) + physicsSetTimeScale( 1.0 ); + + physicsStartSimulation( "client" ); + physicsStartSimulation( "server" ); +} diff --git a/Templates/BaseGame/game/tools/resources/.gitignore b/Templates/BaseGame/game/tools/resources/.gitignore new file mode 100644 index 000000000..1bc0e838a --- /dev/null +++ b/Templates/BaseGame/game/tools/resources/.gitignore @@ -0,0 +1 @@ +# Keep directory in git repo diff --git a/Templates/BaseGame/game/tools/riverEditor/RiverEditorGui.gui b/Templates/BaseGame/game/tools/riverEditor/RiverEditorGui.gui new file mode 100644 index 000000000..1a6831489 --- /dev/null +++ b/Templates/BaseGame/game/tools/riverEditor/RiverEditorGui.gui @@ -0,0 +1,412 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiRiverEditorCtrl(RiverEditorGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "RiverEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + DefaultWidth = "10"; + HoverSplineColor = "0 255 0 255"; + SelectedSplineColor = "255 0 255 255"; + HoverNodeColor = "255 255 255 255"; + + new GuiWindowCollapseCtrl(RiverEditorTreeWindow) { + internalName = ""; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 167"; + MinExtent = "210 100"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Rivers"; + + /* + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "LockSelection"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "167 148"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EWorldEditor.lockSelection(true); EditorTree.toggleLock();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "World Editor"; + hovertime = "1000"; + bitmap = "tools/gui/images/lock"; + buttonType = "ToggleButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "DeleteSelection"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "185 148"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EditorMenuEditDelete();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "World Editor"; + hovertime = "1000"; + bitmap = "tools/gui/images/delete"; + buttonType = "PushButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; + + */ + new GuiContainer(){ + profile = "ToolsGuiDefaultProfile"; + Position = "5 25"; + Extent = "200 120"; + Docking = "Client"; + Margin = "3 1 3 3 "; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "200 118"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl(RiverTreeView) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "193 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "0"; + internalNamesOnly = "0"; + }; + }; + }; + }; + new GuiWindowCollapseCtrl(RiverEditorOptionsWindow) { + internalName = "Window"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(RiverEditorTreeWindow.extent, 1) - 2; + Extent = "210 530"; + MinExtent = "210 300"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Properties"; + + new GuiContainer(){ //Node Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 24"; + Extent = "202 85"; + Docking = "Top"; + Margin = "3 3 3 3"; + + new GuiTextCtrl(){ + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "86 18"; + text = "Node Properties"; + }; + + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 21"; + Extent = "46 18"; + text = "Position"; + }; + new GuiTextEditCtrl(){ + internalName = "position"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 21"; + Extent = "141 18"; + text = ""; + AltCommand = "RiverEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 42"; + Extent = "46 18"; + text = "Rotation"; + }; + new GuiTextEditCtrl(){ + internalName = "rotation"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 42"; + Extent = "141 18"; + text = ""; + AltCommand = "RiverEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 63"; + Extent = "46 18"; + text = "Width"; + }; + new GuiTextEditCtrl(){ + internalName = "width"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "57 63"; + Extent = "52 18"; + text = ""; + AltCommand = "RiverEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "110 63"; + Extent = "32 18"; + text = "Depth"; + }; + new GuiTextEditCtrl(){ + internalName = "depth"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "146 63"; + Extent = "52 18"; + text = ""; + AltCommand = "RiverEditorGui.editNodeDetails();"; + }; + }; + new GuiContainer(){ //River Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 112"; + Extent = "202 31"; + Docking = "Top"; + Margin = "0 0 3 3"; + + new GuiTextCtrl(){ + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "121 18"; + text = "River Properties"; + }; + }; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 129"; + Extent = "202 357"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "-14 41 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(RiverInspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + name = "RiverInspector"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "1 1"; + Extent = "178 16"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + }; + }; + new GuiMLTextCtrl(RiverFieldInfoControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "1 485"; + Extent = "202 42"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; + +}; + +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/riverEditor/RiverEditorSettingsTab.gui b/Templates/BaseGame/game/tools/riverEditor/RiverEditorSettingsTab.gui new file mode 100644 index 000000000..553e2d7c6 --- /dev/null +++ b/Templates/BaseGame/game/tools/riverEditor/RiverEditorSettingsTab.gui @@ -0,0 +1,517 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(RiverEditorSettingsTab,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(ERiverEditorSettingsPage) { + fitBook = "1"; + text = "River Editor"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Defaults"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Width:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "RiverEditorPlugin.readSettings();"; + editorSettingsValue = "RiverEditor/DefaultWidth"; + editorSettingsWrite = "RiverEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Depth:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "RiverEditorPlugin.readSettings();"; + editorSettingsValue = "RiverEditor/DefaultDepth"; + editorSettingsWrite = "RiverEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Normal:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "RiverEditorPlugin.readSettings();"; + editorSettingsValue = "RiverEditor/DefaultNormal"; + editorSettingsWrite = "RiverEditorPlugin.writeSettings();"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Colors"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 10"; + Extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "RiverEditorPlugin.readSettings();"; + editorSettingsValue = "RiverEditor/HoverSplineColor"; + editorSettingsWrite = "RiverEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Hover Spline:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "80 0"; + Extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 30"; + Extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "RiverEditorPlugin.readSettings();"; + editorSettingsValue = "RiverEditor/SelectedSplineColor"; + editorSettingsWrite = "RiverEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Sel. Spline:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "80 0"; + Extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/riverEditor/RiverEditorToolbar.gui b/Templates/BaseGame/game/tools/riverEditor/RiverEditorToolbar.gui new file mode 100644 index 000000000..f6e34b7c1 --- /dev/null +++ b/Templates/BaseGame/game/tools/riverEditor/RiverEditorToolbar.gui @@ -0,0 +1,323 @@ +%guiContent = new GuiControl(RiverEditorToolbar, EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorToolbar"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "306 0"; + Extent = "800 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "6 6"; + extent = "100 20"; + minExtent = "8 8"; + visible = "1"; + text = "River Settings"; + maxLength = "255"; + helpTag = "0"; + }; + new GuiDynamicCtrlArrayControl(){ + Position = "83 3"; + extent = "111 32"; + colCount = "31"; + colSize = "29"; + rowCount = "1"; + RowSize = "27"; + rowSpacing = "2"; + colspacing = "4"; + + new GuiBitmapButtonCtrl(RiverEditorShowSplineBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "167 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$River::showSpline"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Spline"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-spline"; + groupNum = "7"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiBitmapButtonCtrl(RiverEditorWireframeBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "253 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$River::showWireframe"; + Command = "$River::showWireframe = $ThisControl.getValue();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Wireframe"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-wireframe"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiBitmapButtonCtrl(RiverEditorShowRoadBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefalutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "89 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$River::showRiver"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show River Texture"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-texture"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + new GuiControl(RiverDefaultWidthTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "197 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 6"; + Extent = "68 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Default Width"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="ToolsGuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "67 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.DefaultWidth = $ThisControl.getValue();"; + hovertime = "1000"; + text = "10"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "101 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(RiverDefaultWidthSliderCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes Default River Width"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/dropslider"; + }; + }; + new GuiControl(RiverDefaultDepthTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "327 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 6"; + Extent = "68 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Default Depth"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="ToolsGuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "67 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.DefaultDepth = $ThisControl.getValue();"; + hovertime = "1000"; + text = "10"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "101 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(RiverDefaultDepthSliderCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes Default River Depth"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/dropslider"; + }; + }; +}; +new GuiMouseEventCtrl(RiverDefaultWidthSliderCtrlContainer, EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(RiverDefaultWidthTextEditContainer.position) + firstWord(RiverEditorToolbar.position) + 10 SPC + (getWord(RiverDefaultWidthTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "RiverDefaultWidthTextEditContainer-->textEdit.setText( mFloatLength($ThisControl.getValue(), 2)); RiverEditorGui.DefaultWidth = $ThisControl.getValue();"; + range = "0 100"; + ticks = "0"; + value = "10"; + }; +}; +new GuiMouseEventCtrl(RiverDefaultDepthSliderCtrlContainer, EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(RiverDefaultDepthTextEditContainer.position) + firstWord(RiverEditorToolbar.position) + 10 SPC + (getWord(RiverDefaultDepthTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "RiverDefaultDepthTextEditContainer-->textEdit.setValue( mFloatLength($ThisControl.getValue(), 2)); RiverEditorGui.DefaultWidth = $ThisControl.getValue();"; + range = "0 100"; + ticks = "0"; + value = "10"; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/riverEditor/main.cs b/Templates/BaseGame/game/tools/riverEditor/main.cs new file mode 100644 index 000000000..eafb3c3c8 --- /dev/null +++ b/Templates/BaseGame/game/tools/riverEditor/main.cs @@ -0,0 +1,230 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function initializeRiverEditor() +{ + echo(" % - Initializing River Editor"); + + exec( "./riverEditor.cs" ); + exec( "./RiverEditorGui.gui" ); + exec( "./RiverEditorToolbar.gui" ); + exec( "./riverEditorGui.cs" ); + + // Add ourselves to EditorGui, where all the other tools reside + RiverEditorGui.setVisible( false ); + RiverEditorToolbar.setVisible(false); + RiverEditorOptionsWindow.setVisible( false ); + RiverEditorTreeWindow.setVisible( false ); + + EditorGui.add( RiverEditorGui ); + EditorGui.add( RiverEditorToolbar ); + EditorGui.add( RiverEditorOptionsWindow ); + EditorGui.add( RiverEditorTreeWindow ); + + new ScriptObject( RiverEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = RiverEditorGui; + }; + + %map = new ActionMap(); + %map.bindCmd( keyboard, "backspace", "RiverEditorGui.deleteNode();", "" ); + %map.bindCmd( keyboard, "1", "RiverEditorGui.prepSelectionMode();", "" ); + %map.bindCmd( keyboard, "2", "ToolsPaletteArray->RiverEditorMoveMode.performClick();", "" ); + %map.bindCmd( keyboard, "3", "ToolsPaletteArray->RiverEditorRotateMode.performClick();", "" ); + %map.bindCmd( keyboard, "4", "ToolsPaletteArray->RiverEditorScaleMode.performClick();", "" ); + %map.bindCmd( keyboard, "5", "ToolsPaletteArray->RiverEditorAddRiverMode.performClick();", "" ); + %map.bindCmd( keyboard, "=", "ToolsPaletteArray->RiverEditorInsertPointMode.performClick();", "" ); + %map.bindCmd( keyboard, "numpadadd", "ToolsPaletteArray->RiverEditorInsertPointMode.performClick();", "" ); + %map.bindCmd( keyboard, "-", "ToolsPaletteArray->RiverEditorRemovePointMode.performClick();", "" ); + %map.bindCmd( keyboard, "numpadminus", "ToolsPaletteArray->RiverEditorRemovePointMode.performClick();", "" ); + %map.bindCmd( keyboard, "z", "RiverEditorShowSplineBtn.performClick();", "" ); + %map.bindCmd( keyboard, "x", "RiverEditorWireframeBtn.performClick();", "" ); + %map.bindCmd( keyboard, "v", "RiverEditorShowRoadBtn.performClick();", "" ); + RiverEditorPlugin.map = %map; + + RiverEditorPlugin.initSettings(); +} + +function destroyRiverEditor() +{ +} + +function RiverEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "River Editor", "", RiverEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "River Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "RiverEditorPlugin", "RiverEditorPalette", expandFilename("tools/worldEditor/images/toolbar/river-editor"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( RiverEditorOptionsWindow, RiverEditorTreeWindow); + + // Add ourselves to the Editor Settings window + exec( "./RiverEditorSettingsTab.gui" ); + ESettingsWindow.addTabPage( ERiverEditorSettingsPage ); +} + +function RiverEditorPlugin::onActivated( %this ) +{ + %this.readSettings(); + + $River::EditorOpen = true; + + ToolsPaletteArray->RiverEditorAddRiverMode.performClick(); + EditorGui.bringToFront( RiverEditorGui ); + + RiverEditorGui.setVisible(true); + RiverEditorGui.makeFirstResponder( true ); + RiverEditorToolbar.setVisible(true); + + RiverEditorOptionsWindow.setVisible( true ); + RiverEditorTreeWindow.setVisible( true ); + + RiverTreeView.open(ServerRiverSet,true); + %this.map.push(); + + // Store this on a dynamic field + // in order to restore whatever setting + // the user had before. + %this.prevGizmoAlignment = GlobalGizmoProfile.alignment; + + // The DecalEditor always uses Object alignment. + GlobalGizmoProfile.alignment = "Object"; + + // Set the status bar here until all tool have been hooked up + EditorGuiStatusBar.setInfo("River editor."); + EditorGuiStatusBar.setSelection(""); + + // Allow the Gui to setup. + RiverEditorGui.onEditorActivated(); + + Parent::onActivated(%this); +} + +function RiverEditorPlugin::onDeactivated( %this ) +{ + %this.writeSettings(); + + $River::EditorOpen = false; + + RiverEditorGui.setVisible(false); + RiverEditorToolbar.setVisible(false); + RiverEditorOptionsWindow.setVisible( false ); + RiverEditorTreeWindow.setVisible( false ); + %this.map.pop(); + + // Restore the previous Gizmo + // alignment settings. + GlobalGizmoProfile.alignment = %this.prevGizmoAlignment; + + // Allow the Gui to cleanup. + RiverEditorGui.onEditorDeactivated(); + + Parent::onDeactivated(%this); +} + +function RiverEditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %hasSelection = false; + + if( isObject( RiverEditorGui.river ) ) + %hasSelection = true; + + %editMenu.enableItem( 3, false ); // Cut + %editMenu.enableItem( 4, false ); // Copy + %editMenu.enableItem( 5, false ); // Paste + %editMenu.enableItem( 6, %hasSelection ); // Delete + %editMenu.enableItem( 8, false ); // Deselect +} + +function RiverEditorPlugin::handleDelete( %this ) +{ + RiverEditorGui.deleteNode(); +} + +function RiverEditorPlugin::handleEscape( %this ) +{ + return RiverEditorGui.onEscapePressed(); +} + +function RiverEditorPlugin::isDirty( %this ) +{ + return RiverEditorGui.isDirty; +} + +function RiverEditorPlugin::onSaveMission( %this, %missionFile ) +{ + if( RiverEditorGui.isDirty ) + { + MissionGroup.save( %missionFile ); + RiverEditorGui.isDirty = false; + } +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +function RiverEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup( "RiverEditor", true ); + + EditorSettings.setDefaultValue( "DefaultWidth", "10" ); + EditorSettings.setDefaultValue( "DefaultDepth", "5" ); + EditorSettings.setDefaultValue( "DefaultNormal", "0 0 1" ); + EditorSettings.setDefaultValue( "HoverSplineColor", "255 0 0 255" ); + EditorSettings.setDefaultValue( "SelectedSplineColor", "0 255 0 255" ); + EditorSettings.setDefaultValue( "HoverNodeColor", "255 255 255 255" ); //<-- Not currently used + + EditorSettings.endGroup(); +} + +function RiverEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup( "RiverEditor", true ); + + RiverEditorGui.DefaultWidth = EditorSettings.value("DefaultWidth"); + RiverEditorGui.DefaultDepth = EditorSettings.value("DefaultDepth"); + RiverEditorGui.DefaultNormal = EditorSettings.value("DefaultNormal"); + RiverEditorGui.HoverSplineColor = EditorSettings.value("HoverSplineColor"); + RiverEditorGui.SelectedSplineColor = EditorSettings.value("SelectedSplineColor"); + RiverEditorGui.HoverNodeColor = EditorSettings.value("HoverNodeColor"); + + EditorSettings.endGroup(); +} + +function RiverEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "RiverEditor", true ); + + EditorSettings.setValue( "DefaultWidth", RiverEditorGui.DefaultWidth ); + EditorSettings.setValue( "DefaultDepth", RiverEditorGui.DefaultDepth ); + EditorSettings.setValue( "DefaultNormal", RiverEditorGui.DefaultNormal ); + EditorSettings.setValue( "HoverSplineColor", RiverEditorGui.HoverSplineColor ); + EditorSettings.setValue( "SelectedSplineColor", RiverEditorGui.SelectedSplineColor ); + EditorSettings.setValue( "HoverNodeColor", RiverEditorGui.HoverNodeColor ); + + EditorSettings.endGroup(); +} diff --git a/Templates/BaseGame/game/tools/riverEditor/riverEditor.cs b/Templates/BaseGame/game/tools/riverEditor/riverEditor.cs new file mode 100644 index 000000000..83da8b85c --- /dev/null +++ b/Templates/BaseGame/game/tools/riverEditor/riverEditor.cs @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( RiverEditorProfile ) +{ + canKeyFocus = true; + opaque = true; + fillColor = "192 192 192 192"; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiSimpleBorderProfile) +{ + opaque = false; + border = 1; + category = "Editor"; +}; + \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/riverEditor/riverEditorGui.cs b/Templates/BaseGame/game/tools/riverEditor/riverEditorGui.cs new file mode 100644 index 000000000..af88e1c1f --- /dev/null +++ b/Templates/BaseGame/game/tools/riverEditor/riverEditorGui.cs @@ -0,0 +1,261 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +$River::EditorOpen = false; +$River::wireframe = true; +$River::showSpline = true; +$River::showRiver = true; +$River::showWalls = true; + +function RiverEditorGui::onEditorActivated( %this ) +{ + %count = EWorldEditor.getSelectionSize(); + for ( %i = 0; %i < %count; %i++ ) + { + %obj = EWorldEditor.getSelectedObject(%i); + if ( %obj.getClassName() !$= "River" ) + EWorldEditor.unselectObject( %obj ); + else + %this.setSelectedRiver( %obj ); + } + + %this.onRiverSelected( %this.getSelectedRiver() ); + %this.onNodeSelected(-1); +} + +function RiverEditorGui::onEditorDeactivated( %this ) +{ +} + +function RiverEditorGui::createRiver( %this ) +{ + %river = new River() + { + rippleDir[0] = "0.000000 1.000000"; + rippleDir[1] = "0.707000 0.707000"; + rippleDir[2] = "0.500000 0.860000"; + + rippleSpeed[0] = "-0.065"; + rippleSpeed[1] = "0.09"; + rippleSpeed[2] = "0.04"; + + rippleTexScale[0] = "7.140000 7.140000"; + rippleTexScale[1] = "6.250000 12.500000"; + rippleTexScale[2] = "50.000000 50.000000"; + + waveDir[0] = "0.000000 1.000000"; + waveDir[1] = "0.707000 0.707000"; + waveDir[2] = "0.500000 0.860000"; + + waveSpeed[0] = "1"; + waveSpeed[1] = "1"; + waveSpeed[2] = "1"; + + waveMagnitude[0] = "0.2"; + waveMagnitude[1] = "0.2"; + waveMagnitude[2] = "0.2"; + + baseColor = "45 108 171 255"; + + rippleTex = "art/water/ripple.dds"; + foamTex = "art/water/foam"; + depthGradientTex = "art/water/depthcolor_ramp"; + }; + + return %river; +} + +function RiverEditorGui::paletteSync( %this, %mode ) +{ + %evalShortcut = "ToolsPaletteArray-->" @ %mode @ ".setStateOn(1);"; + eval(%evalShortcut); +} + +function RiverEditorGui::onEscapePressed( %this ) +{ + if( %this.getMode() $= "RiverEditorAddNodeMode" ) + { + %this.prepSelectionMode(); + return true; + } + return false; +} + +function RiverEditorGui::onRiverSelected( %this, %river ) +{ + %this.river = %river; + RiverInspector.inspect( %river ); + RiverTreeView.buildVisibleTree(true); + if( RiverTreeView.getSelectedObject() != %river ) + { + RiverTreeView.clearSelection(); + %treeId = RiverTreeView.findItemByObjectId( %river ); + RiverTreeView.selectItem( %treeId ); + } +} + +function RiverEditorGui::onNodeSelected( %this, %nodeIdx ) +{ + if ( %nodeIdx == -1 ) + { + RiverEditorOptionsWindow-->position.setActive( false ); + RiverEditorOptionsWindow-->position.setValue( "" ); + + RiverEditorOptionsWindow-->rotation.setActive( false ); + RiverEditorOptionsWindow-->rotation.setValue( "" ); + + RiverEditorOptionsWindow-->width.setActive( false ); + RiverEditorOptionsWindow-->width.setValue( "" ); + + RiverEditorOptionsWindow-->depth.setActive( false ); + RiverEditorOptionsWindow-->depth.setValue( "" ); + } + else + { + RiverEditorOptionsWindow-->position.setActive( true ); + RiverEditorOptionsWindow-->position.setValue( %this.getNodePosition() ); + + RiverEditorOptionsWindow-->rotation.setActive( true ); + RiverEditorOptionsWindow-->rotation.setValue( %this.getNodeNormal() ); + + RiverEditorOptionsWindow-->width.setActive( true ); + RiverEditorOptionsWindow-->width.setValue( %this.getNodeWidth() ); + + RiverEditorOptionsWindow-->depth.setActive( true ); + RiverEditorOptionsWindow-->depth.setValue( %this.getNodeDepth() ); + } +} + +function RiverEditorGui::onNodeModified( %this, %nodeIdx ) +{ + RiverEditorOptionsWindow-->position.setValue( %this.getNodePosition() ); + RiverEditorOptionsWindow-->rotation.setValue( %this.getNodeNormal() ); + RiverEditorOptionsWindow-->width.setValue( %this.getNodeWidth() ); + RiverEditorOptionsWindow-->depth.setValue( %this.getNodeDepth() ); +} + +function RiverEditorGui::editNodeDetails( %this ) +{ + + %this.setNodePosition( RiverEditorOptionsWindow-->position.getText() ); + %this.setNodeNormal( RiverEditorOptionsWindow-->rotation.getText() ); + %this.setNodeWidth( RiverEditorOptionsWindow-->width.getText() ); + %this.setNodeDepth( RiverEditorOptionsWindow-->depth.getText() ); +} + +function RiverInspector::inspect( %this, %obj ) +{ + %name = ""; + if ( isObject( %obj ) ) + %name = %obj.getName(); + else + RiverFieldInfoControl.setText( "" ); + + //RiverInspectorNameEdit.setValue( %name ); + Parent::inspect( %this, %obj ); +} + +function RiverInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + // Same work to do as for the regular WorldEditor Inspector. + Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ); +} + +function RiverInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + RiverFieldInfoControl.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} + +function RiverTreeView::onInspect(%this, %obj) +{ + RiverInspector.inspect(%obj); +} + +function RiverTreeView::onSelect(%this, %obj) +{ + RiverEditorGui.road = %obj; + RiverInspector.inspect( %obj ); + if(%obj != RiverEditorGui.getSelectedRiver()) + { + RiverEditorGui.setSelectedRiver( %obj ); + } +} + +function RiverEditorGui::prepSelectionMode( %this ) +{ + %mode = %this.getMode(); + + if ( %mode $= "RiverEditorAddNodeMode" ) + { + if ( isObject( %this.getSelectedRiver() ) ) + %this.deleteNode(); + } + + %this.setMode( "RiverEditorSelectMode" ); + ToolsPaletteArray-->RiverEditorSelectMode.setStateOn(1); +} + +//------------------------------------------------------------------------------ +function ERiverEditorSelectModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERiverEditorAddModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERiverEditorMoveModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERiverEditorRotateModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERiverEditorScaleModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERiverEditorInsertModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERiverEditorRemoveModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function RiverDefaultWidthSliderCtrlContainer::onWake(%this) +{ + RiverDefaultWidthSliderCtrlContainer-->slider.setValue(RiverDefaultWidthTextEditContainer-->textEdit.getText()); +} + +function RiverDefaultDepthSliderCtrlContainer::onWake(%this) +{ + RiverDefaultDepthSliderCtrlContainer-->slider.setValue(RiverDefaultDepthTextEditContainer-->textEdit.getText()); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/roadEditor/RoadEditorGui.gui b/Templates/BaseGame/game/tools/roadEditor/RoadEditorGui.gui new file mode 100644 index 000000000..7f9eba0f6 --- /dev/null +++ b/Templates/BaseGame/game/tools/roadEditor/RoadEditorGui.gui @@ -0,0 +1,386 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiRoadEditorCtrl(RoadEditorGui) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "RoadEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + DefaultWidth = "10"; + HoverSplineColor = "0 255 0 255"; + SelectedSplineColor = "255 0 255 255"; + HoverNodeColor = "255 255 255 255"; + + new GuiWindowCollapseCtrl(RoadEditorTreeWindow) { + internalName = ""; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 167"; + MinExtent = "210 100"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Roads & Paths"; + + /* + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "LockSelection"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "167 148"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EWorldEditor.lockSelection(true); EditorTree.toggleLock();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "World Editor"; + hovertime = "1000"; + bitmap = "tools/gui/images/lock"; + buttonType = "ToggleButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "DeleteSelection"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "185 148"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EditorMenuEditDelete();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "World Editor"; + hovertime = "1000"; + bitmap = "tools/gui/images/delete"; + buttonType = "PushButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; + */ + new GuiContainer(){ + profile = "ToolsGuiDefaultProfile"; + Position = "5 25"; + Extent = "200 120"; + Docking = "Client"; + Margin = "3 1 3 3 "; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "200 118"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl(RoadTreeView) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "193 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "0"; + internalNamesOnly = "0"; + }; + }; + }; + }; + new GuiWindowCollapseCtrl(RoadEditorOptionsWindow) { + internalName = "Window"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 SPC + getWord(EditorGuiToolbar.extent, 1) + getWord(RoadEditorTreeWindow.extent, 1) - 2; + Extent = "210 530"; + MinExtent = "210 298"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Properties"; + + new GuiContainer(RoadEditorProperties){ //Node Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 24"; + Extent = "202 64"; + Docking = "Top"; + Margin = "3 3 3 3"; + + new GuiTextCtrl(){ + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "86 18"; + text = "Node Properties"; + }; + + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 21"; + Extent = "46 18"; + text = "Position"; + }; + new GuiTextEditCtrl(){ + internalName = "position"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 21"; + Extent = "141 18"; + text = ""; + AltCommand = "RoadEditorGui.editNodeDetails();"; + }; + new GuiTextCtrl(){ + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 42"; + Extent = "46 18"; + text = "Width"; + }; + new GuiTextEditCtrl(){ + internalName = "width"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "57 42"; + Extent = "141 18"; + text = ""; + AltCommand = "RoadEditorGui.editNodeDetails();"; + }; + }; + new GuiContainer(){ //Decal Road Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 91"; + Extent = "202 31"; + Docking = "Top"; + Margin = "0 0 3 3"; + + new GuiTextCtrl(){ + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "121 18"; + text = "Decal Road Properties"; + }; + }; + + new GuiContainer(){ + profile = ToolsGuiDefaultProfile; + Position = "4 108"; + Extent = "202 377"; + HorizSizing = "width"; + VertSizing = "height"; + isContainer = "1"; + Docking = "Client"; + Margin = "-14 41 3 3"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 377"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(RoadInspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "200 196"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + groupFilters = "+SimBase,+DecalRoad"; + }; + }; + }; + new GuiMLTextCtrl(RoadFieldInfoControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "1 485"; + Extent = "202 42"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; + +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/roadEditor/RoadEditorSettingsTab.gui b/Templates/BaseGame/game/tools/roadEditor/RoadEditorSettingsTab.gui new file mode 100644 index 000000000..b37485cda --- /dev/null +++ b/Templates/BaseGame/game/tools/roadEditor/RoadEditorSettingsTab.gui @@ -0,0 +1,457 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(RoadEditorSettingsTab,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(ERoadEditorSettingsPage) { + fitBook = "1"; + text = "Road Editor"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Defaults"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Width:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "RoadEditorPlugin.readSettings();"; + editorSettingsValue = "RoadEditor/DefaultWidth"; + editorSettingsWrite = "RoadEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Material:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "RoadEditorPlugin.readSettings();"; + editorSettingsValue = "RoadEditor/MaterialName"; + editorSettingsWrite = "RoadEditorPlugin.writeSettings();"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Colors"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 10"; + Extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "RoadEditorPlugin.readSettings();"; + editorSettingsValue = "RoadEditor/HoverSplineColor"; + editorSettingsWrite = "RoadEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Hover Spline:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "80 0"; + Extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 30"; + Extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "RoadEditorPlugin.readSettings();"; + editorSettingsValue = "RoadEditor/SelectedSplineColor"; + editorSettingsWrite = "RoadEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Sel. Spline:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "80 0"; + Extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/roadEditor/RoadEditorToolbar.gui b/Templates/BaseGame/game/tools/roadEditor/RoadEditorToolbar.gui new file mode 100644 index 000000000..01171bf0b --- /dev/null +++ b/Templates/BaseGame/game/tools/roadEditor/RoadEditorToolbar.gui @@ -0,0 +1,273 @@ +%guiContent = new GuiControl(RoadEditorToolbar) { + canSaveDynamicFields = "0"; + internalName = "RoadEditorToolbar"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "306 0"; + Extent = "800 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "6 6"; + extent = "70 20"; + minExtent = "8 8"; + visible = "1"; + text = "Road Settings"; + maxLength = "255"; + helpTag = "0"; + }; + new GuiDynamicCtrlArrayControl(){ + Position = "83 3"; + extent = "111 32"; + colCount = "31"; + colSize = "29"; + rowCount = "1"; + RowSize = "27"; + rowSpacing = "2"; + colspacing = "4"; + + new GuiBitmapButtonCtrl(RoadEditorShowSplineBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "167 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$DecalRoad::showSpline"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Spline"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-spline"; + groupNum = "7"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiBitmapButtonCtrl(RoadEditorWireframeBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "253 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$DecalRoad::wireframe"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Wireframe"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-wireframe"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiBitmapButtonCtrl(RoadEditorShowRoadBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiDefalutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "89 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Variable = "$DecalRoad::showRoad"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + toolTip = "Show Road Texture"; + bitmap = "tools/worldEditor/images/road-river/menubar/show-texture"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + new GuiControl(RoadDefaultWidthTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "197 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 6"; + Extent = "68 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Default Width"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="ToolsGuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "67 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "RoadEditorGui.DefaultWidth = $ThisControl.getValue();"; + hovertime = "1000"; + text = "10"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "101 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(RoadDefaultWidthSliderCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes Default Road Width"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/dropslider"; + }; + }; + /*new GuiTextEditSliderCtrl(RoadEditorDefaultWidthSlider) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "429 6"; + Extent = "46 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "RoadEditorGui.DefaultWidth = $ThisControl.getValue();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "10.0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + format = "%2.1f"; + range = "0 100"; + increment = "0.5"; + focusOnMouseWheel = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "347 7"; + Extent = "66 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + text = "Default Width"; + maxLength = "1024"; + };*/ +}; +new GuiMouseEventCtrl(RoadDefaultWidthSliderCtrlContainer, EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(RoadDefaultWidthTextEditContainer.position) + firstWord(RoadEditorToolbar.position) + 10 SPC + (getWord(RoadDefaultWidthTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "RoadDefaultWidthTextEditContainer-->textEdit.setText( mFloatLength($ThisControl.getValue(), 2)); RoadEditorGui.DefaultWidth = $ThisControl.getValue();"; + range = "0 100"; + ticks = "0"; + value = "10"; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/roadEditor/main.cs b/Templates/BaseGame/game/tools/roadEditor/main.cs new file mode 100644 index 000000000..f45823670 --- /dev/null +++ b/Templates/BaseGame/game/tools/roadEditor/main.cs @@ -0,0 +1,215 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function initializeRoadEditor() +{ + echo( " - Initializing Road and Path Editor" ); + + exec( "./roadEditor.cs" ); + exec( "./RoadEditorGui.gui" ); + exec( "./RoadEditorToolbar.gui"); + exec( "./roadEditorGui.cs" ); + + // Add ourselves to EditorGui, where all the other tools reside + RoadEditorGui.setVisible( false ); + RoadEditorToolbar.setVisible( false ); + RoadEditorOptionsWindow.setVisible( false ); + RoadEditorTreeWindow.setVisible( false ); + + EditorGui.add( RoadEditorGui ); + EditorGui.add( RoadEditorToolbar ); + EditorGui.add( RoadEditorOptionsWindow ); + EditorGui.add( RoadEditorTreeWindow ); + + new ScriptObject( RoadEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = RoadEditorGui; + }; + + %map = new ActionMap(); + %map.bindCmd( keyboard, "backspace", "RoadEditorGui.onDeleteKey();", "" ); + %map.bindCmd( keyboard, "1", "RoadEditorGui.prepSelectionMode();", "" ); + %map.bindCmd( keyboard, "2", "ToolsPaletteArray->RoadEditorMoveMode.performClick();", "" ); + %map.bindCmd( keyboard, "4", "ToolsPaletteArray->RoadEditorScaleMode.performClick();", "" ); + %map.bindCmd( keyboard, "5", "ToolsPaletteArray->RoadEditorAddRoadMode.performClick();", "" ); + %map.bindCmd( keyboard, "=", "ToolsPaletteArray->RoadEditorInsertPointMode.performClick();", "" ); + %map.bindCmd( keyboard, "numpadadd", "ToolsPaletteArray->RoadEditorInsertPointMode.performClick();", "" ); + %map.bindCmd( keyboard, "-", "ToolsPaletteArray->RoadEditorRemovePointMode.performClick();", "" ); + %map.bindCmd( keyboard, "numpadminus", "ToolsPaletteArray->RoadEditorRemovePointMode.performClick();", "" ); + %map.bindCmd( keyboard, "z", "RoadEditorShowSplineBtn.performClick();", "" ); + %map.bindCmd( keyboard, "x", "RoadEditorWireframeBtn.performClick();", "" ); + %map.bindCmd( keyboard, "v", "RoadEditorShowRoadBtn.performClick();", "" ); + RoadEditorPlugin.map = %map; + + RoadEditorPlugin.initSettings(); +} + +function destroyRoadEditor() +{ +} + +function RoadEditorPlugin::onWorldEditorStartup( %this ) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Road and Path Editor", "", RoadEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Road Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "RoadEditorPlugin", "RoadEditorPalette", expandFilename("tools/worldEditor/images/toolbar/road-path-editor"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( RoadEditorOptionsWindow, RoadEditorTreeWindow); + + // Add ourselves to the Editor Settings window + exec( "./RoadEditorSettingsTab.gui" ); + ESettingsWindow.addTabPage( ERoadEditorSettingsPage ); +} + +function RoadEditorPlugin::onActivated( %this ) +{ + %this.readSettings(); + + ToolsPaletteArray->RoadEditorAddRoadMode.performClick(); + EditorGui.bringToFront( RoadEditorGui ); + + RoadEditorGui.setVisible( true ); + RoadEditorGui.makeFirstResponder( true ); + RoadEditorToolbar.setVisible( true ); + + RoadEditorOptionsWindow.setVisible( true ); + RoadEditorTreeWindow.setVisible( true ); + + RoadTreeView.open(ServerDecalRoadSet,true); + + %this.map.push(); + + // Set the status bar here until all tool have been hooked up + EditorGuiStatusBar.setInfo("Road editor."); + EditorGuiStatusBar.setSelection(""); + + Parent::onActivated(%this); +} + +function RoadEditorPlugin::onDeactivated( %this ) +{ + %this.writeSettings(); + + RoadEditorGui.setVisible( false ); + RoadEditorToolbar.setVisible( false ); + RoadEditorOptionsWindow.setVisible( false ); + RoadEditorTreeWindow.setVisible( false ); + %this.map.pop(); + + Parent::onDeactivated(%this); +} + +function RoadEditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %hasSelection = false; + + if( isObject( RoadEditorGui.road ) ) + %hasSelection = true; + + %editMenu.enableItem( 3, false ); // Cut + %editMenu.enableItem( 4, false ); // Copy + %editMenu.enableItem( 5, false ); // Paste + %editMenu.enableItem( 6, %hasSelection ); // Delete + %editMenu.enableItem( 8, false ); // Deselect +} + +function RoadEditorPlugin::handleDelete( %this ) +{ + RoadEditorGui.onDeleteKey(); +} + +function RoadEditorPlugin::handleEscape( %this ) +{ + return RoadEditorGui.onEscapePressed(); +} + +function RoadEditorPlugin::isDirty( %this ) +{ + return RoadEditorGui.isDirty; +} + +function RoadEditorPlugin::onSaveMission( %this, %missionFile ) +{ + if( RoadEditorGui.isDirty ) + { + MissionGroup.save( %missionFile ); + RoadEditorGui.isDirty = false; + } +} + +function RoadEditorPlugin::setEditorFunction( %this ) +{ + %terrainExists = parseMissionGroup( "TerrainBlock" ); + + if( %terrainExists == false ) + MessageBoxYesNoCancel("No Terrain","Would you like to create a New Terrain?", "Canvas.pushDialog(CreateNewTerrainGui);"); + + return %terrainExists; +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +function RoadEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup( "RoadEditor", true ); + + EditorSettings.setDefaultValue( "DefaultWidth", "10" ); + EditorSettings.setDefaultValue( "HoverSplineColor", "255 0 0 255" ); + EditorSettings.setDefaultValue( "SelectedSplineColor", "0 255 0 255" ); + EditorSettings.setDefaultValue( "HoverNodeColor", "255 255 255 255" ); //<-- Not currently used + EditorSettings.setDefaultValue( "MaterialName", "DefaultDecalRoadMaterial" ); + + EditorSettings.endGroup(); +} + +function RoadEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup( "RoadEditor", true ); + + RoadEditorGui.DefaultWidth = EditorSettings.value("DefaultWidth"); + RoadEditorGui.HoverSplineColor = EditorSettings.value("HoverSplineColor"); + RoadEditorGui.SelectedSplineColor = EditorSettings.value("SelectedSplineColor"); + RoadEditorGui.HoverNodeColor = EditorSettings.value("HoverNodeColor"); + RoadEditorGui.materialName = EditorSettings.value("MaterialName"); + + EditorSettings.endGroup(); +} + +function RoadEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "RoadEditor", true ); + + EditorSettings.setValue( "DefaultWidth", RoadEditorGui.DefaultWidth ); + EditorSettings.setValue( "HoverSplineColor", RoadEditorGui.HoverSplineColor ); + EditorSettings.setValue( "SelectedSplineColor", RoadEditorGui.SelectedSplineColor ); + EditorSettings.setValue( "HoverNodeColor", RoadEditorGui.HoverNodeColor ); + EditorSettings.setValue( "MaterialName", RoadEditorGui.materialName ); + + EditorSettings.endGroup(); +} diff --git a/Templates/BaseGame/game/tools/roadEditor/roadEditor.cs b/Templates/BaseGame/game/tools/roadEditor/roadEditor.cs new file mode 100644 index 000000000..0822050b0 --- /dev/null +++ b/Templates/BaseGame/game/tools/roadEditor/roadEditor.cs @@ -0,0 +1,76 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton GuiControlProfile( RoadEditorProfile ) +{ + canKeyFocus = true; + opaque = true; + fillColor = "192 192 192 192"; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiSimpleBorderProfile) +{ + opaque = false; + border = 1; + category = "Editor"; +}; + +singleton GuiCursor(RoadEditorMoveCursor) +{ + hotSpot = "4 4"; + renderOffset = "0 0"; + bitmapName = "~/gui/images/macCursor"; + category = "Editor"; +}; + +singleton GuiCursor( RoadEditorMoveNodeCursor ) +{ + hotSpot = "1 1"; + renderOffset = "0 0"; + bitmapName = "./Cursors/outline/drag_node_outline"; + category = "Editor"; +}; + +singleton GuiCursor( RoadEditorAddNodeCursor ) +{ + hotSpot = "1 1"; + renderOffset = "0 0"; + bitmapName = "./Cursors/outline/add_to_end_outline"; + category = "Editor"; +}; + +singleton GuiCursor( RoadEditorInsertNodeCursor ) +{ + hotSpot = "1 1"; + renderOffset = "0 0"; + bitmapName = "./Cursors/outline/insert_in_middle_outline"; + category = "Editor"; +}; + +singleton GuiCursor( RoadEditorResizeNodeCursor ) +{ + hotSpot = "1 1"; + renderOffset = "0 0"; + bitmapName = "./Cursors/outline/widen_path_outline"; + category = "Editor"; +}; diff --git a/Templates/BaseGame/game/tools/roadEditor/roadEditorGui.cs b/Templates/BaseGame/game/tools/roadEditor/roadEditorGui.cs new file mode 100644 index 000000000..5c6a29b40 --- /dev/null +++ b/Templates/BaseGame/game/tools/roadEditor/roadEditorGui.cs @@ -0,0 +1,249 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function RoadEditorGui::onWake( %this ) +{ + $DecalRoad::EditorOpen = true; + + %count = EWorldEditor.getSelectionSize(); + for ( %i = 0; %i < %count; %i++ ) + { + %obj = EWorldEditor.getSelectedObject(%i); + if ( %obj.getClassName() !$= "DecalRoad" ) + EWorldEditor.unselectObject(); + else + %this.setSelectedRoad( %obj ); + } + + %this.onNodeSelected(-1); +} + +function RoadEditorGui::onSleep( %this ) +{ + $DecalRoad::EditorOpen = false; +} + +function RoadEditorGui::paletteSync( %this, %mode ) +{ + %evalShortcut = "ToolsPaletteArray-->" @ %mode @ ".setStateOn(1);"; + eval(%evalShortcut); +} + +function RoadEditorGui::onDeleteKey( %this ) +{ + %road = %this.getSelectedRoad(); + %node = %this.getSelectedNode(); + + if ( !isObject( %road ) ) + return; + + if ( %node != -1 ) + { + %this.deleteNode(); + } + else + { + MessageBoxOKCancel( "Notice", "Delete selected DecalRoad?", "RoadEditorGui.deleteRoad();", "" ); + } +} + +function RoadEditorGui::onEscapePressed( %this ) +{ + if( %this.getMode() $= "RoadEditorAddNodeMode" ) + { + %this.prepSelectionMode(); + return true; + } + return false; +} + +//just in case we need it later +function RoadEditorGui::onRoadCreation( %this ) +{ +} + +function RoadEditorGui::onRoadSelected( %this, %road ) +{ + %this.road = %road; + + // Update the materialEditorList + if(isObject( %road )) + $Tools::materialEditorList = %road.getId(); + + RoadInspector.inspect( %road ); + RoadTreeView.buildVisibleTree(true); + if( RoadTreeView.getSelectedObject() != %road ) + { + RoadTreeView.clearSelection(); + %treeId = RoadTreeView.findItemByObjectId( %road ); + RoadTreeView.selectItem( %treeId ); + } +} + +function RoadEditorGui::onNodeSelected( %this, %nodeIdx ) +{ + + if ( %nodeIdx == -1 ) + { + RoadEditorProperties-->position.setActive( false ); + RoadEditorProperties-->position.setValue( "" ); + + RoadEditorProperties-->width.setActive( false ); + RoadEditorProperties-->width.setValue( "" ); + } + else + { + RoadEditorProperties-->position.setActive( true ); + RoadEditorProperties-->position.setValue( %this.getNodePosition() ); + + RoadEditorProperties-->width.setActive( true ); + RoadEditorProperties-->width.setValue( %this.getNodeWidth() ); + } + +} + +function RoadEditorGui::onNodeModified( %this, %nodeIdx ) +{ + + RoadEditorProperties-->position.setValue( %this.getNodePosition() ); + RoadEditorProperties-->width.setValue( %this.getNodeWidth() ); + +} + +function RoadEditorGui::editNodeDetails( %this ) +{ + + %this.setNodePosition( RoadEditorProperties-->position.getText() ); + %this.setNodeWidth( RoadEditorProperties-->width.getText() ); +} + +function RoadEditorGui::onBrowseClicked( %this ) +{ + //%filename = RETextureFileCtrl.getText(); + + %dlg = new OpenFileDialog() + { + Filters = "All Files (*.*)|*.*|"; + DefaultPath = RoadEditorGui.lastPath; + DefaultFile = %filename; + ChangePath = false; + MustExist = true; + }; + + %ret = %dlg.Execute(); + if(%ret) + { + RoadEditorGui.lastPath = filePath( %dlg.FileName ); + %filename = %dlg.FileName; + RoadEditorGui.setTextureFile( %filename ); + RETextureFileCtrl.setText( %filename ); + } + + %dlg.delete(); +} + +function RoadInspector::inspect( %this, %obj ) +{ + %name = ""; + if ( isObject( %obj ) ) + %name = %obj.getName(); + else + RoadFieldInfoControl.setText( "" ); + + //RoadInspectorNameEdit.setValue( %name ); + Parent::inspect( %this, %obj ); +} + +function RoadInspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + // Same work to do as for the regular WorldEditor Inspector. + Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ); +} + +function RoadInspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + RoadFieldInfoControl.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} + +function RoadTreeView::onInspect(%this, %obj) +{ + RoadInspector.inspect(%obj); +} + +function RoadTreeView::onSelect(%this, %obj) +{ + RoadEditorGui.road = %obj; + RoadInspector.inspect( %obj ); + if(%obj != RoadEditorGui.getSelectedRoad()) + { + RoadEditorGui.setSelectedRoad( %obj ); + } +} + +function RoadEditorGui::prepSelectionMode( %this ) +{ + %mode = %this.getMode(); + + if ( %mode $= "RoadEditorAddNodeMode" ) + { + if ( isObject( %this.getSelectedRoad() ) ) + %this.deleteNode(); + } + + %this.setMode( "RoadEditorSelectMode" ); + ToolsPaletteArray-->RoadEditorSelectMode.setStateOn(1); +} +//------------------------------------------------------------------------------ +function ERoadEditorSelectModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERoadEditorAddModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERoadEditorMoveModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERoadEditorScaleModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERoadEditorInsertModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function ERoadEditorRemoveModeBtn::onClick(%this) +{ + EditorGuiStatusBar.setInfo(%this.ToolTip); +} + +function RoadDefaultWidthSliderCtrlContainer::onWake(%this) +{ + RoadDefaultWidthSliderCtrlContainer-->slider.setValue(RoadDefaultWidthTextEditContainer-->textEdit.getText()); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/settings.xml b/Templates/BaseGame/game/tools/settings.xml new file mode 100644 index 000000000..739530e7b --- /dev/null +++ b/Templates/BaseGame/game/tools/settings.xml @@ -0,0 +1,202 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<EditorSettings> + <Group name="GuiEditor"> + <Setting name="previewResolution">1280 1024</Setting> + <Setting name="lastPath">E:/gamedev/T3DMIT/CLEAN/My Projects/TemplateTest/game/data/scripts/gui</Setting> + <Group name="EngineDevelopment"> + <Setting name="toggleIntoEditor">0</Setting> + <Setting name="showEditorProfiles">0</Setting> + <Setting name="showEditorGuis">0</Setting> + </Group> + <Group name="Help"> + <Setting name="documentationURL">http://www.garagegames.com/products/torque-3d/documentation/user</Setting> + <Setting name="documentationLocal">../../../Documentation/Official Documentation.html</Setting> + <Setting name="documentationReference">../../../Documentation/Torque 3D - Script Manual.chm</Setting> + </Group> + <Group name="Rendering"> + <Setting name="drawBorderLines">1</Setting> + <Setting name="drawGuides">1</Setting> + </Group> + <Group name="Snapping"> + <Setting name="snapToGuides">1</Setting> + <Setting name="snap2GridSize">8</Setting> + <Setting name="snapToEdges">1</Setting> + <Setting name="snapToCanvas">1</Setting> + <Setting name="snapToCenters">1</Setting> + <Setting name="sensitivity">2</Setting> + <Setting name="snapToControls">1</Setting> + <Setting name="snap2Grid">0</Setting> + </Group> + <Group name="Selection"> + <Setting name="fullBox">0</Setting> + </Group> + <Group name="Library"> + <Setting name="viewType">Categorized</Setting> + </Group> + </Group> + <Group name="ShapeEditor"> + <Setting name="showBounds">0</Setting> + <Setting name="gridSize">0.1</Setting> + <Setting name="SunAngleZ">135</Setting> + <Setting name="gridDimension">40 40</Setting> + <Setting name="SunDiffuseColor">255 255 255 255</Setting> + <Setting name="SunAmbientColor">180 180 180 255</Setting> + <Setting name="AdvancedWndVisible">1</Setting> + <Setting name="showObjBox">1</Setting> + <Setting name="renderMounts">1</Setting> + <Setting name="RenderCollision">0</Setting> + <Setting name="ShowGrid">1</Setting> + <Setting name="backgroundColor">0 0 0 100</Setting> + <Setting name="highlightMaterial">1</Setting> + <Setting name="showNodes">1</Setting> + <Setting name="SunAngleX">45</Setting> + </Group> + <Group name="WorldEditor"> + <Setting name="currentEditor">WorldEditorInspectorPlugin</Setting> + <Setting name="dropType">screenCenter</Setting> + <Setting name="orthoFOV">50</Setting> + <Setting name="orthoShowGrid">1</Setting> + <Setting name="forceLoadDAE">0</Setting> + <Setting name="displayType">6</Setting> + <Setting name="undoLimit">40</Setting> + <Group name="Docs"> + <Setting name="documentationReference">../../../Documentation/Torque 3D - Script Manual.chm</Setting> + <Setting name="forumURL">http://www.garagegames.com/products/torque-3d/forums</Setting> + <Setting name="documentationURL">http://www.garagegames.com/products/torque-3d/documentation/user</Setting> + <Setting name="documentationLocal">../../../Documentation/Official Documentation.html</Setting> + </Group> + <Group name="Color"> + <Setting name="dragRectColor">255 255 0 255</Setting> + <Setting name="objectTextColor">255 255 255 255</Setting> + <Setting name="popupBackgroundColor">100 100 100 255</Setting> + <Setting name="objSelectColor">255 0 0 255</Setting> + <Setting name="objMouseOverSelectColor">0 0 255 255</Setting> + <Setting name="selectionBoxColor">255 255 0 255</Setting> + <Setting name="objMouseOverColor">0 255 0 255</Setting> + </Group> + <Group name="Tools"> + <Setting name="objectsUseBoxCenter">1</Setting> + <Setting name="snapSoft">0</Setting> + <Setting name="snapGround">0</Setting> + <Setting name="boundingBoxCollision">0</Setting> + <Setting name="snapSoftSize">2</Setting> + <Setting name="dropAtScreenCenterMax">100</Setting> + <Setting name="dropAtScreenCenterScalar">1</Setting> + </Group> + <Group name="Images"> + <Setting name="lockedHandle">tools/worldEditor/images/LockedHandle</Setting> + <Setting name="selectHandle">tools/worldEditor/images/SelectHandle</Setting> + <Setting name="defaultHandle">tools/worldEditor/images/DefaultHandle</Setting> + </Group> + <Group name="Grid"> + <Setting name="gridMinorColor">51 51 51 100</Setting> + <Setting name="gridOriginColor">255 255 255 100</Setting> + <Setting name="gridSize">1</Setting> + <Setting name="gridColor">102 102 102 100</Setting> + <Setting name="gridSnap">0</Setting> + </Group> + <Group name="ObjectIcons"> + <Setting name="fadeIcons">1</Setting> + <Setting name="fadeIconsStartAlpha">255</Setting> + <Setting name="fadeIconsEndAlpha">0</Setting> + <Setting name="fadeIconsStartDist">8</Setting> + <Setting name="fadeIconsEndDist">20</Setting> + </Group> + <Group name="Render"> + <Setting name="renderObjHandle">1</Setting> + <Setting name="renderObjText">1</Setting> + <Setting name="renderSelectionBox">1</Setting> + <Setting name="showMousePopupInfo">1</Setting> + <Setting name="renderPopupBackground">1</Setting> + </Group> + </Group> + <Group name="NavEditor"> + <Setting name="SpawnClass">AIPlayer</Setting> + <Setting name="spawnDatablock">DefaultPlayerData</Setting> + <Setting name="backgroundBuild">1</Setting> + </Group> + <Group name="RoadEditor"> + <Setting name="DefaultWidth">10</Setting> + <Setting name="HoverNodeColor">255 255 255 255</Setting> + <Setting name="HoverSplineColor">255 0 0 255</Setting> + <Setting name="materialName">DefaultDecalRoadMaterial</Setting> + <Setting name="SelectedSplineColor">0 255 0 255</Setting> + </Group> + <Group name="TerrainEditor"> + <Setting name="currentAction">raiseHeight</Setting> + <Group name="ActionValues"> + <Setting name="softSelectRadius">50</Setting> + <Setting name="SlopeMinAngle">0</Setting> + <Setting name="softSelectDefaultFilter">1.000000 0.833333 0.666667 0.500000 0.333333 0.166667 0.000000</Setting> + <Setting name="SlopeMaxAngle">90</Setting> + <Setting name="softSelectFilter">1.000000 0.833333 0.666667 0.500000 0.333333 0.166667 0.000000</Setting> + <Setting name="setHeightVal">100</Setting> + <Setting name="adjustHeightVal">10</Setting> + <Setting name="noiseFactor">1</Setting> + <Setting name="scaleVal">1</Setting> + <Setting name="smoothFactor">0.1</Setting> + </Group> + <Group name="Brush"> + <Setting name="brushSoftness">1</Setting> + <Setting name="brushType">ellipse</Setting> + <Setting name="maxBrushSize">40 40</Setting> + <Setting name="brushPressure">1</Setting> + <Setting name="brushSize">1 1</Setting> + </Group> + </Group> + <Group name="MeshRoadEditor"> + <Setting name="bottomMaterialName">DefaultRoadMaterialOther</Setting> + <Setting name="topMaterialName">DefaultRoadMaterialTop</Setting> + <Setting name="HoverSplineColor">255 0 0 255</Setting> + <Setting name="DefaultDepth">5</Setting> + <Setting name="SelectedSplineColor">0 255 0 255</Setting> + <Setting name="sideMaterialName">DefaultRoadMaterialOther</Setting> + <Setting name="DefaultNormal">0 0 1</Setting> + <Setting name="HoverNodeColor">255 255 255 255</Setting> + <Setting name="DefaultWidth">10</Setting> + </Group> + <Group name="RiverEditor"> + <Setting name="DefaultDepth">5</Setting> + <Setting name="HoverNodeColor">255 255 255 255</Setting> + <Setting name="DefaultWidth">10</Setting> + <Setting name="HoverSplineColor">255 0 0 255</Setting> + <Setting name="DefaultNormal">0 0 1</Setting> + <Setting name="SelectedSplineColor">0 255 0 255</Setting> + </Group> + <Group name="AxisGizmo"> + <Setting name="rotationSnap">15</Setting> + <Setting name="snapRotations">0</Setting> + <Setting name="mouseRotateScalar">0.8</Setting> + <Setting name="mouseScaleScalar">0.8</Setting> + <Setting name="renderWhenUsed">0</Setting> + <Setting name="renderInfoText">1</Setting> + <Setting name="axisGizmoMaxScreenLen">100</Setting> + <Group name="Grid"> + <Setting name="planeDim">500</Setting> + <Setting name="renderPlane">0</Setting> + <Setting name="gridSize">10 10 10</Setting> + <Setting name="gridColor">255 255 255 20</Setting> + <Setting name="renderPlaneHashes">0</Setting> + <Setting name="snapToGrid">0</Setting> + </Group> + </Group> + <Group name="DatablockEditor"> + <Setting name="libraryTab">0</Setting> + </Group> + <Group name="ConvexEditor"> + <Setting name="materialName">Grid512_OrangeLines_Mat</Setting> + </Group> + <Group name="LevelInformation"> + <Group name="levels"> + <Group name="BlankRoom.mis"> + <Setting name="cameraSpeed">25</Setting> + </Group> + <Group name="Empty_Room.mis"> + <Setting name="cameraSpeed">25</Setting> + </Group> + <Group name="Empty Terrain.mis"> + <Setting name="cameraSpeed">25</Setting> + </Group> + </Group> + </Group> +</EditorSettings> diff --git a/Templates/BaseGame/game/tools/shapeEditor/gui/Profiles.ed.cs b/Templates/BaseGame/game/tools/shapeEditor/gui/Profiles.ed.cs new file mode 100644 index 000000000..cb42ef169 --- /dev/null +++ b/Templates/BaseGame/game/tools/shapeEditor/gui/Profiles.ed.cs @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Shape Editor Profiles +//----------------------------------------------------------------------------- + +singleton GuiControlProfile(GuiShapeEdScrollProfile : GuiEditorScrollProfile) +{ + // Don't clear the scroll area (since we need to be able to see the GuiContainer + // underneath that provides the fill color for the header row) + opaque = false; + category = "Editor"; +}; + +singleton GuiControlProfile(GuiShapeEdTextListProfile : ToolsGuiTextListProfile) +{ + // Customise the not-active font used for the header row + fontColorNA = "75 75 75"; + category = "Editor"; +}; + +singleton GuiControlProfile(GuiShapeEdRolloutProfile : GuiInspectorRolloutProfile0) +{ + bitmap = "tools/editorClasses/gui/images/rollout"; + category = "Editor"; +}; + +singleton GuiControlProfile( GuiShapeEdTransitionSliderProfile ) +{ + bitmap = "tools/shapeEditor/images/transition_slider"; + category = "Core"; +}; diff --git a/Templates/BaseGame/game/tools/shapeEditor/gui/ShapeEditorSettingsTab.gui b/Templates/BaseGame/game/tools/shapeEditor/gui/ShapeEditorSettingsTab.gui new file mode 100644 index 000000000..1a455e9a6 --- /dev/null +++ b/Templates/BaseGame/game/tools/shapeEditor/gui/ShapeEditorSettingsTab.gui @@ -0,0 +1,549 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ShapeEditorSettingsTab,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(EShapeEditorSettingsPage) { + fitBook = "1"; + text = "Shape Editor"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Colors"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 10"; + Extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "ShapeEdShapeView.sunDiffuse = EditorSettings.value(%this.editorSettingsValue);"; + editorSettingsValue = "ShapeEditor/SunDiffuseColor"; + editorSettingsWrite = "ShapeEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Sun Diffuse:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "80 0"; + Extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 30"; + Extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "ShapeEdShapeView.sunAmbient = EditorSettings.value(%this.editorSettingsValue);"; + editorSettingsValue = "ShapeEditor/SunAmbientColor"; + editorSettingsWrite = "ShapeEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Sun Ambient:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "80 0"; + Extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 50"; + Extent = "208 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + className = "ESettingsWindowColor"; + editorSettingsRead = "ShapeEdPreviewGui-->previewBackground.color = ColorIntToFloat(EditorSettings.value(%this.editorSettingsValue));"; + editorSettingsValue = "ShapeEditor/BackgroundColor"; + editorSettingsWrite = "ShapeEditorPlugin.writeSettings();"; + + new GuiTextCtrl() { + text = "Background:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 2"; + Extent = "70 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "80 0"; + Extent = "104 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + className = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + className = "ESettingsWindowColorButton"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Grid"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Grid Size:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "ShapeEdShapeView.gridSize = EditorSettings.value(%this.editorSettingsValue);"; + editorSettingsValue = "ShapeEditor/GridSize"; + editorSettingsWrite = "ShapeEditorPlugin.writeSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Grid Dimension:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "ShapeEdShapeView.gridDimension = EditorSettings.value(%this.editorSettingsValue);"; + editorSettingsValue = "ShapeEditor/GridDimension"; + editorSettingsWrite = "ShapeEditorPlugin.writeSettings();"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/shapeEditor/gui/ShapeEditorToolbar.ed.gui b/Templates/BaseGame/game/tools/shapeEditor/gui/ShapeEditorToolbar.ed.gui new file mode 100644 index 000000000..0435e3837 --- /dev/null +++ b/Templates/BaseGame/game/tools/shapeEditor/gui/ShapeEditorToolbar.ed.gui @@ -0,0 +1,295 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ShapeEditorToolbar, EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = ""; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "102 0"; + Extent = "550" SPC getWord(EditorGuiToolbar.extent, 1); + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + canMove = "0"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + EdgeSnap = "0"; + text =""; + + new GuiContainer() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "menubarProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 32"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 7"; + extent = "86 16"; + minExtent = "8 8"; + visible = "1"; + text = "Preview Settings"; + maxLength = "255"; + helpTag = "0"; + }; + new GuiBitmapCtrl() { + Profile = "ToolsGuiDefaultProfile"; + position = "94 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "showGridBtn"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "100 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdShapeView.renderGrid = $ThisControl.getValue();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Show grid"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/show-grid"; + text = ""; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "fitToShapeBtn"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "134 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdShapeView.fitToShape();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Fit Camera to Shape (F)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/fit-selection"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "orbitNodeBtn"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "168 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdShapeView.orbitNode = $ThisControl.getValue();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Orbit the selected node"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/orbit-cam"; + text = ""; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + new GuiBitmapCtrl() { + Profile = "ToolsGuiDefaultProfile"; + position = "202 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "showNodes"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "210 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdShapeView.renderNodes = $ThisControl.getValue();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Show Nodes (N)"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/shownodes_btn"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + internalName = "ghostMode"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "243 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdShapeView.renderGhost = $ThisControl.getValue();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggle shape transparency in the preview window (T)"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/ghost_btn"; + buttonType = "ToggleButton"; + groupNum = "0"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + internalName = "wireframeMode"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "276 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "shapeEditorWireframeMode();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggle shape wireframe in the preview window (R)"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/show-wireframe"; + buttonType = "ToggleButton"; + groupNum = "0"; + useMouseEvents = "0"; + }; + new GuiBitmapCtrl() { + Profile = "ToolsGuiDefaultProfile"; + position = "309 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "showBounds"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "315 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdShapeView.renderbounds = $ThisControl.getValue();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggle shape bounding box in the preview window"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/object-bounds"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "showObjBox"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "348 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdShapeView.renderObjBox = $ThisControl.getValue();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggle selected object bounding box in the preview window"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/object-fit-bounds"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "renderColMeshes"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "381 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "shapeEdShapeView.renderColMeshes = $ThisControl.getValue();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggle rendering of collision meshes in the preview window"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/collision-shape"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + new GuiBitmapCtrl() { + Profile = "ToolsGuiDefaultProfile"; + position = "415 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + new GuiBitmapButtonCtrl() { + internalName = "showAdvanced"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "423 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAdvancedWindow.setVisible( $ThisControl.getValue() );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggle Advanced Properties Window"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/detail-levels_btn"; + buttonType = "ToggleButton"; + groupNum = "0"; + useMouseEvents = "0"; + }; + }; +}; diff --git a/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdAdvancedWindow.ed.gui b/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdAdvancedWindow.ed.gui new file mode 100644 index 000000000..4a4793072 --- /dev/null +++ b/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdAdvancedWindow.ed.gui @@ -0,0 +1,1845 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiWindowCollapseCtrl(ShapeEdAdvancedWindow, EditorGuiGroup) { + text = "Advanced Properties"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + closeCommand = "ShapeEditorToolbar-->showAdvanced.performClick();"; + EdgeSnap = "1"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = getWord($pref::Video::mode, 0) - 209 - 209 SPC getWord(EditorGuiToolbar.extent, 1) - 1; + extent = "210 272"; + MinExtent = "210 253"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Profile = "ToolsGuiWindowProfile"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + minSize = "50 50"; + + new GuiTabBookCtrl() { + TabPosition = "Top"; + TabMargin = "6"; + MinTabWidth = "32"; + docking = "client"; + Margin = "3 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "4 24"; + extent = "202 243"; + MinExtent = "8 -500"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "ToolsGuiTabBookProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "tabBook"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTabPageCtrl() { + text = "Details"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + Position = "0 19"; + extent = "202 224"; + MinExtent = "0 -500"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "ToolsGuiTabPageProfile"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + docking = "client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "0 0"; + extent = "202 224"; + MinExtent = "8 8"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "ToolsGuiDefaultProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + position = "0 0"; + extent = "202 157"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "inspectorStyleRolloutDarkProfile"; + + new GuiTextCtrl() { + text = "Levels"; + position = "4 1"; + Extent = "192 16"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextProfile"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Levels"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "5 22"; + Extent = "49 13"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiCheckBoxProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.fixedDetail"; + Command = "ShapeEdAdvancedWindow-->detailSlider.setActive($ThisControl.getValue()); ShapeEdAdvancedWindow-->levelsInactive.setVisible( !$ThisControl.getValue() );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Allow the slider to select the current detail level"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0 0"; + ticks = "1"; + snap = "1"; + value = "0"; + position = "57 22"; + Extent = "118 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "ToolsGuiSliderProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.currentDL"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Drag the slider to change the current detail level"; + hovertime = "1000"; + isContainer = "0"; + internalName = "detailSlider"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl(){ + bitmap = "tools/gui/images/inactive-overlay"; + position = "57 19"; + Extent = "122 20"; + tooltip = "Levels needs to be selected to enable the detail level slider"; + hovertime = "500"; + isContainer = true; + internalName = "levelsInactive"; + }; + new GuiTextCtrl() { + text = "0"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "182 20"; + Extent = "15 16"; + MinExtent = "8 2"; + HorizSizing = "left"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.currentDL"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Index of the current detail level"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Polys"; + position = "37 40"; + extent = "26 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "0"; + position = "67 40"; + Extent = "40 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.detailPolys"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Number of polygons in the current detail level"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Size"; + position = "127 40"; + extent = "24 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "160 39"; + extent = "35 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextEditProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.detailSize"; + AltCommand = "ShapeEdAdvancedWindow.onEditDetailSize();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Edit this value to change the size of the current detail"; + hovertime = "1000"; + internalName = "detailSize"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Pixels"; + position = "35 60"; + extent = "28 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "0"; + position = "67 60"; + Extent = "40 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.pixelSize"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Current size (in pixels) of the shape"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Distance"; + position = "109 60"; + Extent = "42 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + position = "160 60"; + extent = "38 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.orbitDist"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Current distance from the shape to the camera"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Materials"; + position = "20 80"; + extent = "43 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + position = "67 80"; + extent = "40 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.numMaterials"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Number of materials used by all meshes at this detail level"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Bones"; + position = "120 80"; + extent = "31 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "5"; + position = "160 80"; + extent = "38 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.numBones"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Number of bones at this detail level (skins only)"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Primitives"; + position = "19 100"; + extent = "44 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = ""; + position = "67 100"; + extent = "40 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.numDrawCalls"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Total number of mesh primitives (triangle lists) at this detail level"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Weights"; + position = "109 100"; + Extent = "42 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "5"; + position = "160 100"; + extent = "38 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.numWeights"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Number of vertex weights at this detail level (skins only)"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Col Meshes"; + position = "7 120"; + extent = "56 16"; + horizSizing = "right"; + vertSizing = "bottom"; + }; + new GuiTextCtrl() { + text = ""; + position = "67 120"; + extent = "40 16"; + horizSizing = "right"; + vertSizing = "bottom"; + Variable = "ShapeEdShapeView.colMeshes"; + }; + new GuiTextCtrl() { + text = "Col Polys"; + position = "108 120"; + extent = "43 16"; + horizSizing = "right"; + vertSizing = "bottom"; + }; + new GuiTextCtrl() { + text = ""; + position = "160 120"; + extent = "38 16"; + horizSizing = "right"; + vertSizing = "bottom"; + Variable = "ShapeEdShapeView.colPolys"; + }; + }; + new GuiContainer() { + position = "0 138"; + Extent = "202 87"; + MinExtent = "8 8"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "inspectorStyleRolloutDarkProfile"; + isContainer = "1"; + + new GuiTextCtrl() { // Header + text = "Imposters"; + position = "4 1"; + Extent = "192 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextProfile"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Use Imposters"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "113 2"; + Extent = "83 13"; + MinExtent = "8 2"; + HorizSizing = "left"; + VertSizing = "bottom"; + Profile = "ToolsGuiCheckBoxProfile"; + Visible = "1"; + Command = "ShapeEdDetails.onToggleImposter( $ThisControl.getValue() );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Controls whether this shape uses an imposter detail level"; + hovertime = "1000"; + isContainer = "0"; + internalName = "bbUseImposters"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Detail Level"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "6 23"; + Extent = "57 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "68 22"; + Extent = "36 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextEditProfile"; + Visible = "1"; + AltCommand = "ShapeEdDetails.onEditImposter();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Specifies the detail level used to generate the imposters"; + hovertime = "1000"; + internalName = "bbDetailLevel"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Dimension"; + position = "6 43"; + Extent = "57 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "68 43"; + Extent = "36 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextEditProfile"; + Visible = "1"; + AltCommand = "ShapeEdDetails.onEditImposter();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Specifies the dimension (width/height) of the imposters in pixels"; + hovertime = "1000"; + internalName = "bbDimension"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "X Steps"; + position = "6 65"; + Extent = "57 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "68 64"; + Extent = "36 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextEditProfile"; + Visible = "1"; + AltCommand = "ShapeEdDetails.onEditImposter();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Number of steps in the horizontal axis"; + hovertime = "1000"; + internalName = "bbEquatorSteps"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Include Poles"; + groupNum = "-1"; + buttonType = "ToggleButton"; + position = "113 24"; + Extent = "83 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiCheckBoxProfile"; + Visible = "1"; + Command = "ShapeEdDetails.onEditImposter();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Specifies whether to include the poles (top and bottom) of the shape"; + hovertime = "1000"; + internalName = "bbIncludePoles"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Y Steps"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "116 44"; + Extent = "41 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + Tooltip = "Number of steps in the vertical axis"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "161 43"; + Extent = "36 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextEditProfile"; + Visible = "1"; + AltCommand = "ShapeEdDetails.onEditImposter();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "bbPolarSteps"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Y Angle"; + position = "116 65"; + Extent = "41 16"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextRightProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Polar Angle - Y axis"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "161 64"; + Extent = "36 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextEditProfile"; + Visible = "1"; + AltCommand = "ShapeEdDetails.onEditImposter();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "bbPolarAngle"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl(){ + bitmap = "tools/gui/images/inactive-overlay"; + position = "4 18"; + Extent = "193 64"; + tooltip = "Imposters must be enabled, and an imposter detail level selected to edit these properties"; + hovertime = "500"; + isContainer = "1"; + internalName = "imposterInactive"; + }; + }; + }; + }; + new GuiTabPageCtrl() { + text = "Mounting"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + Position = "0 19"; + extent = "202 224"; + MinExtent = "0 -500"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "ToolsGuiTabPageProfile"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + isContainer = "1"; + + new GuiControl(){ + docking = "client"; + Margin = "0 0 0 0"; + Profile = "ToolsGuiScrollProfile"; + position = "0 0"; + extent = "202 224"; + + }; + new GuiContainer(ShapeEdMountWindow) { + docking = "none"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + position = "0 0"; + extent = "202 224"; + MinExtent = "8 8"; + HorizSizing = "width"; + vertSizing = "height"; + Profile = "ToolsGuiDefaultProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Render mounted shapes"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "2 2"; + extent = "139 13"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiCheckBoxProfile"; + Visible = "1"; + Variable = "ShapeEdShapeView.renderMounts"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Controls whether mounted shapes will be rendered in the 3D view"; + hovertime = "1000"; + isContainer = "0"; + internalName = "renderMounts"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "0 17"; + extent = "202 124"; + MinExtent = "8 8"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "GuiShapeEdScrollProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + canSave = "1"; + isContainer = "1"; + + new GuiContainer() { + position = "0 0"; + extent = "200 121"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "inspectorStyleRolloutListProfile"; + }; + new GuiTextListCtrl() { + columns = "-1 0 110 152"; + fitParentWidth = "1"; + clipColumnText = "1"; + Position = "1 1"; + Extent = "200 11"; + MinExtent = "8 11"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiShapeEdTextListProfile"; + Visible = "1"; + Command = "ShapeEdMountWindow.update_onMountSelectionChanged();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "mountList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer() { + position = "0 140"; + extent = "202 85"; + HorizSizing = "width"; + VertSizing = "top"; + Profile = "inspectorStyleRolloutDarkProfile"; + + new GuiTextCtrl() { + text = "Mount Item"; + position = "5 1"; + extent = "134 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "182 1"; + Extent = "16 16"; + MinExtent = "8 2"; + HorizSizing = "left"; + VertSizing = "bottom"; + Profile = "ToolsGuiDefaultProfile"; + Visible = "1"; + Command = "ShapeEdMountWindow.unmountShape();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Delete the selected mount item"; + canSaveDynamicFields = "0"; + canSave = "1"; + isContainer = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/new"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "168 1"; + Extent = "16 16"; + MinExtent = "8 2"; + HorizSizing = "left"; + VertSizing = "bottom"; + Profile = "ToolsGuiDefaultProfile"; + Visible = "1"; + Command = "ShapeEdMountWindow.mountShape(-1);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Mounts a new shape to the current model"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + /*new GuiButtonCtrl() { + text = "Unmount All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "109 97"; + extent = "78 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + vertSizing = "top"; + Profile = "ToolsGuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdMountWindow.unmountAll();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Unmount all shapes"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + };*/ + new GuiTextCtrl() { + text = "Shape"; + position = "5 21"; + extent = "33 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextRightProfile"; + }; + new GuiPopUpMenuCtrl(ShapeEdMountShapeMenu) { + position = "42 20"; + extent = "156 18"; + HorizSizing = "width"; + vertSizing = "bottom"; + Profile = "ToolsGuiPopUpMenuProfile"; + ToolTip = "Select the model to mount"; + }; + new GuiTextCtrl() { + text = "Node"; + position = "5 42"; + extent = "33 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextRightProfile"; + }; + new GuiPopUpMenuCtrl() { + position = "42 41"; + extent = "62 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + Profile = "ToolsGuiPopUpMenuProfile"; + Command = "ShapeEdMountWindow.updateSelectedMount();"; + ToolTip = "Select the node on which to mount the model"; + internalName = "mountNode"; + }; + new GuiTextCtrl() { + text = "Type"; + position = "110 42"; + extent = "24 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + }; + new GuiPopUpMenuCtrl() { + position = "138 41"; + extent = "60 18"; + horizSizing = "left"; + vertSizing = "bottom"; + Profile = "ToolsGuiPopUpMenuProfile"; + Command = "ShapeEdMountWindow.updateSelectedMount();"; + ToolTip = "Select the type of mounting to use"; + internalName = "mountType"; + }; + new GuiPopUpMenuCtrl() { + position = "5 62"; + extent = "99 18"; + HorizSizing = "width"; + vertSizing = "bottom"; + Profile = "ToolsGuiPopUpMenuProfile"; + Command = "ShapeEdMountWindow.setMountThreadSequence();"; + ToolTip = "Select the sequence to play on the mounted model"; + internalName = "mountSeq"; + }; + new GuiSliderCtrl(ShapeEdMountSeqSlider) { + range = "0 1"; + ticks = "0"; + snap = "0"; + value = "0"; + position = "109 64"; + extent = "68 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "top"; + Profile = "ToolsGuiSliderProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Drag the slider to scrub through the sequence keyframes"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/shapeEditor/images/playfwd_btn"; + groupNum = "0"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "180 62"; + Extent = "18 18"; + MinExtent = "8 2"; + HorizSizing = "left"; + vertSizing = "top"; + Profile = "ToolsGuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdMountWindow.toggleMountThreadPlayback();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Play forwards"; + hovertime = "1000"; + isContainer = "0"; + internalName = "mountPlayBtn"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiTabPageCtrl() { + text = "Threads"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + Position = "0 19"; + extent = "202 224"; + MinExtent = "0 -500"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "ToolsGuiTabPageProfile"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer(ShapeEdThreadWindow) { + docking = "client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "0 0"; + extent = "202 224"; + MinExtent = "8 8"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "ToolsGuiDefaultProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + position = "0 0"; + extent = "203 141"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "inspectorStyleRolloutDarkProfile"; + + new GuiTextCtrl() { + text = "Thread"; + position = "4 1"; + extent = "41 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "0 17"; + extent = "47 124"; + MinExtent = "8 8"; + HorizSizing = "right"; + VertSizing = "height"; + Profile = "GuiShapeEdScrollProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextListCtrl(ShapeEdThreadList) { + fitParentWidth = "1"; + clipColumnText = "1"; + position = "1 1"; + extent = "45 11"; + MinExtent = "8 11"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiShapeEdTextListProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiTextCtrl() { + text = "Sequence"; + position = "52 1"; + extent = "53 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "46 17"; + extent = "157 124"; + MinExtent = "8 8"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "GuiShapeEdScrollProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextListCtrl() { + fitParentWidth = "1"; + clipColumnText = "1"; + Position = "1 1"; + extent = "155 11"; + MinExtent = "8 11"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "GuiShapeEdTextListProfile"; + Visible = "1"; + Command = "ShapeEdSequenceList.setSelectedById( $ThisControl.getSelectedId() );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "seqList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "184 1"; + Extent = "16 16"; + MinExtent = "8 2"; + HorizSizing = "left"; + VertSizing = "bottom"; + Profile = "ToolsGuiDefaultProfile"; + Visible = "1"; + Command = "ShapeEdThreadWindow.onRemoveThread();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Delete the selected thread"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/new"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "171 1"; + Extent = "16 16"; + MinExtent = "8 2"; + HorizSizing = "left"; + VertSizing = "bottom"; + Profile = "ToolsGuiDefaultProfile"; + Visible = "1"; + Command = "ShapeEdThreadWindow.onAddThread();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Add a new thread"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiSliderCtrl(ShapeEdThreadSlider) { + range = "0 0"; + ticks = "0"; + snap = "0"; + value = "0"; + position = "29 146"; + extent = "133 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "top"; + Profile = "ToolsGuiSliderProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Drag the slider to scrub through the sequence keyframes"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/shapeEditor/images/playbkwd_btn"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "6 144"; + extent = "18 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + vertSizing = "top"; + Profile = "ToolsGuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdAnimWindow-->playBkwdBtn.performClick();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Play backwards"; + hovertime = "1000"; + isContainer = "0"; + internalName = "playBkwdBtn"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/shapeEditor/images/pause_btn"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "166 144"; + Extent = "18 18"; + MinExtent = "8 2"; + HorizSizing = "left"; + vertSizing = "top"; + Profile = "ToolsGuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdAnimWindow-->pauseBtn.performClick();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggle Pause (SPACE)"; + hovertime = "1000"; + isContainer = "0"; + internalName = "pauseBtn"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/shapeEditor/images/playfwd_btn"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "184 144"; + Extent = "18 18"; + MinExtent = "8 2"; + HorizSizing = "left"; + vertSizing = "top"; + Profile = "ToolsGuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdAnimWindow-->playFwdBtn.performClick();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Play forwards"; + hovertime = "1000"; + isContainer = "0"; + internalName = "playFwdBtn"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = " Transition lasts"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "3 167"; + extent = "88 13"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "top"; + Profile = "ToolsGuiCheckBoxProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Controls whether the thread will smoothly transition when a new sequence is selected"; + hovertime = "1000"; + isContainer = "0"; + internalName = "useTransitions"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "98 164"; + extent = "49 18"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "top"; + Profile = "ToolsGuiTextEditProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Number of seconds over which to transition to the new sequence"; + hovertime = "1000"; + internalName = "transitionTime"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "seconds"; + position = "153 165"; + extent = "44 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiTextProfile"; + }; + new GuiTextCtrl() { + text = "Transition to"; + position = "4 186"; + extent = "62 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "top"; + profile = "ToolsGuiTextProfile"; + }; + new GuiPopUpMenuCtrl() { + position = "68 185"; + extent = "133 18"; + HorizSizing = "width"; + vertSizing = "top"; + Profile = "ToolsGuiPopUpMenuProfile"; + ToolTip = "Select the start position of the new sequence"; + internalName = "transitionTo"; + }; + new GuiTextCtrl() { + text = "Target anim"; + position = "4 207"; + extent = "58 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "top"; + profile = "ToolsGuiTextProfile"; + }; + new GuiPopUpMenuCtrl() { + position = "68 206"; + extent = "133 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "top"; + Profile = "ToolsGuiPopUpMenuProfile"; + ToolTip = "Select the initial play state of the new sequence"; + internalName = "transitionTarget"; + }; + }; + }; + new GuiTabPageCtrl() { + text = "Collision"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + Position = "0 19"; + extent = "202 224"; + MinExtent = "0 -500"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "ToolsGuiTabPageProfile"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer(ShapeEdColWindow) { + docking = "client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "0 0"; + extent = "202 225"; + MinExtent = "8 8"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "ToolsGuiDefaultProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Fit Type"; + position = "5 5"; + extent = "41 16"; + horizSizing = "right"; + vertSizing = "bottom"; + }; + new GuiPopUpMenuCtrl() { + position = "70 4"; + extent = "108 18"; + horizSizing = "right"; + vertSizing = "bottom"; + Profile = "ToolsGuiPopUpMenuProfile"; + Command = "ShapeEdColWindow.editCollision();"; + ToolTip = "Select the method used to auto-generate the collision geometry"; + internalName = "colType"; + }; + new GuiTextCtrl() { + text = "Fit Target"; + position = "5 25"; + extent = "45 16"; + horizSizing = "right"; + vertSizing = "bottom"; + }; + new GuiPopUpMenuCtrl() { + position = "70 24"; + extent = "108 18"; + horizSizing = "right"; + vertSizing = "bottom"; + Profile = "ToolsGuiPopUpMenuProfile"; + Command = "ShapeEdColWindow.editCollision();"; + ToolTip = "Select the object to fit collision geometry to"; + internalName = "colTarget"; + }; + new GuiTextCtrl() { + text = "Max Depth"; + position = "5 47"; + extent = "53 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + }; + new GuiSliderCtrl() { + range = "0 8"; + ticks = "4"; + snap = "0"; + value = "4"; + position = "70 48"; + extent = "104 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "ToolsGuiSliderProfile"; + Visible = "1"; + AltCommand = "ShapeEdColWindow-->hullDepthText.setText( mFloor($ThisControl.getValue()) );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Maximum hull split depth"; + hovertime = "1000"; + isContainer = "0"; + internalName = "hullDepth"; + }; + new GuiTextCtrl() { + text = "4"; + position = "181 47"; + extent = "18 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + internalName = "hullDepthText"; + }; + new GuiTextCtrl() { + text = "Merge %"; + position = "5 68"; + extent = "53 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + }; + new GuiSliderCtrl() { + range = "0 60"; + ticks = "4"; + snap = "0"; + value = "30"; + position = "70 69"; + extent = "104 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "ToolsGuiSliderProfile"; + Visible = "1"; + AltCommand = "ShapeEdColWindow-->hullMergeText.setText( mFloor($ThisControl.getValue()) );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Hull volume merge threshold"; + hovertime = "1000"; + isContainer = "0"; + internalName = "hullMergeThreshold"; + }; + new GuiTextCtrl() { + text = "30"; + position = "179 68"; + extent = "18 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + internalName = "hullMergeText"; + }; + new GuiTextCtrl() { + text = "Concavity %"; + position = "5 89"; + extent = "59 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + }; + new GuiSliderCtrl() { + range = "0 60"; + ticks = "4"; + snap = "0"; + value = "30"; + position = "70 90"; + extent = "104 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "ToolsGuiSliderProfile"; + Visible = "1"; + AltCommand = "ShapeEdColWindow-->hullConcaveText.setText( mFloor($ThisControl.getValue()) );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Hull concavity threshold"; + hovertime = "1000"; + isContainer = "0"; + internalName = "hullConcaveThreshold"; + }; + new GuiTextCtrl() { + text = "30"; + position = "179 89"; + extent = "18 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + internalName = "hullConcaveText"; + }; + new GuiTextCtrl() { + text = "Max Verts"; + position = "5 110"; + extent = "53 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + }; + new GuiSliderCtrl() { + range = "8 64"; + ticks = "4"; + snap = "0"; + value = "32"; + position = "70 111"; + extent = "104 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "ToolsGuiSliderProfile"; + Visible = "1"; + AltCommand = "ShapeEdColWindow-->hullMaxVertsText.setText( mFloor($ThisControl.getValue()) );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Maximum number of verts in a convex hull"; + hovertime = "1000"; + isContainer = "0"; + internalName = "hullMaxVerts"; + }; + new GuiTextCtrl() { + text = "32"; + position = "179 110"; + extent = "18 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + internalName = "hullMaxVertsText"; + }; + new GuiTextCtrl() { + text = "Box %"; + position = "5 131"; + extent = "53 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + }; + new GuiSliderCtrl() { + range = "0 100"; + ticks = "4"; + snap = "0"; + value = "30"; + position = "70 132"; + extent = "104 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "ToolsGuiSliderProfile"; + Visible = "1"; + AltCommand = "ShapeEdColWindow-->hullMaxBoxErrorText.setText( mFloor($ThisControl.getValue()) );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Maximum box volume error %"; + hovertime = "1000"; + isContainer = "0"; + internalName = "hullMaxBoxError"; + }; + new GuiTextCtrl() { + text = "30"; + position = "179 131"; + extent = "18 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + internalName = "hullMaxBoxErrorText"; + }; + new GuiTextCtrl() { + text = "Sphere %"; + position = "5 152"; + extent = "53 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + }; + new GuiSliderCtrl() { + range = "0 100"; + ticks = "4"; + snap = "0"; + value = "30"; + position = "70 153"; + extent = "104 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "ToolsGuiSliderProfile"; + Visible = "1"; + AltCommand = "ShapeEdColWindow-->hullMaxSphereErrorText.setText( mFloor($ThisControl.getValue()) );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Maximum sphere volume error %"; + hovertime = "1000"; + isContainer = "0"; + internalName = "hullMaxSphereError"; + }; + new GuiTextCtrl() { + text = "30"; + position = "179 152"; + extent = "18 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + internalName = "hullMaxSphereErrorText"; + }; + new GuiTextCtrl() { + text = "Capsule %"; + position = "5 173"; + extent = "53 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + }; + new GuiSliderCtrl() { + range = "0 100"; + ticks = "4"; + snap = "0"; + value = "30"; + position = "70 174"; + extent = "104 14"; + MinExtent = "8 2"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "ToolsGuiSliderProfile"; + Visible = "1"; + AltCommand = "ShapeEdColWindow-->hullMaxCapsuleErrorText.setText( mFloor($ThisControl.getValue()) );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Maximum capsule volume error %"; + hovertime = "1000"; + isContainer = "0"; + internalName = "hullMaxCapsuleError"; + }; + new GuiTextCtrl() { + text = "30"; + position = "179 173"; + extent = "18 16"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + internalName = "hullMaxCapsuleErrorText"; + }; + new GuiButtonCtrl() { + text = "Update Hulls"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "7 200"; + extent = "88 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + vertSizing = "bottom"; + Profile = "ToolsGuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdColWindow.editCollision();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Update the convex hull(s)"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Revert Changes"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "105 200"; + extent = "88 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + vertSizing = "bottom"; + Profile = "ToolsGuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdColWindow.update_onCollisionChanged();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Revert changes to settings"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl() { + bitmap = "tools/gui/images/inactive-overlay"; + position = "0 47"; + extent = "199 175"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + internalName = "hullInactive"; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- + +new GuiControl(ShapeEdWaitGui,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiOverlayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiControl() { + isContainer = "1"; + Profile = "editorMenu_wBorderProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "277 271"; + Extent = "245 57"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "Dialog"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = ""; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextBoldCenterProfile"; + HorizSizing = "width"; + VertSizing = "center"; + position = "5 19"; + Extent = "236 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + internalName = "message"; + }; + }; +}; + +function ShapeEdWaitGui::show(%this, %text) +{ + %this-->message.setText( %text ); + Canvas.pushDialog( %this ); + Canvas.repaint(); +} + +function ShapeEdWaitGui::hide(%this) +{ + Canvas.popDialog( %this ); +} + +function ShapeEdWaitGui::onWake(%this) +{ + %res = %this.getExtent(); + %resX = getWord( %res, 0 ); + %resY = getWord( %res, 1 ); + + %dialog = %this-->Dialog; + %dialogExtent = %dialog.getExtent(); + %dialogWidth = getWord( %dialogExtent, 0 ); + %dialogHeight = getWord( %dialogExtent, 1 ); + %dialogPostion = %dialog.getPosition(); + + %posX = ( %resX / 2 ) - ( %dialogWidth / 2 ); + %posY = ( %resY / 2 ) - ( %dialogHeight / 2 ); + %dialog.setPosition( %posX, %posY ); +} diff --git a/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdAnimWindow.ed.gui b/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdAnimWindow.ed.gui new file mode 100644 index 000000000..79c298a27 --- /dev/null +++ b/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdAnimWindow.ed.gui @@ -0,0 +1,438 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiWindowCtrl(ShapeEdAnimWindow) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiToolbarWindowProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = -1 SPC getWord(ShapeEdPreviewGui.extent,0)-94; + Extent = "817 53"; + MinExtent = "475 53"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "0"; + canCollapse = "0"; + text = ""; + + new GuiContainer() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "5 10"; + Extent = "809 "; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + // Sequence playback controls + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "0 3"; + Extent = "809 38"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiTextCtrl() { + HorizSizing = "left"; + VertSizing = "top"; + position = "740 19"; + Extent = "35 16"; + text = "Frame:"; + }; + new GuiTextCtrl() { + HorizSizing = "left"; + VertSizing = "top"; + Profile = "ToolsGuiTextProfile"; + position = "778 19"; + Extent = "26 18"; + Variable = "$ShapeEdCurrentFrame"; + }; + + new GuiTextEditCtrl() { + internalName = "seqIn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "28 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ShapeEdSequences.onEditSeqInOut(\"in\", $ThisControl.getText());"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Set the In Point to the Current Frame"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "5"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + + new GuiSliderCtrl(ShapeEdSeqSlider) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "35 4"; + Extent = "736 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + range = "0 255"; + ticks = "0"; + value = "0"; + Variable = "$ShapeEdCurrentFrame"; + }; + + new GuiTextEditCtrl() { + internalName = "seqOut"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "778 0"; + Extent = "28 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ShapeEdSequences.onEditSeqInOut(\"out\", $ThisControl.getText());"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Set the Out Point to the Current Frame"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "5"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + + // VCR style buttons: back step_back play step_fwd fwd + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "center"; + VertSizing = "top"; + position = "194 17"; + extent = "420 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "28 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdSequences.onEditSeqInOut(\"in\", ShapeEdSeqSlider.getValue());"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Set the in position to the current frame (I)"; + hovertime = "1000"; + text = "in"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "48 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.setKeyframe( ShapeEdAnimWindow-->seqIn.getText() );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Skip to in frame (SHIFT -)"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/back_btn"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "76 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.setKeyframe( mCeil(ShapeEdSeqSlider.getValue() - 1) );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Previous frame (-)"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/stepback_btn"; + internalName = "stepBkwdBtn"; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "114 0"; + Extent = "94 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl() { + internalName = "playBkwdBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.setNoProxySequence(); ShapeEdAnimWindow.setThreadDirection( -1 );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Play sequence in reverse"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/playbkwd_btn"; + }; + new GuiBitmapButtonCtrl() { + internalName = "pauseBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "38 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.setThreadDirection( 0 );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggle pause (SPACE)"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/pause_btn"; + }; + new GuiBitmapButtonCtrl() { + internalName = "playFwdBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "76 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.setNoProxySequence(); ShapeEdAnimWindow.setThreadDirection( 1 );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Play sequence"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/playfwd_btn"; + }; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "228 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.setKeyframe( mFloor(ShapeEdSeqSlider.getValue() + 1) );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Next frame (+)"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/stepfwd_btn"; + internalName = "stepFwdBtn"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "266 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.setKeyframe( ShapeEdAnimWindow-->seqOut.getText() );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Skip to out frame (SHIFT +)"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/fwd_btn"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + VertSizing = "bottom"; + position = "306 0"; + Extent = "28 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdSequences.onEditSeqInOut(\"out\", ShapeEdSeqSlider.getValue());"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Set the out position to the current frame (O)"; + hovertime = "1000"; + text = "out"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + internalName = "pingpong"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + horizSizing = "left"; + VertSizing = "bottom"; + position = "365 0"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdAnimWindow.togglePingPong();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggle 'pingpong' mode on the current thread"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + bitmap = "tools/shapeEditor/images/pingpong_btn"; + }; + new GuiTextEditCtrl() { + internalName = "timeScale"; + Profile = "ToolsGuiTextEditProfile"; + horizSizing = "left"; + VertSizing = "bottom"; + position = "390 0"; + extent = "30 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Text = "1.0"; + AltCommand = "ShapeEdShapeView.setTimeScale( $ThisControl.getText() );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Edit this value to change the playback speed for all threads"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; + new GuiBitmapButtonCtrl() { + internalName = "seqInBar"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "39 0"; + Extent = "8 13"; + MinExtent = "1 1"; + bitmap = "tools/shapeEditor/images/seq_bar-in"; + ToolTip = "Set the In Point to the Current Frame"; + Command = "ShapeEdSequences.onEditSeqInOut(\"in\", ShapeEdSeqSlider.getValue());"; + }; + new GuiBitmapButtonCtrl() { + internalName = "seqOutBar"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "765 0"; + Extent = "8 13"; + MinExtent = "1 1"; + bitmap = "tools/shapeEditor/images/seq_bar-out"; + ToolTip = "Set the Out Point to the Current Frame"; + Command = "ShapeEdSequences.onEditSeqInOut(\"out\", ShapeEdSeqSlider.getValue());"; + }; + }; +}; + +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdPreviewWindow.ed.gui b/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdPreviewWindow.ed.gui new file mode 100644 index 000000000..81b815d5c --- /dev/null +++ b/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdPreviewWindow.ed.gui @@ -0,0 +1,85 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(ShapeEdPreviewGui) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0" SPC (getWord(EditorGuiToolbar.extent, 1)-1); + Docking = "Client"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiSwatchButtonCtrl() { + internalName = "previewBackground"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiInspectorSwatchButtonProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "-210 -40"; + Extent = getWord(ShapeEdPreviewGui.extent,0)+212 + SPC getWord(ShapeEdPreviewGui.extent,0)+42; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + color = "0 0 0 .39"; + }; + new GuiShapeEdPreview(ShapeEdShapeView) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "-209 -90"; + Extent = getWord(ShapeEdPreviewGui.extent,0)+209 + SPC getWord(ShapeEdPreviewGui.extent, 1)+90; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + renderMissionArea = "0"; + GizmoProfile = "GlobalGizmoProfile"; + cameraZRot = "0"; + forceFOV = "0"; + gridColor = "0 0 0 140"; + renderNodes = "0"; + renderObjBox = "0"; + renderMounts = "0"; + renderColMeshes = "0"; + selectedNode = "-1"; + sunDiffuse = "255 255 255 255"; + sunAmbient = "180 180 180 255"; + timeScale = "1.0"; + fixedDetail = "0"; + orbitNode = "0"; + }; + }; +}; + +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdPropWindow.ed.gui b/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdPropWindow.ed.gui new file mode 100644 index 000000000..e061679c2 --- /dev/null +++ b/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdPropWindow.ed.gui @@ -0,0 +1,1474 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiWindowCollapseCtrl(ShapeEdPropWindow) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) + getWord(ShapeEdSelectWindow.extent, 1) - 2; + Extent = "210 484"; + MinExtent = "210 352"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Properties"; + + //--------------------------------------------------------------------- + // Sequence and Node editors + new GuiTabBookCtrl(ShapeEdSeqNodeTabBook) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "4 42"; + Extent = "202 437"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "client"; + Margin = "3 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "6"; + MinTabWidth = "32"; + + //--------------------------------------------------------------- + // Sequence editor + new GuiTabPageCtrl(ShapeEdSequences) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 19"; + Extent = "202 418"; + MinExtent = "0 -500"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Seq"; + maxLength = "1024"; + + new GuiContainer() { + isContainer = "1"; + Profile = "GuiInspectorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 418"; + MinExtent = "0 8"; + }; + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "ToolsGuiTabBorderProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 418"; + MinExtent = "0 8"; + }; + + // Sequence list + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 211"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiShapeEdScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 211"; + MinExtent = "8 25"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiContainer() { + internalName = "sequenceListHeader"; + Profile = "inspectorStyleRolloutListProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "200 19"; + MinExtent = "8 2"; + }; + new GuiTextListCtrl(ShapeEdSequenceList) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiShapeEdTextListProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "202 20"; + MinExtent = "8 11"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdPropWindow.update_onSeqSelectionChanged();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + enumerate = "0"; + resizeCell = "1"; + columns = "0 100 145 190 235"; + fitParentWidth = "0"; + clipColumnText = "1"; + }; + }; + }; + + // Sequence properties + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "0 210"; + Extent = "202 209"; + MinExtent = "8 11"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ // Sequence Properties Container + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "202 103"; + isContainer = true; + + new GuiTextCtrl() { // Header + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "104 16"; + text = "Sequence Properties"; + }; + new GuiTextCtrl() { // Name + HorizSizing = "right"; + VertSizing = "bottom"; + position = "16 22"; + Extent = "27 16"; + text = "Name"; + }; + new GuiTextEditCtrl() { + internalName = "seqName"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "46 21"; + Extent = "152 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ShapeEdSequences.onEditName();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Name of the selected sequence (edit to rename)"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "256"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + // animation dropdown + new GuiTextCtrl() { + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "-5 42"; + Extent = "48 18"; + text = "Source"; + tooltip = "Animation source data"; + }; + new GuiPopUpMenuCtrl(ShapeEdSeqFromMenu) { + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "46 41"; + Extent = "91 18"; + }; + // Start Frame + new GuiTextCtrl() { + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "32 62"; + Extent = "11 16"; + text = "in"; + }; + new GuiTextEditCtrl() { + internalName = "startFrame"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "46 61"; + Extent = "32 18"; + text = ""; + AltCommand = "ShapeEdSequences.onEditSeqInOut(\"in\", $ThisControl.getText());"; + }; + // End frame + new GuiTextCtrl() { + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "85 62"; + Extent = "18 16"; + text = "out"; + }; + new GuiTextEditCtrl() { + internalName = "endFrame"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "105 61"; + Extent = "32 18"; + text = ""; + AltCommand = "ShapeEdSequences.onEditSeqInOut(\"out\", $ThisControl.getText());"; + }; + // Cyclic flag + new GuiCheckBoxCtrl() { + internalName = "cyclicFlag"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "143 43"; + Extent = "39 13"; + Command = "ShapeEdSequences.onToggleCyclic();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Loop Animation. Toggles the cyclic flag."; + hovertime = "1000"; + text = "Loop"; + }; + // Priority + new GuiTextCtrl() { + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "136 62"; + Extent = "41 16"; + text = "Priority"; + }; + new GuiTextEditCtrl() { + internalName = "priority"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "179 61"; + Extent = "19 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ShapeEdSequences.onEditPriority();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Priority of the selected sequence"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "5"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + // Blend animation dropdown + new GuiCheckBoxCtrl() { + internalName = "blendFlag"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "2 82"; + Extent = "45 16"; + Command = "ShapeEdSequences.onEditBlend();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggle the blend flag for the selected sequence"; + hovertime = "1000"; + text = "Blend"; + }; + new GuiPopUpMenuCtrl() { + internalName = "blendSeq"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "46 81"; + Extent = "91 18"; + tooltip = "Blend reference sequence"; + Command = "ShapeEdSequences.onEditBlend();"; + }; + + // Blend frame + new GuiTextCtrl() { + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "142 81"; + Extent = "29 18"; + text = "Frame"; + }; + new GuiTextEditCtrl() { + internalName = "blendFrame"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "173 81"; + Extent = "25 18"; + text = ""; + tooltip = "Blend reference frame"; + AltCommand = "ShapeEdSequences.onEditBlend();"; + }; + }; + new GuiContainer(){ // Triggers Container + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 102"; + Extent = "202 106"; + isContainer = true; + + // Triggers + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 0"; + Extent = "50 18"; + text = "Triggers"; + }; + new GuiBitmapButtonCtrl() { + internalName = "addTriggerBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "170 2"; + Extent = "15 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdSequences.onAddTrigger();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Add a new trigger"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/new"; + }; + new GuiBitmapButtonCtrl() { + internalName = "deleteTriggerBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "185 2"; + Extent = "15 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdTriggerList.onDeleteSelection();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Delete the selected trigger"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + // Trigger list + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 17"; + Extent = "202 66"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiShapeEdScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 66"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiContainer() { + Profile = "inspectorStyleRolloutListProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "200 19"; + }; + new GuiTextListCtrl(ShapeEdTriggerList) { + canSaveDynamicFields = "0"; + Profile = "GuiShapeEdTextListProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "177 16"; + MinExtent = "8 11"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdPropWindow.onTriggerSelectionChanged();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + enumerate = "0"; + resizeCell = "1"; + columns = "-1 0 60 118"; + fitParentWidth = "1"; + clipColumnText = "1"; + }; + }; + }; + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 85"; + Extent = "35 18"; + text = "Frame"; + }; + new GuiTextEditCtrl() { + internalName = "triggerFrame"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "36 85"; + Extent = "32 18"; + text = ""; + AltCommand = "ShapeEdTriggerList.onEditSelection();"; + }; + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "75 85"; + Extent = "35 18"; + text = "Trigger"; + }; + new GuiTextEditCtrl() { + internalName = "triggerNum"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "110 85"; + Extent = "32 18"; + text = ""; + AltCommand = "ShapeEdTriggerList.onEditSelection();"; + }; + new GuiCheckBoxCtrl() { + internalName = "triggerOnOff"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "152 87"; + Extent = "47 13"; + text = "On/off"; + Command = "ShapeEdTriggerList.onEditSelection();"; + }; + }; + }; + }; + + //--------------------------------------------------------------- + // Node Editor + new GuiTabPageCtrl(ShapeEdNodes) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 19"; + Extent = "202 418"; + MinExtent = "0 -500"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Node"; + maxLength = "1024"; + + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "ToolsGuiTabBorderProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 418"; + MinExtent = "0 8"; + }; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 288"; + MinExtent = "8 0"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl(ShapeEdNodeTreeView) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "height"; + Position = "1 1"; + Extent = "122 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "0"; + internalNamesOnly = "0"; + }; + }; + new GuiContainer(){ // Node Properties Container + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "top"; + position = "0 287"; + Extent = "202 131"; + isContainer = true; + + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "104 16"; + text = "Node Properties"; + }; + // Node property labels + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "6 18"; + Extent = "50 108"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiTextRightProfile"; + position = "9 6"; + Extent = "40 16"; + text = "Name"; + }; + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiTextRightProfile"; + position = "10 26"; + Extent = "40 16"; + text = "Parent"; + }; + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiTextRightProfile"; + position = "-5 49"; + Extent = "54 16"; + text = "Transform"; + }; + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiTextRightProfile"; + position = "11 73"; + Extent = "39 16"; + text = "Position"; + }; + new GuiTextCtrl() { + HorizSizing = "right"; + VertSizing = "bottom"; + profile = "ToolsGuiTextRightProfile"; + position = "8 93"; + Extent = "42 16"; + text = "Rotation"; + }; + }; + + // Node properties + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "49 16"; + Extent = "155 109"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiTextEditCtrl() { + internalName = "nodeName"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "12 5"; + Extent = "137 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ShapeEdNodes.onEditName();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Name of the selected node (edit to rename)"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiPopUpMenuCtrl(ShapeEdNodeParentMenu) { + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "12 25"; + Extent = "137 18"; + tooltip = "Selected node's parent"; + }; + new GuiIconButtonCtrl() { + internalName = "worldTransform"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "12 45"; + Extent = "65 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdPropWindow.update_onNodeTransformChanged();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "View global node transform"; + hovertime = "1000"; + text = "World"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + buttonMargin = "0 4"; + iconBitmap = "tools/gui/images/menubar/world-transform_n"; + textMargin = "25"; + }; + new GuiIconButtonCtrl() { + internalName = "objectTransform"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "84 45"; + Extent = "65 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdPropWindow.update_onNodeTransformChanged();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "View local node transform (relative to parent)"; + hovertime = "1000"; + text = "Object"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + buttonMargin = "0 4"; + iconBitmap = "tools/gui/images/menubar/object-transform_n"; + textMargin = "26"; + }; + new GuiTextEditCtrl() { + internalName = "nodePosition"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "12 72"; + Extent = "137 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ShapeEdNodes.onEditTransform();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Node position (x y z)"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextEditCtrl() { + internalName = "nodeRotation"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "12 92"; + Extent = "137 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "ShapeEdNodes.onEditTransform();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Node rotation (axis.x axis.y axis.z angle)"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + }; + }; + }; + + //--------------------------------------------------------------- + // Details/Objects + new GuiTabPageCtrl(ShapeEdDetails) { + fitBook = "0"; + text = "Detail"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + position = "0 19"; + extent = "202 418"; + MinExtent = "0 -500"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "ToolsGuiTabPageProfile"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + + new GuiContainer() { + position = "0 0"; + extent = "202 418"; + minExtent = "0 8"; + horizSizing = "width"; + vertSizing = "height"; + profile = "GuiInspectorProfile"; + isContainer = "1"; + }; + new GuiBitmapBorderCtrl() { + position = "0 0"; + extent = "202 418"; + minExtent = "0 8"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "ToolsGuiTabBorderProfile"; + isContainer = "1"; + }; + + // Detail/object tree + new GuiControl() { + Position = "0 0"; + extent = "202 276"; + MinExtent = "8 8"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "ToolsGuiDefaultProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + Position = "0 0"; + extent = "202 276"; + MinExtent = "8 25"; + HorizSizing = "width"; + VertSizing = "height"; + Profile = "GuiShapeEdScrollProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTreeViewCtrl(ShapeEdDetailTree) { + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "0"; + showRoot = "0"; + Position = "1 1"; + extent = "85 110"; + MinExtent = "8 8"; + HorizSizing = "right"; + VertSizing = "height"; + Profile = "ToolsGuiTreeViewProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + + // Detail/Object properties + new GuiControl() { + position = "0 275"; + extent = "202 143"; + MinExtent = "8 8"; + HorizSizing = "width"; + vertSizing = "top"; + Profile = "ToolsGuiDefaultProfile"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiContainer() { + position = "0 0"; + extent = "202 143"; + HorizSizing = "width"; + VertSizing = "bottom"; + Profile = "inspectorStyleRolloutDarkProfile"; + isContainer = "1"; + + new GuiTextCtrl() { // Header + text = "Detail/Object Properties"; + position = "4 1"; + extent = "112 16"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + new GuiTextEditCtrl() { + position = "5 23"; + extent = "130 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextEditProfile"; + Visible = "1"; + AltCommand = "ShapeEdDetails.onEditName();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Edit this value to rename the current object or detail"; + hovertime = "1000"; + internalName = "meshName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + position = "157 23"; + extent = "40 18"; + MinExtent = "8 2"; + HorizSizing = "right"; + VertSizing = "bottom"; + Profile = "ToolsGuiTextEditProfile"; + Visible = "1"; + AltCommand = "ShapeEdDetails.onEditSize();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Edit this value to change the size of the current mesh or detail"; + hovertime = "1000"; + internalName = "meshSize"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Billboarding"; + position = "5 44"; + extent = "57 16"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + new GuiPopUpMenuCtrl() { + position = "88 45"; + extent = "109 18"; + HorizSizing = "right"; + vertSizing = "bottom"; + Profile = "ToolsGuiPopUpMenuProfile"; + Command = "ShapeEdDetails.onEditBBType();"; + ToolTip = "The type of billboarding used by the mesh"; + internalName = "bbType"; + }; + new GuiTextCtrl() { + text = "Object Node"; + position = "5 66"; + extent = "60 16"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + new GuiPopUpMenuCtrl() { + position = "88 67"; + extent = "109 18"; + HorizSizing = "right"; + vertSizing = "bottom"; + Profile = "ToolsGuiPopUpMenuProfile"; + Command = "ShapeEdDetails.onSetObjectNode();"; + ToolTip = "The node this object is attached to (all detail levels)"; + internalName = "objectNode"; + }; + new GuiBitmapCtrl(){ + bitmap = "tools/gui/images/inactive-overlay"; + position = "4 45"; + extent = "193 42"; + tooltip = "A mesh must be selected to edit these properties"; + hovertime = "500"; + isContainer = "1"; + internalName = "editMeshInactive"; + }; + new GuiButtonCtrl() { + text = "Import Shape into..."; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "4 91"; + extent = "102 22"; + MinExtent = "8 2"; + HorizSizing = "right"; + vertSizing = "bottom"; + Profile = "ToolsGuiButtonProfile"; + Visible = "1"; + Command = "ShapeEdDetails.onAddMeshFromFile(\"\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Add geometry from a different model file into the current shape"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + position = "111 92"; + extent = "85 18"; + horizSizing = "right"; + vertSizing = "bottom"; + Profile = "ToolsGuiPopUpMenuProfile"; + tooltip = "Select which detail level new geometry will be added to"; + internalName = "addGeomTo"; + }; + new GuiButtonCtrl() { + text = "Re-compute bounds"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "40 117"; + extent = "122 22"; + MinExtent = "8 2"; + HorizSizing = "right"; + vertSizing = "bottom"; + Profile = "ToolsGuiButtonProfile"; + Visible = "1"; + Command = "ShapeEditor.doSetBounds();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Recompute the shape bounding box using the geometry in the current detail level"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + + //--------------------------------------------------------------- + // Materials + new GuiTabPageCtrl(ShapeEdMaterials) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 19"; + Extent = "202 418"; + MinExtent = "0 -500"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Mat"; + maxLength = "1024"; + + new GuiContainer() { + isContainer = "1"; + Profile = "GuiInspectorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 418"; + MinExtent = "0 8"; + }; + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "ToolsGuiTabBorderProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 418"; + MinExtent = "0 8"; + }; + + // Material list + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 345"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiShapeEdScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 345"; + MinExtent = "8 25"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiContainer() { + internalName = "materialListHeader"; + Profile = "inspectorStyleRolloutListProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "200 19"; + MinExtent = "8 2"; + }; + new GuiTextListCtrl(ShapeEdMaterialList) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiShapeEdTextListProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "202 20"; + MinExtent = "8 11"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdMaterials.updateSelectedMaterial(ShapeEdMaterials-->highlightMaterial.getValue());"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + enumerate = "0"; + resizeCell = "1"; + columns = "0 130"; + fitParentWidth = "0"; + clipColumnText = "1"; + }; + }; + }; + + // Material properties + new GuiContainer() { + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "0 344"; + Extent = "202 74"; + isContainer = true; + + new GuiTextCtrl() { // Header + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "104 16"; + text = "Material Options"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 21"; + Extent = "150 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdMaterials.editSelectedMaterial();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Open the Material Editor to edit the selected material"; + hovertime = "1000"; + text = "Edit the selected Material"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + buttonMargin = "0 4"; + iconBitmap = "tools/worldEditor/images/toolbar/matterial-editor_n"; + textMargin = "25"; + }; + new GuiCheckBoxCtrl() { + internalName = "highlightMaterial"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "7 52"; + Extent = "150 13"; + Command = "ShapeEdMaterials.updateSelectedMaterial($ThisControl.getValue());"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Highlight the primitives that use the selected Material"; + hovertime = "1000"; + text = "Highlight selected Material"; + }; + }; + }; + }; + + // Save/New/Delete buttons (node or sequence, depending on which tab is active) + new GuiBitmapButtonCtrl() { + internalName = "saveBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "154 25"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEditor.saveChanges();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Save the current shape"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/save-icon"; + }; + new GuiBitmapButtonCtrl() { + internalName = "newBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "176 25"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = ""; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/new"; + }; + new GuiBitmapButtonCtrl() { + internalName = "deleteBtn"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "190 25"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = ""; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; +}; +//--- OBJECT WRITE END --- + +new GuiControl(GenImposterGui,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiOverlayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiControl() { + isContainer = "1"; + Profile = "editorMenu_wBorderProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "277 271"; + Extent = "245 57"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "Dialog"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Generating imposter bitmaps..."; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextBoldCenterProfile"; + HorizSizing = "width"; + VertSizing = "center"; + position = "5 19"; + Extent = "236 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; + +function GenImposterGui::onWake(%this) +{ + %res = %this.getExtent(); + %resX = getWord(%res, 0); + %resY = getWord(%res, 1); + + %dialog = %this-->Dialog; + %dialogExtent = %dialog.getExtent(); + %dialogWidth = getWord(%dialogExtent, 0); + %dialogHeight = getWord(%dialogExtent, 1); + %dialogPostion = %dialog.getPosition(); + + %posX = (%resX / 2) - (%dialogWidth / 2); + %posY = (%resY / 2) - (%dialogHeight / 2); + %dialog.setPosition(%posX, %posY); +} diff --git a/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdSelectWindow.ed.gui b/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdSelectWindow.ed.gui new file mode 100644 index 000000000..b73fe709e --- /dev/null +++ b/Templates/BaseGame/game/tools/shapeEditor/gui/shapeEdSelectWindow.ed.gui @@ -0,0 +1,504 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + //--------------------------------------------------------------------------- + // Shape selector window + new GuiWindowCollapseCtrl(ShapeEdSelectWindow) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) - 1; + Extent = "210 213"; + MinExtent = "210 114"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Shapes"; + + new GuiTabBookCtrl() { + internalName = "tabBook"; + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "4 24"; + Extent = "202 165"; + MinExtent = "8 -500"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + docking = "client"; + Margin = "3 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "6"; + MinTabWidth = "32"; + + //--------------------------------------------------------------- + // Scene shapes (ie. the MissionGroup) + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 19"; + Extent = "202 146"; + MinExtent = "0 -500"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Scene"; + maxLength = "1024"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 146"; + MinExtent = "8 -500"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl(ShapeEdShapeTreeView) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "190 144"; + MinExtent = "8 -500"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "1"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "1"; + showRoot = "1"; + internalNamesOnly = "0"; + showObjectIds = "0"; + showClassNames = "0"; + showObjectNames = "1"; + showInternalNames = "1"; + showClassNameForUnnamedObjects = "1"; + }; + }; + }; + + //--------------------------------------------------------------- + // All shapes + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "202 146"; + MinExtent = "0 -500"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Library"; + maxLength = "1024"; + + new GuiContainer() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 146"; + MinExtent = "0 -500"; + Profile = "GuiInspectorProfile"; + }; + new GuiBitmapBorderCtrl() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 146"; + MinExtent = "0 -500"; + Profile = "ToolsGuiTabBorderProfile"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "3 4"; + Extent = "20 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ShapeEdSelectWindow.navigateUp();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/folderUp"; + }; + new GuiPopUpMenuCtrl(ShapeEdSelectMenu) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "26 4"; + Extent = "172 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "art"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 24"; + Extent = "202 122"; + MinExtent = "8 -500"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiDynamicCtrlArrayControl() { + internalName = "shapeLibrary"; + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "189 42"; + MinExtent = "8 11"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + colCount = "1"; + colSize = "64"; + rowCount = "0"; + RowSize = "64"; + rowSpacing = "4"; + colSpacing = "4"; + frozen = "0"; + autoCellSize = "1"; + fillRowFirst = "1"; + dynamicSize = "1"; + }; + }; + }; + + //--------------------------------------------------------------- + // Shape hints + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "202 146"; + MinExtent = "0 -500"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Hints"; + maxLength = "1024"; + + new GuiContainer() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 146"; + MinExtent = "0 -500"; + Profile = "GuiInspectorProfile"; + }; + new GuiBitmapBorderCtrl() { + isContainer = "1"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "202 146"; + MinExtent = "0 -500"; + Profile = "ToolsGuiTabBorderProfile"; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 24"; + Extent = "202 123"; + MinExtent = "8 -500"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiStackControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 1"; + Extent = "185 50"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "2"; + + new GuiRolloutCtrl() { + Profile = "GuiShapeEdRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 0"; + Extent = "184 24"; + MinExtent = "8 -500"; + Caption = "Nodes"; + Margin = "2 2 2 2"; + Expanded = "0"; + + new GuiStackControl() { + internalName = "nodeHints"; + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 24"; + Extent = "184 0"; + MinExtent = "8 -500"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "2"; + }; + }; + + new GuiRolloutCtrl() { + Profile = "GuiShapeEdRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 26"; + Extent = "184 24"; + MinExtent = "8 -500"; + Caption = "Sequences"; + Margin = "2 2 2 2"; + Expanded = "0"; + + new GuiStackControl() { + internalName = "sequenceHints"; + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "184 24"; + MinExtent = "8 -500"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "2"; + }; + }; + }; + }; + new GuiTextCtrl(){ + Position = "5 5"; + Extent = "60 16"; + text = "Shape Type"; + }; + new GuiPopUpMenuCtrl(ShapeEdHintMenu) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "66 4"; + Extent = "132 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "art"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + }; + }; + + // Force load DAEs + new GuiCheckBoxCtrl() { + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "135 27"; + Extent = "72 13"; + Variable = "EWorldEditor.forceLoadDAE"; + Command = "EWorldEditor.forceLoadDAE = $ThisControl.getValue(); EditorSettings.setValue(\"forceLoadDAE\", EWorldEditor.forceLoadDAE);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Forces loading of DAE files (ignores cached.dts if present)"; + hovertime = "1000"; + text = " Force DAE"; + }; + + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/back_btn_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/back_btn_d.png new file mode 100644 index 000000000..41a33f548 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/back_btn_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/back_btn_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/back_btn_h.png new file mode 100644 index 000000000..ce9a266c5 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/back_btn_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/back_btn_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/back_btn_n.png new file mode 100644 index 000000000..5daf81682 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/back_btn_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/collision-shape_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/collision-shape_d.png new file mode 100644 index 000000000..83969b176 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/collision-shape_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/collision-shape_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/collision-shape_h.png new file mode 100644 index 000000000..378c734e8 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/collision-shape_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/collision-shape_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/collision-shape_n.png new file mode 100644 index 000000000..743bc4091 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/collision-shape_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/detail-levels_btn_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/detail-levels_btn_d.png new file mode 100644 index 000000000..4bfa56aa3 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/detail-levels_btn_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/detail-levels_btn_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/detail-levels_btn_h.png new file mode 100644 index 000000000..8ca5a0b1c Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/detail-levels_btn_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/detail-levels_btn_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/detail-levels_btn_n.png new file mode 100644 index 000000000..f7788fb21 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/detail-levels_btn_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/fwd_btn_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/fwd_btn_d.png new file mode 100644 index 000000000..0dd59b856 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/fwd_btn_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/fwd_btn_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/fwd_btn_h.png new file mode 100644 index 000000000..65147daa6 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/fwd_btn_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/fwd_btn_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/fwd_btn_n.png new file mode 100644 index 000000000..ba5f67aab Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/fwd_btn_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/ghost_btn_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/ghost_btn_d.png new file mode 100644 index 000000000..ce7522ebf Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/ghost_btn_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/ghost_btn_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/ghost_btn_h.png new file mode 100644 index 000000000..efc103ef8 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/ghost_btn_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/ghost_btn_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/ghost_btn_n.png new file mode 100644 index 000000000..79d2cebf7 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/ghost_btn_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/highlight_material.png b/Templates/BaseGame/game/tools/shapeEditor/images/highlight_material.png new file mode 100644 index 000000000..78ac974a3 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/highlight_material.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/object-bounds_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/object-bounds_d.png new file mode 100644 index 000000000..98253e586 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/object-bounds_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/object-bounds_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/object-bounds_h.png new file mode 100644 index 000000000..aa41d5ac7 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/object-bounds_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/object-bounds_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/object-bounds_n.png new file mode 100644 index 000000000..3bd3633e8 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/object-bounds_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/object-fit-bounds_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/object-fit-bounds_d.png new file mode 100644 index 000000000..8071e25b5 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/object-fit-bounds_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/object-fit-bounds_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/object-fit-bounds_h.png new file mode 100644 index 000000000..a0a4cd3bc Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/object-fit-bounds_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/object-fit-bounds_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/object-fit-bounds_n.png new file mode 100644 index 000000000..aaaed8e10 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/object-fit-bounds_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/pause_btn_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/pause_btn_d.png new file mode 100644 index 000000000..3caa5f8f8 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/pause_btn_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/pause_btn_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/pause_btn_h.png new file mode 100644 index 000000000..361275542 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/pause_btn_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/pause_btn_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/pause_btn_n.png new file mode 100644 index 000000000..d9a398521 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/pause_btn_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/pingpong_btn_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/pingpong_btn_d.png new file mode 100644 index 000000000..3d26cabb7 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/pingpong_btn_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/pingpong_btn_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/pingpong_btn_h.png new file mode 100644 index 000000000..ecdf5a3c0 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/pingpong_btn_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/pingpong_btn_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/pingpong_btn_n.png new file mode 100644 index 000000000..60a9c1548 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/pingpong_btn_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/playbkwd_btn_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/playbkwd_btn_d.png new file mode 100644 index 000000000..ef0e45000 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/playbkwd_btn_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/playbkwd_btn_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/playbkwd_btn_h.png new file mode 100644 index 000000000..73837b5d5 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/playbkwd_btn_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/playbkwd_btn_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/playbkwd_btn_n.png new file mode 100644 index 000000000..6e5f277bc Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/playbkwd_btn_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/playfwd_btn_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/playfwd_btn_d.png new file mode 100644 index 000000000..835e3f6fa Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/playfwd_btn_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/playfwd_btn_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/playfwd_btn_h.png new file mode 100644 index 000000000..87543b362 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/playfwd_btn_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/playfwd_btn_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/playfwd_btn_n.png new file mode 100644 index 000000000..7fadf843d Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/playfwd_btn_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-in_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-in_d.png new file mode 100644 index 000000000..dedef925e Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-in_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-in_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-in_h.png new file mode 100644 index 000000000..c443af280 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-in_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-in_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-in_n.png new file mode 100644 index 000000000..cf5091875 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-in_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-out_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-out_d.png new file mode 100644 index 000000000..540f5a9b1 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-out_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-out_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-out_h.png new file mode 100644 index 000000000..2feb3bfb6 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-out_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-out_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-out_n.png new file mode 100644 index 000000000..cac5d5b54 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/seq_bar-out_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/show-wireframe_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/show-wireframe_d.png new file mode 100644 index 000000000..6f94d00d4 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/show-wireframe_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/show-wireframe_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/show-wireframe_h.png new file mode 100644 index 000000000..d88297ec2 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/show-wireframe_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/show-wireframe_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/show-wireframe_n.png new file mode 100644 index 000000000..bab4eb253 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/show-wireframe_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/shownodes_btn_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/shownodes_btn_d.png new file mode 100644 index 000000000..a9a358d46 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/shownodes_btn_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/shownodes_btn_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/shownodes_btn_h.png new file mode 100644 index 000000000..6958e6ab8 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/shownodes_btn_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/shownodes_btn_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/shownodes_btn_n.png new file mode 100644 index 000000000..599deaba4 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/shownodes_btn_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/stepback_btn_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/stepback_btn_d.png new file mode 100644 index 000000000..e4c0fb52a Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/stepback_btn_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/stepback_btn_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/stepback_btn_h.png new file mode 100644 index 000000000..46fbd79fa Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/stepback_btn_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/stepback_btn_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/stepback_btn_n.png new file mode 100644 index 000000000..f0c114002 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/stepback_btn_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/stepfwd_btn_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/stepfwd_btn_d.png new file mode 100644 index 000000000..f0160a16a Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/stepfwd_btn_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/stepfwd_btn_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/stepfwd_btn_h.png new file mode 100644 index 000000000..4513970b5 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/stepfwd_btn_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/stepfwd_btn_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/stepfwd_btn_n.png new file mode 100644 index 000000000..eb98eb498 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/stepfwd_btn_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/sun-btn_d.png b/Templates/BaseGame/game/tools/shapeEditor/images/sun-btn_d.png new file mode 100644 index 000000000..c357d6889 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/sun-btn_d.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/sun-btn_h.png b/Templates/BaseGame/game/tools/shapeEditor/images/sun-btn_h.png new file mode 100644 index 000000000..813b0a7b6 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/sun-btn_h.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/sun-btn_n.png b/Templates/BaseGame/game/tools/shapeEditor/images/sun-btn_n.png new file mode 100644 index 000000000..70152a8be Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/sun-btn_n.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/transition_slider.png b/Templates/BaseGame/game/tools/shapeEditor/images/transition_slider.png new file mode 100644 index 000000000..9aa51ab50 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/transition_slider.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/images/trigger_marker.png b/Templates/BaseGame/game/tools/shapeEditor/images/trigger_marker.png new file mode 100644 index 000000000..ea7dab994 Binary files /dev/null and b/Templates/BaseGame/game/tools/shapeEditor/images/trigger_marker.png differ diff --git a/Templates/BaseGame/game/tools/shapeEditor/main.cs b/Templates/BaseGame/game/tools/shapeEditor/main.cs new file mode 100644 index 000000000..721313e95 --- /dev/null +++ b/Templates/BaseGame/game/tools/shapeEditor/main.cs @@ -0,0 +1,420 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Shape Editor +//------------------------------------------------------------------------------ + +function initializeShapeEditor() +{ + echo(" % - Initializing Shape Editor"); + + exec("./gui/Profiles.ed.cs"); + + exec("./gui/shapeEdPreviewWindow.ed.gui"); + exec("./gui/shapeEdAnimWindow.ed.gui"); + exec("./gui/shapeEdAdvancedWindow.ed.gui"); + exec("./gui/ShapeEditorToolbar.ed.gui"); + exec("./gui/shapeEdSelectWindow.ed.gui"); + exec("./gui/shapeEdPropWindow.ed.gui"); + + exec("./scripts/shapeEditor.ed.cs"); + exec("./scripts/shapeEditorHints.ed.cs"); + exec("./scripts/shapeEditorActions.ed.cs"); + + // Add windows to editor gui + ShapeEdPreviewGui.setVisible(false); + ShapeEdAnimWindow.setVisible(false); + + ShapeEditorToolbar.setVisible(false); + ShapeEdSelectWindow.setVisible(false); + ShapeEdPropWindow.setVisible(false); + + EditorGui.add(ShapeEdPreviewGui); + EditorGui.add(ShapeEdAnimWindow); + EditorGui.add(ShapeEdAdvancedWindow); + + EditorGui.add(ShapeEditorToolbar); + EditorGui.add(ShapeEdSelectWindow); + EditorGui.add(ShapeEdPropWindow); + + new ScriptObject(ShapeEditorPlugin) + { + superClass = "EditorPlugin"; + editorGui = ShapeEdShapeView; + }; + + %map = new ActionMap(); + %map.bindCmd( keyboard, "escape", "ToolsToolbarArray->WorldEditorInspectorPalette.performClick();", "" ); + %map.bindCmd( keyboard, "1", "ShapeEditorNoneModeBtn.performClick();", "" ); + %map.bindCmd( keyboard, "2", "ShapeEditorMoveModeBtn.performClick();", "" ); + %map.bindCmd( keyboard, "3", "ShapeEditorRotateModeBtn.performClick();", "" ); + //%map.bindCmd( keyboard, "4", "ShapeEditorScaleModeBtn.performClick();", "" ); // not needed for the shape editor + %map.bindCmd( keyboard, "n", "ShapeEditorToolbar->showNodes.performClick();", "" ); + %map.bindCmd( keyboard, "t", "ShapeEditorToolbar->ghostMode.performClick();", "" ); + %map.bindCmd( keyboard, "r", "ShapeEditorToolbar->wireframeMode.performClick();", "" ); + %map.bindCmd( keyboard, "f", "ShapeEditorToolbar->fitToShapeBtn.performClick();", "" ); + %map.bindCmd( keyboard, "g", "ShapeEditorToolbar->showGridBtn.performClick();", "" ); + %map.bindCmd( keyboard, "h", "ShapeEdSelectWindow->tabBook.selectPage( 2 );", "" ); // Load help tab + %map.bindCmd( keyboard, "l", "ShapeEdSelectWindow->tabBook.selectPage( 1 );", "" ); // load Library Tab + %map.bindCmd( keyboard, "j", "ShapeEdSelectWindow->tabBook.selectPage( 0 );", "" ); // load scene object Tab + %map.bindCmd( keyboard, "SPACE", "ShapeEdAnimWindow.togglePause();", "" ); + %map.bindCmd( keyboard, "i", "ShapeEdSequences.onEditSeqInOut(\"in\", ShapeEdSeqSlider.getValue());", "" ); + %map.bindCmd( keyboard, "o", "ShapeEdSequences.onEditSeqInOut(\"out\", ShapeEdSeqSlider.getValue());", "" ); + %map.bindCmd( keyboard, "shift -", "ShapeEdSeqSlider.setValue(ShapeEdAnimWindow-->seqIn.getText());", "" ); + %map.bindCmd( keyboard, "shift =", "ShapeEdSeqSlider.setValue(ShapeEdAnimWindow-->seqOut.getText());", "" ); + %map.bindCmd( keyboard, "=", "ShapeEdAnimWindow-->stepFwdBtn.performClick();", "" ); + %map.bindCmd( keyboard, "-", "ShapeEdAnimWindow-->stepBkwdBtn.performClick();", "" ); + + ShapeEditorPlugin.map = %map; + + ShapeEditorPlugin.initSettings(); +} + +function destroyShapeEditor() +{ +} + +function SetToggleButtonValue(%ctrl, %value) +{ + if ( %ctrl.getValue() != %value ) + %ctrl.performClick(); +} + +// Replace the command field in an Editor PopupMenu item (returns the original value) +function ShapeEditorPlugin::replaceMenuCmd(%this, %menuTitle, %id, %newCmd) +{ + %menu = EditorGui.findMenu( %menuTitle ); + %cmd = getField( %menu.item[%id], 2 ); + %menu.setItemCommand( %id, %newCmd ); + + return %cmd; +} + +function ShapeEditorPlugin::onWorldEditorStartup(%this) +{ + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu("Shape Editor", "", ShapeEditorPlugin); + + // Add ourselves to the ToolsToolbar + %tooltip = "Shape Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "ShapeEditorPlugin", "ShapeEditorPalette", expandFilename("tools/worldEditor/images/toolbar/shape-editor"), %tooltip ); + + // Add ourselves to the Editor Settings window + exec( "./gui/ShapeEditorSettingsTab.gui" ); + ESettingsWindow.addTabPage( EShapeEditorSettingsPage ); + + GuiWindowCtrl::attach(ShapeEdPropWindow, ShapeEdSelectWindow); + ShapeEdAnimWindow.resize( -1, 526, 593, 53 ); + + // Initialise gui + ShapeEdSeqNodeTabBook.selectPage(0); + ShapeEdAdvancedWindow-->tabBook.selectPage(0); + ShapeEdSelectWindow-->tabBook.selectPage(0); + ShapeEdSelectWindow.navigate(""); + + SetToggleButtonValue( ShapeEditorToolbar-->orbitNodeBtn, 0 ); + SetToggleButtonValue( ShapeEditorToolbar-->ghostMode, 0 ); + + // Initialise hints menu + ShapeEdHintMenu.clear(); + %count = ShapeHintGroup.getCount(); + for (%i = 0; %i < %count; %i++) + { + %hint = ShapeHintGroup.getObject(%i); + ShapeEdHintMenu.add(%hint.objectType, %hint); + } +} + +function ShapeEditorPlugin::open(%this, %filename) +{ + if ( !%this.isActivated ) + { + // Activate the Shape Editor + EditorGui.setEditor( %this, true ); + + // Get editor settings (note the sun angle is not configured in the settings + // dialog, so apply the settings here instead of in readSettings) + %this.readSettings(); + ShapeEdShapeView.sunAngleX = EditorSettings.value("ShapeEditor/SunAngleX"); + ShapeEdShapeView.sunAngleZ = EditorSettings.value("ShapeEditor/SunAngleZ"); + EWorldEditor.forceLoadDAE = EditorSettings.value("forceLoadDAE"); + + $wasInWireFrameMode = $gfx::wireframe; + ShapeEditorToolbar-->wireframeMode.setStateOn($gfx::wireframe); + + if ( GlobalGizmoProfile.getFieldValue(alignment) $= "Object" ) + ShapeEdNodes-->objectTransform.setStateOn(1); + else + ShapeEdNodes-->worldTransform.setStateOn(1); + + // Initialise and show the shape editor + ShapeEdShapeTreeView.open(MissionGroup); + ShapeEdShapeTreeView.buildVisibleTree(true); + + ShapeEdPreviewGui.setVisible(true); + ShapeEdSelectWindow.setVisible(true); + ShapeEdPropWindow.setVisible(true); + ShapeEdAnimWindow.setVisible(true); + ShapeEdAdvancedWindow.setVisible(ShapeEditorToolbar-->showAdvanced.getValue()); + ShapeEditorToolbar.setVisible(true); + EditorGui.bringToFront(ShapeEdPreviewGui); + + ToolsPaletteArray->WorldEditorMove.performClick(); + %this.map.push(); + + // Switch to the ShapeEditor UndoManager + %this.oldUndoMgr = Editor.getUndoManager(); + Editor.setUndoManager( ShapeEdUndoManager ); + + ShapeEdShapeView.setDisplayType( EditorGui.currentDisplayType ); + %this.initStatusBar(); + + // Customise menu bar + %this.oldCamFitCmd = %this.replaceMenuCmd( "Camera", 8, "ShapeEdShapeView.fitToShape();" ); + %this.oldCamFitOrbitCmd = %this.replaceMenuCmd( "Camera", 9, "ShapeEdShapeView.fitToShape();" ); + + Parent::onActivated(%this); + } + + // Select the new shape + if (isObject(ShapeEditor.shape) && (ShapeEditor.shape.baseShape $= %filename)) + { + // Shape is already selected => re-highlight the selected material if necessary + ShapeEdMaterials.updateSelectedMaterial(ShapeEdMaterials-->highlightMaterial.getValue()); + } + else if (%filename !$= "") + { + ShapeEditor.selectShape(%filename, ShapeEditor.isDirty()); + + // 'fitToShape' only works after the GUI has been rendered, so force a repaint first + Canvas.repaint(); + ShapeEdShapeView.fitToShape(); + } +} + +function ShapeEditorPlugin::onActivated(%this) +{ + %this.open(""); + + // Try to start with the shape selected in the world editor + %count = EWorldEditor.getSelectionSize(); + for (%i = 0; %i < %count; %i++) + { + %obj = EWorldEditor.getSelectedObject(%i); + %shapeFile = ShapeEditor.getObjectShapeFile(%obj); + if (%shapeFile !$= "") + { + if (!isObject(ShapeEditor.shape) || (ShapeEditor.shape.baseShape !$= %shapeFile)) + { + // Call the 'onSelect' method directly if the object is not in the + // MissionGroup tree (such as a Player or Projectile object). + ShapeEdShapeTreeView.clearSelection(); + if (!ShapeEdShapeTreeView.selectItem(%obj)) + ShapeEdShapeTreeView.onSelect(%obj); + + // 'fitToShape' only works after the GUI has been rendered, so force a repaint first + Canvas.repaint(); + ShapeEdShapeView.fitToShape(); + } + break; + } + } +} + +function ShapeEditorPlugin::initStatusBar(%this) +{ + EditorGuiStatusBar.setInfo("Shape editor ( Shift Click ) to speed up camera."); + EditorGuiStatusBar.setSelection( ShapeEditor.shape.baseShape ); +} + +function ShapeEditorPlugin::onDeactivated(%this) +{ + %this.writeSettings(); + + // Notify game objects if shape has been modified + if ( ShapeEditor.isDirty() ) + ShapeEditor.shape.notifyShapeChanged(); + + $gfx::wireframe = $wasInWireFrameMode; + + ShapeEdMaterials.updateSelectedMaterial(false); + ShapeEditorToolbar.setVisible(false); + + ShapeEdPreviewGui.setVisible(false); + ShapeEdSelectWindow.setVisible(false); + ShapeEdPropWindow.setVisible(false); + ShapeEdAnimWindow.setVisible(false); + ShapeEdAdvancedWindow.setVisible(false); + + if( EditorGui-->MatEdPropertiesWindow.visible ) + { + ShapeEdMaterials.editSelectedMaterialEnd( true ); + } + + %this.map.pop(); + + // Restore the original undo manager + Editor.setUndoManager( %this.oldUndoMgr ); + + // Restore menu bar + %this.replaceMenuCmd( "Camera", 8, %this.oldCamFitCmd ); + %this.replaceMenuCmd( "Camera", 9, %this.oldCamFitOrbitCmd ); + + Parent::onDeactivated(%this); +} + +function ShapeEditorPlugin::onExitMission( %this ) +{ + // unselect the current shape + ShapeEdShapeView.setModel( "" ); + if (ShapeEditor.shape != -1) + ShapeEditor.shape.delete(); + ShapeEditor.shape = 0; + ShapeEdUndoManager.clearAll(); + ShapeEditor.setDirty( false ); + + ShapeEdSequenceList.clear(); + ShapeEdNodeTreeView.removeItem( 0 ); + ShapeEdPropWindow.update_onNodeSelectionChanged( -1 ); + ShapeEdDetailTree.removeItem( 0 ); + ShapeEdMaterialList.clear(); + + ShapeEdMountWindow-->mountList.clear(); + ShapeEdThreadWindow-->seqList.clear(); + ShapeEdThreadList.clear(); +} + +function ShapeEditorPlugin::openShape( %this, %path, %discardChangesToCurrent ) +{ + EditorGui.setEditor( ShapeEditorPlugin ); + + if( ShapeEditor.isDirty() && !%discardChangesToCurrent ) + { + MessageBoxYesNo( "Save Changes?", + "Save changes to current shape?", + "ShapeEditor.saveChanges(); ShapeEditorPlugin.openShape(\"" @ %path @ "\");", + "ShapeEditorPlugin.openShape(\"" @ %path @ "\");" ); + return; + } + + ShapeEditor.selectShape( %path ); + ShapeEdShapeView.fitToShape(); +} + +function shapeEditorWireframeMode() +{ + $gfx::wireframe = !$gfx::wireframe; + ShapeEditorToolbar-->wireframeMode.setStateOn($gfx::wireframe); +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +function ShapeEditorPlugin::initSettings( %this ) +{ + EditorSettings.beginGroup( "ShapeEditor", true ); + + // Display options + EditorSettings.setDefaultValue( "BackgroundColor", "0 0 0 100" ); + EditorSettings.setDefaultValue( "HighlightMaterial", 1 ); + EditorSettings.setDefaultValue( "ShowNodes", 1 ); + EditorSettings.setDefaultValue( "ShowBounds", 0 ); + EditorSettings.setDefaultValue( "ShowObjBox", 1 ); + EditorSettings.setDefaultValue( "RenderMounts", 1 ); + EditorSettings.setDefaultValue( "RenderCollision", 0 ); + + // Grid + EditorSettings.setDefaultValue( "ShowGrid", 1 ); + EditorSettings.setDefaultValue( "GridSize", 0.1 ); + EditorSettings.setDefaultValue( "GridDimension", "40 40" ); + + // Sun + EditorSettings.setDefaultValue( "SunDiffuseColor", "255 255 255 255" ); + EditorSettings.setDefaultValue( "SunAmbientColor", "180 180 180 255" ); + EditorSettings.setDefaultValue( "SunAngleX", "45" ); + EditorSettings.setDefaultValue( "SunAngleZ", "135" ); + + // Sub-windows + EditorSettings.setDefaultValue( "AdvancedWndVisible", "1" ); + + EditorSettings.endGroup(); +} + +function ShapeEditorPlugin::readSettings( %this ) +{ + EditorSettings.beginGroup( "ShapeEditor", true ); + + // Display options + ShapeEdPreviewGui-->previewBackground.color = ColorIntToFloat( EditorSettings.value("BackgroundColor") ); + SetToggleButtonValue( ShapeEdMaterials-->highlightMaterial, EditorSettings.value( "HighlightMaterial" ) ); + SetToggleButtonValue( ShapeEditorToolbar-->showNodes, EditorSettings.value( "ShowNodes" ) ); + SetToggleButtonValue( ShapeEditorToolbar-->showBounds, EditorSettings.value( "ShowBounds" ) ); + SetToggleButtonValue( ShapeEditorToolbar-->showObjBox, EditorSettings.value( "ShowObjBox" ) ); + SetToggleButtonValue( ShapeEditorToolbar-->renderColMeshes, EditorSettings.value( "RenderCollision" ) ); + SetToggleButtonValue( ShapeEdMountWindow-->renderMounts, EditorSettings.value( "RenderMounts" ) ); + + // Grid + SetToggleButtonValue( ShapeEditorToolbar-->showGridBtn, EditorSettings.value( "ShowGrid" ) ); + ShapeEdShapeView.gridSize = EditorSettings.value( "GridSize" ); + ShapeEdShapeView.gridDimension = EditorSettings.value( "GridDimension" ); + + // Sun + ShapeEdShapeView.sunDiffuse = EditorSettings.value("SunDiffuseColor"); + ShapeEdShapeView.sunAmbient = EditorSettings.value("SunAmbientColor"); + + // Sub-windows + SetToggleButtonValue( ShapeEditorToolbar-->showAdvanced, EditorSettings.value( "AdvancedWndVisible" ) ); + + EditorSettings.endGroup(); +} + +function ShapeEditorPlugin::writeSettings( %this ) +{ + EditorSettings.beginGroup( "ShapeEditor", true ); + + // Display options + EditorSettings.setValue( "BackgroundColor", ColorFloatToInt( ShapeEdPreviewGui-->previewBackground.color ) ); + EditorSettings.setValue( "HighlightMaterial", ShapeEdMaterials-->highlightMaterial.getValue() ); + EditorSettings.setValue( "ShowNodes", ShapeEditorToolbar-->showNodes.getValue() ); + EditorSettings.setValue( "ShowBounds", ShapeEditorToolbar-->showBounds.getValue() ); + EditorSettings.setValue( "ShowObjBox", ShapeEditorToolbar-->showObjBox.getValue() ); + EditorSettings.setValue( "RenderCollision", ShapeEditorToolbar-->renderColMeshes.getValue() ); + EditorSettings.setValue( "RenderMounts", ShapeEdMountWindow-->renderMounts.getValue() ); + + // Grid + EditorSettings.setValue( "ShowGrid", ShapeEditorToolbar-->showGridBtn.getValue() ); + EditorSettings.setValue( "GridSize", ShapeEdShapeView.gridSize ); + EditorSettings.setValue( "GridDimension", ShapeEdShapeView.gridDimension ); + + // Sun + EditorSettings.setValue( "SunDiffuseColor", ShapeEdShapeView.sunDiffuse ); + EditorSettings.setValue( "SunAmbientColor", ShapeEdShapeView.sunAmbient ); + EditorSettings.setValue( "SunAngleX", ShapeEdShapeView.sunAngleX ); + EditorSettings.setValue( "SunAngleZ", ShapeEdShapeView.sunAngleZ ); + + // Sub-windows + EditorSettings.setValue( "AdvancedWndVisible", ShapeEditorToolbar-->showAdvanced.getValue() ); + + EditorSettings.endGroup(); +} diff --git a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.cs b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.cs new file mode 100644 index 000000000..d79923776 --- /dev/null +++ b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.cs @@ -0,0 +1,3395 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// @todo: +// +// - split node transform editboxes into X Y Z and rot X Y Z with spin controls +// to allow easier manual editing +// - add groundspeed editing ( use same format as node transform editing ) +// +// Known bugs/limitations: +// +// - resizing the GuiTextListCtrl should resize the columns as well +// - modifying the from/in/out properties of a sequence will change the sequence +// order in the shape ( since it results in remove/add sequence commands ) +// - deleting a node should not delete its children as well? +// + +//------------------------------------------------------------------------------ +// Utility Methods +//------------------------------------------------------------------------------ + +if ( !isObject( ShapeEditor ) ) new ScriptObject( ShapeEditor ) +{ + shape = -1; + deletedCount = 0; +}; + + +// Capitalise the first letter of the input string +function strcapitalise( %str ) +{ + %len = strlen( %str ); + return strupr( getSubStr( %str,0,1 ) ) @ getSubStr( %str,1,%len-1 ); +} + +function ShapeEditor::getObjectShapeFile( %this, %obj ) +{ + // Get the path to the shape file used by the given object (not perfect, but + // works for the vast majority of object types) + %path = ""; + if ( %obj.isMemberOfClass( "TSStatic" ) ) + %path = %obj.shapeName; + else if ( %obj.isMemberOfClass( "PhysicsShape" ) ) + %path = %obj.getDataBlock().shapeName; + else if ( %obj.isMemberOfClass( "GameBase" ) ) + %path = %obj.getDataBlock().shapeFile; + + return %path; +} + +// Check if the given name already exists +function ShapeEditor::nameExists( %this, %type, %name ) +{ + if ( ShapeEditor.shape == -1 ) + return false; + + if ( %type $= "node" ) + return ( ShapeEditor.shape.getNodeIndex( %name ) >= 0 ); + else if ( %type $= "sequence" ) + return ( ShapeEditor.shape.getSequenceIndex( %name ) >= 0 ); + else if ( %type $= "object" ) + return ( ShapeEditor.shape.getObjectIndex( %name ) >= 0 ); +} + +// Check if the given 'hint' name exists (spaces could also be underscores) +function ShapeEditor::hintNameExists( %this, %type, %name ) +{ + if ( ShapeEditor.nameExists( %type, %name ) ) + return true; + + // If the name contains spaces, try replacing with underscores + %name = strreplace( %name, " ", "_" ); + if ( ShapeEditor.nameExists( %type, %name ) ) + return true; + + return false; +} + +// Generate a unique name from a given base by appending an integer +function ShapeEditor::getUniqueName( %this, %type, %name ) +{ + for ( %idx = 1; %idx < 100; %idx++ ) + { + %uniqueName = %name @ %idx; + if ( !%this.nameExists( %type, %uniqueName ) ) + break; + } + + return %uniqueName; +} + +function ShapeEditor::getProxyName( %this, %seqName ) +{ + return "__proxy__" @ %seqName; +} + +function ShapeEditor::getUnproxyName( %this, %proxyName ) +{ + return strreplace( %proxyName, "__proxy__", "" ); +} + +function ShapeEditor::getBackupName( %this, %seqName ) +{ + return "__backup__" @ %seqName; +} + +// Check if this mesh name is a collision hint +function ShapeEditor::isCollisionMesh( %this, %name ) +{ + return ( startswith( %name, "ColBox" ) || + startswith( %name, "ColSphere" ) || + startswith( %name, "ColCapsule" ) || + startswith( %name, "ColConvex" ) ); +} + +// +function ShapeEditor::getSequenceSource( %this, %seqName ) +{ + %source = %this.shape.getSequenceSource( %seqName ); + + // Use the sequence name as the source for DTS built-in sequences + %src0 = getField( %source, 0 ); + %src1 = getField( %source, 1 ); + if ( %src0 $= %src1 ) + %source = setField( %source, 1, "" ); + if ( %src0 $= "" ) + %source = setField( %source, 0, %seqName ); + + return %source; +} + +// Recursively get names for a node and its children +function ShapeEditor::getNodeNames( %this, %nodeName, %names, %exclude ) +{ + if ( %nodeName $= %exclude ) + return %names; + + %count = %this.shape.getNodeChildCount( %nodeName ); + for ( %i = 0; %i < %count; %i++ ) + { + %childName = %this.shape.getNodeChildName( %nodeName, %i ); + %names = %this.getNodeNames( %childName, %names, %exclude ); + } + + %names = %names TAB %nodeName; + + return trim( %names ); +} + +// Get the list of meshes for a particular object +function ShapeEditor::getObjectMeshList( %this, %name ) +{ + %list = ""; + %count = %this.shape.getMeshCount( %name ); + for ( %i = 0; %i < %count; %i++ ) + %list = %list TAB %this.shape.getMeshName( %name, %i ); + return trim( %list ); +} + +// Get the list of meshes for a particular detail level +function ShapeEditor::getDetailMeshList( %this, %detSize ) +{ + %list = ""; + %objCount = ShapeEditor.shape.getObjectCount(); + for ( %i = 0; %i < %objCount; %i++ ) + { + %objName = ShapeEditor.shape.getObjectName( %i ); + %meshCount = ShapeEditor.shape.getMeshCount( %objName ); + for ( %j = 0; %j < %meshCount; %j++ ) + { + %size = ShapeEditor.shape.getMeshSize( %objName, %j ); + if ( %size == %detSize ) + %list = %list TAB %this.shape.getMeshName( %objName, %j ); + } + } + return trim( %list ); +} + +function ShapeEditor::isDirty( %this ) +{ + return ( isObject( %this.shape ) && ShapeEdPropWindow-->saveBtn.isActive() ); +} + +function ShapeEditor::setDirty( %this, %dirty ) +{ + if ( %dirty ) + ShapeEdSelectWindow.text = "Shapes *"; + else + ShapeEdSelectWindow.text = "Shapes"; + + ShapeEdPropWindow-->saveBtn.setActive( %dirty ); +} + +function ShapeEditor::saveChanges( %this ) +{ + if ( isObject( ShapeEditor.shape ) ) + { + ShapeEditor.saveConstructor( ShapeEditor.shape ); + ShapeEditor.shape.writeChangeSet(); + ShapeEditor.shape.notifyShapeChanged(); // Force game objects to reload shape + ShapeEditor.setDirty( false ); + } +} + +//------------------------------------------------------------------------------ +// Shape Selection +//------------------------------------------------------------------------------ + +function ShapeEditor::findConstructor( %this, %path ) +{ + %count = TSShapeConstructorGroup.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %obj = TSShapeConstructorGroup.getObject( %i ); + if ( %obj.baseShape $= %path ) + return %obj; + } + return -1; +} + +function ShapeEditor::createConstructor( %this, %path ) +{ + %name = strcapitalise( fileBase( %path ) ) @ strcapitalise( getSubStr( fileExt( %path ), 1, 3 ) ); + %name = strreplace( %name, "-", "_" ); + %name = strreplace( %name, ".", "_" ); + %name = getUniqueName( %name ); + return new TSShapeConstructor( %name ) { baseShape = %path; }; +} + +function ShapeEditor::saveConstructor( %this, %constructor ) +{ + %savepath = filePath( %constructor.baseShape ) @ "/" @ fileBase( %constructor.baseShape ) @ ".cs"; + new PersistenceManager( shapeEd_perMan ); + shapeEd_perMan.setDirty( %constructor, %savepath ); + shapeEd_perMan.saveDirtyObject( %constructor ); + shapeEd_perMan.delete(); +} + +// Handle a selection in the shape selector list +function ShapeEdSelectWindow::onSelect( %this, %path ) +{ + // Prompt user to save the old shape if it is dirty + if ( ShapeEditor.isDirty() ) + { + %cmd = "ColladaImportDlg.showDialog( \"" @ %path @ "\", \"ShapeEditor.selectShape( \\\"" @ %path @ "\\\", "; + MessageBoxYesNoCancel( "Shape Modified", "Would you like to save your changes?", %cmd @ "true );\" );", %cmd @ "false );\" );" ); + } + else + { + %cmd = "ShapeEditor.selectShape( \"" @ %path @ "\", false );"; + ColladaImportDlg.showDialog( %path, %cmd ); + } +} + +function ShapeEditor::selectShape( %this, %path, %saveOld ) +{ + ShapeEdShapeView.setModel( "" ); + + if ( %saveOld ) + { + // Save changes to a TSShapeConstructor script + %this.saveChanges(); + } + else if ( ShapeEditor.isDirty() ) + { + // Purge all unsaved changes + %oldPath = ShapeEditor.shape.baseShape; + ShapeEditor.shape.delete(); + ShapeEditor.shape = 0; + + reloadResource( %oldPath ); // Force game objects to reload shape + } + + // Initialise the shape preview window + if ( !ShapeEdShapeView.setModel( %path ) ) + { + MessageBoxOK( "Error", "Failed to load '" @ %path @ "'. Check the console for error messages." ); + return; + } + ShapeEdShapeView.fitToShape(); + + ShapeEdUndoManager.clearAll(); + ShapeEditor.setDirty( false ); + + // Get ( or create ) the TSShapeConstructor object for this shape + ShapeEditor.shape = ShapeEditor.findConstructor( %path ); + if ( ShapeEditor.shape <= 0 ) + { + ShapeEditor.shape = %this.createConstructor( %path ); + if ( ShapeEditor.shape <= 0 ) + { + error( "ShapeEditor: Error - could not select " @ %path ); + return; + } + } + + // Initialise the editor windows + ShapeEdAdvancedWindow.update_onShapeSelectionChanged(); + ShapeEdMountWindow.update_onShapeSelectionChanged(); + ShapeEdThreadWindow.update_onShapeSelectionChanged(); + ShapeEdColWindow.update_onShapeSelectionChanged(); + ShapeEdPropWindow.update_onShapeSelectionChanged(); + ShapeEdShapeView.refreshShape(); + + // Update object type hints + ShapeEdSelectWindow.updateHints(); + + // Update editor status bar + EditorGuiStatusBar.setSelection( %path ); +} + +// Handle a selection in the MissionGroup shape selector +function ShapeEdShapeTreeView::onSelect( %this, %obj ) +{ + %path = ShapeEditor.getObjectShapeFile( %obj ); + if ( %path !$= "" ) + ShapeEdSelectWindow.onSelect( %path ); + + // Set the object type (for required nodes and sequences display) + %objClass = %obj.getClassName(); + %hintId = -1; + + %count = ShapeHintGroup.getCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %hint = ShapeHintGroup.getObject( %i ); + if ( %objClass $= %hint.objectType ) + { + %hintId = %hint; + break; + } + else if ( isMemberOfClass( %objClass, %hint.objectType ) ) + { + %hintId = %hint; + } + } + ShapeEdHintMenu.setSelected( %hintId ); +} + +// Find all DTS or COLLADA models. Note: most of this section was shamelessly +// stolen from creater.ed.cs => great work whoever did the original! +function ShapeEdSelectWindow::navigate( %this, %address ) +{ + // Freeze the icon array so it doesn't update until we've added all of the + // icons + %this-->shapeLibrary.frozen = true; + %this-->shapeLibrary.clear(); + ShapeEdSelectMenu.clear(); + + %filePatterns = getFormatExtensions(); + %fullPath = findFirstFileMultiExpr( %filePatterns ); + + while ( %fullPath !$= "" ) + { + // Ignore cached DTS files + if ( endswith( %fullPath, "cached.dts" ) ) + { + %fullPath = findNextFileMultiExpr( %filePatterns ); + continue; + } + + // Ignore assets in the tools folder + %fullPath = makeRelativePath( %fullPath, getMainDotCSDir() ); + %splitPath = strreplace( %fullPath, " ", "_" ); + %splitPath = strreplace( %splitPath, "/", " " ); + if ( getWord( %splitPath, 0 ) $= "tools" ) + { + %fullPath = findNextFileMultiExpr( %filePatterns ); + continue; + } + + %dirCount = getWordCount( %splitPath ) - 1; + %pathFolders = getWords( %splitPath, 0, %dirCount - 1 ); + + // Add this file's path ( parent folders ) to the + // popup menu if it isn't there yet. + %temp = strreplace( %pathFolders, " ", "/" ); + %temp = strreplace( %temp, "_", " " ); + %r = ShapeEdSelectMenu.findText( %temp ); + if ( %r == -1 ) + ShapeEdSelectMenu.add( %temp ); + + // Is this file in the current folder? + if ( stricmp( %pathFolders, %address ) == 0 ) + { + %this.addShapeIcon( %fullPath ); + } + // Then is this file in a subfolder we need to add + // a folder icon for? + else + { + %wordIdx = 0; + %add = false; + + if ( %address $= "" ) + { + %add = true; + %wordIdx = 0; + } + else + { + for ( ; %wordIdx < %dirCount; %wordIdx++ ) + { + %temp = getWords( %splitPath, 0, %wordIdx ); + if ( stricmp( %temp, %address ) == 0 ) + { + %add = true; + %wordIdx++; + break; + } + } + } + + if ( %add == true ) + { + %folder = getWord( %splitPath, %wordIdx ); + + // Add folder icon if not already present + %ctrl = %this.findIconCtrl( %folder ); + if ( %ctrl == -1 ) + %this.addFolderIcon( %folder ); + } + } + + %fullPath = findNextFileMultiExpr( %filePatterns ); + } + + %this-->shapeLibrary.sort( "alphaIconCompare" ); + for ( %i = 0; %i < %this-->shapeLibrary.getCount(); %i++ ) + %this-->shapeLibrary.getObject( %i ).autoSize = false; + + %this-->shapeLibrary.frozen = false; + %this-->shapeLibrary.refresh(); + %this.address = %address; + + ShapeEdSelectMenu.sort(); + + %str = strreplace( %address, " ", "/" ); + %r = ShapeEdSelectMenu.findText( %str ); + if ( %r != -1 ) + ShapeEdSelectMenu.setSelected( %r, false ); + else + ShapeEdSelectMenu.setText( %str ); +} + +function ShapeEdSelectWindow::navigateDown( %this, %folder ) +{ + if ( %this.address $= "" ) + %address = %folder; + else + %address = %this.address SPC %folder; + + // Because this is called from an IconButton::onClick command + // we have to wait a tick before actually calling navigate, else + // we would delete the button out from under itself. + %this.schedule( 1, "navigate", %address ); +} + +function ShapeEdSelectWindow::navigateUp( %this ) +{ + %count = getWordCount( %this.address ); + + if ( %count == 0 ) + return; + + if ( %count == 1 ) + %address = ""; + else + %address = getWords( %this.address, 0, %count - 2 ); + + %this.navigate( %address ); +} + +function ShapeEdSelectWindow::findIconCtrl( %this, %name ) +{ + for ( %i = 0; %i < %this-->shapeLibrary.getCount(); %i++ ) + { + %ctrl = %this-->shapeLibrary.getObject( %i ); + if ( %ctrl.text $= %name ) + return %ctrl; + } + return -1; +} + +function ShapeEdSelectWindow::createIcon( %this ) +{ + %ctrl = new GuiIconButtonCtrl() + { + profile = "GuiCreatorIconButtonProfile"; + iconLocation = "Left"; + textLocation = "Right"; + extent = "348 19"; + textMargin = 8; + buttonMargin = "2 2"; + autoSize = false; + sizeIconToButton = true; + makeIconSquare = true; + buttonType = "radioButton"; + groupNum = "-1"; + }; + + return %ctrl; +} + +function ShapeEdSelectWindow::addFolderIcon( %this, %text ) +{ + %ctrl = %this.createIcon(); + + %ctrl.altCommand = "ShapeEdSelectWindow.navigateDown( \"" @ %text @ "\" );"; + %ctrl.iconBitmap = "tools/gui/images/folder.png"; + %ctrl.text = %text; + %ctrl.tooltip = %text; + %ctrl.class = "CreatorFolderIconBtn"; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + %this-->shapeLibrary.addGuiControl( %ctrl ); +} + +function ShapeEdSelectWindow::addShapeIcon( %this, %fullPath ) +{ + %ctrl = %this.createIcon(); + + %ext = fileExt( %fullPath ); + %file = fileBase( %fullPath ); + %fileLong = %file @ %ext; + %tip = %fileLong NL + "Size: " @ fileSize( %fullPath ) / 1000.0 SPC "KB" NL + "Date Created: " @ fileCreatedTime( %fullPath ) NL + "Last Modified: " @ fileModifiedTime( %fullPath ); + + %ctrl.altCommand = "ShapeEdSelectWindow.onSelect( \"" @ %fullPath @ "\" );"; + %ctrl.iconBitmap = ( ( %ext $= ".dts" ) ? EditorIconRegistry::findIconByClassName( "TSStatic" ) : "tools/gui/images/iconCollada" ); + %ctrl.text = %file; + %ctrl.class = "CreatorStaticIconBtn"; + %ctrl.tooltip = %tip; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + // Check if a shape specific icon is available + %formats = ".png .jpg .dds .bmp .gif .jng .tga"; + %count = getWordCount( %formats ); + for ( %i = 0; %i < %count; %i++ ) + { + %ext = getWord( %formats, %i ); + if ( isFile( %fullPath @ %ext ) ) + { + %ctrl.iconBitmap = %fullPath @ %ext; + break; + } + } + + %this-->shapeLibrary.addGuiControl( %ctrl ); +} + +function ShapeEdSelectMenu::onSelect( %this, %id, %text ) +{ + %split = strreplace( %text, "/", " " ); + ShapeEdSelectWindow.navigate( %split ); +} + +// Update the GUI in response to the shape selection changing +function ShapeEdPropWindow::update_onShapeSelectionChanged( %this ) +{ + // --- NODES TAB --- + ShapeEdNodeTreeView.removeItem( 0 ); + %rootId = ShapeEdNodeTreeView.insertItem( 0, "<root>", 0, "" ); + %count = ShapeEditor.shape.getNodeCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %name = ShapeEditor.shape.getNodeName( %i ); + if ( ShapeEditor.shape.getNodeParentName( %name ) $= "" ) + ShapeEdNodeTreeView.addNodeTree( %name ); + } + %this.update_onNodeSelectionChanged( -1 ); // no node selected + + // --- SEQUENCES TAB --- + ShapeEdSequenceList.clear(); + ShapeEdSequenceList.addRow( -1, "Name" TAB "Cyclic" TAB "Blend" TAB "Frames" TAB "Priority" ); + ShapeEdSequenceList.setRowActive( -1, false ); + ShapeEdSequenceList.addRow( 0, "<rootpose>" TAB "" TAB "" TAB "" TAB "" ); + + %count = ShapeEditor.shape.getSequenceCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %name = ShapeEditor.shape.getSequenceName( %i ); + + // Ignore __backup__ sequences (only used by editor) + if ( !startswith( %name, "__backup__" ) ) + ShapeEdSequenceList.addItem( %name ); + } + ShapeEdThreadWindow.onAddThread(); // add thread 0 + + // --- DETAILS TAB --- + // Add detail levels and meshes to tree + ShapeEdDetailTree.clearSelection(); + ShapeEdDetailTree.removeItem( 0 ); + %root = ShapeEdDetailTree.insertItem( 0, "<root>", "", "" ); + %objCount = ShapeEditor.shape.getObjectCount(); + for ( %i = 0; %i < %objCount; %i++ ) + { + %objName = ShapeEditor.shape.getObjectName( %i ); + %meshCount = ShapeEditor.shape.getMeshCount( %objName ); + for ( %j = 0; %j < %meshCount; %j++ ) + { + %meshName = ShapeEditor.shape.getMeshName( %objName, %j ); + ShapeEdDetailTree.addMeshEntry( %meshName, 1 ); + } + } + + // Initialise object node list + ShapeEdDetails-->objectNode.clear(); + ShapeEdDetails-->objectNode.add( "<root>" ); + %nodeCount = ShapeEditor.shape.getNodeCount(); + for ( %i = 0; %i < %nodeCount; %i++ ) + ShapeEdDetails-->objectNode.add( ShapeEditor.shape.getNodeName( %i ) ); + + // --- MATERIALS TAB --- + ShapeEdMaterials.updateMaterialList(); +} + +//------------------------------------------------------------------------------ +// Shape Hints +//------------------------------------------------------------------------------ + +function ShapeEdHintMenu::onSelect( %this, %id, %text ) +{ + ShapeEdSelectWindow.updateHints(); +} + +function ShapeEdSelectWindow::updateHints( %this ) +{ + %objectType = ShapeEdHintMenu.getText(); + + ShapeEdSelectWindow-->nodeHints.freeze( true ); + ShapeEdSelectWindow-->sequenceHints.freeze( true ); + + // Move all current hint controls to a holder SimGroup + for ( %i = ShapeEdSelectWindow-->nodeHints.getCount()-1; %i >= 0; %i-- ) + ShapeHintControls.add( ShapeEdSelectWindow-->nodeHints.getObject( %i ) ); + for ( %i = ShapeEdSelectWindow-->sequenceHints.getCount()-1; %i >= 0; %i-- ) + ShapeHintControls.add( ShapeEdSelectWindow-->sequenceHints.getObject( %i ) ); + + // Update node and sequence hints, modifying and/or creating gui controls as needed + for ( %i = 0; %i < ShapeHintGroup.getCount(); %i++ ) + { + %hint = ShapeHintGroup.getObject( %i ); + if ( ( %objectType $= %hint.objectType ) || isMemberOfClass( %objectType, %hint.objectType ) ) + { + for ( %idx = 0; %hint.node[%idx] !$= ""; %idx++ ) + ShapeEdHintMenu.processHint( "node", %hint.node[%idx] ); + + for ( %idx = 0; %hint.sequence[%idx] !$= ""; %idx++ ) + ShapeEdHintMenu.processHint( "sequence", %hint.sequence[%idx] ); + } + } + + ShapeEdSelectWindow-->nodeHints.freeze( false ); + ShapeEdSelectWindow-->nodeHints.updateStack(); + ShapeEdSelectWindow-->sequenceHints.freeze( false ); + ShapeEdSelectWindow-->sequenceHints.updateStack(); + +} + +function ShapeEdHintMenu::processHint( %this, %type, %hint ) +{ + %name = getField( %hint, 0 ); + %desc = getField( %hint, 1 ); + + // check for arrayed names (ending in 0-N or 1-N) + %pos = strstr( %name, "0-" ); + if ( %pos == -1 ) + %pos = strstr( %name, "1-" ); + + if ( %pos > 0 ) + { + // arrayed name => add controls for each name in the array, but collapse + // consecutive indices where possible. eg. if the model only has nodes + // mount1-3, we should create: mount0 (red), mount1-3 (green), mount4-31 (red) + %base = getSubStr( %name, 0, %pos ); // array name + %first = getSubStr( %name, %pos, 1 ); // first index + %last = getSubStr( %name, %pos+2, 3 ); // last index + + // get the state of the first element + %arrayStart = %first; + %prevPresent = ShapeEditor.hintNameExists( %type, %base @ %first ); + + for ( %j = %first + 1; %j <= %last; %j++ ) + { + // if the state of this element is different to the previous one, we + // need to add a hint + %present = ShapeEditor.hintNameExists( %type, %base @ %j ); + if ( %present != %prevPresent ) + { + ShapeEdSelectWindow.addObjectHint( %type, %base, %desc, %prevPresent, %arrayStart, %j-1 ); + %arrayStart = %j; + %prevPresent = %present; + } + } + + // add hint for the last group + ShapeEdSelectWindow.addObjectHint( %type, %base, %desc, %prevPresent, %arrayStart, %last ); + } + else + { + // non-arrayed name + %present = ShapeEditor.hintNameExists( %type, %name ); + ShapeEdSelectWindow.addObjectHint( %type, %name, %desc, %present ); + } +} + +function ShapeEdSelectWindow::addObjectHint( %this, %type, %name, %desc, %present, %start, %end ) +{ + // Get a hint gui control (create one if needed) + if ( ShapeHintControls.getCount() == 0 ) + { + // Create a new hint gui control + %ctrl = new GuiIconButtonCtrl() + { + profile = "GuiCreatorIconButtonProfile"; + iconLocation = "Left"; + textLocation = "Right"; + extent = "348 19"; + textMargin = 8; + buttonMargin = "2 2"; + autoSize = true; + buttonType = "radioButton"; + groupNum = "-1"; + iconBitmap = "tools/editorClasses/gui/images/iconCancel"; + text = "hint"; + tooltip = ""; + }; + + ShapeHintControls.add( %ctrl ); + } + %ctrl = ShapeHintControls.getObject( 0 ); + + // Initialise the control, then add it to the appropriate list + %name = %name @ %start; + if ( %end !$= %start ) + %ctrl.text = %name @ "-" @ %end; + else + %ctrl.text = %name; + + %ctrl.tooltip = %desc; + %ctrl.setBitmap( "tools/editorClasses/gui/images/" @ ( %present ? "iconAccept" : "iconCancel" ) ); + %ctrl.setStateOn( false ); + %ctrl.resetState(); + + switch$ ( %type ) + { + case "node": + %ctrl.altCommand = %present ? "" : "ShapeEdNodes.onAddNode( \"" @ %name @ "\" );"; + ShapeEdSelectWindow-->nodeHints.addGuiControl( %ctrl ); + case "sequence": + %ctrl.altCommand = %present ? "" : "ShapeEdSequences.onAddSequence( \"" @ %name @ "\" );"; + ShapeEdSelectWindow-->sequenceHints.addGuiControl( %ctrl ); + } +} + +//------------------------------------------------------------------------------ + +function ShapeEdSeqNodeTabBook::onTabSelected( %this, %name, %index ) +{ + %this.activePage = %name; + + switch$ ( %name ) + { + case "Seq": + ShapeEdPropWindow-->newBtn.ToolTip = "Add new sequence"; + ShapeEdPropWindow-->newBtn.Command = "ShapeEdSequences.onAddSequence();"; + ShapeEdPropWindow-->newBtn.setActive( true ); + ShapeEdPropWindow-->deleteBtn.ToolTip = "Delete selected sequence (cannot be undone)"; + ShapeEdPropWindow-->deleteBtn.Command = "ShapeEdSequences.onDeleteSequence();"; + ShapeEdPropWindow-->deleteBtn.setActive( true ); + + case "Node": + ShapeEdPropWindow-->newBtn.ToolTip = "Add new node"; + ShapeEdPropWindow-->newBtn.Command = "ShapeEdNodes.onAddNode();"; + ShapeEdPropWindow-->newBtn.setActive( true ); + ShapeEdPropWindow-->deleteBtn.ToolTip = "Delete selected node (cannot be undone)"; + ShapeEdPropWindow-->deleteBtn.Command = "ShapeEdNodes.onDeleteNode();"; + ShapeEdPropWindow-->deleteBtn.setActive( true ); + + case "Detail": + ShapeEdPropWindow-->newBtn.ToolTip = ""; + ShapeEdPropWindow-->newBtn.Command = ""; + ShapeEdPropWindow-->newBtn.setActive( false ); + ShapeEdPropWindow-->deleteBtn.ToolTip = "Delete the selected mesh or detail level (cannot be undone)"; + ShapeEdPropWindow-->deleteBtn.Command = "ShapeEdDetails.onDeleteMesh();"; + ShapeEdPropWindow-->deleteBtn.setActive( true ); + + case "Mat": + ShapeEdPropWindow-->newBtn.ToolTip = ""; + ShapeEdPropWindow-->newBtn.Command = ""; + ShapeEdPropWindow-->newBtn.setActive( false ); + ShapeEdPropWindow-->deleteBtn.ToolTip = ""; + ShapeEdPropWindow-->deleteBtn.Command = ""; + ShapeEdPropWindow-->deleteBtn.setActive( false ); + + // For some reason, the header is not resized correctly until the Materials tab has been + // displayed at least once, so resize it here too + ShapeEdMaterials-->materialListHeader.setExtent( getWord( ShapeEdMaterialList.extent, 0 ) SPC "19" ); + } +} + +//------------------------------------------------------------------------------ +// Node Editing +//------------------------------------------------------------------------------ + +// Update the GUI in response to the node selection changing +function ShapeEdPropWindow::update_onNodeSelectionChanged( %this, %id ) +{ + if ( %id > 0 ) + { + // Enable delete button and edit boxes + if ( ShapeEdSeqNodeTabBook.activePage $= "Node" ) + ShapeEdPropWindow-->deleteBtn.setActive( true ); + ShapeEdNodes-->nodeName.setActive( true ); + ShapeEdNodes-->nodePosition.setActive( true ); + ShapeEdNodes-->nodeRotation.setActive( true ); + + // Update the node inspection data + %name = ShapeEdNodeTreeView.getItemText( %id ); + + ShapeEdNodes-->nodeName.setText( %name ); + + // Node parent list => ancestor and sibling nodes only (can't re-parent to a descendent) + ShapeEdNodeParentMenu.clear(); + %parentNames = ShapeEditor.getNodeNames( "", "<root>", %name ); + %count = getWordCount( %parentNames ); + for ( %i = 0; %i < %count; %i++ ) + ShapeEdNodeParentMenu.add( getWord(%parentNames, %i), %i ); + + %pName = ShapeEditor.shape.getNodeParentName( %name ); + if ( %pName $= "" ) + %pName = "<root>"; + ShapeEdNodeParentMenu.setText( %pName ); + + if ( ShapeEdNodes-->worldTransform.getValue() ) + { + // Global transform + %txfm = ShapeEditor.shape.getNodeTransform( %name, 1 ); + ShapeEdNodes-->nodePosition.setText( getWords( %txfm, 0, 2 ) ); + ShapeEdNodes-->nodeRotation.setText( getWords( %txfm, 3, 6 ) ); + } + else + { + // Local transform (relative to parent) + %txfm = ShapeEditor.shape.getNodeTransform( %name, 0 ); + ShapeEdNodes-->nodePosition.setText( getWords( %txfm, 0, 2 ) ); + ShapeEdNodes-->nodeRotation.setText( getWords( %txfm, 3, 6 ) ); + } + + ShapeEdShapeView.selectedNode = ShapeEditor.shape.getNodeIndex( %name ); + } + else + { + // Disable delete button and edit boxes + if ( ShapeEdSeqNodeTabBook.activePage $= "Node" ) + ShapeEdPropWindow-->deleteBtn.setActive( false ); + ShapeEdNodes-->nodeName.setActive( false ); + ShapeEdNodes-->nodePosition.setActive( false ); + ShapeEdNodes-->nodeRotation.setActive( false ); + + ShapeEdNodes-->nodeName.setText( "" ); + ShapeEdNodes-->nodePosition.setText( "" ); + ShapeEdNodes-->nodeRotation.setText( "" ); + + ShapeEdShapeView.selectedNode = -1; + } +} + +// Update the GUI in response to a node being added +function ShapeEdPropWindow::update_onNodeAdded( %this, %nodeName, %oldTreeIndex ) +{ + // --- MISC --- + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.updateNodeTransforms(); + ShapeEdSelectWindow.updateHints(); + + // --- MOUNT WINDOW --- + if ( ShapeEdMountWindow.isMountableNode( %nodeName ) ) + { + ShapeEdMountWindow-->mountNode.add( %nodeName ); + ShapeEdMountWindow-->mountNode.sort(); + } + + // --- NODES TAB --- + %id = ShapeEdNodeTreeView.addNodeTree( %nodeName ); + if ( %oldTreeIndex <= 0 ) + { + // This is a new node => make it the current selection + if ( %id > 0 ) + { + ShapeEdNodeTreeView.clearSelection(); + ShapeEdNodeTreeView.selectItem( %id ); + } + } + else + { + // This node has been un-deleted. Inserting a new item puts it at the + // end of the siblings, but we want to restore the original order as + // if the item was never deleted, so move it up as required. + %childIndex = ShapeEdNodeTreeView.getChildIndexByName( %nodeName ); + while ( %childIndex > %oldTreeIndex ) + { + ShapeEdNodeTreeView.moveItemUp( %id ); + %childIndex--; + } + } + + // --- DETAILS TAB --- + ShapeEdDetails-->objectNode.add( %nodeName ); +} + +// Update the GUI in response to a node(s) being removed +function ShapeEdPropWindow::update_onNodeRemoved( %this, %nameList, %nameCount ) +{ + // --- MISC --- + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.updateNodeTransforms(); + ShapeEdSelectWindow.updateHints(); + + // Remove nodes from the mountable list, and any shapes mounted to the node + for ( %i = 0; %i < %nameCount; %i++ ) + { + %nodeName = getField( %nameList, %i ); + ShapeEdMountWindow-->mountNode.clearEntry( ShapeEdMountWindow-->mountNode.findText( %nodeName ) ); + + for ( %j = ShapeEdMountWindow-->mountList.rowCount()-1; %j >= 1; %j-- ) + { + %text = ShapeEdMountWindow-->mountList.getRowText( %j ); + if ( getField( %text, 1 ) $= %nodeName ) + { + ShapeEdShapeView.unmountShape( %j-1 ); + ShapeEdMountWindow-->mountList.removeRow( %j ); + } + } + } + + // --- NODES TAB --- + %lastName = getField( %nameList, %nameCount-1 ); + %id = ShapeEdNodeTreeView.findItemByName( %lastName ); // only need to remove the parent item + if ( %id > 0 ) + { + ShapeEdNodeTreeView.removeItem( %id ); + if ( ShapeEdNodeTreeView.getSelectedItem() <= 0 ) + ShapeEdPropWindow.update_onNodeSelectionChanged( -1 ); + } + + // --- DETAILS TAB --- + for ( %i = 0; %i < %nameCount; %i++ ) + { + %nodeName = getField( %nameList, %i ); + ShapeEdDetails-->objectNode.clearEntry( ShapeEdDetails-->objectNode.findText( %nodeName ) ); + } +} + +// Update the GUI in response to a node being renamed +function ShapeEdPropWindow::update_onNodeRenamed( %this, %oldName, %newName ) +{ + // --- MISC --- + ShapeEdSelectWindow.updateHints(); + + // --- MOUNT WINDOW --- + // Update entries for any shapes mounted to this node + %rowCount = ShapeEdMountWindow-->mountList.rowCount(); + for ( %i = 1; %i < %rowCount; %i++ ) + { + %text = ShapeEdMountWindow-->mountList.getRowText( %i ); + if ( getField( %text, 1 ) $= %oldName ) + { + %text = setField( %text, 1, %newName ); + ShapeEdMountWindow-->mountList.setRowById( ShapeEdMountWindow-->mountList.getRowId( %i ), %text ); + } + } + + // Update list of mountable nodes + ShapeEdMountWindow-->mountNode.clearEntry( ShapeEdMountWindow-->mountNode.findText( %oldName ) ); + if ( ShapeEdMountWindow.isMountableNode( %newName ) ) + { + ShapeEdMountWindow-->mountNode.add( %newName ); + ShapeEdMountWindow-->mountNode.sort(); + } + + // --- NODES TAB --- + %id = ShapeEdNodeTreeView.findItemByName( %oldName ); + ShapeEdNodeTreeView.editItem( %id, %newName, 0 ); + if ( ShapeEdNodeTreeView.getSelectedItem() == %id ) + ShapeEdNodes-->nodeName.setText( %newName ); + + // --- DETAILS TAB --- + %id = ShapeEdDetails-->objectNode.findText( %oldName ); + if ( %id != -1 ) + { + ShapeEdDetails-->objectNode.clearEntry( %id ); + ShapeEdDetails-->objectNode.add( %newName, %id ); + ShapeEdDetails-->objectNode.sortID(); + if ( ShapeEdDetails-->objectNode.getText() $= %oldName ) + ShapeEdDetails-->objectNode.setText( %newName ); + } +} + +// Update the GUI in response to a node's parent being changed +function ShapeEdPropWindow::update_onNodeParentChanged( %this, %nodeName ) +{ + // --- MISC --- + ShapeEdShapeView.updateNodeTransforms(); + + // --- NODES TAB --- + %isSelected = 0; + %id = ShapeEdNodeTreeView.findItemByName( %nodeName ); + if ( %id > 0 ) + { + %isSelected = ( ShapeEdNodeTreeView.getSelectedItem() == %id ); + ShapeEdNodeTreeView.removeItem( %id ); + } + ShapeEdNodeTreeView.addNodeTree( %nodeName ); + if ( %isSelected ) + ShapeEdNodeTreeView.selectItem( ShapeEdNodeTreeView.findItemByName( %nodeName ) ); +} + +function ShapeEdPropWindow::update_onNodeTransformChanged( %this, %nodeName ) +{ + // Default to the selected node if none is specified + if ( %nodeName $= "" ) + { + %id = ShapeEdNodeTreeView.getSelectedItem(); + if ( %id > 0 ) + %nodeName = ShapeEdNodeTreeView.getItemText( %id ); + else + return; + } + + // --- MISC --- + ShapeEdShapeView.updateNodeTransforms(); + if ( ShapeEdNodes-->objectTransform.getValue() ) + GlobalGizmoProfile.setFieldValue(alignment, Object); + else + GlobalGizmoProfile.setFieldValue(alignment, World); + + // --- NODES TAB --- + // Update the node transform fields if necessary + %id = ShapeEdNodeTreeView.getSelectedItem(); + if ( ( %id > 0 ) && ( ShapeEdNodeTreeView.getItemText( %id ) $= %nodeName ) ) + { + %isWorld = ShapeEdNodes-->worldTransform.getValue(); + %transform = ShapeEditor.shape.getNodeTransform( %nodeName, %isWorld ); + ShapeEdNodes-->nodePosition.setText( getWords( %transform, 0, 2 ) ); + ShapeEdNodes-->nodeRotation.setText( getWords( %transform, 3, 6 ) ); + } +} + +function ShapeEdNodeTreeView::onClearSelection( %this ) +{ + ShapeEdPropWindow.update_onNodeSelectionChanged( -1 ); +} + +function ShapeEdNodeTreeView::onSelect( %this, %id ) +{ + // Update the node name and transform controls + ShapeEdPropWindow.update_onNodeSelectionChanged( %id ); + + // Update orbit position if orbiting the selected node + if ( ShapeEdShapeView.orbitNode ) + { + %name = %this.getItemText( %id ); + %transform = ShapeEditor.shape.getNodeTransform( %name, 1 ); + ShapeEdShapeView.setOrbitPos( getWords( %transform, 0, 2 ) ); + } +} + +function ShapeEdShapeView::onNodeSelected( %this, %index ) +{ + ShapeEdNodeTreeView.clearSelection(); + if ( %index > 0 ) + { + %name = ShapeEditor.shape.getNodeName( %index ); + %id = ShapeEdNodeTreeView.findItemByName( %name ); + if ( %id > 0 ) + ShapeEdNodeTreeView.selectItem( %id ); + } +} + +function ShapeEdNodes::onAddNode( %this, %name ) +{ + // Add a new node, using the currently selected node as the initial parent + if ( %name $= "" ) + %name = ShapeEditor.getUniqueName( "node", "myNode" ); + + %id = ShapeEdNodeTreeView.getSelectedItem(); + if ( %id <= 0 ) + %parent = ""; + else + %parent = ShapeEdNodeTreeView.getItemText( %id ); + + ShapeEditor.doAddNode( %name, %parent, "0 0 0 0 0 1 0" ); +} + +function ShapeEdNodes::onDeleteNode( %this ) +{ + // Remove the node and all its children from the shape + %id = ShapeEdNodeTreeView.getSelectedItem(); + if ( %id > 0 ) + { + %name = ShapeEdNodeTreeView.getItemText( %id ); + ShapeEditor.doRemoveShapeData( "Node", %name ); + } +} + +// Determine the index of a node in the tree relative to its parent +function ShapeEdNodeTreeView::getChildIndexByName( %this, %name ) +{ + %id = %this.findItemByName( %name ); + %parentId = %this.getParentItem( %id ); + %childId = %this.getChild( %parentId ); + if ( %childId <= 0 ) + return 0; // bad! + + %index = 0; + while ( %childId != %id ) + { + %childId = %this.getNextSibling( %childId ); + %index++; + } + + return %index; +} + +// Add a node and its children to the node tree view +function ShapeEdNodeTreeView::addNodeTree( %this, %nodeName ) +{ + // Abort if already added => something dodgy has happened and we'd end up + // recursing indefinitely + if ( %this.findItemByName( %nodeName ) ) + { + error( "Recursion error in ShapeEdNodeTreeView::addNodeTree" ); + return 0; + } + + // Find parent and add me to it + %parentName = ShapeEditor.shape.getNodeParentName( %nodeName ); + if ( %parentName $= "" ) + %parentName = "<root>"; + + %parentId = %this.findItemByName( %parentName ); + %id = %this.insertItem( %parentId, %nodeName, 0, "" ); + + // Add children + %count = ShapeEditor.shape.getNodeChildCount( %nodeName ); + for ( %i = 0; %i < %count; %i++ ) + %this.addNodeTree( ShapeEditor.shape.getNodeChildName( %nodeName, %i ) ); + + return %id; +} + +function ShapeEdNodes::onEditName( %this ) +{ + %id = ShapeEdNodeTreeView.getSelectedItem(); + if ( %id > 0 ) + { + %oldName = ShapeEdNodeTreeView.getItemText( %id ); + %newName = %this-->nodeName.getText(); + if ( %newName !$= "" ) + ShapeEditor.doRenameNode( %oldName, %newName ); + } +} + +function ShapeEdNodeParentMenu::onSelect( %this, %id, %text ) +{ + %id = ShapeEdNodeTreeView.getSelectedItem(); + if ( %id > 0 ) + { + %name = ShapeEdNodeTreeView.getItemText( %id ); + ShapeEditor.doSetNodeParent( %name, %text ); + } +} + +function ShapeEdNodes::onEditTransform( %this ) +{ + %id = ShapeEdNodeTreeView.getSelectedItem(); + if ( %id > 0 ) + { + %name = ShapeEdNodeTreeView.getItemText( %id ); + + // Get the node transform from the gui + %pos = %this-->nodePosition.getText(); + %rot = %this-->nodeRotation.getText(); + %txfm = %pos SPC %rot; + %isWorld = ShapeEdNodes-->worldTransform.getValue(); + + // Do a quick sanity check to avoid setting wildly invalid transforms + for ( %i = 0; %i < 7; %i++ ) // "x y z aa.x aa.y aa.z aa.angle" + { + if ( getWord( %txfm, %i ) $= "" ) + return; + } + + ShapeEditor.doEditNodeTransform( %name, %txfm, %isWorld, -1 ); + } +} + +function ShapeEdShapeView::onEditNodeTransform( %this, %node, %txfm, %gizmoID ) +{ + ShapeEditor.doEditNodeTransform( %node, %txfm, 1, %gizmoID ); +} + +//------------------------------------------------------------------------------ +// Sequence Editing +//------------------------------------------------------------------------------ + +function ShapeEdPropWindow::onWake( %this ) +{ + ShapeEdTriggerList.triggerId = 1; + + ShapeEdTriggerList.addRow( -1, "-1" TAB "Frame" TAB "Trigger" TAB "State" ); + ShapeEdTriggerList.setRowActive( -1, false ); +} + +function ShapeEdPropWindow::update_onSeqSelectionChanged( %this ) +{ + // Sync the Thread window sequence selection + %row = ShapeEdSequenceList.getSelectedRow(); + if ( ShapeEdThreadWindow-->seqList.getSelectedRow() != ( %row-1 ) ) + { + ShapeEdThreadWindow-->seqList.setSelectedRow( %row-1 ); + return; // selecting a sequence in the Thread window will re-call this function + } + + ShapeEdSeqFromMenu.clear(); + ShapeEdSequences-->blendSeq.clear(); + + // Clear the trigger list + ShapeEdTriggerList.removeAll(); + + // Update the active sequence data + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + // Enable delete button and edit boxes + if ( ShapeEdSeqNodeTabBook.activePage $= "Seq" ) + ShapeEdPropWindow-->deleteBtn.setActive( true ); + ShapeEdSequences-->seqName.setActive( true ); + ShapeEdSequences-->blendFlag.setActive( true ); + ShapeEdSequences-->cyclicFlag.setActive( true ); + ShapeEdSequences-->priority.setActive( true ); + ShapeEdSequences-->addTriggerBtn.setActive( true ); + ShapeEdSequences-->deleteTriggerBtn.setActive( true ); + + // Initialise the sequence properties + %blendData = ShapeEditor.shape.getSequenceBlend( %seqName ); + ShapeEdSequences-->seqName.setText( %seqName ); + ShapeEdSequences-->cyclicFlag.setValue( ShapeEditor.shape.getSequenceCyclic( %seqName ) ); + ShapeEdSequences-->blendFlag.setValue( getField( %blendData, 0 ) ); + ShapeEdSequences-->priority.setText( ShapeEditor.shape.getSequencePriority( %seqName ) ); + + // 'From' and 'Blend' sequence menus + ShapeEdSeqFromMenu.add( "Browse..." ); + %count = ShapeEdSequenceList.rowCount(); + for ( %i = 2; %i < %count; %i++ ) // skip header row and <rootpose> + { + %name = ShapeEdSequenceList.getItemName( %i ); + if ( %name !$= %seqName ) + { + ShapeEdSeqFromMenu.add( %name ); + ShapeEdSequences-->blendSeq.add( %name ); + } + } + ShapeEdSequences-->blendSeq.setText( getField( %blendData, 1 ) ); + ShapeEdSequences-->blendFrame.setText( getField( %blendData, 2 ) ); + + %this.syncPlaybackDetails(); + + // Triggers (must occur after syncPlaybackDetails is called so the slider range is correct) + %count = ShapeEditor.shape.getTriggerCount( %seqName ); + for ( %i = 0; %i < %count; %i++ ) + { + %trigger = ShapeEditor.shape.getTrigger( %seqName, %i ); + ShapeEdTriggerList.addItem( getWord( %trigger, 0 ), getWord( %trigger, 1 ) ); + } + } + else + { + // Disable delete button and edit boxes + if ( ShapeEdSeqNodeTabBook.activePage $= "Seq" ) + ShapeEdPropWindow-->deleteBtn.setActive( false ); + ShapeEdSequences-->seqName.setActive( false ); + ShapeEdSequences-->blendFlag.setActive( false ); + ShapeEdSequences-->cyclicFlag.setActive( false ); + ShapeEdSequences-->priority.setActive( false ); + ShapeEdSequences-->addTriggerBtn.setActive( false ); + ShapeEdSequences-->deleteTriggerBtn.setActive( false ); + + // Clear sequence properties + ShapeEdSequences-->seqName.setText( "" ); + ShapeEdSequences-->cyclicFlag.setValue( 0 ); + ShapeEdSequences-->blendSeq.setText( "" ); + ShapeEdSequences-->blendFlag.setValue( 0 ); + ShapeEdSequences-->priority.setText( 0 ); + + %this.syncPlaybackDetails(); + } + + %this.onTriggerSelectionChanged(); + + ShapeEdSequences-->sequenceListHeader.setExtent( getWord( ShapeEdSequenceList.extent, 0 ) SPC "19" ); + + // Reset current frame + //ShapeEdAnimWindow.setKeyframe( ShapeEdAnimWindow-->seqIn.getText() ); +} + +// Update the GUI in response to a sequence being added +function ShapeEdPropWindow::update_onSequenceAdded( %this, %seqName, %oldIndex ) +{ + // --- MISC --- + ShapeEdSelectWindow.updateHints(); + + // --- SEQUENCES TAB --- + if ( %oldIndex == -1 ) + { + // This is a brand new sequence => add it to the list and make it the + // current selection + %row = ShapeEdSequenceList.insertItem( %seqName, ShapeEdSequenceList.rowCount() ); + ShapeEdSequenceList.scrollVisible( %row ); + ShapeEdSequenceList.setSelectedRow( %row ); + } + else + { + // This sequence has been un-deleted => add it back to the list at the + // original position + ShapeEdSequenceList.insertItem( %seqName, %oldIndex ); + } +} + +function ShapeEdPropWindow::update_onSequenceRemoved( %this, %seqName ) +{ + // --- MISC --- + ShapeEdSelectWindow.updateHints(); + + // --- SEQUENCES TAB --- + %isSelected = ( ShapeEdSequenceList.getSelectedName() $= %seqName ); + ShapeEdSequenceList.removeItem( %seqName ); + if ( %isSelected ) + ShapeEdPropWindow.update_onSeqSelectionChanged(); + + // --- THREADS WINDOW --- + ShapeEdShapeView.refreshThreadSequences(); +} + +function ShapeEdPropWindow::update_onSequenceRenamed( %this, %oldName, %newName ) +{ + // --- MISC --- + ShapeEdSelectWindow.updateHints(); + + // Rename the proxy sequence as well + %oldProxy = ShapeEditor.getProxyName( %oldName ); + %newProxy = ShapeEditor.getProxyName( %newName ); + if ( ShapeEditor.shape.getSequenceIndex( %oldProxy ) != -1 ) + ShapeEditor.shape.renameSequence( %oldProxy, %newProxy ); + + // --- SEQUENCES TAB --- + ShapeEdSequenceList.editColumn( %oldName, 0, %newName ); + if ( ShapeEdSequenceList.getSelectedName() $= %newName ) + ShapeEdSequences-->seqName.setText( %newName ); + + // --- THREADS WINDOW --- + // Update any threads that use this sequence + %active = ShapeEdShapeView.activeThread; + for ( %i = 0; %i < ShapeEdShapeView.getThreadCount(); %i++ ) + { + ShapeEdShapeView.activeThread = %i; + if ( ShapeEdShapeView.getThreadSequence() $= %oldName ) + ShapeEdShapeView.setThreadSequence( %newName, 0, ShapeEdShapeView.threadPos, 0 ); + else if ( ShapeEdShapeView.getThreadSequence() $= %oldProxy ) + ShapeEdShapeView.setThreadSequence( %newProxy, 0, ShapeEdShapeView.threadPos, 0 ); + } + ShapeEdShapeView.activeThread = %active; +} + +function ShapeEdPropWindow::update_onSequenceCyclicChanged( %this, %seqName, %cyclic ) +{ + // --- MISC --- + // Apply the same transformation to the proxy animation if necessary + %proxyName = ShapeEditor.getProxyName( %seqName ); + if ( ShapeEditor.shape.getSequenceIndex( %proxyName ) != -1 ) + ShapeEditor.shape.setSequenceCyclic( %proxyName, %cyclic ); + + // --- SEQUENCES TAB --- + ShapeEdSequenceList.editColumn( %seqName, 1, %cyclic ? "yes" : "no" ); + if ( ShapeEdSequenceList.getSelectedName() $= %seqName ) + ShapeEdSequences-->cyclicFlag.setStateOn( %cyclic ); +} + +function ShapeEdPropWindow::update_onSequenceBlendChanged( %this, %seqName, %blend, + %oldBlendSeq, %oldBlendFrame, %blendSeq, %blendFrame ) +{ + // --- MISC --- + // Apply the same transformation to the proxy animation if necessary + %proxyName = ShapeEditor.getProxyName( %seqName ); + if ( ShapeEditor.shape.getSequenceIndex( %proxyName ) != -1 ) + { + if ( %blend && %oldBlend ) + ShapeEditor.shape.setSequenceBlend( %proxyName, false, %oldBlendSeq, %oldBlendFrame ); + ShapeEditor.shape.setSequenceBlend( %proxyName, %blend, %blendSeq, %blendFrame ); + } + ShapeEdShapeView.updateNodeTransforms(); + + // --- SEQUENCES TAB --- + ShapeEdSequenceList.editColumn( %seqName, 2, %blend ? "yes" : "no" ); + if ( ShapeEdSequenceList.getSelectedName() $= %seqName ) + { + ShapeEdSequences-->blendFlag.setStateOn( %blend ); + ShapeEdSequences-->blendSeq.setText( %blendSeq ); + ShapeEdSequences-->blendFrame.setText( %blendFrame ); + } +} + +function ShapeEdPropWindow::update_onSequencePriorityChanged( %this, %seqName ) +{ + // --- SEQUENCES TAB --- + %priority = ShapeEditor.shape.getSequencePriority( %seqName ); + ShapeEdSequenceList.editColumn( %seqName, 4, %priority ); + if ( ShapeEdSequenceList.getSelectedName() $= %seqName ) + ShapeEdSequences-->priority.setText( %priority ); +} + +function ShapeEdPropWindow::update_onSequenceGroundSpeedChanged( %this, %seqName ) +{ + // nothing to do yet +} + +function ShapeEdPropWindow::syncPlaybackDetails( %this ) +{ + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + // Show sequence in/out bars + ShapeEdAnimWindow-->seqInBar.setVisible( true ); + ShapeEdAnimWindow-->seqOutBar.setVisible( true ); + + // Sync playback controls + %sourceData = ShapeEditor.getSequenceSource( %seqName ); + %seqFrom = rtrim( getFields( %sourceData, 0, 1 ) ); + %seqStart = getField( %sourceData, 2 ); + %seqEnd = getField( %sourceData, 3 ); + %seqFromTotal = getField( %sourceData, 4 ); + + // Display the original source for edited sequences + if ( startswith( %seqFrom, "__backup__" ) ) + { + %backupData = ShapeEditor.getSequenceSource( getField( %seqFrom, 0 ) ); + %seqFrom = rtrim( getFields( %backupData, 0, 1 ) ); + } + + ShapeEdSeqFromMenu.setText( %seqFrom ); + ShapeEdSeqFromMenu.tooltip = ShapeEdSeqFromMenu.getText(); // use tooltip to show long names + ShapeEdSequences-->startFrame.setText( %seqStart ); + ShapeEdSequences-->endFrame.setText( %seqEnd ); + + %val = ShapeEdSeqSlider.getValue() / getWord( ShapeEdSeqSlider.range, 1 ); + ShapeEdSeqSlider.range = "0" SPC ( %seqFromTotal-1 ); + ShapeEdSeqSlider.setValue( %val * getWord( ShapeEdSeqSlider.range, 1 ) ); + ShapeEdThreadSlider.range = ShapeEdSeqSlider.range; + ShapeEdThreadSlider.setValue( ShapeEdSeqSlider.value ); + + ShapeEdAnimWindow.setSequence( %seqName ); + ShapeEdAnimWindow.setPlaybackLimit( "in", %seqStart ); + ShapeEdAnimWindow.setPlaybackLimit( "out", %seqEnd ); + } + else + { + // Hide sequence in/out bars + ShapeEdAnimWindow-->seqInBar.setVisible( false ); + ShapeEdAnimWindow-->seqOutBar.setVisible( false ); + + ShapeEdSeqFromMenu.setText( "" ); + ShapeEdSeqFromMenu.tooltip = ""; + ShapeEdSequences-->startFrame.setText( 0 ); + ShapeEdSequences-->endFrame.setText( 0 ); + + ShapeEdSeqSlider.range = "0 1"; + ShapeEdSeqSlider.setValue( 0 ); + ShapeEdThreadSlider.range = ShapeEdSeqSlider.range; + ShapeEdThreadSlider.setValue( ShapeEdSeqSlider.value ); + ShapeEdAnimWindow.setPlaybackLimit( "in", 0 ); + ShapeEdAnimWindow.setPlaybackLimit( "out", 1 ); + ShapeEdAnimWindow.setSequence( "" ); + } +} + +function ShapeEdSequences::onEditSeqInOut( %this, %type, %val ) +{ + %frameCount = getWord( ShapeEdSeqSlider.range, 1 ); + + // Force value to a frame index within the slider range + %val = mRound( %val ); + if ( %val < 0 ) + %val = 0; + if ( %val > %frameCount ) + %val = %frameCount; + + // Enforce 'in' value must be < 'out' value + if ( %type $= "in" ) + { + if ( %val >= %this-->endFrame.getText() ) + %val = %this-->endFrame.getText() - 1; + %this-->startFrame.setText( %val ); + } + else + { + if ( %val <= %this-->startFrame.getText() ) + %val = %this-->startFrame.getText() + 1; + %this-->endFrame.setText( %val ); + } + + %this.onEditSequenceSource( "" ); +} + +function ShapeEdSequences::onEditSequenceSource( %this, %from ) +{ + // ignore for shapes without sequences + if (ShapeEditor.shape.getSequenceCount() == 0) + return; + + %start = %this-->startFrame.getText(); + %end = %this-->endFrame.getText(); + + if ( ( %start !$= "" ) && ( %end !$= "" ) ) + { + %seqName = ShapeEdSequenceList.getSelectedName(); + %oldSource = ShapeEditor.getSequenceSource( %seqName ); + + if ( %from $= "" ) + %from = rtrim( getFields( %oldSource, 0, 0 ) ); + + if ( getFields( %oldSource, 0, 3 ) !$= ( %from TAB "" TAB %start TAB %end ) ) + ShapeEditor.doEditSeqSource( %seqName, %from, %start, %end ); + } +} + +function ShapeEdSequences::onToggleCyclic( %this ) +{ + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + %cyclic = %this-->cyclicFlag.getValue(); + ShapeEditor.doEditCyclic( %seqName, %cyclic ); + } +} + +function ShapeEdSequences::onEditPriority( %this ) +{ + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + %newPriority = %this-->priority.getText(); + if ( %newPriority !$= "" ) + ShapeEditor.doEditSequencePriority( %seqName, %newPriority ); + } +} + +function ShapeEdSequences::onEditBlend( %this ) +{ + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + // Get the blend flags (current and new) + %oldBlendData = ShapeEditor.shape.getSequenceBlend( %seqName ); + %oldBlend = getField( %oldBlendData, 0 ); + %blend = %this-->blendFlag.getValue(); + + // Ignore changes to the blend reference for non-blend sequences + if ( !%oldBlend && !%blend ) + return; + + // OK - we're trying to change the blend properties of this sequence. The + // new reference sequence and frame must be set. + %blendSeq = %this-->blendSeq.getText(); + %blendFrame = %this-->blendFrame.getText(); + if ( ( %blendSeq $= "" ) || ( %blendFrame $= "" ) ) + { + MessageBoxOK( "Blend reference not set", "The blend reference sequence and " @ + "frame must be set before changing the blend flag or frame." ); + ShapeEdSequences-->blendFlag.setStateOn( %oldBlend ); + return; + } + + // Get the current blend properties (use new values if not specified) + %oldBlendSeq = getField( %oldBlendData, 1 ); + if ( %oldBlendSeq $= "" ) + %oldBlendSeq = %blendSeq; + %oldBlendFrame = getField( %oldBlendData, 2 ); + if ( %oldBlendFrame $= "" ) + %oldBlendFrame = %blendFrame; + + // Check if there is anything to do + if ( ( %oldBlend TAB %oldBlendSeq TAB %oldBlendFrame ) !$= ( %blend TAB %blendSeq TAB %blendFrame ) ) + ShapeEditor.doEditBlend( %seqName, %blend, %blendSeq, %blendFrame ); + } +} + +function ShapeEdSequences::onAddSequence( %this, %name ) +{ + if ( %name $= "" ) + %name = ShapeEditor.getUniqueName( "sequence", "mySequence" ); + + // Use the currently selected sequence as the base + %from = ShapeEdSequenceList.getSelectedName(); + %row = ShapeEdSequenceList.getSelectedRow(); + if ( ( %row < 2 ) && ( ShapeEdSequenceList.rowCount() > 2 ) ) + %row = 2; + if ( %from $= "" ) + { + // No sequence selected => open dialog to browse for one + getLoadFormatFilename( %this @ ".onAddSequenceFromBrowse", ShapeEdFromMenu.lastPath ); + return; + } + else + { + // Add the new sequence + %start = ShapeEdSequences-->startFrame.getText(); + %end = ShapeEdSequences-->endFrame.getText(); + ShapeEditor.doAddSequence( %name, %from, %start, %end ); + } +} + +function ShapeEdSequences::onAddSequenceFromBrowse( %this, %path ) +{ + // Add a new sequence from the browse path + %path = makeRelativePath( %path, getMainDotCSDir() ); + ShapeEdFromMenu.lastPath = %path; + + %name = ShapeEditor.getUniqueName( "sequence", "mySequence" ); + ShapeEditor.doAddSequence( %name, %path, 0, -1 ); +} + +// Delete the selected sequence +function ShapeEdSequences::onDeleteSequence( %this ) +{ + %row = ShapeEdSequenceList.getSelectedRow(); + if ( %row != -1 ) + { + %seqName = ShapeEdSequenceList.getItemName( %row ); + ShapeEditor.doRemoveShapeData( "Sequence", %seqName ); + } +} + +// Get the name of the currently selected sequence +function ShapeEdSequenceList::getSelectedName( %this ) +{ + %row = %this.getSelectedRow(); + return ( %row > 1 ) ? %this.getItemName( %row ) : ""; // ignore header row +} + +// Get the sequence name from the indexed row +function ShapeEdSequenceList::getItemName( %this, %row ) +{ + return getField( %this.getRowText( %row ), 0 ); +} + +// Get the index in the list of the sequence with the given name +function ShapeEdSequenceList::getItemIndex( %this, %name ) +{ + for ( %i = 1; %i < %this.rowCount(); %i++ ) // ignore header row + { + if ( %this.getItemName( %i ) $= %name ) + return %i; + } + return -1; +} + +// Change one of the fields in the sequence list +function ShapeEdSequenceList::editColumn( %this, %name, %col, %text ) +{ + %row = %this.getItemIndex( %name ); + %rowText = setField( %this.getRowText( %row ), %col, %text ); + + // Update the Properties and Thread sequence lists + %id = %this.getRowId( %row ); + if ( %col == 0 ) + ShapeEdThreadWindow-->seqList.setRowById( %id, %text ); // Sync name in Thread window + %this.setRowById( %id, %rowText ); +} + +function ShapeEdSequenceList::addItem( %this, %name ) +{ + return %this.insertItem( %name, %this.rowCount() ); +} + +function ShapeEdSequenceList::insertItem( %this, %name, %index ) +{ + %cyclic = ShapeEditor.shape.getSequenceCyclic( %name ) ? "yes" : "no"; + %blend = getField( ShapeEditor.shape.getSequenceBlend( %name ), 0 ) ? "yes" : "no"; + %frameCount = ShapeEditor.shape.getSequenceFrameCount( %name ); + %priority = ShapeEditor.shape.getSequencePriority( %name ); + + // Add the item to the Properties and Thread sequence lists + %this.seqId++; // use this to keep the row IDs synchronised + ShapeEdThreadWindow-->seqList.addRow( %this.seqId, %name, %index-1 ); // no header row + return %this.addRow( %this.seqId, %name TAB %cyclic TAB %blend TAB %frameCount TAB %priority, %index ); +} + +function ShapeEdSequenceList::removeItem( %this, %name ) +{ + %index = %this.getItemIndex( %name ); + if ( %index >= 0 ) + { + %this.removeRow( %index ); + ShapeEdThreadWindow-->seqList.removeRow( %index-1 ); // no header row + } +} + +function ShapeEdSeqFromMenu::onSelect( %this, %id, %text ) +{ + if ( %text $= "Browse..." ) + { + // Reset menu text + %seqName = ShapeEdSequenceList.getSelectedName(); + %seqFrom = rtrim( getFields( ShapeEditor.getSequenceSource( %seqName ), 0, 1 ) ); + %this.setText( %seqFrom ); + + // Allow the user to browse for an external source of animation data + getLoadFormatFilename( %this @ ".onBrowseSelect", %this.lastPath ); + } + else + { + ShapeEdSequences.onEditSequenceSource( %text ); + } +} + +function ShapeEdSeqFromMenu::onBrowseSelect( %this, %path ) +{ + %path = makeRelativePath( %path, getMainDotCSDir() ); + %this.lastPath = %path; + %this.setText( %path ); + ShapeEdSequences.onEditSequenceSource( %path ); +} + +//------------------------------------------------------------------------------ +// Threads and Animation +//------------------------------------------------------------------------------ + +function ShapeEdThreadWindow::onWake( %this ) +{ + %this-->useTransitions.setValue( 1 ); + %this-->transitionTime.setText( "0.5" ); + + %this-->transitionTo.clear(); + %this-->transitionTo.add( "synched position", 0 ); + %this-->transitionTo.add( "slider position", 1 ); + %this-->transitionTo.setSelected( 0 ); + + %this-->transitionTarget.clear(); + %this-->transitionTarget.add( "plays during transition", 0 ); + %this-->transitionTarget.add( "pauses during transition", 1 ); + %this-->transitionTarget.setSelected( 0 ); +} + +// Update the GUI in response to the shape selection changing +function ShapeEdThreadWindow::update_onShapeSelectionChanged( %this ) +{ + ShapeEdThreadList.clear(); + %this-->seqList.clear(); + %this-->seqList.addRow( 0, "<rootpose>" ); +} + +function ShapeEdAnimWIndow::threadPosToKeyframe( %this, %pos ) +{ + if ( %this.usingProxySeq ) + { + %start = getWord( ShapeEdSeqSlider.range, 0 ); + %end = getWord( ShapeEdSeqSlider.range, 1 ); + } + else + { + %start = ShapeEdAnimWindow.seqStartFrame; + %end = ShapeEdAnimWindow.seqEndFrame; + } + + return %start + ( %end - %start ) * %pos; +} + +function ShapeEdAnimWindow::keyframeToThreadPos( %this, %frame ) +{ + if ( %this.usingProxySeq ) + { + %start = getWord( ShapeEdSeqSlider.range, 0 ); + %end = getWord( ShapeEdSeqSlider.range, 1 ); + } + else + { + %start = ShapeEdAnimWindow.seqStartFrame; + %end = ShapeEdAnimWindow.seqEndFrame; + } + + return ( %frame - %start ) / ( %end - %start ); +} + +function ShapeEdAnimWindow::setKeyframe( %this, %frame ) +{ + ShapeEdSeqSlider.setValue( %frame ); + if ( ShapeEdThreadWindow-->transitionTo.getText() $= "synched position" ) + ShapeEdThreadSlider.setValue( %frame ); + + // Update the position of the active thread => if outside the in/out range, + // need to switch to the proxy sequence + if ( !%this.usingProxySeq ) + { + if ( ( %frame < %this.seqStartFrame ) || ( %frame > %this.seqEndFrame) ) + { + %this.usingProxySeq = true; + %proxyName = ShapeEditor.getProxyName( ShapeEdShapeView.getThreadSequence() ); + ShapeEdShapeView.setThreadSequence( %proxyName, 0, 0, false ); + } + } + + ShapeEdShapeView.threadPos = %this.keyframeToThreadPos( %frame ); +} + +function ShapeEdAnimWindow::setNoProxySequence( %this ) +{ + // no need to use the proxy sequence during playback + if ( %this.usingProxySeq ) + { + %this.usingProxySeq = false; + %seqName = ShapeEditor.getUnproxyName( ShapeEdShapeView.getThreadSequence() ); + ShapeEdShapeView.setThreadSequence( %seqName, 0, 0, false ); + ShapeEdShapeView.threadPos = %this.keyframeToThreadPos( ShapeEdSeqSlider.getValue() ); + } +} + +function ShapeEdAnimWindow::togglePause( %this ) +{ + if ( %this-->pauseBtn.getValue() == 0 ) + { + %this.lastDirBkwd = %this-->playBkwdBtn.getValue(); + %this-->pauseBtn.performClick(); + } + else + { + %this.setNoProxySequence(); + if ( %this.lastDirBkwd ) + %this-->playBkwdBtn.performClick(); + else + %this-->playFwdBtn.performClick(); + } +} + +function ShapeEdAnimWindow::togglePingPong( %this ) +{ + ShapeEdShapeView.threadPingPong = %this-->pingpong.getValue(); + if ( %this-->playFwdBtn.getValue() ) + %this-->playFwdBtn.performClick(); + else if ( %this-->playBkwdBtn.getValue() ) + %this-->playBkwdBtn.performClick(); +} + +function ShapeEdSeqSlider::onMouseDragged( %this ) +{ + // Pause the active thread when the slider is dragged + if ( ShapeEdAnimWindow-->pauseBtn.getValue() == 0 ) + ShapeEdAnimWindow-->pauseBtn.performClick(); + + ShapeEdAnimWindow.setKeyframe( %this.getValue() ); +} + +function ShapeEdThreadSlider::onMouseDragged( %this ) +{ + if ( ShapeEdThreadWindow-->transitionTo.getText() $= "synched position" ) + { + // Pause the active thread when the slider is dragged + if ( ShapeEdAnimWindow-->pauseBtn.getValue() == 0 ) + ShapeEdAnimWindow-->pauseBtn.performClick(); + + ShapeEdAnimWindow.setKeyframe( %this.getValue() ); + } +} + +function ShapeEdShapeView::onThreadPosChanged( %this, %pos, %inTransition ) +{ + // Update sliders + %frame = ShapeEdAnimWindow.threadPosToKeyframe( %pos ); + ShapeEdSeqSlider.setValue( %frame ); + + if ( ShapeEdThreadWindow-->transitionTo.getText() $= "synched position" ) + { + ShapeEdThreadSlider.setValue( %frame ); + + // Highlight the slider during transitions + if ( %inTransition ) + ShapeEdThreadSlider.profile = GuiShapeEdTransitionSliderProfile; + else + ShapeEdThreadSlider.profile = ToolsGuiSliderProfile; + } +} + +// Set the direction of the current thread (-1: reverse, 0: paused, 1: forward) +function ShapeEdAnimWindow::setThreadDirection( %this, %dir ) +{ + // Update thread direction + ShapeEdShapeView.threadDirection = %dir; + + // Sync the controls in the thread window + switch ( %dir ) + { + case -1: ShapeEdThreadWindow-->playBkwdBtn.setStateOn( 1 ); + case 0: ShapeEdThreadWindow-->pauseBtn.setStateOn( 1 ); + case 1: ShapeEdThreadWindow-->playFwdBtn.setStateOn( 1 ); + } +} + +// Set the sequence to play +function ShapeEdAnimWindow::setSequence( %this, %seqName ) +{ + %this.usingProxySeq = false; + + if ( ShapeEdThreadWindow-->useTransitions.getValue() ) + { + %transTime = ShapeEdThreadWindow-->transitionTime.getText(); + if ( ShapeEdThreadWindow-->transitionTo.getText() $= "synched position" ) + %transPos = -1; + else + %transPos = %this.keyframeToThreadPos( ShapeEdThreadSlider.getValue() ); + %transPlay = ( ShapeEdThreadWindow-->transitionTarget.getText() $= "plays during transition" ); + } + else + { + %transTime = 0; + %transPos = 0; + %transPlay = 0; + } + + // No transition when sequence is not changing + if ( %seqName $= ShapeEdShapeView.getThreadSequence() ) + %transTime = 0; + + if ( %seqName !$= "" ) + { + // To be able to effectively scrub through the animation, we need to have all + // frames available, even if it was added with only a subset. If that is the + // case, then create a proxy sequence that has all the frames instead. + %sourceData = ShapeEditor.getSequenceSource( %seqName ); + %from = rtrim( getFields( %sourceData, 0, 1 ) ); + %startFrame = getField( %sourceData, 2 ); + %endFrame = getField( %sourceData, 3 ); + %frameCount = getField( %sourceData, 4 ); + + if ( ( %startFrame != 0 ) || ( %endFrame != ( %frameCount-1 ) ) ) + { + %proxyName = ShapeEditor.getProxyName( %seqName ); + if ( ShapeEditor.shape.getSequenceIndex( %proxyName ) != -1 ) + { + ShapeEditor.shape.removeSequence( %proxyName ); + ShapeEdShapeView.refreshThreadSequences(); + } + ShapeEditor.shape.addSequence( %from, %proxyName ); + + // Limit the transition position to the in/out range + %transPos = mClamp( %transPos, 0, 1 ); + } + } + + ShapeEdShapeView.setThreadSequence( %seqName, %transTime, %transPos, %transPlay ); +} + +function ShapeEdAnimWindow::getTimelineBitmapPos( %this, %val, %width ) +{ + %frameCount = getWord( ShapeEdSeqSlider.range, 1 ); + %pos_x = getWord( ShapeEdSeqSlider.getPosition(), 0 ); + %len_x = getWord( ShapeEdSeqSlider.getExtent(), 0 ) - %width; + return %pos_x + ( ( %len_x * %val / %frameCount ) ); +} + +// Set the in or out sequence limit +function ShapeEdAnimWindow::setPlaybackLimit( %this, %limit, %val ) +{ + // Determine where to place the in/out bar on the slider + %thumbWidth = 8; // width of the thumb bitmap + %pos_x = %this.getTimelineBitmapPos( %val, %thumbWidth ); + + if ( %limit $= "in" ) + { + %this.seqStartFrame = %val; + %this-->seqIn.setText( %val ); + %this-->seqInBar.setPosition( %pos_x, 0 ); + } + else + { + %this.seqEndFrame = %val; + %this-->seqOut.setText( %val ); + %this-->seqOutBar.setPosition( %pos_x, 0 ); + } +} + +function ShapeEdThreadWindow::onAddThread( %this ) +{ + ShapeEdShapeView.addThread(); + ShapeEdThreadList.addRow( %this.threadID++, ShapeEdThreadList.rowCount() ); + ShapeEdThreadList.setSelectedRow( ShapeEdThreadList.rowCount()-1 ); +} + +function ShapeEdThreadWindow::onRemoveThread( %this ) +{ + if ( ShapeEdThreadList.rowCount() > 1 ) + { + // Remove the selected thread + %row = ShapeEdThreadList.getSelectedRow(); + ShapeEdShapeView.removeThread( %row ); + ShapeEdThreadList.removeRow( %row ); + + // Update list (threads are always numbered 0-N) + %rowCount = ShapeEdThreadList.rowCount(); + for ( %i = %row; %i < %rowCount; %i++ ) + ShapeEdThreadList.setRowById( ShapeEdThreadList.getRowId( %i ), %i ); + + // Select the next thread + if ( %row >= %rowCount ) + %row = %rowCount - 1; + + ShapeEdThreadList.setSelectedRow( %row ); + } +} + +function ShapeEdThreadList::onSelect( %this, %row, %text ) +{ + ShapeEdShapeView.activeThread = ShapeEdThreadList.getSelectedRow(); + + // Select the active thread's sequence in the list + %seqName = ShapeEdShapeView.getThreadSequence(); + if ( %seqName $= "" ) + %seqName = "<rootpose>"; + else if ( startswith( %seqName, "__proxy__" ) ) + %seqName = ShapeEditor.getUnproxyName( %seqName ); + + %seqIndex = ShapeEdSequenceList.getItemIndex( %seqName ); + ShapeEdSequenceList.setSelectedRow( %seqIndex ); + + // Update the playback controls + switch ( ShapeEdShapeView.threadDirection ) + { + case -1: ShapeEdAnimWindow-->playBkwdBtn.performClick(); + case 0: ShapeEdAnimWindow-->pauseBtn.performClick(); + case 1: ShapeEdAnimWindow-->playFwdBtn.performClick(); + } + SetToggleButtonValue( ShapeEdAnimWindow-->pingpong, ShapeEdShapeView.threadPingPong ); +} + +//------------------------------------------------------------------------------ +// Trigger Editing +//------------------------------------------------------------------------------ + +function ShapeEdPropWindow::onTriggerSelectionChanged( %this ) +{ + %row = ShapeEdTriggerList.getSelectedRow(); + if ( %row > 0 ) // skip header row + { + %text = ShapeEdTriggerList.getRowText( %row ); + + ShapeEdSequences-->triggerFrame.setActive( true ); + ShapeEdSequences-->triggerNum.setActive( true ); + ShapeEdSequences-->triggerOnOff.setActive( true ); + + ShapeEdSequences-->triggerFrame.setText( getField( %text, 1 ) ); + ShapeEdSequences-->triggerNum.setText( getField( %text, 2 ) ); + ShapeEdSequences-->triggerOnOff.setValue( getField( %text, 3 ) $= "on" ); + } + else + { + // No trigger selected + ShapeEdSequences-->triggerFrame.setActive( false ); + ShapeEdSequences-->triggerNum.setActive( false ); + ShapeEdSequences-->triggerOnOff.setActive( false ); + + ShapeEdSequences-->triggerFrame.setText( "" ); + ShapeEdSequences-->triggerNum.setText( "" ); + ShapeEdSequences-->triggerOnOff.setValue( 0 ); + } +} + +function ShapeEdSequences::onEditName( %this ) +{ + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + %newName = %this-->seqName.getText(); + if ( %newName !$= "" ) + ShapeEditor.doRenameSequence( %seqName, %newName ); + } +} + +function ShapeEdPropWindow::update_onTriggerAdded( %this, %seqName, %frame, %state ) +{ + // --- SEQUENCES TAB --- + // Add trigger to list if this sequence is selected + if ( ShapeEdSequenceList.getSelectedName() $= %seqName ) + ShapeEdTriggerList.addItem( %frame, %state ); +} + +function ShapeEdPropWindow::update_onTriggerRemoved( %this, %seqName, %frame, %state ) +{ + // --- SEQUENCES TAB --- + // Remove trigger from list if this sequence is selected + if ( ShapeEdSequenceList.getSelectedName() $= %seqName ) + ShapeEdTriggerList.removeItem( %frame, %state ); +} + +function ShapeEdTriggerList::getTriggerText( %this, %frame, %state ) +{ + // First column is invisible and used only for sorting + %sortKey = ( %frame * 1000 ) + ( mAbs( %state ) * 10 ) + ( ( %state > 0 ) ? 1 : 0 ); + return %sortKey TAB %frame TAB mAbs( %state ) TAB ( ( %state > 0 ) ? "on" : "off" ); +} + +function ShapeEdTriggerList::addItem( %this, %frame, %state ) +{ + // Add to text list + %row = %this.addRow( %this.triggerId, %this.getTriggerText( %frame, %state ) ); + %this.sortNumerical( 0, true ); + + // Add marker to animation timeline + %pos = ShapeEdAnimWindow.getTimelineBitmapPos( ShapeEdAnimWindow-->seqIn.getText() + %frame, 2 ); + %ctrl = new GuiBitmapCtrl() + { + internalName = "trigger" @ %this.triggerId; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = %pos SPC "0"; + Extent = "2 12"; + bitmap = "tools/shapeEditor/images/trigger_marker"; + }; + ShapeEdAnimWindow.getObject(0).addGuiControl( %ctrl ); + %this.triggerId++; +} + +function ShapeEdTriggerList::removeItem( %this, %frame, %state ) +{ + // Remove from text list + %row = %this.findTextIndex( %this.getTriggerText( %frame, %state ) ); + if ( %row > 0 ) + { + eval( "ShapeEdAnimWindow-->trigger" @ %this.getRowId( %row ) @ ".delete();" ); + %this.removeRow( %row ); + } +} + +function ShapeEdTriggerList::removeAll( %this ) +{ + %count = %this.rowCount(); + for ( %row = %count-1; %row > 0; %row-- ) + { + eval( "ShapeEdAnimWindow-->trigger" @ %this.getRowId( %row ) @ ".delete();" ); + %this.removeRow( %row ); + } +} + +function ShapeEdTriggerList::updateItem( %this, %oldFrame, %oldState, %frame, %state ) +{ + // Update text list entry + %oldText = %this.getTriggerText( %oldFrame, %oldState ); + %row = %this.getSelectedRow(); + if ( ( %row <= 0 ) || ( %this.getRowText( %row ) !$= %oldText ) ) + %row = %this.findTextIndex( %oldText ); + if ( %row > 0 ) + { + %updatedId = %this.getRowId( %row ); + %newText = %this.getTriggerText( %frame, %state ); + %this.setRowById( %updatedId, %newText ); + + // keep selected row the same + %selectedId = %this.getSelectedId(); + %this.sortNumerical( 0, true ); + %this.setSelectedById( %selectedId ); + + // Update animation timeline marker + if ( %frame != %oldFrame ) + { + %pos = ShapeEdAnimWindow.getTimelineBitmapPos( ShapeEdAnimWindow-->seqIn.getText() + %frame, 2 ); + eval( "%ctrl = ShapeEdAnimWindow-->trigger" @ %updatedId @ ";" ); + %ctrl.position = %pos SPC "0"; + } + } +} + +function ShapeEdSequences::onAddTrigger( %this ) +{ + // Can only add triggers if a sequence is selected + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + // Add a new trigger at the current frame + %frame = mRound( ShapeEdSeqSlider.getValue() ) - %this-->startFrame.getText(); + if ((%frame < 0) || (%frame > %this-->endFrame.getText() - %this-->startFrame.getText())) + { + MessageBoxOK( "Error", "Trigger out of range of the selected animation." ); + } + else + { + %state = ShapeEdTriggerList.rowCount() % 30; + ShapeEditor.doAddTrigger( %seqName, %frame, %state ); + } + } +} + +function ShapeEdTriggerList::onDeleteSelection( %this ) +{ + // Can only delete a trigger if a sequence and trigger are selected + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + %row = %this.getSelectedRow(); + if ( %row > 0 ) + { + %text = %this.getRowText( %row ); + %frame = getWord( %text, 1 ); + %state = getWord( %text, 2 ); + %state *= ( getWord( %text, 3 ) $= "on" ) ? 1 : -1; + ShapeEditor.doRemoveTrigger( %seqName, %frame, %state ); + } + } +} + +function ShapeEdTriggerList::onEditSelection( %this ) +{ + // Can only edit triggers if a sequence and trigger are selected + %seqName = ShapeEdSequenceList.getSelectedName(); + if ( %seqName !$= "" ) + { + %row = ShapeEdTriggerList.getSelectedRow(); + if ( %row > 0 ) + { + %text = %this.getRowText( %row ); + %oldFrame = getWord( %text, 1 ); + %oldState = getWord( %text, 2 ); + %oldState *= ( getWord( %text, 3 ) $= "on" ) ? 1 : -1; + + %frame = mRound( ShapeEdSequences-->triggerFrame.getText() ); + %state = mRound( mAbs( ShapeEdSequences-->triggerNum.getText() ) ); + %state *= ShapeEdSequences-->triggerOnOff.getValue() ? 1 : -1; + + if ( ( %frame >= 0 ) && ( %state != 0 ) ) + ShapeEditor.doEditTrigger( %seqName, %oldFrame, %oldState, %frame, %state ); + } + } +} + +//------------------------------------------------------------------------------ +// Material Editing +//------------------------------------------------------------------------------ + +function ShapeEdMaterials::updateMaterialList( %this ) +{ + // --- MATERIALS TAB --- + ShapeEdMaterialList.clear(); + ShapeEdMaterialList.addRow( -2, "Name" TAB "Mapped" ); + ShapeEdMaterialList.setRowActive( -2, false ); + ShapeEdMaterialList.addRow( -1, "<none>" ); + %count = ShapeEditor.shape.getTargetCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %matName = ShapeEditor.shape.getTargetName( %i ); + %mapped = getMaterialMapping( %matName ); + if ( %mapped $= "" ) + ShapeEdMaterialList.addRow( WarningMaterial.getID(), %matName TAB "unmapped" ); + else + ShapeEdMaterialList.addRow( %mapped.getID(), %matName TAB %mapped ); + } + + ShapeEdMaterials-->materialListHeader.setExtent( getWord( ShapeEdMaterialList.extent, 0 ) SPC "19" ); +} + +function ShapeEdMaterials::updateSelectedMaterial( %this, %highlight ) +{ + // Remove the highlight effect from the old selection + if ( isObject( %this.selectedMaterial ) ) + { + %this.selectedMaterial.diffuseMap[1] = %this.savedMap; + %this.selectedMaterial.reload(); + } + + // Apply the highlight effect to the new selected material + %this.selectedMapTo = getField( ShapeEdMaterialList.getRowText( ShapeEdMaterialList.getSelectedRow() ), 0 ); + %this.selectedMaterial = ShapeEdMaterialList.getSelectedId(); + %this.savedMap = %this.selectedMaterial.diffuseMap[1]; + if ( %highlight && isObject( %this.selectedMaterial ) ) + { + %this.selectedMaterial.diffuseMap[1] = "tools/shapeEditor/images/highlight_material"; + %this.selectedMaterial.reload(); + } +} + +function ShapeEdMaterials::editSelectedMaterial( %this ) +{ + if ( isObject( %this.selectedMaterial ) ) + { + // Remove the highlight effect from the selected material, then switch + // to the Material Editor + %this.updateSelectedMaterial( false ); + + // Create a temporary TSStatic so the MaterialEditor can query the model's + // materials. + pushInstantGroup(); + %this.tempShape = new TSStatic() { + shapeName = ShapeEditor.shape.baseShape; + collisionType = "None"; + }; + popInstantGroup(); + + MaterialEditorGui.currentMaterial = %this.selectedMaterial; + MaterialEditorGui.currentObject = $Tools::materialEditorList = %this.tempShape; + + ShapeEdSelectWindow.setVisible( false ); + ShapeEdPropWindow.setVisible( false ); + + EditorGui-->MatEdPropertiesWindow.setVisible( true ); + EditorGui-->MatEdPreviewWindow.setVisible( true ); + + MatEd_phoBreadcrumb.setVisible( true ); + MatEd_phoBreadcrumb.command = "ShapeEdMaterials.editSelectedMaterialEnd();"; + + advancedTextureMapsRollout.Expanded = false; + materialAnimationPropertiesRollout.Expanded = false; + materialAdvancedPropertiesRollout.Expanded = false; + + MaterialEditorGui.open(); + MaterialEditorGui.setActiveMaterial( %this.selectedMaterial ); + + %id = SubMaterialSelector.findText( %this.selectedMapTo ); + if( %id != -1 ) + SubMaterialSelector.setSelected( %id ); + } +} + +function ShapeEdMaterials::editSelectedMaterialEnd( %this, %closeEditor ) +{ + MatEd_phoBreadcrumb.setVisible( false ); + MatEd_phoBreadcrumb.command = ""; + + MaterialEditorGui.quit(); + EditorGui-->MatEdPropertiesWindow.setVisible( false ); + EditorGui-->MatEdPreviewWindow.setVisible( false ); + + // Delete the temporary TSStatic + %this.tempShape.delete(); + + if( !%closeEditor ) + { + ShapeEdSelectWindow.setVisible( true ); + ShapeEdPropWindow.setVisible( true ); + } +} + +//------------------------------------------------------------------------------ +// Detail/Mesh Editing +//------------------------------------------------------------------------------ + +function ShapeEdDetails::onWake( %this ) +{ + // Initialise popup menus + %this-->bbType.clear(); + %this-->bbType.add( "None", 0 ); + %this-->bbType.add( "Billboard", 1 ); + %this-->bbType.add( "Z Billboard", 2 ); + + %this-->addGeomTo.clear(); + %this-->addGeomTo.add( "current detail", 0 ); + %this-->addGeomTo.add( "new detail", 1 ); + %this-->addGeomTo.setSelected( 0, false ); + + ShapeEdDetailTree.onDefineIcons(); +} + +function ShapeEdDetailTree::onDefineIcons(%this) +{ + // Set the tree view icon indices and texture paths + %this._imageNone = 0; + %this._imageHidden = 1; + + %icons = ":" @ // no icon + "tools/gui/images/visible_i:"; // hidden + + %this.buildIconTable( %icons ); +} + +// Return true if the item in the details tree view is a detail level (false if +// a mesh) +function ShapeEdDetailTree::isDetailItem( %this, %id ) +{ + return ( %this.getParentItem( %id ) == 1 ); +} + +// Get the detail level index from the ID of an item in the details tree view +function ShapeEdDetailTree::getDetailLevelFromItem( %this, %id ) +{ + if ( %this.isDetailItem( %id ) ) + %detSize = %this.getItemValue( %id ); + + else + %detSize = %this.getItemValue( %this.getParentItem( %id ) ); + return ShapeEditor.shape.getDetailLevelIndex( %detSize ); +} + +function ShapeEdDetailTree::addMeshEntry( %this, %name, %noSync ) +{ + // Add new detail level if required + %size = getTrailingNumber( %name ); + %detailID = %this.findItemByValue( %size ); + if ( %detailID <= 0 ) + { + %dl = ShapeEditor.shape.getDetailLevelIndex( %size ); + %detName = ShapeEditor.shape.getDetailLevelName( %dl ); + %detailID = ShapeEdDetailTree.insertItem( 1, %detName, %size, "" ); + + // Sort details by decreasing size + for ( %sibling = ShapeEdDetailTree.getPrevSibling( %detailID ); + ( %sibling > 0 ) && ( ShapeEdDetailTree.getItemValue( %sibling ) < %size ); + %sibling = ShapeEdDetailTree.getPrevSibling( %detailID ) ) + ShapeEdDetailTree.moveItemUp( %detailID ); + + if ( !%noSync ) + ShapeEdDetails.update_onDetailsChanged(); + } + return %this.insertItem( %detailID, %name, "", "" ); +} + +function ShapeEdDetailTree::removeMeshEntry( %this, %name, %size ) +{ + %size = getTrailingNumber( %name ); + %id = ShapeEdDetailTree.findItemByName( %name ); + if ( ShapeEditor.shape.getDetailLevelIndex( %size ) < 0 ) + { + // Last mesh of a detail level has been removed => remove the detail level + %this.removeItem( %this.getParentItem( %id ) ); + ShapeEdDetails.update_onDetailsChanged(); + } + else + %this.removeItem( %id ); +} + +function ShapeEdAdvancedWindow::update_onShapeSelectionChanged( %this ) +{ + ShapeEdShapeView.currentDL = 0; + ShapeEdShapeView.onDetailChanged(); +} + +function ShapeEdPropWindow::update_onDetailRenamed( %this, %oldName, %newName ) +{ + // --- DETAILS TAB --- + // Rename detail entry + %id = ShapeEdDetailTree.findItemByName( %oldName ); + if ( %id > 0 ) + { + %size = ShapeEdDetailTree.getItemValue( %id ); + ShapeEdDetailTree.editItem( %id, %newName, %size ); + + // Sync text if item is selected + if ( ShapeEdDetailTree.isItemSelected( %id ) && + ( ShapeEdDetails-->meshName.getText() !$= %newName ) ) + ShapeEdDetails-->meshName.setText( stripTrailingNumber( %newName ) ); + } +} + +function ShapeEdPropWindow::update_onDetailSizeChanged( %this, %oldSize, %newSize ) +{ + // --- MISC --- + ShapeEdShapeView.refreshShape(); + %dl = ShapeEditor.shape.getDetailLevelIndex( %newSize ); + if ( ShapeEdAdvancedWindow-->detailSize.getText() $= %oldSize ) + { + ShapeEdShapeView.currentDL = %dl; + ShapeEdAdvancedWindow-->detailSize.setText( %newSize ); + ShapeEdDetails-->meshSize.setText( %newSize ); + } + + // --- DETAILS TAB --- + // Update detail entry then resort details by size + %id = ShapeEdDetailTree.findItemByValue( %oldSize ); + %detName = ShapeEditor.shape.getDetailLevelName( %dl ); + ShapeEdDetailTree.editItem( %id, %detName, %newSize ); + + for ( %sibling = ShapeEdDetailTree.getPrevSibling( %id ); + ( %sibling > 0 ) && ( ShapeEdDetailTree.getItemValue( %sibling ) < %newSize ); + %sibling = ShapeEdDetailTree.getPrevSibling( %id ) ) + ShapeEdDetailTree.moveItemUp( %id ); + for ( %sibling = ShapeEdDetailTree.getNextSibling( %id ); + ( %sibling > 0 ) && ( ShapeEdDetailTree.getItemValue( %sibling ) > %newSize ); + %sibling = ShapeEdDetailTree.getNextSibling( %id ) ) + ShapeEdDetailTree.moveItemDown( %id ); + + // Update size values for meshes of this detail + for ( %child = ShapeEdDetailTree.getChild( %id ); + %child > 0; + %child = ShapeEdDetailTree.getNextSibling( %child ) ) + { + %meshName = stripTrailingNumber( ShapeEdDetailTree.getItemText( %child ) ); + ShapeEdDetailTree.editItem( %child, %meshName SPC %newSize, "" ); + } +} + +function ShapeEdDetails::update_onDetailsChanged( %this ) +{ + %detailCount = ShapeEditor.shape.getDetailLevelCount(); + ShapeEdAdvancedWindow-->detailSlider.range = "0" SPC ( %detailCount-1 ); + if ( %detailCount >= 2 ) + ShapeEdAdvancedWindow-->detailSlider.ticks = %detailCount - 2; + else + ShapeEdAdvancedWindow-->detailSlider.ticks = 0; + + // Initialise imposter settings + ShapeEdAdvancedWindow-->bbUseImposters.setValue( ShapeEditor.shape.getImposterDetailLevel() != -1 ); + + // Update detail parameters + if ( ShapeEdShapeView.currentDL < %detailCount ) + { + %settings = ShapeEditor.shape.getImposterSettings( ShapeEdShapeView.currentDL ); + %isImposter = getWord( %settings, 0 ); + + ShapeEdAdvancedWindow-->imposterInactive.setVisible( !%isImposter ); + + ShapeEdAdvancedWindow-->bbEquatorSteps.setText( getField( %settings, 1 ) ); + ShapeEdAdvancedWindow-->bbPolarSteps.setText( getField( %settings, 2 ) ); + ShapeEdAdvancedWindow-->bbDetailLevel.setText( getField( %settings, 3 ) ); + ShapeEdAdvancedWindow-->bbDimension.setText( getField( %settings, 4 ) ); + ShapeEdAdvancedWindow-->bbIncludePoles.setValue( getField( %settings, 5 ) ); + ShapeEdAdvancedWindow-->bbPolarAngle.setText( getField( %settings, 6 ) ); + } +} + +function ShapeEdPropWindow::update_onObjectNodeChanged( %this, %objName ) +{ + // --- MISC --- + ShapeEdShapeView.refreshShape(); + + // --- DETAILS TAB --- + // Update the node popup menu if this object is selected + if ( ShapeEdDetails-->meshName.getText() $= %objName ) + { + %nodeName = ShapeEditor.shape.getObjectNode( %objName ); + if ( %nodeName $= "" ) + %nodeName = "<root>"; + %id = ShapeEdDetails-->objectNode.findText( %nodeName ); + ShapeEdDetails-->objectNode.setSelected( %id, false ); + } +} + +function ShapeEdPropWindow::update_onObjectRenamed( %this, %oldName, %newName ) +{ + // --- DETAILS TAB --- + // Rename tree entries for this object + %count = ShapeEditor.shape.getMeshCount( %newName ); + for ( %i = 0; %i < %count; %i++ ) + { + %size = getTrailingNumber( ShapeEditor.shape.getMeshName( %newName, %i ) ); + %id = ShapeEdDetailTree.findItemByName( %oldName SPC %size ); + if ( %id > 0 ) + { + ShapeEdDetailTree.editItem( %id, %newName SPC %size, "" ); + + // Sync text if item is selected + if ( ShapeEdDetailTree.isItemSelected( %id ) && + ( ShapeEdDetails-->meshName.getText() !$= %newName ) ) + ShapeEdDetails-->meshName.setText( %newName ); + } + } +} + +function ShapeEdPropWindow::update_onMeshAdded( %this, %meshName ) +{ + // --- MISC --- + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.updateNodeTransforms(); + + // --- COLLISION WINDOW --- + // Add object to target list if it does not already exist + if ( !ShapeEditor.isCollisionMesh( %meshName ) ) + { + %objName = stripTrailingNumber( %meshName ); + %id = ShapeEdColWindow-->colTarget.findText( %objName ); + if ( %id == -1 ) + ShapeEdColWindow-->colTarget.add( %objName ); + } + + // --- DETAILS TAB --- + %id = ShapeEdDetailTree.addMeshEntry( %meshName ); + ShapeEdDetailTree.clearSelection(); + ShapeEdDetailTree.selectItem( %id ); +} + +function ShapeEdPropWindow::update_onMeshSizeChanged( %this, %meshName, %oldSize, %newSize ) +{ + // --- MISC --- + ShapeEdShapeView.refreshShape(); + + // --- DETAILS TAB --- + // Move the mesh to the new location in the tree + %selected = ShapeEdDetailTree.getSelectedItem(); + %id = ShapeEdDetailTree.findItemByName( %meshName SPC %oldSize ); + ShapeEdDetailTree.removeMeshEntry( %meshName SPC %oldSize ); + %newId = ShapeEdDetailTree.addMeshEntry( %meshName SPC %newSize ); + + // Re-select the new entry if it was selected + if ( %selected == %id ) + { + ShapeEdDetailTree.clearSelection(); + ShapeEdDetailTree.selectItem( %newId ); + } +} + +function ShapeEdPropWindow::update_onMeshRemoved( %this, %meshName ) +{ + // --- MISC --- + ShapeEdShapeView.refreshShape(); + + // --- COLLISION WINDOW --- + // Remove object from target list if it no longer exists + %objName = stripTrailingNumber( %meshName ); + if ( ShapeEditor.shape.getObjectIndex( %objName ) == -1 ) + { + %id = ShapeEdColWindow-->colTarget.findText( %objName ); + if ( %id != -1 ) + ShapeEdColWindow-->colTarget.clearEntry( %id ); + } + + // --- DETAILS TAB --- + // Determine which item to select next + %id = ShapeEdDetailTree.findItemByName( %meshName ); + if ( %id > 0 ) + { + %nextId = ShapeEdDetailTree.getPrevSibling( %id ); + if ( %nextId <= 0 ) + { + %nextId = ShapeEdDetailTree.getNextSibling( %id ); + if ( %nextId <= 0 ) + %nextId = 2; + } + + // Remove the entry from the tree + %meshSize = getTrailingNumber( %meshName ); + ShapeEdDetailTree.removeMeshEntry( %meshName, %meshSize ); + + // Change selection if needed + if ( ShapeEdDetailTree.getSelectedItem() == -1 ) + ShapeEdDetailTree.selectItem( %nextId ); + } +} + +function ShapeEdDetailTree::onSelect( %this, %id ) +{ + %name = %this.getItemText( %id ); + %baseName = stripTrailingNumber( %name ); + %size = getTrailingNumber( %name ); + + ShapeEdDetails-->meshName.setText( %baseName ); + ShapeEdDetails-->meshSize.setText( %size ); + + // Select the appropriate detail level + %dl = %this.getDetailLevelFromItem( %id ); + ShapeEdShapeView.currentDL = %dl; + + if ( %this.isDetailItem( %id ) ) + { + // Selected a detail => disable mesh controls + ShapeEdDetails-->editMeshInactive.setVisible( true ); + ShapeEdShapeView.selectedObject = -1; + ShapeEdShapeView.selectedObjDetail = 0; + } + else + { + // Selected a mesh => sync mesh controls + ShapeEdDetails-->editMeshInactive.setVisible( false ); + + switch$ ( ShapeEditor.shape.getMeshType( %name ) ) + { + case "normal": ShapeEdDetails-->bbType.setSelected( 0, false ); + case "billboard": ShapeEdDetails-->bbType.setSelected( 1, false ); + case "billboardzaxis": ShapeEdDetails-->bbType.setSelected( 2, false ); + } + + %node = ShapeEditor.shape.getObjectNode( %baseName ); + if ( %node $= "" ) + %node = "<root>"; + ShapeEdDetails-->objectNode.setSelected( ShapeEdDetails-->objectNode.findText( %node ), false ); + ShapeEdShapeView.selectedObject = ShapeEditor.shape.getObjectIndex( %baseName ); + ShapeEdShapeView.selectedObjDetail = %dl; + } +} + +function ShapeEdDetailTree::onRightMouseUp( %this, %itemId, %mouse ) +{ + // Open context menu if this is a Mesh item + if ( !%this.isDetailItem( %itemId ) ) + { + if( !isObject( "ShapeEdMeshPopup" ) ) + { + new PopupMenu( ShapeEdMeshPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Hidden" TAB "" TAB "ShapeEdDetailTree.onHideMeshItem( %this._objName, !%this._itemHidden );"; + item[ 1 ] = "-"; + item[ 2 ] = "Hide all" TAB "" TAB "ShapeEdDetailTree.onHideMeshItem( \"\", true );"; + item[ 3 ] = "Show all" TAB "" TAB "ShapeEdDetailTree.onHideMeshItem( \"\", false );"; + }; + } + + ShapeEdMeshPopup._objName = stripTrailingNumber( %this.getItemText( %itemId ) ); + ShapeEdMeshPopup._itemHidden = ShapeEdShapeView.getMeshHidden( ShapeEdMeshPopup._objName ); + + ShapeEdMeshPopup.checkItem( 0, ShapeEdMeshPopup._itemHidden ); + ShapeEdMeshPopup.showPopup( Canvas ); + } +} + +function ShapeEdDetailTree::onHideMeshItem( %this, %objName, %hide ) +{ + if ( %hide ) + %imageId = %this._imageHidden; + else + %imageId = %this._imageNone; + + if ( %objName $= "" ) + { + // Show/hide all + ShapeEdShapeView.setAllMeshesHidden( %hide ); + for ( %parent = %this.getChild(%this.getFirstRootItem()); %parent > 0; %parent = %this.getNextSibling(%parent) ) + for ( %child = %this.getChild(%parent); %child > 0; %child = %this.getNextSibling(%child) ) + %this.setItemImages( %child, %imageId, %imageId ); + } + else + { + // Show/hide all meshes for this object + ShapeEdShapeView.setMeshHidden( %objName, %hide ); + %count = ShapeEditor.shape.getMeshCount( %objName ); + for ( %i = 0; %i < %count; %i++ ) + { + %meshName = ShapeEditor.shape.getMeshName( %objName, %i ); + %id = ShapeEdDetailTree.findItemByName( %meshName ); + if ( %id > 0 ) + %this.setItemImages( %id, %imageId, %imageId ); + } + } +} + +function ShapeEdShapeView::onDetailChanged( %this ) +{ + // Update slider + if ( mRound( ShapeEdAdvancedWindow-->detailSlider.getValue() ) != %this.currentDL ) + ShapeEdAdvancedWindow-->detailSlider.setValue( %this.currentDL ); + ShapeEdAdvancedWindow-->detailSize.setText( %this.detailSize ); + + ShapeEdDetails.update_onDetailsChanged(); + + %id = ShapeEdDetailTree.getSelectedItem(); + if ( ( %id <= 0 ) || ( %this.currentDL != ShapeEdDetailTree.getDetailLevelFromItem( %id ) ) ) + { + %id = ShapeEdDetailTree.findItemByValue( %this.detailSize ); + if ( %id > 0 ) + { + ShapeEdDetailTree.clearSelection(); + ShapeEdDetailTree.selectItem( %id ); + } + } +} + +function ShapeEdAdvancedWindow::onEditDetailSize( %this ) +{ + // Change the size of the current detail level + %oldSize = ShapeEditor.shape.getDetailLevelSize( ShapeEdShapeView.currentDL ); + %detailSize = %this-->detailSize.getText(); + ShapeEditor.doEditDetailSize( %oldSize, %detailSize ); +} + +function ShapeEdDetails::onEditName( %this ) +{ + %newName = %this-->meshName.getText(); + + // Check if we are renaming a detail or a mesh + %id = ShapeEdDetailTree.getSelectedItem(); + %oldName = ShapeEdDetailTree.getItemText( %id ); + + if ( ShapeEdDetailTree.isDetailItem( %id ) ) + { + // Rename the selected detail level + %oldSize = getTrailingNumber( %oldName ); + ShapeEditor.doRenameDetail( %oldName, %newName @ %oldSize ); + } + else + { + // Rename the selected mesh + ShapeEditor.doRenameObject( stripTrailingNumber( %oldName ), %newName ); + } +} + +function ShapeEdDetails::onEditSize( %this ) +{ + %newSize = %this-->meshSize.getText(); + + // Check if we are changing the size for a detail or a mesh + %id = ShapeEdDetailTree.getSelectedItem(); + if ( ShapeEdDetailTree.isDetailItem( %id ) ) + { + // Change the size of the selected detail level + %oldSize = ShapeEdDetailTree.getItemValue( %id ); + ShapeEditor.doEditDetailSize( %oldSize, %newSize ); + } + else + { + // Change the size of the selected mesh + %meshName = ShapeEdDetailTree.getItemText( %id ); + ShapeEditor.doEditMeshSize( %meshName, %newSize ); + } +} + +function ShapeEdDetails::onEditBBType( %this ) +{ + // This command is only valid for meshes (not details) + %id = ShapeEdDetailTree.getSelectedItem(); + if ( !ShapeEdDetailTree.isDetailItem( %id ) ) + { + %meshName = ShapeEdDetailTree.getItemText( %id ); + %bbType = ShapeEdDetails-->bbType.getText(); + switch$ ( %bbType ) + { + case "None": %bbType = "normal"; + case "Billboard": %bbType = "billboard"; + case "Z Billboard": %bbType = "billboardzaxis"; + } + ShapeEditor.doEditMeshBillboard( %meshName, %bbType ); + } +} + +function ShapeEdDetails::onSetObjectNode( %this ) +{ + // This command is only valid for meshes (not details) + %id = ShapeEdDetailTree.getSelectedItem(); + if ( !ShapeEdDetailTree.isDetailItem( %id ) ) + { + %meshName = ShapeEdDetailTree.getItemText( %id ); + %objName = stripTrailingNumber( %meshName ); + %node = %this-->objectNode.getText(); + if ( %node $= "<root>" ) + %node = ""; + ShapeEditor.doSetObjectNode( %objName, %node ); + } +} + +function ShapeEdDetails::onAddMeshFromFile( %this, %path ) +{ + if ( %path $= "" ) + { + getLoadFormatFilename( %this @ ".onAddMeshFromFile", %this.lastPath ); + return; + } + + %path = makeRelativePath( %path, getMainDotCSDir() ); + %this.lastPath = %path; + + // Determine the detail level to use for the new geometry + if ( %this-->addGeomTo.getText() $= "current detail" ) + { + %size = ShapeEditor.shape.getDetailLevelSize( ShapeEdShapeView.currentDL ); + } + else + { + // Check if the file has an LODXXX hint at the end of it + %base = fileBase( %path ); + %pos = strstr( %base, "_LOD" ); + if ( %pos > 0 ) + %size = getSubStr( %base, %pos + 4, strlen( %base ) ) + 0; + else + %size = 2; + + // Make sure size is not in use + while ( ShapeEditor.shape.getDetailLevelIndex( %size ) != -1 ) + %size++; + } + + ShapeEditor.doAddMeshFromFile( %path, %size ); +} + +function ShapeEdDetails::onDeleteMesh( %this ) +{ + %id = ShapeEdDetailTree.getSelectedItem(); + if ( ShapeEdDetailTree.isDetailItem( %id ) ) + { + %detSize = ShapeEdDetailTree.getItemValue( %id ); + ShapeEditor.doRemoveShapeData( "Detail", %detSize ); + } + else + { + %name = ShapeEdDetailTree.getItemText( %id ); + ShapeEditor.doRemoveShapeData( "Mesh", %name ); + } +} + +function ShapeEdDetails::onToggleImposter( %this, %useImposter ) +{ + %hasImposterDetail = ( ShapeEditor.shape.getImposterDetailLevel() != -1 ); + if ( %useImposter == %hasImposterDetail ) + return; + + if ( %useImposter ) + { + // Determine an unused detail size + for ( %detailSize = 0; %detailSize < 50; %detailSize++ ) + { + if ( ShapeEditor.shape.getDetailLevelIndex( %detailSize ) == -1 ) + break; + } + + // Set some initial values for the imposter + %bbEquatorSteps = 6; + %bbPolarSteps = 0; + %bbDetailLevel = 0; + %bbDimension = 128; + %bbIncludePoles = 0; + %bbPolarAngle = 0; + + // Add a new imposter detail level to the shape + ShapeEditor.doEditImposter( -1, %detailSize, %bbEquatorSteps, %bbPolarSteps, + %bbDetailLevel, %bbDimension, %bbIncludePoles, %bbPolarAngle ); + } + else + { + // Remove the imposter detail level + ShapeEditor.doRemoveImposter(); + } +} + +function ShapeEdDetails::onEditImposter( %this ) +{ + // Modify the parameters of the current imposter detail level + %detailSize = ShapeEditor.shape.getDetailLevelSize( ShapeEdShapeView.currentDL ); + %bbDimension = ShapeEdAdvancedWindow-->bbDimension.getText(); + %bbDetailLevel = ShapeEdAdvancedWindow-->bbDetailLevel.getText(); + %bbEquatorSteps = ShapeEdAdvancedWindow-->bbEquatorSteps.getText(); + %bbIncludePoles = ShapeEdAdvancedWindow-->bbIncludePoles.getValue(); + %bbPolarSteps = ShapeEdAdvancedWindow-->bbPolarSteps.getText(); + %bbPolarAngle = ShapeEdAdvancedWindow-->bbPolarAngle.getText(); + + ShapeEditor.doEditImposter( ShapeEdShapeView.currentDL, %detailSize, + %bbEquatorSteps, %bbPolarSteps, %bbDetailLevel, %bbDimension, + %bbIncludePoles, %bbPolarAngle ); +} + + +function ShapeEditor::autoAddDetails( %this, %dest ) +{ + // Sets of LOD files are named like: + // + // MyShape_LOD200.dae + // MyShape_LOD64.dae + // MyShape_LOD2.dae + // + // Determine the base name of the input file (MyShape_LOD in the example above) + // and use that to find any other shapes in the set. + %base = fileBase( %dest.baseShape ); + %pos = strstr( %base, "_LOD" ); + if ( %pos < 0 ) + { + echo( "Not an LOD shape file" ); + return; + } + + %base = getSubStr( %base, 0, %pos + 4 ); + + echo( "Base is: " @ %base ); + + %filePatterns = filePath( %dest.baseShape ) @ "/" @ %base @ "*" @ fileExt( %dest.baseShape ); + + echo( "Pattern is: " @ %filePatterns ); + + %fullPath = findFirstFileMultiExpr( %filePatterns ); + while ( %fullPath !$= "" ) + { + %fullPath = makeRelativePath( %fullPath, getMainDotCSDir() ); + + if ( %fullPath !$= %dest.baseShape ) + { + echo( "Found LOD shape file: " @ %fullPath ); + + // Determine the detail size ( number after the base name ), then add the + // new mesh + %size = strreplace( fileBase( %fullPath ), %base, "" ); + ShapeEditor.addLODFromFile( %dest, %fullPath, %size, 0 ); + } + + %fullPath = findNextFileMultiExpr( %filePatterns ); + } + + if ( %this.shape == %dest ) + { + ShapeEdShapeView.refreshShape(); + ShapeEdDetails.update_onDetailsChanged(); + } +} + +function ShapeEditor::addLODFromFile( %this, %dest, %filename, %size, %allowUnmatched ) +{ + // Get (or create) a TSShapeConstructor object for the source shape. Need to + // exec the script manually as the resource may not have been loaded yet + %csPath = filePath( %filename ) @ "/" @ fileBase( %filename ) @ ".cs"; + if ( isFile( %csPath ) ) + exec( %csPath ); + + %source = ShapeEditor.findConstructor( %filename ); + if ( %source == -1 ) + %source = ShapeEditor.createConstructor( %filename ); + %source.lodType = "SingleSize"; + %source.singleDetailSize = %size; + + // Create a temporary TSStatic to ensure the resource is loaded + %temp = new TSStatic() { + shapeName = %filename; + collisionType = "None"; + }; + + %meshList = ""; + if ( isObject( %temp ) ) + { + // Add a new mesh for each object in the source shape + %objCount = %source.getObjectCount(); + for ( %i = 0; %i < %objCount; %i++ ) + { + %objName = %source.getObjectName( %i ); + + echo( "Checking for object " @ %objName ); + + if ( %allowUnmatched || ( %dest.getObjectIndex( %objName ) != -1 ) ) + { + // Add the source object's highest LOD mesh to the destination shape + echo( "Adding detail size" SPC %size SPC "for object" SPC %objName ); + %srcName = %source.getMeshName( %objName, 0 ); + %destName = %objName SPC %size; + %dest.addMesh( %destName, %filename, %srcName ); + %meshList = %meshList TAB %destName; + } + } + + %temp.delete(); + } + + return trim( %meshList ); +} + +//------------------------------------------------------------------------------ +// Collision editing +//------------------------------------------------------------------------------ + +function ShapeEdColWindow::onWake( %this ) +{ + %this-->colType.clear(); + %this-->colType.add( "Box" ); + %this-->colType.add( "Sphere" ); + %this-->colType.add( "Capsule" ); + %this-->colType.add( "10-DOP X" ); + %this-->colType.add( "10-DOP Y" ); + %this-->colType.add( "10-DOP Z" ); + %this-->colType.add( "18-DOP" ); + %this-->colType.add( "26-DOP" ); + %this-->colType.add( "Convex Hulls" ); +} + +function ShapeEdColWindow::update_onShapeSelectionChanged( %this ) +{ + %this.lastColSettings = "" TAB "Bounds"; + + // Initialise collision mesh target list + %this-->colTarget.clear(); + %this-->colTarget.add( "Bounds" ); + %objCount = ShapeEditor.shape.getObjectCount(); + for ( %i = 0; %i < %objCount; %i++ ) + %this-->colTarget.add( ShapeEditor.shape.getObjectName( %i ) ); + + %this-->colTarget.setSelected( %this-->colTarget.findText( "Bounds" ), false ); +} + +function ShapeEdColWindow::update_onCollisionChanged( %this ) +{ + // Sync collision settings + %colData = %this.lastColSettings; + + %typeId = %this-->colType.findText( getField( %colData, 0 ) ); + %this-->colType.setSelected( %typeId, false ); + + %targetId = %this-->colTarget.findText( getField( %colData, 1 ) ); + %this-->colTarget.setSelected( %targetId, false ); + + if ( %this-->colType.getText() $= "Convex Hulls" ) + { + %this-->hullInactive.setVisible( false ); + %this-->hullDepth.setValue( getField( %colData, 2 ) ); + %this-->hullDepthText.setText( mFloor( %this-->hullDepth.getValue() ) ); + %this-->hullMergeThreshold.setValue( getField( %colData, 3 ) ); + %this-->hullMergeText.setText( mFloor( %this-->hullMergeThreshold.getValue() ) ); + %this-->hullConcaveThreshold.setValue( getField( %colData, 4 ) ); + %this-->hullConcaveText.setText( mFloor( %this-->hullConcaveThreshold.getValue() ) ); + %this-->hullMaxVerts.setValue( getField( %colData, 5 ) ); + %this-->hullMaxVertsText.setText( mFloor( %this-->hullMaxVerts.getValue() ) ); + %this-->hullMaxBoxError.setValue( getField( %colData, 6 ) ); + %this-->hullMaxBoxErrorText.setText( mFloor( %this-->hullMaxBoxError.getValue() ) ); + %this-->hullMaxSphereError.setValue( getField( %colData, 7 ) ); + %this-->hullMaxSphereErrorText.setText( mFloor( %this-->hullMaxSphereError.getValue() ) ); + %this-->hullMaxCapsuleError.setValue( getField( %colData, 8 ) ); + %this-->hullMaxCapsuleErrorText.setText( mFloor( %this-->hullMaxCapsuleError.getValue() ) ); + } + else + { + %this-->hullInactive.setVisible( true ); + } +} + +function ShapeEdColWindow::editCollision( %this ) +{ + // If the shape already contains a collision detail size-1, warn the user + // that it will be removed + if ( ( ShapeEditor.shape.getDetailLevelIndex( -1 ) >= 0 ) && + ( getField(%this.lastColSettings, 0) $= "" ) ) + { + MessageBoxYesNo( "Warning", "Existing collision geometry at detail size " @ + "-1 will be removed, and this cannot be undone. Do you want to continue?", + "ShapeEdColWindow.editCollisionOK();", "" ); + } + else + { + %this.editCollisionOK(); + } +} + +function ShapeEdColWindow::editCollisionOK( %this ) +{ + %type = %this-->colType.getText(); + %target = %this-->colTarget.getText(); + %depth = %this-->hullDepth.getValue(); + %merge = %this-->hullMergeThreshold.getValue(); + %concavity = %this-->hullConcaveThreshold.getValue(); + %maxVerts = %this-->hullMaxVerts.getValue(); + %maxBox = %this-->hullMaxBoxError.getValue(); + %maxSphere = %this-->hullMaxSphereError.getValue(); + %maxCapsule = %this-->hullMaxCapsuleError.getValue(); + + ShapeEditor.doEditCollision( %type, %target, %depth, %merge, %concavity, %maxVerts, + %maxBox, %maxSphere, %maxCapsule ); +} + +//------------------------------------------------------------------------------ +// Mounted Shapes +//------------------------------------------------------------------------------ + +function ShapeEdMountWindow::onWake( %this ) +{ + %this-->mountType.clear(); + %this-->mountType.add( "Object", 0 ); + %this-->mountType.add( "Image", 1 ); + %this-->mountType.add( "Wheel", 2 ); + %this-->mountType.setSelected( 1, false ); + + %this-->mountSeq.clear(); + %this-->mountSeq.add( "<rootpose>", 0 ); + %this-->mountSeq.setSelected( 0, false ); + %this-->mountPlayBtn.setStateOn( false ); + + // Only add the Browse entry the first time so we keep any files the user has + // set up previously + if ( ShapeEdMountShapeMenu.size() == 0 ) + { + ShapeEdMountShapeMenu.add( "Browse...", 0 ); + ShapeEdMountShapeMenu.setSelected( 0, false ); + } +} + +function ShapeEdMountWindow::isMountableNode( %this, %nodeName ) +{ + return ( startswith( %nodeName, "mount" ) || startswith( %nodeName, "hub" ) ); +} + +function ShapeEdMountWindow::update_onShapeSelectionChanged( %this ) +{ + %this.unmountAll(); + + // Initialise the dropdown menus + %this-->mountNode.clear(); + %this-->mountNode.add( "<origin>" ); + %count = ShapeEditor.shape.getNodeCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %name = ShapeEditor.shape.getNodeName( %i ); + if ( %this.isMountableNode( %name ) ) + %this-->mountNode.add( %name ); + } + %this-->mountNode.sort(); + %this-->mountNode.setFirstSelected(); + + %this-->mountSeq.clear(); + %this-->mountSeq.add( "<rootpose>", 0 ); + %this-->mountSeq.setSelected( 0, false ); +} + +function ShapeEdMountWindow::update_onMountSelectionChanged( %this ) +{ + %row = %this-->mountList.getSelectedRow(); + if ( %row > 0 ) + { + %text = %this-->mountList.getRowText( %row ); + %shapePath = getField( %text, 0 ); + + ShapeEdMountShapeMenu.setText( %shapePath ); + %this-->mountNode.setText( getField( %text, 2 ) ); + %this-->mountType.setText( getField( %text, 3 ) ); + + // Fill in sequence list + %this-->mountSeq.clear(); + %this-->mountSeq.add( "<rootpose>", 0 ); + + %tss = ShapeEditor.findConstructor( %shapePath ); + if ( !isObject( %tss ) ) + %tss = ShapeEditor.createConstructor( %shapePath ); + if ( isObject( %tss ) ) + { + %count = %tss.getSequenceCount(); + for ( %i = 0; %i < %count; %i++ ) + %this-->mountSeq.add( %tss.getSequenceName( %i ) ); + } + + // Select the currently playing sequence + %slot = %row - 1; + %seq = ShapeEdShapeView.getMountThreadSequence( %slot ); + %id = %this-->mountSeq.findText( %seq ); + if ( %id == -1 ) + %id = 0; + %this-->mountSeq.setSelected( %id, false ); + + ShapeEdMountSeqSlider.setValue( ShapeEdShapeView.getMountThreadPos( %slot ) ); + %this-->mountPlayBtn.setStateOn( ShapeEdShapeView.getMountThreadPos( %slot ) != 0 ); + } +} + +function ShapeEdMountWindow::updateSelectedMount( %this ) +{ + %row = %this-->mountList.getSelectedRow(); + if ( %row > 0 ) + %this.mountShape( %row-1 ); +} + +function ShapeEdMountWindow::setMountThreadSequence( %this ) +{ + %row = %this-->mountList.getSelectedRow(); + if ( %row > 0 ) + { + ShapeEdShapeView.setMountThreadSequence( %row-1, %this-->mountSeq.getText() ); + ShapeEdShapeView.setMountThreadDir( %row-1, %this-->mountPlayBtn.getValue() ); + } +} + +function ShapeEdMountSeqSlider::onMouseDragged( %this ) +{ + %row = ShapeEdMountWindow-->mountList.getSelectedRow(); + if ( %row > 0 ) + { + ShapeEdShapeView.setMountThreadPos( %row-1, %this.getValue() ); + + // Pause the sequence when the slider is dragged + ShapeEdShapeView.setMountThreadDir( %row-1, 0 ); + ShapeEdMountWindow-->mountPlayBtn.setStateOn( false ); + } +} + +function ShapeEdMountWindow::toggleMountThreadPlayback( %this ) +{ + %row = %this-->mountList.getSelectedRow(); + if ( %row > 0 ) + ShapeEdShapeView.setMountThreadDir( %row-1, %this-->mountPlayBtn.getValue() ); +} + +function ShapeEdMountShapeMenu::onSelect( %this, %id, %text ) +{ + if ( %text $= "Browse..." ) + { + // Allow the user to browse for an external model file + getLoadFormatFilename( %this @ ".onBrowseSelect", %this.lastPath ); + } + else + { + // Modify the current mount + ShapeEdMountWindow.updateSelectedMount(); + } +} + +function ShapeEdMountShapeMenu::onBrowseSelect( %this, %path ) +{ + %path = makeRelativePath( %path, getMainDotCSDir() ); + %this.lastPath = %path; + %this.setText( %path ); + + // Add entry if unique + if ( %this.findText( %path ) == -1 ) + %this.add( %path ); + + ShapeEdMountWindow.updateSelectedMount(); +} + +function ShapeEdMountWindow::mountShape( %this, %slot ) +{ + %model = ShapeEdMountShapeMenu.getText(); + %node = %this-->mountNode.getText(); + %type = %this-->mountType.getText(); + + if ( %model $= "Browse..." ) + %model = "core/art/shapes/octahedron.dts"; + + if ( ShapeEdShapeView.mountShape( %model, %node, %type, %slot ) ) + { + %rowText = %model TAB fileName( %model ) TAB %node TAB %type; + if ( %slot == -1 ) + { + %id = %this.mounts++; + %this-->mountList.addRow( %id, %rowText ); + } + else + { + %id = %this-->mountList.getRowId( %slot+1 ); + %this-->mountList.setRowById( %id, %rowText ); + } + + %this-->mountList.setSelectedById( %id ); + } + else + { + MessageBoxOK( "Error", "Failed to mount \"" @ %model @ "\". Check the console for error messages.", "" ); + } +} + +function ShapeEdMountWindow::unmountShape( %this ) +{ + %row = %this-->mountList.getSelectedRow(); + if ( %row > 0 ) + { + ShapeEdShapeView.unmountShape( %row-1 ); + %this-->mountList.removeRow( %row ); + + // Select the next row (if any) + %count = %this-->mountList.rowCount(); + if ( %row >= %count ) + %row = %count-1; + if ( %row > 0 ) + %this-->mountList.setSelectedRow( %row ); + } +} + +function ShapeEdMountWindow::unmountAll( %this ) +{ + ShapeEdShapeView.unmountAll(); + %this-->mountList.clear(); + %this-->mountList.addRow( -1, "FullPath" TAB "Filename" TAB "Node" TAB "Type" ); + %this-->mountList.setRowActive( -1, false ); +} + +//------------------------------------------------------------------------------ +// Shape Preview +//------------------------------------------------------------------------------ + +function ShapeEdPreviewGui::updatePreviewBackground( %color ) +{ + ShapeEdPreviewGui-->previewBackground.color = %color; + ShapeEditorToolbar-->previewBackgroundPicker.color = %color; +} + +function showShapeEditorPreview() +{ + %visible = ShapeEditorToolbar-->showPreview.getValue(); + ShapeEdPreviewGui.setVisible( %visible ); +} diff --git a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.cs b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.cs new file mode 100644 index 000000000..2c48b25a1 --- /dev/null +++ b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.cs @@ -0,0 +1,1304 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// The TSShapeConstructor object allows you to apply a set of transformations +// to a 3space shape after it is loaded by Torque, but _before_ the shape is used +// by any other object (eg. Player, StaticShape etc). The sort of transformations +// available include adding, renaming and removing nodes and sequences. This GUI +// is a visual wrapper around TSShapeConstructor which allows you to build up the +// transformation set without having to get your hands dirty with TorqueScript. +// +// Removing a node, sequence, mesh or detail poses a problem. These operations +// permanently delete a potentially large amount of data scattered throughout +// the shape, and there is no easy way to restore it if the user 'undoes' the +// delete. Although it is possible to store the deleted data somewhere and restore +// it on undo, it is not easy to get right, and ugly as hell to implement. For +// example, removing a node would require storing the node name, the +// translation/rotation/scale matters bit for each sequence, all node transform +// keyframes, the IDs of any objects that were attached to the node, skin weights +// etc, then restoring all that data into the original place on undo. Frankly, +// TSShape was never designed to be modified dynamically like that. +// +// So......currently we wimp out completely and just don't support undo for those +// remove operations. Lame, I know, but the best I can do for now. +// +// This file implements all of the actions that can be applied by the GUI. Each +// action has 3 methods: +// +// doit: called the first time the action is performed +// undo: called to undo the action +// redo: called to redo the action (usually the same as doit) +// +// In each case, the appropriate change is made to the shape, and the GUI updated. +// +// TSShapeConstructor keeps track of all the changes made and provides a simple +// way to save the modifications back out to a script file. + +// The ShapeEditor uses its own UndoManager +if ( !isObject( ShapeEdUndoManager ) ) + new UndoManager( ShapeEdUndoManager ); + +function ShapeEdUndoManager::updateUndoMenu( %this, %editMenu ) +{ + %undoName = %this.getNextUndoName(); + %redoName = %this.getNextRedoName(); + + %editMenu.setItemName( 0, "Undo " @ %undoName ); + %editMenu.setItemName( 1, "Redo " @ %redoName ); + + %editMenu.enableItem( 0, %undoName !$= "" ); + %editMenu.enableItem( 1, %redoName !$= "" ); +} + +//------------------------------------------------------------------------------ +// Helper functions for creating and applying GUI operations + +function ShapeEditor::createAction( %this, %class, %desc ) +{ + pushInstantGroup(); + %action = new UndoScriptAction() + { + class = %class; + superClass = BaseShapeEdAction; + actionName = %desc; + done = 0; + }; + popInstantGroup(); + return %action; +} + +function ShapeEditor::doAction( %this, %action ) +{ + if ( %action.doit() ) + { + ShapeEditor.setDirty( true ); + %action.addToManager( ShapeEdUndoManager ); + } + else + { + MessageBoxOK( "Error", %action.actionName SPC "failed. Check the console for error messages.", "" ); + } +} + +function BaseShapeEdAction::redo( %this ) +{ + // Default redo action is the same as the doit action + if ( %this.doit() ) + { + ShapeEditor.setDirty( true ); + } + else + { + MessageBoxOK( "Error", "Redo" SPC %this.actionName SPC "failed. Check the console for error messages.", "" ); + } +} + +function BaseShapeEdAction::undo( %this ) +{ + ShapeEditor.setDirty( true ); +} + +//------------------------------------------------------------------------------ + +function ShapeEditor::doRemoveShapeData( %this, %type, %name ) +{ + // Removing data from the shape cannot be undone => so warn the user first + MessageBoxYesNo( "Warning", "Deleting a " @ %type @ " cannot be undone. Do " @ + "you want to continue?", "ShapeEditor.doRemove" @ %type @ "( \"" @ %name @ "\" );", "" ); +} + +//------------------------------------------------------------------------------ +// Add node +function ShapeEditor::doAddNode( %this, %nodeName, %parentName, %transform ) +{ + %action = %this.createAction( ActionAddNode, "Add node" ); + %action.nodeName = %nodeName; + %action.parentName = %parentName; + %action.transform = %transform; + + %this.doAction( %action ); +} + +function ActionAddNode::doit( %this ) +{ + if ( ShapeEditor.shape.addNode( %this.nodeName, %this.parentName, %this.transform ) ) + { + ShapeEdPropWindow.update_onNodeAdded( %this.nodeName, -1 ); + return true; + } + return false; +} + +function ActionAddNode::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.removeNode( %this.nodeName ) ) + ShapeEdPropWindow.update_onNodeRemoved( %this.nodeName, 1 ); +} + +//------------------------------------------------------------------------------ +// Remove node +function ShapeEditor::doRemoveNode( %this, %nodeName ) +{ + %action = %this.createAction( ActionRemoveNode, "Remove node" ); + %action.nodeName =%nodeName; + %action.nodeChildIndex = ShapeEdNodeTreeView.getChildIndexByName( %nodeName ); + + // Need to delete all child nodes of this node as well, so recursively collect + // all of the names. + %action.nameList = %this.getNodeNames( %nodeName, "" ); + %action.nameCount = getFieldCount( %action.nameList ); + for ( %i = 0; %i < %action.nameCount; %i++ ) + %action.names[%i] = getField( %action.nameList, %i ); + + %this.doAction( %action ); +} + +function ActionRemoveNode::doit( %this ) +{ + for ( %i = 0; %i < %this.nameCount; %i++ ) + ShapeEditor.shape.removeNode( %this.names[%i] ); + + // Update GUI + ShapeEdPropWindow.update_onNodeRemoved( %this.nameList, %this.nameCount ); + + return true; +} + +function ActionRemoveNode::undo( %this ) +{ + Parent::undo( %this ); +} + +//------------------------------------------------------------------------------ +// Rename node +function ShapeEditor::doRenameNode( %this, %oldName, %newName ) +{ + %action = %this.createAction( ActionRenameNode, "Rename node" ); + %action.oldName = %oldName; + %action.newName = %newName; + + %this.doAction( %action ); +} + +function ActionRenameNode::doit( %this ) +{ + if ( ShapeEditor.shape.renameNode( %this.oldName, %this.newName ) ) + { + ShapeEdPropWindow.update_onNodeRenamed( %this.oldName, %this.newName ); + return true; + } + return false; +} + +function ActionRenameNode::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.renameNode( %this.newName, %this.oldName ) ) + ShapeEdPropWindow.update_onNodeRenamed( %this.newName, %this.oldName ); +} + +//------------------------------------------------------------------------------ +// Set node parent +function ShapeEditor::doSetNodeParent( %this, %name, %parent ) +{ + if ( %parent $= "<root>" ) + %parent = ""; + + %action = %this.createAction( ActionSetNodeParent, "Set parent node" ); + %action.nodeName = %name; + %action.parentName = %parent; + %action.oldParentName = ShapeEditor.shape.getNodeParentName( %name ); + + %this.doAction( %action ); +} + +function ActionSetNodeParent::doit( %this ) +{ + if ( ShapeEditor.shape.setNodeParent( %this.nodeName, %this.parentName ) ) + { + ShapeEdPropWindow.update_onNodeParentChanged( %this.nodeName ); + return true; + } + return false; +} + +function ActionSetNodeParent::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.setNodeParent( %this.nodeName, %this.oldParentName ) ) + ShapeEdPropWindow.update_onNodeParentChanged( %this.nodeName ); +} + +//------------------------------------------------------------------------------ +// Edit node transform +function ShapeEditor::doEditNodeTransform( %this, %nodeName, %newTransform, %isWorld, %gizmoID ) +{ + // If dragging the 3D gizmo, combine all movement into a single action. Undoing + // that action will return the node to where it was when the gizmo drag started. + %last = ShapeEdUndoManager.getUndoAction( ShapeEdUndoManager.getUndoCount() - 1 ); + if ( ( %last != -1 ) && ( %last.class $= ActionEditNodeTransform ) && + ( %last.nodeName $= %nodeName ) && ( %last.gizmoID != -1 ) && ( %last.gizmoID == %gizmoID ) ) + { + // Use the last action to do the edit, and modify it so it only applies + // the latest transform + %last.newTransform = %newTransform; + %last.isWorld = %isWorld; + %last.doit(); + ShapeEditor.setDirty( true ); + } + else + { + %action = %this.createAction( ActionEditNodeTransform, "Edit node transform" ); + %action.nodeName = %nodeName; + %action.newTransform = %newTransform; + %action.isWorld = %isWorld; + %action.gizmoID = %gizmoID; + %action.oldTransform = %this.shape.getNodeTransform( %nodeName, %isWorld ); + + %this.doAction( %action ); + } +} + +function ActionEditNodeTransform::doit( %this ) +{ + ShapeEditor.shape.setNodeTransform( %this.nodeName, %this.newTransform, %this.isWorld ); + ShapeEdPropWindow.update_onNodeTransformChanged(); + return true; +} + +function ActionEditNodeTransform::undo( %this ) +{ + Parent::undo( %this ); + + ShapeEditor.shape.setNodeTransform( %this.nodeName, %this.oldTransform, %this.isWorld ); + ShapeEdPropWindow.update_onNodeTransformChanged(); +} + +//------------------------------------------------------------------------------ +// Add sequence +function ShapeEditor::doAddSequence( %this, %seqName, %from, %start, %end ) +{ + %action = %this.createAction( ActionAddSequence, "Add sequence" ); + %action.seqName = %seqName; + %action.origFrom = %from; + %action.from = %from; + %action.start = %start; + %action.end = %end; + + %this.doAction( %action ); +} + +function ActionAddSequence::doit( %this ) +{ + // If adding this sequence from an existing sequence, make a backup copy of + // the existing sequence first, so we can edit the start/end frames later + // without having to worry if the original source sequence has changed. + if ( ShapeEditor.shape.getSequenceIndex( %this.from ) >= 0 ) + { + %this.from = ShapeEditor.getUniqueName( "sequence", "__backup__" @ %this.origFrom @ "_" ); + ShapeEditor.shape.addSequence( %this.origFrom, %this.from ); + } + + // Add the sequence + $collada::forceLoadDAE = EditorSettings.value( "forceLoadDAE" ); + %success = ShapeEditor.shape.addSequence( %this.from, %this.seqName, %this.start, %this.end ); + $collada::forceLoadDAE = false; + + if ( %success ) + { + ShapeEdPropWindow.update_onSequenceAdded( %this.seqName, -1 ); + return true; + } + return false; +} + +function ActionAddSequence::undo( %this ) +{ + Parent::undo( %this ); + + // Remove the backup sequence if one was created + if ( %this.origFrom !$= %this.from ) + { + ShapeEditor.shape.removeSequence( %this.from ); + %this.from = %this.origFrom; + } + + // Remove the actual sequence + if ( ShapeEditor.shape.removeSequence( %this.seqName ) ) + ShapeEdPropWindow.update_onSequenceRemoved( %this.seqName ); +} + +//------------------------------------------------------------------------------ +// Remove sequence + +function ShapeEditor::doRemoveSequence( %this, %seqName ) +{ + %action = %this.createAction( ActionRemoveSequence, "Remove sequence" ); + %action.seqName = %seqName; + + %this.doAction( %action ); +} + +function ActionRemoveSequence::doit( %this ) +{ + if ( ShapeEditor.shape.removeSequence( %this.seqName ) ) + { + ShapeEdPropWindow.update_onSequenceRemoved( %this.seqName ); + return true; + } + return false; +} + +function ActionRemoveSequence::undo( %this ) +{ + Parent::undo( %this ); +} + +//------------------------------------------------------------------------------ +// Rename sequence +function ShapeEditor::doRenameSequence( %this, %oldName, %newName ) +{ + %action = %this.createAction( ActionRenameSequence, "Rename sequence" ); + %action.oldName = %oldName; + %action.newName = %newName; + + %this.doAction( %action ); +} + +function ActionRenameSequence::doit( %this ) +{ + if ( ShapeEditor.shape.renameSequence( %this.oldName, %this.newName ) ) + { + ShapeEdPropWindow.update_onSequenceRenamed( %this.oldName, %this.newName ); + return true; + } + return false; +} + +function ActionRenameSequence::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.renameSequence( %this.newName, %this.oldName ) ) + ShapeEdPropWindow.update_onSequenceRenamed( %this.newName, %this.oldName ); +} + +//------------------------------------------------------------------------------ +// Edit sequence source data ( parent, start or end ) +function ShapeEditor::doEditSeqSource( %this, %seqName, %from, %start, %end ) +{ + %action = %this.createAction( ActionEditSeqSource, "Edit sequence source data" ); + %action.seqName = %seqName; + %action.origFrom = %from; + %action.from = %from; + %action.start = %start; + %action.end = %end; + + // To support undo, the sequence will be renamed instead of removed (undo just + // removes the added sequence and renames the original back). Generate a unique + // name for the backed up sequence + %action.seqBackup = ShapeEditor.getUniqueName( "sequence", "__backup__" @ %action.seqName @ "_" ); + + // If editing an internal sequence, the source is the renamed backup + if ( %action.from $= %action.seqName ) + %action.from = %action.seqBackup; + + %this.doAction( %action ); +} + +function ActionEditSeqSource::doit( %this ) +{ + // If changing the source to an existing sequence, make a backup copy of + // the existing sequence first, so we can edit the start/end frames later + // without having to worry if the original source sequence has changed. + if ( !startswith( %this.from, "__backup__" ) && + ShapeEditor.shape.getSequenceIndex( %this.from ) >= 0 ) + { + %this.from = ShapeEditor.getUniqueName( "sequence", "__backup__" @ %this.origFrom @ "_" ); + ShapeEditor.shape.addSequence( %this.origFrom, %this.from ); + } + + // Get settings we want to retain + %priority = ShapeEditor.shape.getSequencePriority( %this.seqName ); + %cyclic = ShapeEditor.shape.getSequenceCyclic( %this.seqName ); + %blend = ShapeEditor.shape.getSequenceBlend( %this.seqName ); + + // Rename this sequence (instead of removing it) so we can undo this action + ShapeEditor.shape.renameSequence( %this.seqName, %this.seqBackup ); + + // Add the new sequence + if ( ShapeEditor.shape.addSequence( %this.from, %this.seqName, %this.start, %this.end ) ) + { + // Restore original settings + if ( ShapeEditor.shape.getSequencePriority ( %this.seqName ) != %priority ) + ShapeEditor.shape.setSequencePriority( %this.seqName, %priority ); + if ( ShapeEditor.shape.getSequenceCyclic( %this.seqName ) != %cyclic ) + ShapeEditor.shape.setSequenceCyclic( %this.seqName, %cyclic ); + + %newBlend = ShapeEditor.shape.getSequenceBlend( %this.seqName ); + if ( %newBlend !$= %blend ) + { + // Undo current blend, then apply new one + ShapeEditor.shape.setSequenceBlend( %this.seqName, 0, getField( %newBlend, 1 ), getField( %newBlend, 2 ) ); + if ( getField( %blend, 0 ) == 1 ) + ShapeEditor.shape.setSequenceBlend( %this.seqName, getField( %blend, 0 ), getField( %blend, 1 ), getField( %blend, 2 ) ); + } + + if ( ShapeEdSequenceList.getSelectedName() $= %this.seqName ) + { + ShapeEdSequenceList.editColumn( %this.seqName, 3, %this.end - %this.start + 1 ); + ShapeEdPropWindow.syncPlaybackDetails(); + } + + return true; + } + return false; +} + +function ActionEditSeqSource::undo( %this ) +{ + Parent::undo( %this ); + + // Remove the source sequence backup if one was created + if ( ( %this.from !$= %this.origFrom ) && ( %this.from !$= %this.seqBackup ) ) + { + ShapeEditor.shape.removeSequence( %this.from ); + %this.from = %this.origFrom; + } + + // Remove the added sequence, and rename the backup back + if ( ShapeEditor.shape.removeSequence( %this.seqName ) && + ShapeEditor.shape.renameSequence( %this.seqBackup, %this.seqName ) ) + { + if ( ShapeEdSequenceList.getSelectedName() $= %this.seqName ) + { + ShapeEdSequenceList.editColumn( %this.seqName, 3, %this.end - %this.start + 1 ); + ShapeEdPropWindow.syncPlaybackDetails(); + } + } +} + +//------------------------------------------------------------------------------ +// Edit cyclic flag +function ShapeEditor::doEditCyclic( %this, %seqName, %cyclic ) +{ + %action = %this.createAction( ActionEditCyclic, "Toggle cyclic flag" ); + %action.seqName = %seqName; + %action.cyclic = %cyclic; + + %this.doAction( %action ); +} + +function ActionEditCyclic::doit( %this ) +{ + if ( ShapeEditor.shape.setSequenceCyclic( %this.seqName, %this.cyclic ) ) + { + ShapeEdPropWindow.update_onSequenceCyclicChanged( %this.seqName, %this.cyclic ); + return true; + } + return false; +} + +function ActionEditCyclic::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.setSequenceCyclic( %this.seqName, !%this.cyclic ) ) + ShapeEdPropWindow.update_onSequenceCyclicChanged( %this.seqName, !%this.cyclic ); +} + +//------------------------------------------------------------------------------ +// Edit blend properties +function ShapeEditor::doEditBlend( %this, %seqName, %blend, %blendSeq, %blendFrame ) +{ + %action = %this.createAction( ActionEditBlend, "Edit blend properties" ); + %action.seqName = %seqName; + %action.blend = %blend; + %action.blendSeq = %blendSeq; + %action.blendFrame = %blendFrame; + + // Store the current blend settings + %oldBlend = ShapeEditor.shape.getSequenceBlend( %seqName ); + %action.oldBlend = getField( %oldBlend, 0 ); + %action.oldBlendSeq = getField( %oldBlend, 1 ); + %action.oldBlendFrame = getField( %oldBlend, 2 ); + + // Use new values if the old ones do not exist ( for blend sequences embedded + // in the DTS/DSQ file ) + if ( %action.oldBlendSeq $= "" ) + %action.oldBlendSeq = %action.blendSeq; + if ( %action.oldBlendFrame $= "" ) + %action.oldBlendFrame = %action.blendFrame; + + %this.doAction( %action ); +} + +function ActionEditBlend::doit( %this ) +{ + // If we are changing the blend reference ( rather than just toggling the flag ) + // we need to undo the current blend first. + if ( %this.blend && %this.oldBlend ) + { + if ( !ShapeEditor.shape.setSequenceBlend( %this.seqName, false, %this.oldBlendSeq, %this.oldBlendFrame ) ) + return false; + } + + if ( ShapeEditor.shape.setSequenceBlend( %this.seqName, %this.blend, %this.blendSeq, %this.blendFrame ) ) + { + ShapeEdPropWindow.update_onSequenceBlendChanged( %this.seqName, %this.blend, + %this.oldBlendSeq, %this.oldBlendFrame, %this.blendSeq, %this.blendFrame ); + return true; + } + return false; +} + +function ActionEditBlend::undo( %this ) +{ + Parent::undo( %this ); + + // If we are changing the blend reference ( rather than just toggling the flag ) + // we need to undo the current blend first. + if ( %this.blend && %this.oldBlend ) + { + if ( !ShapeEditor.shape.setSequenceBlend( %this.seqName, false, %this.blendSeq, %this.blendFrame ) ) + return; + } + + if ( ShapeEditor.shape.setSequenceBlend( %this.seqName, %this.oldBlend, %this.oldBlendSeq, %this.oldBlendFrame ) ) + { + ShapeEdPropWindow.update_onSequenceBlendChanged( %this.seqName, !%this.blend, + %this.blendSeq, %this.blendFrame, %this.oldBlendSeq, %this.oldBlendFrame ); + } +} + +//------------------------------------------------------------------------------ +// Edit sequence priority +function ShapeEditor::doEditSequencePriority( %this, %seqName, %newPriority ) +{ + %action = %this.createAction( ActionEditSequencePriority, "Edit sequence priority" ); + %action.seqName = %seqName; + %action.newPriority = %newPriority; + %action.oldPriority = %this.shape.getSequencePriority( %seqName ); + + %this.doAction( %action ); +} + +function ActionEditSequencePriority::doit( %this ) +{ + if ( ShapeEditor.shape.setSequencePriority( %this.seqName, %this.newPriority ) ) + { + ShapeEdPropWindow.update_onSequencePriorityChanged( %this.seqName ); + return true; + } + return false; +} + +function ActionEditSequencePriority::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.setSequencePriority( %this.seqName, %this.oldPriority ) ) + ShapeEdPropWindow.update_onSequencePriorityChanged( %this.seqName ); +} + +//------------------------------------------------------------------------------ +// Edit sequence ground speed +function ShapeEditor::doEditSequenceGroundSpeed( %this, %seqName, %newSpeed ) +{ + %action = %this.createAction( ActionEditSequenceGroundSpeed, "Edit sequence ground speed" ); + %action.seqName = %seqName; + %action.newSpeed = %newSpeed; + %action.oldSpeed = %this.shape.getSequenceGroundSpeed( %seqName ); + + %this.doAction( %action ); +} + +function ActionEditSequenceGroundSpeed::doit( %this ) +{ + if ( ShapeEditor.shape.setSequenceGroundSpeed( %this.seqName, %this.newSpeed ) ) + { + ShapeEdPropWindow.update_onSequenceGroundSpeedChanged( %this.seqName ); + return true; + } + return false; +} + +function ActionEditSequenceGroundSpeed::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.setSequenceGroundSpeed( %this.seqName, %this.oldSpeed ) ) + ShapeEdPropWindow.update_onSequenceGroundSpeedChanged( %this.seqName ); +} + +//------------------------------------------------------------------------------ +// Add trigger +function ShapeEditor::doAddTrigger( %this, %seqName, %frame, %state ) +{ + %action = %this.createAction( ActionAddTrigger, "Add trigger" ); + %action.seqName = %seqName; + %action.frame = %frame; + %action.state = %state; + + %this.doAction( %action ); +} + +function ActionAddTrigger::doit( %this ) +{ + if ( ShapeEditor.shape.addTrigger( %this.seqName, %this.frame, %this.state ) ) + { + ShapeEdPropWindow.update_onTriggerAdded( %this.seqName, %this.frame, %this.state ); + return true; + } + return false; +} + +function ActionAddTrigger::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.removeTrigger( %this.seqName, %this.frame, %this.state ) ) + ShapeEdPropWindow.update_onTriggerRemoved( %this.seqName, %this.frame, %this.state ); +} + +//------------------------------------------------------------------------------ +// Remove trigger +function ShapeEditor::doRemoveTrigger( %this, %seqName, %frame, %state ) +{ + %action = %this.createAction( ActionRemoveTrigger, "Remove trigger" ); + %action.seqName = %seqName; + %action.frame = %frame; + %action.state = %state; + + %this.doAction( %action ); +} + +function ActionRemoveTrigger::doit( %this ) +{ + if ( ShapeEditor.shape.removeTrigger( %this.seqName, %this.frame, %this.state ) ) + { + ShapeEdPropWindow.update_onTriggerRemoved( %this.seqName, %this.frame, %this.state ); + return true; + } + return false; +} + +function ActionRemoveTrigger::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.addTrigger( %this.seqName, %this.frame, %this.state ) ) + ShapeEdPropWindow.update_onTriggerAdded( %this.seqName, %this.frame, %this.state ); +} + +//------------------------------------------------------------------------------ +// Edit trigger +function ShapeEditor::doEditTrigger( %this, %seqName, %oldFrame, %oldState, %frame, %state ) +{ + %action = %this.createAction( ActionEditTrigger, "Edit trigger" ); + %action.seqName = %seqName; + %action.oldFrame = %oldFrame; + %action.oldState = %oldState; + %action.frame = %frame; + %action.state = %state; + + %this.doAction( %action ); +} + +function ActionEditTrigger::doit( %this ) +{ + if ( ShapeEditor.shape.addTrigger( %this.seqName, %this.frame, %this.state ) && + ShapeEditor.shape.removeTrigger( %this.seqName, %this.oldFrame, %this.oldState ) ) + { + ShapeEdTriggerList.updateItem( %this.oldFrame, %this.oldState, %this.frame, %this.state ); + return true; + } + return false; +} + +function ActionEditTrigger::undo( %this ) +{ + Parent::undo( %this ); + + if ( ShapeEditor.shape.addTrigger( %this.seqName, %this.oldFrame, %this.oldState ) && + ShapeEditor.shape.removeTrigger( %this.seqName, %this.frame, %this.state ) ) + ShapeEdTriggerList.updateItem( %this.frame, %this.state, %this.oldFrame, %this.oldState ); +} + +//------------------------------------------------------------------------------ +// Rename detail +function ShapeEditor::doRenameDetail( %this, %oldName, %newName ) +{ + %action = %this.createAction( ActionRenameDetail, "Rename detail" ); + %action.oldName = %oldName; + %action.newName = %newName; + + %this.doAction( %action ); +} + +function ActionRenameDetail::doit( %this ) +{ + if ( ShapeEditor.shape.renameDetailLevel( %this.oldName, %this.newName ) ) + { + ShapeEdPropWindow.update_onDetailRenamed( %this.oldName, %this.newName ); + return true; + } + return false; +} + +function ActionRenameDetail::undo( %this ) +{ + Parent::undo( %this ); + if ( ShapeEditor.shape.renameDetailLevel( %this.newName, %this.oldName ) ) + ShapeEdPropWindow.update_onDetailRenamed( %this.newName, %this.oldName ); +} + +//------------------------------------------------------------------------------ +// Edit detail size +function ShapeEditor::doEditDetailSize( %this, %oldSize, %newSize ) +{ + %action = %this.createAction( ActionEditDetailSize, "Edit detail size" ); + %action.oldSize = %oldSize; + %action.newSize = %newSize; + + %this.doAction( %action ); +} + +function ActionEditDetailSize::doit( %this ) +{ + %dl = ShapeEditor.shape.setDetailLevelSize( %this.oldSize, %this.newSize ); + if ( %dl != -1 ) + { + ShapeEdPropWindow.update_onDetailSizeChanged( %this.oldSize, %this.newSize ); + return true; + } + return false; +} + +function ActionEditDetailSize::undo( %this ) +{ + Parent::undo( %this ); + %dl = ShapeEditor.shape.setDetailLevelSize( %this.newSize, %this.oldSize ); + if ( %dl != -1 ) + ShapeEdPropWindow.update_onDetailSizeChanged( %this.newSize, %this.oldSize ); +} + +//------------------------------------------------------------------------------ +// Rename object +function ShapeEditor::doRenameObject( %this, %oldName, %newName ) +{ + %action = %this.createAction( ActionRenameObject, "Rename object" ); + %action.oldName = %oldName; + %action.newName = %newName; + + %this.doAction( %action ); +} + +function ActionRenameObject::doit( %this ) +{ + if ( ShapeEditor.shape.renameObject( %this.oldName, %this.newName ) ) + { + ShapeEdPropWindow.update_onObjectRenamed( %this.oldName, %this.newName ); + return true; + } + return false; +} + +function ActionRenameObject::undo( %this ) +{ + Parent::undo( %this ); + if ( ShapeEditor.shape.renameObject( %this.newName, %this.oldName ) ) + ShapeEdPropWindow.update_onObjectRenamed( %this.newName, %this.oldName ); +} + +//------------------------------------------------------------------------------ +// Edit mesh size +function ShapeEditor::doEditMeshSize( %this, %meshName, %size ) +{ + %action = %this.createAction( ActionEditMeshSize, "Edit mesh size" ); + %action.meshName = stripTrailingNumber( %meshName ); + %action.oldSize = getTrailingNumber( %meshName ); + %action.newSize = %size; + + %this.doAction( %action ); +} + +function ActionEditMeshSize::doit( %this ) +{ + if ( ShapeEditor.shape.setMeshSize( %this.meshName SPC %this.oldSize, %this.newSize ) ) + { + ShapeEdPropWindow.update_onMeshSizeChanged( %this.meshName, %this.oldSize, %this.newSize ); + return true; + } + return false; +} + +function ActionEditMeshSize::undo( %this ) +{ + Parent::undo( %this ); + if ( ShapeEditor.shape.setMeshSize( %this.meshName SPC %this.newSize, %this.oldSize ) ) + ShapeEdPropWindow.update_onMeshSizeChanged( %this.meshName, %this.oldSize, %this.oldSize ); +} + +//------------------------------------------------------------------------------ +// Edit billboard type +function ShapeEditor::doEditMeshBillboard( %this, %meshName, %type ) +{ + %action = %this.createAction( ActionEditMeshBillboard, "Edit mesh billboard" ); + %action.meshName = %meshName; + %action.oldType = %this.shape.getMeshType( %meshName ); + %action.newType = %type; + + %this.doAction( %action ); +} + +function ActionEditMeshBillboard::doit( %this ) +{ + if ( ShapeEditor.shape.setMeshType( %this.meshName, %this.newType ) ) + { + switch$ ( ShapeEditor.shape.getMeshType( %this.meshName ) ) + { + case "normal": ShapeEdDetails-->bbType.setSelected( 0, false ); + case "billboard": ShapeEdDetails-->bbType.setSelected( 1, false ); + case "billboardzaxis": ShapeEdDetails-->bbType.setSelected( 2, false ); + } + return true; + } + return false; +} + +function ActionEditMeshBillboard::undo( %this ) +{ + Parent::undo( %this ); + if ( ShapeEditor.shape.setMeshType( %this.meshName, %this.oldType ) ) + { + %id = ShapeEdDetailTree.getSelectedItem(); + if ( ( %id > 1 ) && ( ShapeEdDetailTree.getItemText( %id ) $= %this.meshName ) ) + { + switch$ ( ShapeEditor.shape.getMeshType( %this.meshName ) ) + { + case "normal": ShapeEdDetails-->bbType.setSelected( 0, false ); + case "billboard": ShapeEdDetails-->bbType.setSelected( 1, false ); + case "billboardzaxis": ShapeEdDetails-->bbType.setSelected( 2, false ); + } + } + } +} + +//------------------------------------------------------------------------------ +// Edit object node +function ShapeEditor::doSetObjectNode( %this, %objName, %node ) +{ + %action = %this.createAction( ActionSetObjectNode, "Set object node" ); + %action.objName = %objName; + %action.oldNode = %this.shape.getObjectNode( %objName ); + %action.newNode = %node; + + %this.doAction( %action ); +} + +function ActionSetObjectNode::doit( %this ) +{ + if ( ShapeEditor.shape.setObjectNode( %this.objName, %this.newNode ) ) + { + ShapeEdPropWindow.update_onObjectNodeChanged( %this.objName ); + return true; + } + return false; +} + +function ActionSetObjectNode::undo( %this ) +{ + Parent::undo( %this ); + if ( ShapeEditor.shape.setObjectNode( %this.objName, %this.oldNode ) ) + ShapeEdPropWindow.update_onObjectNodeChanged( %this.objName ); +} + +//------------------------------------------------------------------------------ +// Remove mesh +function ShapeEditor::doRemoveMesh( %this, %meshName ) +{ + %action = %this.createAction( ActionRemoveMesh, "Remove mesh" ); + %action.meshName = %meshName; + + %this.doAction( %action ); +} + +function ActionRemoveMesh::doit( %this ) +{ + if ( ShapeEditor.shape.removeMesh( %this.meshName ) ) + { + ShapeEdPropWindow.update_onMeshRemoved( %this.meshName ); + return true; + } + return false; +} + +function ActionRemoveMesh::undo( %this ) +{ + Parent::undo( %this ); +} + +//------------------------------------------------------------------------------ +// Add meshes from file +function ShapeEditor::doAddMeshFromFile( %this, %filename, %size ) +{ + %action = %this.createAction( ActionAddMeshFromFile, "Add mesh from file" ); + %action.filename = %filename; + %action.size = %size; + + %this.doAction( %action ); +} + +function ActionAddMeshFromFile::doit( %this ) +{ + %this.meshList = ShapeEditor.addLODFromFile( ShapeEditor.shape, %this.filename, %this.size, 1 ); + if ( %this.meshList !$= "" ) + { + %count = getFieldCount( %this.meshList ); + for ( %i = 0; %i < %count; %i++ ) + ShapeEdPropWindow.update_onMeshAdded( getField( %this.meshList, %i ) ); + + ShapeEdMaterials.updateMaterialList(); + + return true; + } + return false; +} + +function ActionAddMeshFromFile::undo( %this ) +{ + // Remove all the meshes we added + %count = getFieldCount( %this.meshList ); + for ( %i = 0; %i < %count; %i ++ ) + { + %name = getField( %this.meshList, %i ); + ShapeEditor.shape.removeMesh( %name ); + ShapeEdPropWindow.update_onMeshRemoved( %name ); + } + ShapeEdMaterials.updateMaterialList(); +} + +//------------------------------------------------------------------------------ +// Add/edit collision geometry +function ShapeEditor::doEditCollision( %this, %type, %target, %depth, %merge, %concavity, + %maxVerts, %boxMax, %sphereMax, %capsuleMax ) +{ + %colData = ShapeEdColWindow.lastColSettings; + + %action = %this.createAction( ActionEditCollision, "Edit shape collision" ); + + %action.oldType = getField( %colData, 0 ); + %action.oldTarget = getField( %colData, 1 ); + %action.oldDepth = getField( %colData, 2 ); + %action.oldMerge = getField( %colData, 3 ); + %action.oldConcavity = getField( %colData, 4 ); + %action.oldMaxVerts = getField( %colData, 5 ); + %action.oldBoxMax = getField( %colData, 6 ); + %action.oldSphereMax = getField( %colData, 7 ); + %action.oldCapsuleMax = getField( %colData, 8 ); + + %action.newType = %type; + %action.newTarget = %target; + %action.newDepth = %depth; + %action.newMerge = %merge; + %action.newConcavity = %concavity; + %action.newMaxVerts = %maxVerts; + %action.newBoxMax = %boxMax; + %action.newSphereMax = %sphereMax; + %action.newCapsuleMax = %capsuleMax; + + %this.doAction( %action ); +} + +function ActionEditCollision::updateCollision( %this, %type, %target, %depth, %merge, %concavity, + %maxVerts, %boxMax, %sphereMax, %capsuleMax ) +{ + %colDetailSize = -1; + %colNode = "Col" @ %colDetailSize; + + // TreeView items are case sensitive, but TSShape names are not, so fixup case + // if needed + %index = ShapeEditor.shape.getNodeIndex( %colNode ); + if ( %index != -1 ) + %colNode = ShapeEditor.shape.getNodeName( %index ); + + // First remove the old detail and collision nodes + %meshList = ShapeEditor.getDetailMeshList( %colDetailSize ); + %meshCount = getFieldCount( %meshList ); + if ( %meshCount > 0 ) + { + ShapeEditor.shape.removeDetailLevel( %colDetailSize ); + for ( %i = 0; %i < %meshCount; %i++ ) + ShapeEdPropWindow.update_onMeshRemoved( getField( %meshList, %i ) ); + } + + %nodeList = ShapeEditor.getNodeNames( %colNode, "" ); + %nodeCount = getFieldCount( %nodeList ); + if ( %nodeCount > 0 ) + { + for ( %i = 0; %i < %nodeCount; %i++ ) + ShapeEditor.shape.removeNode( getField( %nodeList, %i ) ); + ShapeEdPropWindow.update_onNodeRemoved( %nodeList, %nodeCount ); + } + + // Add the new node and geometry + if ( %type $= "" ) + return; + + if ( !ShapeEditor.shape.addCollisionDetail( %colDetailSize, %type, %target, + %depth, %merge, %concavity, %maxVerts, + %boxMax, %sphereMax, %capsuleMax ) ) + return false; + + // Update UI + %meshList = ShapeEditor.getDetailMeshList( %colDetailSize ); + ShapeEdPropWindow.update_onNodeAdded( %colNode, ShapeEditor.shape.getNodeCount() ); // will also add child nodes + %count = getFieldCount( %meshList ); + for ( %i = 0; %i < %count; %i++ ) + ShapeEdPropWindow.update_onMeshAdded( getField( %meshList, %i ) ); + + ShapeEdColWindow.lastColSettings = %type TAB %target TAB %depth TAB %merge TAB + %concavity TAB %maxVerts TAB %boxMax TAB %sphereMax TAB %capsuleMax; + ShapeEdColWindow.update_onCollisionChanged(); + + return true; +} + +function ActionEditCollision::doit( %this ) +{ + ShapeEdWaitGui.show( "Generating collision geometry..." ); + %success = %this.updateCollision( %this.newType, %this.newTarget, %this.newDepth, %this.newMerge, + %this.newConcavity, %this.newMaxVerts, %this.newBoxMax, + %this.newSphereMax, %this.newCapsuleMax ); + ShapeEdWaitGui.hide(); + + return %success; +} + +function ActionEditCollision::undo( %this ) +{ + Parent::undo( %this ); + + ShapeEdWaitGui.show( "Generating collision geometry..." ); + %this.updateCollision( %this.oldType, %this.oldTarget, %this.oldDepth, %this.oldMerge, + %this.oldConcavity, %this.oldMaxVerts, %this.oldBoxMax, + %this.oldSphereMax, %this.oldCapsuleMax ); + ShapeEdWaitGui.hide(); +} + +//------------------------------------------------------------------------------ +// Remove Detail + +function ShapeEditor::doRemoveDetail( %this, %size ) +{ + %action = %this.createAction( ActionRemoveDetail, "Remove detail level" ); + %action.size = %size; + + %this.doAction( %action ); +} + +function ActionRemoveDetail::doit( %this ) +{ + %meshList = ShapeEditor.getDetailMeshList( %this.size ); + if ( ShapeEditor.shape.removeDetailLevel( %this.size ) ) + { + %meshCount = getFieldCount( %meshList ); + for ( %i = 0; %i < %meshCount; %i++ ) + ShapeEdPropWindow.update_onMeshRemoved( getField( %meshList, %i ) ); + return true; + } + return false; +} + +function ActionRemoveDetail::undo( %this ) +{ + Parent::undo( %this ); +} + +//------------------------------------------------------------------------------ +// Update bounds +function ShapeEditor::doSetBounds( %this ) +{ + %action = %this.createAction( ActionSetBounds, "Set bounds" ); + %action.oldBounds = ShapeEditor.shape.getBounds(); + %action.newBounds = ShapeEdShapeView.computeShapeBounds(); + + %this.doAction( %action ); +} + +function ActionSetBounds::doit( %this ) +{ + return ShapeEditor.shape.setBounds( %this.newBounds ); +} + +function ActionSetBounds::undo( %this ) +{ + Parent::undo( %this ); + + ShapeEditor.shape.setBounds( %this.oldBounds ); +} + +//------------------------------------------------------------------------------ +// Add/edit imposter +function ShapeEditor::doEditImposter( %this, %dl, %detailSize, %bbEquatorSteps, %bbPolarSteps, + %bbDetailLevel, %bbDimension, %bbIncludePoles, %bbPolarAngle ) +{ + %action = %this.createAction( ActionEditImposter, "Edit imposter" ); + %action.oldDL = %dl; + if ( %action.oldDL != -1 ) + { + %action.oldSize = ShapeEditor.shape.getDetailLevelSize( %dl ); + %action.oldImposter = ShapeEditor.shape.getImposterSettings( %dl ); + } + %action.newSize = %detailSize; + %action.newImposter = "1" TAB %bbEquatorSteps TAB %bbPolarSteps TAB %bbDetailLevel TAB + %bbDimension TAB %bbIncludePoles TAB %bbPolarAngle; + + %this.doAction( %action ); +} + +function ActionEditImposter::doit( %this ) +{ + // Unpack new imposter settings + for ( %i = 0; %i < 7; %i++ ) + %val[%i] = getField( %this.newImposter, %i ); + + ShapeEdWaitGui.show( "Generating imposter bitmaps..." ); + + // Need to de-highlight the current material, or the imposter will have the + // highlight effect baked in! + ShapeEdMaterials.updateSelectedMaterial( false ); + + %dl = ShapeEditor.shape.addImposter( %this.newSize, %val[1], %val[2], %val[3], %val[4], %val[5], %val[6] ); + ShapeEdWaitGui.hide(); + + // Restore highlight effect + ShapeEdMaterials.updateSelectedMaterial( ShapeEdMaterials-->highlightMaterial.getValue() ); + + if ( %dl != -1 ) + { + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.currentDL = %dl; + ShapeEdAdvancedWindow-->detailSize.setText( %this.newSize ); + ShapeEdDetails-->meshSize.setText( %this.newSize ); + ShapeEdDetails.update_onDetailsChanged(); + + return true; + } + return false; +} + +function ActionEditImposter::undo( %this ) +{ + Parent::undo( %this ); + + // If this was a new imposter, just remove it. Otherwise restore the old settings + if ( %this.oldDL < 0 ) + { + if ( ShapeEditor.shape.removeImposter() ) + { + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.currentDL = 0; + ShapeEdDetails.update_onDetailsChanged(); + } + } + else + { + // Unpack old imposter settings + for ( %i = 0; %i < 7; %i++ ) + %val[%i] = getField( %this.oldImposter, %i ); + + ShapeEdWaitGui.show( "Generating imposter bitmaps..." ); + + // Need to de-highlight the current material, or the imposter will have the + // highlight effect baked in! + ShapeEdMaterials.updateSelectedMaterial( false ); + + %dl = ShapeEditor.shape.addImposter( %this.oldSize, %val[1], %val[2], %val[3], %val[4], %val[5], %val[6] ); + ShapeEdWaitGui.hide(); + + // Restore highlight effect + ShapeEdMaterials.updateSelectedMaterial( ShapeEdMaterials-->highlightMaterial.getValue() ); + + if ( %dl != -1 ) + { + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.currentDL = %dl; + ShapeEdAdvancedWindow-->detailSize.setText( %this.oldSize ); + ShapeEdDetails-->meshSize.setText( %this.oldSize ); + } + } +} + +//------------------------------------------------------------------------------ +// Remove imposter +function ShapeEditor::doRemoveImposter( %this ) +{ + %action = %this.createAction( ActionRemoveImposter, "Remove imposter" ); + %dl = ShapeEditor.shape.getImposterDetailLevel(); + if ( %dl != -1 ) + { + %action.oldSize = ShapeEditor.shape.getDetailLevelSize( %dl ); + %action.oldImposter = ShapeEditor.shape.getImposterSettings( %dl ); + %this.doAction( %action ); + } +} + +function ActionRemoveImposter::doit( %this ) +{ + if ( ShapeEditor.shape.removeImposter() ) + { + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.currentDL = 0; + ShapeEdDetails.update_onDetailsChanged(); + + return true; + } + return false; +} + +function ActionRemoveImposter::undo( %this ) +{ + Parent::undo( %this ); + + // Unpack the old imposter settings + for ( %i = 0; %i < 7; %i++ ) + %val[%i] = getField( %this.oldImposter, %i ); + + ShapeEdWaitGui.show( "Generating imposter bitmaps..." ); + %dl = ShapeEditor.shape.addImposter( %this.oldSize, %val[1], %val[2], %val[3], %val[4], %val[5], %val[6] ); + ShapeEdWaitGui.hide(); + + if ( %dl != -1 ) + { + ShapeEdShapeView.refreshShape(); + ShapeEdShapeView.currentDL = %dl; + ShapeEdAdvancedWindow-->detailSize.setText( %this.oldSize ); + ShapeEdDetails-->meshSize.setText( %this.oldSize ); + ShapeEdDetails.update_onDetailsChanged(); + } +} diff --git a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorHints.ed.cs b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorHints.ed.cs new file mode 100644 index 000000000..c8a704644 --- /dev/null +++ b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorHints.ed.cs @@ -0,0 +1,142 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// The Shape Editor tool can provide some simple hints about which nodes and +// sequences are required/desired for a particular type of shape to work with +// Torque. The following objects define the node and sequence hints, and the +// Shape Editor gui marks them as present or not-present in the current shape. + +new SimGroup (ShapeHintControls) +{ +}; + +new SimGroup (ShapeHintGroup) +{ + new ScriptObject() + { + objectType = "ShapeBase"; + node0 = "cam" TAB "This node is used as the 3rd person camera position."; + node1 = "eye" TAB "This node is used as the 1st person camera position."; + node2 = "ear" TAB "This node is where the SFX listener is mounted on (if missing, eye is used)."; + node3 = "mount0-31" TAB "Nodes used for mounting ShapeBaseImages to this object"; + node4 = "AIRepairNode" TAB "unused"; + sequence0 = "Visibility" TAB "2 frame sequence used to show object damage (start=no damage, end=fully damaged)"; + sequence1 = "Damage" TAB "Sequence used to show object damage (start=no damage, end=fully damaged)"; + }; + + new ScriptObject() + { + objectType = "ShapeBaseImageData"; + node0 = "ejectPoint" TAB "Node from which shell casings are emitted (for weapon ShapeImages)"; + node1 = "muzzlePoint" TAB "Node used to fire projectiles and particles (for weapon ShapeImages)"; + node2 = "retractionPoint" TAB "Nearest point to use as muzzle when up against a wall (and muzzle node is inside wall)"; + node3 = "mountPoint" TAB "Where to attach to on this object"; + sequence0 = "ambient" TAB "Cyclic sequence to play while image is mounted"; + sequence1 = "spin" TAB "Cyclic sequence to play while image is mounted"; + }; + + new ScriptObject() + { + objectType = "Player"; + node0 = "Bip01 Pelvis" TAB ""; + node1 = "Bip01 Spine" TAB ""; + node2 = "Bip01 Spine1" TAB ""; + node3 = "Bip01 Spine2" TAB ""; + node4 = "Bip01 Neck" TAB ""; + node5 = "Bip01 Head" TAB ""; + + sequence0 = "head" TAB "Vertical head movement (for looking) (start=full up, end=full down)"; + sequence1 = "headside" TAB "Horizontal head movement (for looking) (start=full left, end=full right)"; + sequence2 = "look" TAB "Vertical arm movement (for looking) (start=full up, end=full down)"; + sequence3 = "light_recoil" TAB "Player has been hit lightly"; + sequence4 = "medium_recoil" TAB "Player has been hit moderately hard"; + sequence5 = "heavy_recoil" TAB "Player has been hit hard"; + + sequence6 = "root" TAB "Player is not moving"; + sequence7 = "run" TAB "Player is running forward"; + sequence8 = "back" TAB "Player is running backward"; + sequence9 = "side" TAB "Player is running sideways left (strafing)"; + sequence9 = "side_right" TAB "Player is running sideways right (strafing)"; + + sequence10 = "crouch_root" TAB "Player is crouched and not moving"; + sequence11 = "crouch_forward" TAB "Player is crouched and moving forward"; + sequence11 = "crouch_backward" TAB "Player is crouched and moving backward"; + sequence11 = "crouch_side" TAB "Player is crouched and moving sideways left"; + sequence11 = "crouch_right" TAB "Player is crouched and moving sideways right"; + + sequence12 = "prone_root" TAB "Player is lying down and not moving"; + sequence13 = "prone_forward" TAB "Player is lying down and moving forward"; + sequence13 = "prone_backward" TAB "Player is lying down and moving backward"; + + sequence14 = "swim_root" TAB "Player is swimming and not moving"; + sequence15 = "swim_forward" TAB "Player is swimming and moving forward"; + sequence16 = "swim_backward" TAB "Player is swimming and moving backward"; + sequence17 = "swim_left" TAB "Player is swimming and moving left"; + sequence18 = "swim_right" TAB "Player is swimming and moving right"; + + sequence19 = "fall" TAB "Player is falling"; + sequence20 = "jump" TAB "Player has jumped from a moving start"; + sequence21 = "standjump" TAB "Player has jumped from a standing start"; + sequence22 = "land" TAB "Player has landed after falling"; + sequence23 = "jet" TAB "Player is jetting"; + + sequence24 = "death1-11" TAB "Player has been killed (only one of these will play)"; + }; + + new ScriptObject() + { + objectType = "WheeledVehicle"; + node0 = "hub0-7" TAB "Placement node for wheel X"; + sequence0 = "spring0-7" TAB "Spring suspension for wheel X (start=fully compressed, end=fully extended)"; + sequence1 = "steering" TAB "Steering mechanism (start=full left, end=full right)"; + sequence2 = "brakelight" TAB "Sequence to play when braking (start=brakes off, end=brakes on)"; + }; + + new ScriptObject() + { + objectType = "HoverVehicle"; + node0 = "JetNozzle0-3" TAB "Nodes for jet engine exhaust particle emission"; + node1 = "JetNozzleX" TAB "Nodes for jet engine exhaust particle emission"; + sequence0 = "activateBack" TAB "Non-cyclic sequence to play when vehicle first starts moving backwards"; + sequence1 = "maintainBack" TAB "Cyclic sequence to play when vehicle continues moving backwards"; + }; + + new ScriptObject() + { + objectType = "FlyingVehicle"; + node0 = "JetNozzle0-3" TAB "Nodes for jet engine exhaust particle emission"; + node1 = "JetNozzleX" TAB "Nodes for jet engine exhaust particle emission"; + node2 = "JetNozzleY" TAB "Nodes for jet engine exhaust particle emission"; + node3 = "contrail0-3" TAB "Nodes for contrail particle emission"; + sequence0 = "activateBack" TAB "Sequence to play when vehicle first starts thrusting backwards"; + sequence1 = "maintainBack" TAB "Cyclic sequence to play when vehicle continues thrusting backwards"; + sequence2 = "activateBot" TAB "Non-cyclic sequence to play when vehicle first starts thrusting upwards"; + sequence3 = "maintainBot" TAB "Cyclic sequence to play when vehicle continues thrusting upwards"; + }; + + new ScriptObject() + { + objectType = "Projectile"; + sequence0 = "activate" TAB "Non-cyclic sequence to play when projectile is first created"; + sequence1 = "maintain" TAB "Cyclic sequence to play for remainder of projectile lifetime"; + }; +}; diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/AddFMODProjectDlg.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/AddFMODProjectDlg.ed.gui new file mode 100644 index 000000000..56c892fa9 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/AddFMODProjectDlg.ed.gui @@ -0,0 +1,284 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AddFMODProjectDlg,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiOverlayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl() { + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "AddFMODProjectDlg.onCancel();"; + EdgeSnap = "1"; + text = "Add FMOD Designer Audio"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "361 196"; + Extent = "303 236"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + internalName = "window"; + + new GuiBitmapBorderCtrl() { + isContainer = "1"; + Profile = "ToolsGuiGroupBorderProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 26"; + Extent = "291 160"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Path to the compiled event file (.fev):"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 51"; + Extent = "176 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 72"; + Extent = "254 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "fileNameField"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 127"; + Extent = "254 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "mediaPathField"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Name for the SFXFMODProject object:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 10"; + Extent = "189 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 30"; + Extent = "277 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "projectNameField"; + canSaveDynamicFields = "0"; + }; + new GuiMLTextCtrl() { + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + text = "Path to the project\'s media files (leave empty if files are in same directory as the project file):"; + useURLMouseCursor = "0"; + isContainer = "0"; + Profile = "ToolsGuiMLTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 96"; + Extent = "276 26"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "..."; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "266 72"; + Extent = "18 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + command = "AddFMODProjectDlg.onSelectFile();"; + }; + new GuiButtonCtrl() { + text = "..."; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "266 127"; + Extent = "18 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + command = "AddFMODProjectDlg.onSelectMediaPath();"; + }; + }; + new GuiButtonCtrl() { + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "206 196"; + Extent = "90 30"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "AddFMODProjectDlg.onCancel();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "112 196"; + Extent = "90 30"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "AddFMODProjectDlg.onOK();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/AxisGizmoSettingsTab.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/AxisGizmoSettingsTab.ed.gui new file mode 100644 index 000000000..e5eba667e --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/AxisGizmoSettingsTab.ed.gui @@ -0,0 +1,524 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(AxisGizmoSettingsTab,EditorGuiGroup) { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(EAxisGizmoSettingsPage) { + fitBook = "1"; + text = "Axis Gizmo"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "ToolsGuiSolidDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "208 568"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "ToolsGuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "208 568"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Gizmo"; + Margin = "0 0 0 -3"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "-1 0"; + Extent = "208 79"; + Docking = "none"; + + new GuiTextCtrl() { + text = "Rotate Scalar:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 6"; + extent = "70 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = "0.8"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiNumericTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "81 5"; + extent = "121 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/mouseRotateScalar"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiTextCtrl() { + text = "Scale Scalar:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 26"; + extent = "70 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = "0.8"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiNumericTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "81 24"; + extent = "121 17"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/mouseScaleScalar"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Render When Manipulated"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 44"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/renderWhenUsed"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Render Tool Text"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 61"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/renderInfoText"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Grid"; + Margin = "0 0 0 -3"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "-1 0"; + Extent = "208 82"; + Docking = "none"; + + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Render Plane"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 4"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/Grid/renderPlane"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Render Plane Hashes"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 21"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/Grid/renderPlaneHashes"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiTextCtrl() { + text = "Plane Size:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 40"; + extent = "70 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + text = "500"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiNumericTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "81 38"; + extent = "121 17"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/Grid/planeDim"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "5 58"; + extent = "208 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "AxisGizmo/Grid/gridColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Plane Color:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 2"; + extent = "70 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "76 0"; + extent = "104 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "0 0 0 0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "184 2"; + extent = "14 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/CameraSettingsTab.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/CameraSettingsTab.ed.gui new file mode 100644 index 000000000..f6018ea9f --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/CameraSettingsTab.ed.gui @@ -0,0 +1,429 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(CameraSettingsTab,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(ECameraSettingsPage) { + fitBook = "1"; + text = "Camera Settings"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "245 568"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "245 568"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + internalName = "content"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "245 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Mouse Control"; + Margin = "0 0 0 -3"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "-1 0"; + Extent = "208 41"; + Docking = "none"; + + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Invert Y Axis"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 5"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "Camera/invertYAxis"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Invert X Axis"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 22"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "Camera/invertXAxis"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- + +function ECameraSettingsPage::init(%this) +{ + %this.currentLevel = ""; + %this.currentRolloutCtrl = ""; + + %levelInfoPath = "LevelInformation/levels"; + for( %fieldName = EditorSettings.findFirstValue(%levelInfoPath, true, true); + %fieldName !$= ""; + %fieldName = EditorSettings.findNextValue() ) + { + %fieldSlashPos = 0; + %levelSlashPos = 0; + while( strpos( %fieldName, "/", %fieldSlashPos ) != -1 ) + { + %levelSlashPos = %fieldSlashPos; + + %temp = strpos( %fieldName, "/", %fieldSlashPos ); + %fieldSlashPos = %temp + 1; + } + %levelName = getSubStr( %fieldName , %levelSlashPos , ((%fieldSlashPos - %levelSlashPos) - 1)); + + for( %i = 0; %i < %this-->content.getCount(); %i++ ) + { + %alreadyExist = false; + if( %this-->content.getObject(%i).caption $= %levelName ) + { + %alreadyExist = true; + break; + } + } + + if( %this.currentLevel !$= %levelName && !%alreadyExist ) + { + //Hold current level and reset gui params + %this.currentLevel = %levelName; + //%this.currentLevel = "\""@%levelName@"\""; + + //Create and hold current rollout ctrl + %this.currentRolloutCtrl = new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = %levelName; + Margin = "0 0 0 -3"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ //spacer + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "208 2"; + }; + + new GuiContainer(){ + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "208 22"; + Docking = "none"; + + new GuiTextCtrl() { + text = "Camera Speed Min:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 3"; + extent = "96 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiNumericTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "106 2"; + extent = "95 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readCameraSettings( \"" @ %levelName @ "\" );"; + editorSettingsValue = "LevelInformation/levels/" @ %levelName @ "/cameraSpeedMin"; + editorSettingsWrite = "EditorGui.writeCameraSettings( \"" @ %levelName @ "\" );"; // not in use + }; + }; + new GuiContainer(){ + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "208 22"; + Docking = "none"; + + new GuiTextCtrl() { + text = "Camera Speed Max:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 3"; + extent = "96 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiNumericTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "106 2"; + extent = "95 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readCameraSettings( \"" @ %levelName @ "\" );"; + editorSettingsValue = "LevelInformation/levels/" @ %levelName @ "/cameraSpeedMax"; + editorSettingsWrite = "EditorGui.writeCameraSettings( \"" @ %levelName @ "\" );"; // not in use + }; + }; + new GuiContainer(){ + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "208 24"; + Docking = "none"; + + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "5 2"; + Extent = "196 18"; + MinExtent = "8 8"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ECameraSettingsPage.deleteCameraSettingsGroup(\"" @ %levelName @ "\", $ThisControl.getParent().getParent().getParent());"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Delete Level Settings"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "1"; + }; + }; + }; + }; + %this-->content.add(%this.currentRolloutCtrl); + } + } +} + +function ECameraSettingsPage::deleteCameraSettingsGroup( %this, %levelName, %rolloutCtrl ) +{ + if( %levelName $= EditorGui.levelName ) + { + MessageBoxOK("Error", "You may not delete the settings group associated with the currently loaded level"); + return; + } + + %levelInfoPath = "LevelInformation/levels/" @ %levelName; + for( %fieldName = EditorSettings.findFirstValue(%levelInfoPath, true, true); + %fieldName !$= ""; + %fieldName = EditorSettings.findNextValue() ) + { + EditorSettings.remove( %fieldName, true ); + } + + %rolloutCtrl.delete(); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/EditorChooseLevelGui.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/EditorChooseLevelGui.ed.gui new file mode 100644 index 000000000..a384f59e7 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/EditorChooseLevelGui.ed.gui @@ -0,0 +1,269 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiContainer(EditorChooseLevelGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiContentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiChunkedBitmapCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiContentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + bitmap = "art/gui/background"; + useVariable = "0"; + tile = "0"; + }; +}; + +%guiContent = new GuiContainer(EditorChooseLevelContainer, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiContentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl(EditorChooseLevelWindow) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "416 187"; + Extent = "192 393"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Level Selector"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 21"; + Extent = "171 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "1: Edit an Existing Level"; + maxLength = "255"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "42 360"; + Extent = "107 23"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "WE_ReturnToMainMenu();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Play Game"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 38"; + Extent = "171 194"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "4 0"; + + new GuiMLTextCtrl(WE_LevelList) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiMLTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 1"; + Extent = "148 70"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "1"; + }; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 250"; + Extent = "171 87"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = false; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "4 0"; + + new GuiMLTextCtrl(WE_TemplateList) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiMLTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 1"; + Extent = "148 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "1"; + }; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 232"; + Extent = "174 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "2: Create New from Template"; + maxLength = "255"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 338"; + Extent = "174 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "3: Play Game from Start"; + maxLength = "255"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/EditorGui.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/EditorGui.ed.gui new file mode 100644 index 000000000..3eb8558e4 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/EditorGui.ed.gui @@ -0,0 +1,1304 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiContainer(EditorGui,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiContainer(EditorGuiToolbar) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "menubarProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 32"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + + new GuiBitmapButtonCtrl(EHWorldEditor) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "4 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = ""; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Open the WorldEditor"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/toolbar/world"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EHGuiEditor) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "34 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "toggleGuiEditor(true); $GuiEditorBtnPressed = true;"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Open the GuiEditor"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/toolbar/gui"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "64 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "Editor.close(\"PlayGui\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Play Game"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/toolbar/playbutton"; + groupNum = "0"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "98 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiBitmapButtonCtrl(EWorldEditorToggleCamera) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "102 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "CameraTypesDropdownToggle();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggle Camera Modes"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/toolbar/player"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + + new GuiBitmapCtrl(){ + HorizSizing = "left"; + VertSizing = "top"; + Position = getWord(EWorldEditorToggleCamera.extent, 0)-6 SPC getWord(EWorldEditorToggleCamera.extent, 1)-6; + Extent = "4 4"; + MinExtent = "4 4"; + bitmap = "tools/gui/images/dropdown-button-arrow"; + }; + }; + new GuiControl(CameraSpeedDropdownContainer, EditorGuiGroup) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "136 5"; + Extent = "136 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 6"; + Extent = "78 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Camera Speed"; + maxLength = "1024"; + }; + new GuiTextEditCtrl(EWorldEditorCameraSpeed) { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="ToolsGuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "78 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "EWorldEditorCameraSpeed.updateMenuBar( $ThisControl );"; + hovertime = "1000"; + text = "100"; + maxLength = "4"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "112 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(CameraSpeedDropdownCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes the Camera Speed"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/dropslider"; + }; + }; + /*new GuiPopUpMenuCtrl(EWorldEditorCameraSpeed) { + canSaveDynamicFields = "0"; + internalName = "CameraSpeedDropdown"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "136 7"; + Extent = "130 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + };*/ + new GuiBitmapButtonCtrl(visibilityToggleBtn) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "270 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "VisibilityDropdownToggle();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggle Visibility Modes (ALT V)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/visibility-toggle"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + + new GuiBitmapCtrl(){ + HorizSizing = "left"; + VertSizing = "top"; + Position = getWord(visibilityToggleBtn.extent, 0)-6 SPC getWord(visibilityToggleBtn.extent, 1)-6; + Extent = "4 4"; + MinExtent = "4 4"; + bitmap = "tools/gui/images/dropdown-button-arrow"; + }; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "303 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiPopUpMenuCtrl(EWorldEditorAlignPopup) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "439 2"; + Extent = "70 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + }; + + new GuiContainer(EditorGuiStatusBar) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "menubarProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "0 578"; + Extent = "800 22"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Docking = "Bottom"; + + new GuiTextCtrl(EWorldEditorStatusBarInfo) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "3 2"; + Extent = "450 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Current Tool"; + maxLength = "255"; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "459 2"; + Extent = "2 18"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiTextCtrl(EWorldEditorStatusBarSelection) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "469 2"; + Extent = "180 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = ""; + maxLength = "255"; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "659 2"; + Extent = "2 18"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiPopUpMenuCtrl(EWorldEditorStatusBarCamera) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "667 2"; + Extent = "120 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "800 2"; + Extent = "2 18"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + }; + + new WorldEditor(EWorldEditor) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "WorldEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "255 0 0 20"; + missionAreaFrameColor = "255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "255 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + isDirty = "0"; + stickToGround = "0"; + dropAtBounds = "1"; + dropBelowCameraOffset = "15"; + dropType = "screenCenter"; + boundingBoxCollision = "1"; + renderPopupBackground = "1"; + popupBackgroundColor = "100 100 100 255"; + popupTextColor = "255 255 0 255"; + objectTextColor = "255 255 255 255"; + objectsUseBoxCenter = "1"; + objSelectColor = "255 0 0 255"; + objMouseOverSelectColor = "0 0 255 255"; + objMouseOverColor = "0 255 0 255"; + showMousePopupInfo = "1"; + dragRectColor = "255 255 0 255"; + renderObjText = "1"; + renderObjHandle = "1"; + objTextFormat = "$name|class$"; + faceSelectColor = "0 0 100 100"; + renderSelectionBox = "1"; + selectionBoxColor = "255 255 0 255"; + selectionLocked = "0"; + toggleIgnoreList = "0"; + selectHandle = "tools/worldEditor/images/SelectHandle.png"; + defaultHandle = "tools/worldEditor/images/DefaultHandle.png"; + lockedHandle = "tools/worldEditor/images/LockedHandle.png"; + }; + new TerrainEditor(ETerrainEditor) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "WorldEditorProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + cameraZRot = "0"; + forceFOV = "0"; + renderMissionArea = "0"; + missionAreaFillColor = "0 0 0 20";//"255 0 0 20"; + missionAreaFrameColor = "0 0 0 128";//"255 0 0 128"; + allowBorderMove = "0"; + borderMovePixelSize = "20"; + borderMoveSpeed = "0.1"; + consoleFrameColor = "0 0 0 255"; + consoleFillColor = "0 0 0 0"; + consoleSphereLevel = "1"; + consoleCircleSegments = "32"; + consoleLineWidth = "1"; + GizmoProfile = "GlobalGizmoProfile"; + isDirty = "0"; + isMissionDirty = "0"; + renderBorder = "1"; + borderHeight = "10"; + borderFillColor = "0 255 0 20"; + borderFrameColor = "0 255 0 128"; + borderLineMode = "0"; + selectionHidden = "1"; + renderVertexSelection = "1"; + processUsesBrush = "0"; + maxBrushSize = "256 256"; + adjustHeightVal = "10"; + setHeightVal = "100"; + scaleVal = "1"; + smoothFactor = "0.1"; + materialGroup = "0"; + softSelectRadius = "50"; + softSelectFilter = "1.000000 0.833333 0.666667 0.500000 0.333333 0.166667 0.000000"; + softSelectDefaultFilter = "1.000000 0.833333 0.666667 0.500000 0.333333 0.166667 0.000000"; + adjustHeightMouseScale = "0.1"; + paintIndex = "-1"; + + new GuiTextCtrl(TESelectionInfo) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "288 549"; + Extent = "120 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " (Selection) #: 0 avg: 0"; + maxLength = "255"; + }; + new GuiTextCtrl(TEMouseBrushInfo) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "40 549"; + Extent = "107 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " (Mouse) #: 0 avg: 0"; + maxLength = "255"; + }; + new GuiTextCtrl(TESelectionInfo1) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfileWhite"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "289 550"; + Extent = "120 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " (Selection) #: 0 avg: 0"; + maxLength = "255"; + }; + new GuiTextCtrl(TEMouseBrushInfo1) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfileWhite"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "41 550"; + Extent = "107 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " (Mouse) #: 0 avg: 0"; + maxLength = "255"; + }; + }; + + new GuiControl(RelightStatus) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiSolidDefaultProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "223 277"; + Extent = "353 45"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + + + new GuiProgressBitmapCtrl(RelightProgress) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiRLProgressBitmapProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "5 0"; + Extent = "440 24"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + + }; + new GuiTextCtrl(RelightProgressTxt) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiProgressTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 20"; + Extent = "440 20"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Loading Mission"; + maxLength = "255"; + }; + }; + new GuiControl(RelightMessage) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "19 570"; + Extent = "583 23"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "5 1"; + Extent = "449 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "A lightmapped object has been altered; relight the scene!"; + maxLength = "255"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "468 2"; + Extent = "75 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Editor.lightScene(\"\", forceAlways); RelightMessage.visible = false;"; + hovertime = "1000"; + text = "Relight Scene"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "548 2"; + Extent = "32 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RelightMessage.visible = false;"; + hovertime = "1000"; + text = "Hide"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + new GuiControl(PhysicsEditMessage) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiSolidDefaultProfile"; + HorizSizing = "center"; + VertSizing = "top"; + Position = "180 560"; + Extent = "440 32"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "width"; + VertSizing = "center"; + Position = "5 0"; + Extent = "238 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "PHYSICS SIMULATION PAUSED FOR EDITING..."; + maxLength = "255"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "337 3"; + Extent = "43 26"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "physicsStart(); PhysicsEditMessage.visible = false;"; + hovertime = "1000"; + text = "Start"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "392 3"; + Extent = "43 26"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "PhysicsEditMessage.visible = false;"; + hovertime = "1000"; + text = "Hide"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + new GuiContainer(CameraTypesDropdown){ + Profile = "IconDropdownProfile"; + Position = getWord(EWorldEditorToggleCamera.position, 0)-5 SPC getWord(EditorGuiToolbar.extent, 1)-1; + Extent = "137" SPC ((6*28)+6);//97"; + isContainer = "1"; + visible = "0"; + + new GuiDynamicCtrlArrayControl(cameraDropdownArray) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "5 5"; + Extent = "132" SPC getWord(CameraTypesDropdown.extent, 1)-5; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + colCount = "1"; + colSize = "127"; + rowCount = "0"; + RowSize = "64"; + rowSpacing = "3"; + colSpacing = "3"; + autoCellSize = "1"; + fillRowFirst = "0"; + + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "StandardCamera"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 5"; + Extent = "127 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "CameraTypesDropdownToggle(); EditorGuiStatusBar.setCamera(\"Standard Camera\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Free Camera"; + hovertime = "1000"; + iconBitmap = "tools/worldEditor/images/toolbar/camera_n"; + groupNum = "0"; + text="Free Camera"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "OrbitCamera"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 32"; + Extent = "127 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "CameraTypesDropdownToggle(); EditorGuiStatusBar.setCamera(\"Orbit Camera\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggle Orbit Cam"; + hovertime = "1000"; + iconBitmap = "tools/gui/images/menubar/orbit-cam_n"; + groupNum = "0"; + text="Orbit Camera"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "PlayerCamera"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 5"; + Extent = "127 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "CameraTypesDropdownToggle(); EditorGuiStatusBar.setCamera(\"1st Person Camera\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Player Camera"; + hovertime = "1000"; + iconBitmap = "tools/worldEditor/images/toolbar/player_n"; + groupNum = "0"; + text="Player Camera"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "trdPersonCamera"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 5"; + Extent = "127 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "CameraTypesDropdownToggle(); EditorGuiStatusBar.setCamera(\"3rd Person Camera\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "3rd Person Camera"; + hovertime = "1000"; + iconBitmap = "tools/worldEditor/images/toolbar/3rd-person-camera_n"; + groupNum = "0"; + text="3rd Person Cam"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "NewtonianCamera"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 64"; + Extent = "127 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "CameraTypesDropdownToggle(); EditorGuiStatusBar.setCamera(\"Smooth Camera\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggle Newtonian Cam"; + hovertime = "1000"; + iconBitmap = "tools/gui/images/menubar/smooth-cam_n"; + groupNum = "0"; + text="Smooth Camera"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "NewtonianRotationCamera"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 64"; + Extent = "127 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "CameraTypesDropdownToggle(); EditorGuiStatusBar.setCamera(\"Smooth Rot Camera\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggle Smooth Camera with Smooth Rotation"; + hovertime = "1000"; + iconBitmap = "tools/gui/images/menubar/smooth-cam-rot_n"; + groupNum = "0"; + text="Smooth Rotate"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + }; + + new GuiDecoyCtrl(CameraTypesDropdownDecoy) { + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = getWord(CameraTypesDropdown.extent, 0) SPC getWord(CameraTypesDropdown.extent, 1); + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + useMouseEvents = "1"; + isDecoy = "1"; + }; + + }; + new GuiContainer(VisibilityDropdown){ + Profile = "IconDropdownProfile"; + Position = getWord(visibilityToggleBtn.position, 0)-5 SPC getWord(EditorGuiToolbar.extent, 1)-1; + Extent = "159 261"; //SPC ((6*28)+6);//97"; + isContainer = "1"; + visible = "0"; + + new GuiTabBookCtrl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Margin = "3 3 3 3"; + Position = "5 24"; + Extent = "170 226"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + TabPosition = "Top"; + TabHeight = "22"; + TabMargin = "7"; + MinTabWidth = "64"; + + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Margin = "-1 0 0 0"; + Position = "0 14"; + Extent = "164 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + text = "Viz Toggles"; + maxLength = "255"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Position = "4 12"; + Extent = "156 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "-2"; + canSaveDynamicFields = "0"; + internalName = "theVisOptionsList"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 0"; + Extent = "156 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Margin = "-1 0 0 0"; + Position = "0 14"; + Extent = "164 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + text = "Class Toggles"; + maxLength = "255"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Position = "4 12"; + Extent = "156 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "-2"; + canSaveDynamicFields = "0"; + internalName = "theClassVisList"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 0"; + Extent = "156 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; + }; + }; +}; + + + + +new GuiMouseEventCtrl(CameraSpeedDropdownCtrlContainer, EditorGuiGroup) { + internalName = "AggregateControl"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiContainer(){ + position = firstWord(CameraSpeedDropdownContainer.position) + firstWord(EditorGuiToolbar.position) + -6 SPC + (getWord(CameraSpeedDropdownContainer, 1)) + 31; + extent = "146 39"; + isContainer = "1"; + Profile = "IconDropdownProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + + new GuiBitmapCtrl(){ // Fast + position = "105 15"; + extent = "2 8"; + bitmap = "tools/gui/images/separator-h.png"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + new GuiBitmapCtrl(){ // normal + position = "73 15"; + extent = "2 8"; + bitmap = "tools/gui/images/separator-h.png"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + new GuiBitmapCtrl(){ // slow + position = "41 15"; + extent = "2 8"; + bitmap = "tools/gui/images/separator-h.png"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + + new GuiSliderCtrl(){ //camera speed slider + internalName = "slider"; + position = "9 17"; + extent = "129 15"; + bitmap = "tools/gui/images/separator-h.png"; + HorizSizing = "width"; + VertSizing = "bottom"; + range = "1 200"; + ticks = "0"; + value = "100"; + AltCommand = "EWorldEditorCameraSpeed.updateMenuBar( $ThisControl );"; + }; + new GuiTextCtrl(){ // Normal + internalName = "text"; + position = "54 3"; + extent = "39 18"; + text = "Normal"; + Profile = "ToolsGuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + new GuiTextCtrl(){ // - + position = "11 2"; + extent = "39 18"; + text = "-"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + new GuiTextCtrl(){ // + + position = "98 5"; + extent = "39 13"; + text = "+"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + }; + }; +}; +//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/EditorSettingsWindow.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/EditorSettingsWindow.ed.gui new file mode 100644 index 000000000..7662ecf00 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/EditorSettingsWindow.ed.gui @@ -0,0 +1,122 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(EditorSettingsWindow,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiWindowCollapseCtrl(ESettingsWindow) { + internalName = "EditorSettingsWindow"; + resizeWidth = "0"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Editor Settings"; + closeCommand = "ESettingsWindow.hideDialog();"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "30 200"; + Extent = "319 320"; + MinExtent = "319 100"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTabBookCtrl(ESettingsWindowTabBook) { + TabPosition = "Top"; + TabMargin = "7"; + MinTabWidth = "64"; + TabHeight = "0"; + AllowReorder = "0"; + FrontTabPadding = "0"; + Docking = "Client"; + Margin = "3 1 4 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabBookNoBitmapProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "201 21"; + Extent = "334 425"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "AlwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Docking = "Left"; + Margin = "3 1 3 -1"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 21"; + Extent = "100 425"; + MinExtent = "100 50"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextListCtrl(ESettingsWindowList) { + AllowMultipleSelections = "1"; + fitParentWidth = "1"; + isContainer = "0"; + Profile = "ToolsGuiListBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "100 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/GeneralSettingsTab.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/GeneralSettingsTab.ed.gui new file mode 100644 index 000000000..b85e78ae0 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/GeneralSettingsTab.ed.gui @@ -0,0 +1,284 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(GeneralSettingsTab,EditorGuiGroup) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(EGeneralSettingsPage) { + fitBook = "1"; + text = "General Settings"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "432 568"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiSolidDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 0"; + extent = "432 568"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "0"; + dynamicSize = "1"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "430 41"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiRolloutCtrl() { + caption = "Paths"; + margin = "0 3 0 0"; + defaultHeight = "40"; + expanded = "1"; + clickCollapse = "1"; + hideHeader = "0"; + autoCollapseSiblings = "0"; + position = "0 0"; + extent = "430 41"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRolloutProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "3"; + dynamicSize = "1"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "0 20"; + extent = "430 18"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiControl() { + position = "0 0"; + extent = "430 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "New Level"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 1"; + extent = "70 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextRightProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "tools/levels/BlankRoom.mis"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "81 0"; + extent = "345 17"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/newLevelFile"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + }; + new GuiControl() { + position = "0 0"; + extent = "430 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "New Game Objects"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "5 1"; + extent = "70 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextRightProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "scripts/server/gameObjects"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "81 0"; + extent = "345 17"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/newGameObjectDir"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/GenericPromptDialog.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/GenericPromptDialog.ed.gui new file mode 100644 index 000000000..ade528157 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/GenericPromptDialog.ed.gui @@ -0,0 +1,115 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(GenericPromptDialog) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiOverlayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + internalName = "GenericPromptWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "336 337"; + Extent = "352 93"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Error"; + closeCommand = "Canvas.popDialog(GenericPromptDialog);"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + internalName = "GenericPromptText"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiProgressTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "13 33"; + Extent = "328 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Cannot use the Terrain Editor without a terrain"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "center"; + VertSizing = "top"; + Position = "134 61"; + Extent = "88 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.popDialog(GenericPromptDialog);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "center"; + VertSizing = "top"; + Position = "230 61"; + Extent = "88 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + Command = "Canvas.popDialog(GenericPromptDialog);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ManageBookmarksWindow.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ManageBookmarksWindow.ed.gui new file mode 100644 index 000000000..49ec1d65b --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ManageBookmarksWindow.ed.gui @@ -0,0 +1,145 @@ +%guiContent = new GuiControl(ManageBookmarksContainer, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiModelessDialogProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(EManageBookmarks) { + internalName = "ManageBookmarksWindow"; + Enabled = "1"; + isContainer = "1"; + profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + resizeWidth = "1"; + resizeHeight = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + position = "50 90"; + extent = "180 306"; + MinExtent = "120 130"; + text = "Camera Bookmark Manager"; + closeCommand = "EManageBookmarks.hideDialog();"; + EdgeSnap = "0"; + canCollapse = "0"; + visible = "0"; + Margin = "5 5 5 5"; + Padding = "5 5 5 5"; + + new GuiControl(){ + horizSizing = "width"; + vertSizing = "bottom"; + position = "4 23"; + extent = "170 20"; + //Docking = "Top"; + + new GuiTextCtrl() { + profile = "GuiCenterTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "1 2"; + extent = "24 16"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + text = "New"; + }; + new GuiTextEditCtrl(EAddBookmarkWindowName) { + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "27 2"; + extent = "126 18"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + historySize = "0"; + }; + new GuiBitmapButtonCtrl(EAddBookmarkWindowOK) { + profile = "ToolsGuiButtonProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "158 3"; + extent = "17 17"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + command = "ManageBookmarksContainer.onOK();"; + bitmap = "tools/gui/images/new"; + helpTag = "0"; + text = "Create"; + tooltip = "Create New Camera Bookmark"; + accelerator = "return"; + }; + }; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 12"; + Extent = "300 200"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "26 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 2"; + + new GuiStackControl() { + internalName = "ManageBookmarksWindowStack"; + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "2"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "300 200"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; +}; diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ManageSFXParametersWindow.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ManageSFXParametersWindow.ed.gui new file mode 100644 index 000000000..29c55dc74 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ManageSFXParametersWindow.ed.gui @@ -0,0 +1,240 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ManageSFXParametersContainer,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiModelessDialogProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + enabled = "1"; + isDecoy = "0"; + + new GuiWindowCollapseCtrl(EManageSFXParameters) { + CollapseGroup = "-1"; + CollapseGroupNum = "-1"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EManageSFXParameters.setVisible( false );"; + EdgeSnap = "0"; + text = "Audio Parameters"; + Margin = "5 5 5 5"; + Padding = "5 5 5 5"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + position = "49 68"; + Extent = "446 392"; + MinExtent = "120 130"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ManageSFXParametersWindow"; + canSaveDynamicFields = "0"; + + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "4 23"; + Extent = "484 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Name"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 2"; + Extent = "29 17"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "36 2"; + Extent = "226 17"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "AddSFXParameterName"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/new"; + autoFit = "0"; + text = "Create"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "266 2"; + Extent = "17 17"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "EManageSFXParameters.createNewParameter( EManageSFXParameters-->AddSFXParameterName.getText() );"; + Accelerator = "return"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Create New SFX Parameter"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "325 1"; + Extent = "113 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EManageSFXParameters.initList( $ThisControl.getText() );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "SFXParameterFilter"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Filter"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiAutoSizeTextProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "296 2"; + Extent = "24 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "2 2"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "4 46"; + Extent = "438 344"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "2"; + DynamicSize = "1"; + ChangeChildSizeToFit = "1"; + ChangeChildPosition = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "3 3"; + Extent = "419 10008"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "SFXParametersStack"; + canSaveDynamicFields = "0"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ObjectEditorSettingsTab.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ObjectEditorSettingsTab.ed.gui new file mode 100644 index 000000000..b8928eb7d --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ObjectEditorSettingsTab.ed.gui @@ -0,0 +1,1093 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ObjectEditorSettingsTab,EditorGuiGroup) { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(EObjectEditorSettingsPage) { + fitBook = "1"; + text = "Object Editor"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "ToolsGuiSolidDefaultProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "208 568"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "1"; + profile = "ToolsGuiScrollProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "208 568"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Render"; + Margin = "4 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Object Icons"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 10"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Render/renderObjHandle"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Object Text"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 30"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Render/renderObjText"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Mouse Popup Info"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 50"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Render/showMousePopupInfo"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Popup Menu Background"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 70"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Render/renderPopupBackground"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + }; + }; + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Colors"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 90"; + extent = "204 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Grid/gridColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Grid Major:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 110"; + extent = "204 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Grid/gridMinorColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Grid Minor:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 130"; + extent = "204 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Grid/gridOriginColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Grid Origin:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 17"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 10"; + extent = "204 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Color/dragRectColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Drag Rect:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 30"; + extent = "204 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Color/objectTextColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Object Text:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 50"; + extent = "204 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Color/popupTextColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Popup Text:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 70"; + extent = "204 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColor"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Color/popupBackgroundColor"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + + new GuiTextCtrl() { + text = "Popup Back:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextRightProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 1"; + extent = "70 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "80 0"; + extent = "104 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorEdit"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorEdit"; + }; + new GuiSwatchButtonCtrl() { + color = "1 1 1 1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "188 2"; + extent = "14 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "ColorButton"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowColorButton"; + }; + }; + }; + }; + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Misc"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "210 14"; + + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Force Load DAE"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + profile = "ToolsGuiCheckBoxProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 0"; + extent = "140 14"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + variable = "EWorldEditor.forceLoadDAE"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowCheckbox"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/forceLoadDAE"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 70"; + extent = "210 18"; + + new GuiTextCtrl() { + text = "Screen Center Scalar:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 1"; + extent = "110 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiNumericTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "120 0"; + extent = "80 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Tools/dropAtScreenCenterScalar"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 70"; + extent = "210 18"; + + new GuiTextCtrl() { + text = "Screen Center Max:"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "5 1"; + extent = "110 16"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiNumericTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "120 0"; + extent = "80 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + editorSettingsRead = "EditorGui.readWorldEditorSettings();"; + editorSettingsValue = "WorldEditor/Tools/dropAtScreenCenterMax"; + editorSettingsWrite = "EditorGui.writeWorldEditorSettings();"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ObjectSnapOptionsWindow.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ObjectSnapOptionsWindow.ed.gui new file mode 100644 index 000000000..24f5c8172 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ObjectSnapOptionsWindow.ed.gui @@ -0,0 +1,871 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ObjectSnapOptionsContainer, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiModelessDialogProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(ESnapOptions) { + internalName = "SnapOptionsWindow"; + Enabled = "1"; + isContainer = "1"; + profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + resizeWidth = "0"; + resizeHeight = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + position = "400 31"; + extent =" 175 257"; + MinExtent = "175 130"; + text = "Snap Options"; + closeCommand = "ESnapOptions.hideDialog();"; + EdgeSnap = "0"; + canCollapse = "0"; + visible = "0"; + Margin = "5 5 5 5"; + Padding = "5 5 5 5"; + + new GuiTabBookCtrl(ESnapOptionsTabBook) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "5 52"; + Extent = "190 240"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Docking = "Client"; + Margin = "3 22 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "10"; + MinTabWidth = "8"; + + new GuiTabPageCtrl(ESnapOptionsTabTerrain) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Margin = "0 0 0 0"; + Position = "0 19"; + Extent = "190 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Docking = "None"; + text = "Terrain"; + maxLength = "255"; + command = "toggleSnappingOptions(\"terrain\");"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Position = "4 12"; + Extent = "156 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 2"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "190 90"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiDynamicCtrlArrayControl() { + canSaveDynamicFields = "0"; + internalName = "TerrainSnapAlignment"; + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 18"; + Extent = "190 72"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + colCount = "2"; + colSize = "78"; + rowSize = "20"; + rowSpacing = "2"; + colSpacing = "2"; + dynamicSize = true; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "190 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " Alignment:"; + maxLength = "1024"; + }; + new GuiRadioCtrl() { + canSaveDynamicFields = "0"; + internalName = "NoAlignment"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiRadioProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setTerrainSnapAlignment(\"None\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "None"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "negX"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setTerrainSnapAlignment(\"-X\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "- X Axis"; + iconBitmap = "tools/gui/images/axis-icon_-x"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "posX"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setTerrainSnapAlignment(\"+X\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "+ X Axis"; + iconBitmap = "tools/gui/images/axis-icon_x"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "negY"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setTerrainSnapAlignment(\"-Y\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "- Y Axis"; + iconBitmap = "tools/gui/images/axis-icon_-y"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "posY"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setTerrainSnapAlignment(\"+Y\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "+ Y Axis"; + iconBitmap = "tools/gui/images/axis-icon_y"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "negZ"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setTerrainSnapAlignment(\"-Z\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "- Z Axis"; + iconBitmap = "tools/gui/images/axis-icon_-z"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "posZ"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setTerrainSnapAlignment(\"+Z\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "+ Z Axis"; + iconBitmap = "tools/gui/images/axis-icon_z"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + new GuiCheckBoxCtrl() { + text = "Snap to object bounding box"; + groupNum = "1"; + useMouseEvents = "0"; + isContainer = "0"; + horizSizing = "right"; + vertSizing = "top"; + position = "4 249"; + extent = "165 24"; + minExtent = "8 8"; + visible = "1"; + active = "1"; + Variable = "EWorldEditor.dropAtBounds"; + Command = "EWorldEditor.dropAtBounds = $ThisControl.getValue();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; + }; + new GuiTabPageCtrl(ESnapOptionsTabSoft) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Margin = "0 0 0 0"; + Position = "0 19"; + Extent = "190 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + Docking = "None"; + text = "Soft"; + maxLength = "255"; + command = "toggleSnappingOptions(\"soft\");"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Position = "4 12"; + Extent = "186 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 2"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "5"; + canSaveDynamicFields = "0"; + internalName = "theVisOptionsList"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "2 2"; + Extent = "190 190"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + Position = "0 0"; + Extent = "190 18"; + MinExtent = "16 16"; + Visible = "1"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "90 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Snap Size:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + internalName = "SnapSize"; + profile="ToolsGuiNumericTextEditProfile"; + HorizSizing = "left"; + position = "136 0"; + Extent = "44 18"; + text ="2.0"; + maxLength = "6"; + AltCommand = "ESnapOptions.setSoftSnapSize();"; + }; + }; + + new GuiControl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + Position = "0 0"; + Extent = "190 90"; + MinExtent = "16 16"; + Visible = "1"; + + new GuiDynamicCtrlArrayControl() { + canSaveDynamicFields = "0"; + internalName = "SoftSnapAlignment"; + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "190 90"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + colCount = "2"; + colSize = "78"; + rowSize = "20"; + rowSpacing = "2"; + colSpacing = "2"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "190 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " Alignment:"; + maxLength = "1024"; + }; + new GuiRadioCtrl() { + canSaveDynamicFields = "0"; + internalName = "NoAlignment"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiRadioProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setSoftSnapAlignment(\"None\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "None"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "negX"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setSoftSnapAlignment(\"-X\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "- X Axis"; + iconBitmap = "tools/gui/images/axis-icon_-x"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "posX"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setSoftSnapAlignment(\"+X\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "+ X Axis"; + iconBitmap = "tools/gui/images/axis-icon_x"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "negY"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setSoftSnapAlignment(\"-Y\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "- Y Axis"; + iconBitmap = "tools/gui/images/axis-icon_-y"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "posY"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setSoftSnapAlignment(\"+Y\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "+ Y Axis"; + iconBitmap = "tools/gui/images/axis-icon_y"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "negZ"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setSoftSnapAlignment(\"-Z\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "- Z Axis"; + iconBitmap = "tools/gui/images/axis-icon_-z"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "posZ"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonSmallProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "40 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "ESnapOptions.setSoftSnapAlignment(\"+Z\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "+ Z Axis"; + iconBitmap = "tools/gui/images/axis-icon_z"; + textMargin = "24"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + }; + + new GuiCheckBoxCtrl(){ + internalName = "RenderSnapBounds"; + Enabled = "1"; + Profile = "ToolsGuiCheckBoxProfile"; + position = "1 0"; + Extent = "190 18"; + text = "Render Snap Bounds"; + Command = "ESnapOptions.toggleRenderSnapBounds();"; + }; + + new GuiCheckBoxCtrl(){ + internalName = "RenderSnappedTriangle"; + Enabled = "1"; + Profile = "ToolsGuiCheckBoxProfile"; + position = "1 0"; + Extent = "190 18"; + text = "Render Snapped Triangle"; + Command = "ESnapOptions.toggleRenderSnappedTriangle();"; + }; + + new GuiControl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + Position = "0 0"; + Extent = "190 18"; + MinExtent = "16 16"; + Visible = "1"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "110 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Backface Tolerance:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + internalName = "SnapBackfaceTolerance"; + profile="ToolsGuiNumericTextEditProfile"; + HorizSizing = "left"; + position = "136 0"; + Extent = "44 18"; + text ="0.5"; + maxLength = "6"; + AltCommand = "ESnapOptions.getSoftSnapBackfaceTolerance();"; + }; + }; + }; + }; + }; + }; + new GuiCheckBoxCtrl() { + text = "Grid Snapping"; + groupNum = "1"; + useMouseEvents = "0"; + isContainer = "0"; + horizSizing = "right"; + vertSizing = "top"; + position = "4 231"; + extent = "95 24"; + minExtent = "8 8"; + visible = "1"; + active = "1"; + command = "toggleSnappingOptions(\"grid\");"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "GridSnapButton"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Size"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiDefaultProfile"; + horizSizing = "left"; + vertSizing = "top"; + position = "103 234"; + extent = "25 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + text = "2.0"; + maxLength = "6"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + isContainer = "0"; + profile = "ToolsGuiNumericTextEditProfile"; + horizSizing = "left"; + vertSizing = "top"; + position = "127 235"; + extent = "44 18"; + minExtent = "8 2"; + visible = "1"; + active = "1"; + altCommand = "ESnapOptions.setGridSnapSize();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "gridSize"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + internalName = "NoSnapButton"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "133 23"; + Extent = "38 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "toggleSnappingOptions(\"\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Off"; + groupNum = "1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ProceduralTerrainPainterGui.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ProceduralTerrainPainterGui.gui new file mode 100644 index 000000000..c00e31e4f --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ProceduralTerrainPainterGui.gui @@ -0,0 +1,405 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ProceduralTerrainPainterGui) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl(ProceduralTerrainPainterDescription) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "285 83"; + Extent = "175 233"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + canCollapse = "0"; + CollapseGroup = "-1"; + CollapseGroupNum = "-1"; + closeCommand = "Canvas.popDialog(ProceduralTerrainPainterGui);"; + text = "Generate layer mask"; + + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "19 193"; + Extent = "140 30"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "generateProceduralTerrainMask();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Generate"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "15 37"; + Extent = "33 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "HEIGHT"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "59 37"; + Extent = "23 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Min."; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "59 62"; + Extent = "23 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Max."; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "97 35"; + Extent = "66 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = "$TPPHeightMin"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "97 60"; + Extent = "66 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = "$TPPHeightMax"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "15 101"; + Extent = "33 13"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "SLOPE"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "59 101"; + Extent = "23 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Min."; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "59 126"; + Extent = "23 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Max."; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "97 99"; + Extent = "66 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = "$TPPSlopeMin"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "97 124"; + Extent = "66 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = "$TPPSlopeMax"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + + + new GuiTextCtrl() { + text = "COVERAGE"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "10 165"; + extent = "55 13"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "1"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "97 162"; + extent = "66 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + variable = "$TPPCoverage"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "%"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "77 164"; + extent = "11 14"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +$TPPHeightMin = -10000; +$TPPHeightMax = 10000; +$TPPSlopeMin = 0; +$TPPSlopeMax = 90; +$TPPCoverage = 100; + +function autoLayers() +{ + Canvas.pushDialog(ProceduralTerrainPainterGui); +} + +function generateProceduralTerrainMask() +{ + Canvas.popDialog(ProceduralTerrainPainterGui); + ETerrainEditor.autoMaterialLayer($TPPHeightMin, $TPPHeightMax, $TPPSlopeMin, $TPPSlopeMax, $TPPCoverage); +} + diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/SelectObjectsWindow.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/SelectObjectsWindow.ed.gui new file mode 100644 index 000000000..3e95e91d4 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/SelectObjectsWindow.ed.gui @@ -0,0 +1,566 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ESelectObjectsWindowContainer,EditorGuiGroup) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl(ESelectObjectsWindow) { + text = "Select Objects"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "1"; + closeCommand = "$ThisControl.toggleVisibility();"; + edgeSnap = "1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "268 177"; + extent = "380 373"; + minExtent = "200 100"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + class = "EObjectSelection"; + internalName = "SelectObjectsWindow"; + + new GuiBitmapBorderCtrl() { + position = "7 104"; + extent = "265 262"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiGroupBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "10 25"; + extent = "246 200"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "0"; + dynamicSize = "1"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "246 1242"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "classList"; + canSave = "1"; + canSaveDynamicFields = "0"; + + }; + }; + new GuiButtonCtrl() { + text = "Select All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "10 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ESelectObjectsWindow.selectAllInClassList( true );"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Classes"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "113 6"; + extent = "40 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Deselect All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "76 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ESelectObjectsWindow.selectAllInClassList( false );"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + position = "7 25"; + extent = "366 74"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiGroupBorderProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Name Pattern"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 9"; + extent = "67 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Retain Current Selection"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "216 46"; + extent = "140 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "retainSelection"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Create Selection Set"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "13 73"; + extent = "117 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiCheckBoxProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "createSelectionSet"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "•"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "157 80"; + extent = "199 17"; + minExtent = "20 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiTextEditProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "selectionSetName"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "•"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "91 9"; + extent = "265 17"; + minExtent = "20 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "namePattern"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Select Objects in Group"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 30"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "138 30"; + extent = "218 17"; + minExtent = "20 2"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "groupList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapBorderCtrl() { + position = "246 104"; + extent = "233 262"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiGroupBorderProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "0"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "9 25"; + extent = "215 200"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + stackingType = "Vertical"; + horizStacking = "Left to Right"; + vertStacking = "Top to Bottom"; + padding = "0"; + dynamicSize = "1"; + changeChildSizeToFit = "1"; + changeChildPosition = "1"; + position = "1 1"; + extent = "215 16"; + minExtent = "16 16"; + horizSizing = "width"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "filterList"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Select All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "9 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Filters"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "101 6"; + extent = "30 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiAutoSizeTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Deselect All"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "75 231"; + extent = "65 20"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiButtonCtrl() { + text = "Select"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "278 104"; + extent = "95 30"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ESelectObjectsWindow.onSelectObjects(true);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Deselect"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "278 137"; + extent = "95 30"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + fixedAspectRatio = "0"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "ESelectObjectsWindow.onSelectObjects(false);"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/TerrainBrushSoftnessCurveDlg.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/TerrainBrushSoftnessCurveDlg.ed.gui new file mode 100644 index 000000000..6fb188adf --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/TerrainBrushSoftnessCurveDlg.ed.gui @@ -0,0 +1,232 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TerrainBrushSoftnessCurveDlg, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiOverlayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "231 204"; + Extent = "175 228"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "0"; + text = "Brush Softness Curve"; + + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "84 196"; + Extent = "83 24"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "TerrainBrushSoftnessCurveDlg.onOk();"; + hovertime = "1000"; + text = "Ok"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiFilterCtrl() { + canSaveDynamicFields = "0"; + internalName = "FilterCurveCtrl"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "35 46"; + Extent = "130 128"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + controlPoints = "7"; + filter = "1 0.833333 0.666667 0.5 0.333333 0.166667 0"; + identity = "1 0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 43"; + Extent = "22 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Hard"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 159"; + Extent = "20 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Soft"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "36 174"; + Extent = "33 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Inside"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "129 176"; + Extent = "39 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Outside"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 196"; + Extent = "69 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.popDialog( TerrainBrushSoftnessCurveDlg );"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "122 26"; + Extent = "44 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainBrushSoftnessCurveDlg.resetCurve();"; + hovertime = "1000"; + text = "Reset"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + + +function TerrainBrushSoftnessCurveDlg::onWake( %this ) +{ + %curve = %this-->FilterCurveCtrl; + %curve.setValue( ETerrainEditor.softSelectFilter ); +} + +function TerrainBrushSoftnessCurveDlg::onOk( %this ) +{ + %curve = %this-->FilterCurveCtrl; + ETerrainEditor.softSelectFilter = %curve.getValue(); + ETerrainEditor.resetSelWeights(true); + + Canvas.popDialog( %this ); +} + +function TerrainBrushSoftnessCurveDlg::resetCurve( %this ) +{ + %curve = %this-->FilterCurveCtrl; + %curve.identity(); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/TerrainEditToolbar.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/TerrainEditToolbar.ed.gui new file mode 100644 index 000000000..cc9d6983b --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/TerrainEditToolbar.ed.gui @@ -0,0 +1,615 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(EWTerrainEditToolbar,EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = "TerrainEditToolbar"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "306 0"; + Extent = "800 40"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "6 7"; + extent = "70 16"; + minExtent = "8 8"; + visible = "1"; + text = "Brush Settings"; + maxLength = "255"; + helpTag = "0"; + }; + + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "760 40"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiControl(EWTerrainEditToolbarBrushType){ + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + Position = "83 2"; + Extent = "94 27"; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "ellipse"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.toggleBrushType($ThisControl);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Circle Brush (V)"; + hovertime = "750"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/circleBrush"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "box"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "31 0"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.toggleBrushType($ThisControl);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Box Brush (B)"; + hovertime = "750"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/boxBrush"; + }; + + /* + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "selection"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "62 0"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.toggleBrushType($ThisControl);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggles the brush type."; + hovertime = "750"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/maskBrush"; + }; + */ + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "152 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiControl(TerrainBrushSizeTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "145 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "21 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Size"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + HorizSizing = "right"; + profile="ToolsGuiNumericDropSliderTextProfile"; + VertSizing = "bottom"; + position = "49 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.setBrushSize( $ThisControl.getText() );"; + validate = "TerrainEditorPlugin.validateBrushSize();"; + hovertime = "1000"; + text = "9"; + maxLength = "4"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(TerrainBrushSizeSliderCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes size of the brush (CTRL + Mouse Wheel)"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/dropslider"; + }; + }; + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "272 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiControl(TerrainBrushPressureTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "287 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Pressure"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="ToolsGuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "49 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.setBrushPressure( ($ThisControl.getValue() / 100) );"; + hovertime = "1000"; + text = "100"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(TerrainBrushPressureSliderCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes the pressure (CTRL + SHIFT + Mouse Wheel)"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/dropslider"; + }; + }; + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "412 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiControl(TerrainBrushSoftnessTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "429 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Softness"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + HorizSizing = "right"; + profile="ToolsGuiNumericDropSliderTextProfile"; + VertSizing = "bottom"; + position = "49 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.setBrushSoftness( ($ThisControl.getValue() / 100) );"; + hovertime = "1000"; + text = "1"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(TerrainBrushSoftnessSliderCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes the softness (SHIFT + Mouse Wheel)"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/dropslider"; + }; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "547 3"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog( TerrainBrushSoftnessCurveDlg );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes the softness curve"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/softCurve"; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "589 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiControl(TerrainSetHeightTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "605 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 5"; + Extent = "33 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Height"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + HorizSizing = "right"; + profile="ToolsGuiNumericDropSliderTextProfile"; + VertSizing = "bottom"; + position = "34 2"; + Extent = "62 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.setHeightVal = $ThisControl.getValue();"; + hovertime = "1000"; + text = "1"; + maxLength = "7"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "88 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(TerrainSetHeightSliderCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes the height for the SetHeight tool (ALT + Left Mouse)"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/dropslider"; + }; + }; + }; +}; + +new GuiMouseEventCtrl(TerrainBrushSizeSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(TerrainBrushSizeTextEditContainer.position) + firstWord(EWTerrainEditToolbar.position)+11 SPC + (getWord(TerrainBrushSizeTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "TerrainBrushSizeTextEditContainer-->textEdit.setValue(mCeil($ThisControl.getValue())); ETerrainEditor.setBrushSize( $ThisControl.value );"; + range = "1 256"; + ticks = "0"; + value = "0"; + }; +}; + +new GuiMouseEventCtrl(TerrainBrushPressureSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(TerrainBrushPressureTextEditContainer.position) + firstWord(EWTerrainEditToolbar.position) SPC + (getWord(TerrainBrushPressureTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "TerrainBrushPressureTextEditContainer-->textEdit.setValue( mCeil(100 * $ThisControl.getValue()) @ \"%\"); ETerrainEditor.setBrushPressure( $ThisControl.value );"; + range = "0.01 1"; + ticks = "0"; + value = "0"; + }; +}; + +new GuiMouseEventCtrl(TerrainBrushSoftnessSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(TerrainBrushSoftnessTextEditContainer.position) + firstWord(EWTerrainEditToolbar.position) SPC + (getWord(TerrainBrushSoftnessTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "TerrainBrushSoftnessTextEditContainer-->textEdit.setValue( mCeil(100 * $ThisControl.getValue()) @ \"%\"); ETerrainEditor.setBrushSoftness( $ThisControl.value );"; + range = "0 1"; + ticks = "0"; + value = "0"; + }; +}; + +new GuiMouseEventCtrl(TerrainSetHeightSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(TerrainSetHeightTextEditContainer.position) + firstWord(EWTerrainEditToolbar.position) SPC + (getWord(TerrainSetHeightTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "TerrainSetHeightTextEditContainer-->textEdit.setValue( $ThisControl.getValue() ); ETerrainEditor.setHeightVal = $ThisControl.getValue();"; + range = "0 2047"; + ticks = "0"; + value = "100"; + }; +}; +//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/TerrainEditorSettingsTab.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/TerrainEditorSettingsTab.ed.gui new file mode 100644 index 000000000..8f219ec67 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/TerrainEditorSettingsTab.ed.gui @@ -0,0 +1,301 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TerrainEditorSettingsTab,EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiTabPageCtrl(ETerrainEditorSettingsPage) { + fitBook = "1"; + text = "Terrain Editor"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "208 400"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 1"; + extent = "208 210"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiRolloutCtrl() { + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "10 10"; + extent = "208 95"; + Caption = "Tool Values"; + Margin = "0 3 0 0"; + DragSizable = false; + container = true; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "208 0"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + padding = "3"; + + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Raise/Lower Height:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "ETerrainEditor.adjustHeightVal = EditorSettings.value(%this.editorSettingsValue);"; + editorSettingsValue = "TerrainEditor/ActionValues/adjustHeightVal"; + editorSettingsWrite = "EditorGui.writeTerrainEditorSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Smooth Factor:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "ETerrainEditor.smoothFactor = EditorSettings.value(%this.editorSettingsValue);"; + editorSettingsValue = "TerrainEditor/ActionValues/smoothFactor"; + editorSettingsWrite = "EditorGui.writeTerrainEditorSettings();"; + }; + }; + new GuiControl() { + isContainer = "1"; + horizSizing = "right"; + vertSizing = "bottom"; + extent = "208 18"; + + new GuiTextCtrl() { + text = "Noise Factor:"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextRightProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 1"; + Extent = "70 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "81 0"; + Extent = "121 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + class = "ESettingsWindowTextEdit"; + className = "ESettingsWindowTextEdit"; + editorSettingsRead = "ETerrainEditor.noiseFactor = EditorSettings.value(%this.editorSettingsValue);"; + editorSettingsValue = "TerrainEditor/ActionValues/noiseFactor"; + editorSettingsWrite = "EditorGui.writeTerrainEditorSettings();"; + }; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/TerrainEditorVSettingsGui.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/TerrainEditorVSettingsGui.ed.gui new file mode 100644 index 000000000..0a046a402 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/TerrainEditorVSettingsGui.ed.gui @@ -0,0 +1,276 @@ +//--- OBJECT WRITE BEGIN --- +new GuiControl(TerrainEditorValuesSettingsGui, EditorGuiGroup) { + profile = "ToolsGuiOverlayProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiWindowCtrl() { + profile = "ToolsGuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "117 113"; + extent = "408 247"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "Terrain Action Values"; + maxLength = "255"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "Canvas.popDIalog(TerrainEditorValuesSettingsGui);"; + + new GuiControl() { + profile = "ToolsGuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "198 27"; + extent = "203 115"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiTextEditCtrl() { + profile = "ToolsGuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "86 12"; + extent = "107 18"; + minExtent = "8 8"; + visible = "1"; + variable = "ETerrainEditor.adjustHeightVal"; + command = "ETerrainEditor.adjustHeightVal = $ThisControl.getValue();"; + helpTag = "0"; + maxLength = "255"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Adjust height increment."; + }; + new GuiTextEditCtrl() { + profile = "ToolsGuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "86 62"; + extent = "107 18"; + minExtent = "8 8"; + visible = "1"; + variable = "ETerrainEditor.scaleVal"; + command = "ETerrainEditor.scaleVal = $ThisControl.getValue();"; + helpTag = "0"; + maxLength = "255"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Scale height increment."; + }; + new GuiTextEditCtrl() { + profile = "ToolsGuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "86 87"; + extent = "107 18"; + minExtent = "8 8"; + visible = "1"; + variable = "ETerrainEditor.smoothFactor"; + command = "ETerrainEditor.smoothFactor = $ThisControl.getValue();"; + helpTag = "0"; + maxLength = "255"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Smoothing factor -- lower values are less agressive."; + }; + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "11 12"; + extent = "64 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "Adjust Height"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Adjust height increment."; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "11 37"; + extent = "49 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "Set Height"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Elevation for set height operation."; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "11 62"; + extent = "60 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "Scale Height"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Scale height increment."; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "10 87"; + extent = "70 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "Smooth Factor"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Smoothing factor -- lower values are less agressive."; + maxLength = "255"; + }; + }; + new GuiButtonCtrl() { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "218 205"; + extent = "80 20"; + minExtent = "8 8"; + visible = "1"; + command = "Canvas.popDIalog(TerrainEditorValuesSettingsGui);"; + helpTag = "0"; + text = "OK"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + new GuiControl() { + profile = "ToolsGuiWindowProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "7 27"; + extent = "188 212"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + + new GuiFilterCtrl(TESoftSelectFilter) { + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "20 22"; + extent = "155 162"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + controlPoints = "7"; + filter = "1.000000 0.833333 0.666667 0.500000 0.333333 0.166667 0.000000"; + }; + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "6 4"; + extent = "67 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "Soft Selection"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "This spline scale modifies the hardness of the brush. Left is center, right is outer edge."; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "12 189"; + extent = "8 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "0"; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "12 26"; + extent = "8 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "1"; + maxLength = "255"; + }; + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "60 190"; + extent = "45 18"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "<Radius>"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Brush radius for Selection Mode."; + maxLength = "255"; + }; + new GuiTextEditCtrl() { + profile = "ToolsGuiTextEditProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "125 187"; + extent = "50 18"; + minExtent = "8 8"; + visible = "1"; + variable = "ETerrainEditor.softSelectRadius"; + command = "ETerrainEditor.softSelectRadius = $ThisControl.getValue();"; + helpTag = "0"; + maxLength = "255"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Brush radius for Selection Mode."; + }; + }; + new GuiButtonCtrl(TESettingsApplyButton) { + profile = "ToolsGuiButtonProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "307 205"; + extent = "80 20"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + text = "Apply"; + groupNum = "-1"; + buttonType = "PushButton"; + }; + }; +}; +//--- OBJECT WRITE END --- + diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui new file mode 100644 index 000000000..8cdba481d --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/TerrainPainterToolbar.ed.gui @@ -0,0 +1,637 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(EWTerrainPainterToolbar,EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = "TerrainPainterToolbar"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "306 0"; + Extent = "800 40"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "6 7"; + extent = "70 16"; + minExtent = "8 8"; + visible = "1"; + text = "Brush Settings"; + maxLength = "255"; + helpTag = "0"; + }; + + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "760 40"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiControl(EWTerrainPainterToolbarBrushType){ + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + Position = "83 2"; + Extent = "94 27"; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "ellipse"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.toggleBrushType($ThisControl);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Circle Brush (V)"; + hovertime = "750"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/circleBrush"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "box"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "31 0"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.toggleBrushType($ThisControl);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Box Brush (B)"; + hovertime = "750"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/boxBrush"; + }; + + /* + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "selection"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "62 0"; + Extent = "29 27"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.toggleBrushType($ThisControl);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggles the brush type."; + hovertime = "750"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/maskBrush"; + }; + */ + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "152 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiControl(PaintBrushSizeTextEditContainer) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "145 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "21 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Size"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + profile="ToolsGuiNumericDropSliderTextProfile"; + position = "49 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.setBrushSize( $ThisControl.getText() );"; + validate = "TerrainPainterPlugin.validateBrushSize();"; + hovertime = "1000"; + text = "9"; + maxLength = "4"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(PaintBrushSizeSliderCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes the size of the brush (CTRL + Mouse Wheel)"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/dropslider"; + }; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "270 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiControl(PaintBrushSlopeControl) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "262 5"; + Extent = "256 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "21 5"; + Extent = "78 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Allows painting on the terrain within a specified slope"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Slope Mask Min"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + internalName = "SlopeMinAngle"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "104 2"; + Extent = "51 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + validate = "TerrainPainterPlugin.validateSlopeMinAngle();"; + Command = "ETerrainEditor.setSlopeLimitMinAngle( $ThisControl.getText() );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Minimum terrain angle that will be paintable"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "0.0"; + maxLength = "4"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "137 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Minimum terrain angle that will be paintable"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/dropslider"; + Command = "Canvas.pushDialog(PaintBrushSlopeMinContainer);"; + }; + new GuiTextCtrl() { + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "165 5"; + Extent = "27 10"; + MinExtent = "8 2"; + text = "Max"; + tooltip = "Max terrain angle that will be paintable"; + }; + new GuiTextEditCtrl() { + internalName = "SlopeMaxAngle"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "190 2"; + Extent = "51 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + validate = "TerrainPainterPlugin.validateSlopeMaxAngle();"; + Command = "ETerrainEditor.setSlopeLimitMaxAngle( $ThisControl.getText() );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Max terrain angle that will be paintable"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "90.0"; + maxLength = "4"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "223 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + tooltip = "Max terrain angle that will be paintable"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/dropslider"; + Command = "Canvas.pushDialog(PaintBrushSlopeMaxContainer);"; + }; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "525 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiControl(PaintBrushPressureTextEditContainer,EditorGuiGroup) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "540 5"; + Extent = "120 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 5"; + Extent = "47 10"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Pressure"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "textEdit"; + isContainer = "0"; + profile="ToolsGuiNumericDropSliderTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "49 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.setBrushPressure( ($ThisControl.getValue() / 100) );"; + hovertime = "1000"; + text = "100"; + maxLength = "3"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "83 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(PaintBrushPressureSliderCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes the pressure (CTRL + SHIFT + Mouse Wheel)"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/dropslider"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- + +function setTerrainEditorMinSlope(%value) +{ + %val = ETerrainEditor.setSlopeLimitMinAngle( %value ); + PaintBrushSlopeControl-->SlopeMinAngle.setValue(mFloatLength( %val, 1 )); +} + +function setTerrainEditorMaxSlope(%value) +{ + %val = ETerrainEditor.setSlopeLimitMaxAngle( %value ); + PaintBrushSlopeControl-->SlopeMaxAngle.setValue(mFloatLength( %val, 1 )); +} + +new GuiMouseEventCtrl(PaintBrushSizeSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(PaintBrushSizeTextEditContainer.position) + firstWord(EWTerrainPainterToolbar.position)+11 SPC + (getWord(PaintBrushSizeTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "PaintBrushSizeTextEditContainer-->textEdit.setValue(mFloatLength( ($ThisControl.getValue()), 2 )); ETerrainEditor.setBrushSize( $ThisControl.value );"; + range = "1 256"; + ticks = "0"; + value = "0"; + }; +}; + +new GuiMouseEventCtrl(PaintBrushSlopeMinContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(PaintBrushSlopeControl.position) + firstWord(EWTerrainPainterToolbar.position)+firstWord(PaintBrushSlopeControl->SlopeMinAngle.position) - 40 SPC + (getWord(PaintBrushSlopeControl, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "PaintBrushSlopeControl-->SlopeMinAngle.setValue(mFloatLength( ($ThisControl.getValue()), 1 )); ETerrainEditor.setSlopeLimitMinAngle(mFloatLength( ($ThisControl.getValue()), 1 ));TerrainPainterPlugin.validateSlopeMinAngle();"; + range = "0 89.9"; + ticks = "0"; + value = "0"; + }; +}; + +function PaintBrushSlopeMinContainer::onWake(%this) +{ + %this-->slider.setValue(PaintBrushSlopeControl-->SlopeMinAngle.getText()); +} + +new GuiMouseEventCtrl(PaintBrushSlopeMaxContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(PaintBrushSlopeControl.position) + firstWord(EWTerrainPainterToolbar.position)+firstWord(PaintBrushSlopeControl->SlopeMaxAngle.position) - 40 SPC + (getWord(PaintBrushSlopeControl, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "PaintBrushSlopeControl-->SlopeMaxAngle.setValue(mFloatLength( ($ThisControl.getValue()), 1 )); ETerrainEditor.setSlopeLimitMaxAngle(mFloatLength( ($ThisControl.getValue()), 1 ));TerrainPainterPlugin.validateSlopeMaxAngle();"; + range = "0.1 90.0"; + ticks = "0"; + value = "0"; + }; +}; + +function PaintBrushSlopeMaxContainer::onWake(%this) +{ + %this-->slider.setValue(PaintBrushSlopeControl-->SlopeMaxAngle.getText()); +} + +function PaintBrushSlopeMaxContainer::init(%this) +{ + %this-->slider.setValue("90.0"); +} + +new GuiMouseEventCtrl(PaintBrushPressureSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(PaintBrushPressureTextEditContainer.position) + firstWord(EWTerrainPainterToolbar.position) SPC + (getWord(PaintBrushPressureTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "PaintBrushPressureTextEditContainer-->textEdit.setValue(mFloatLength( ($ThisControl.getValue()), 2 )); ETerrainEditor.setBrushPressure( $ThisControl.value );"; + range = "0 1"; + ticks = "0"; + value = "0"; + }; +}; + +new GuiMouseEventCtrl(PaintBrushSoftnessSliderCtrlContainer,EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(PaintBrushSoftnessTextEditContainer.position) + firstWord(EWTerrainPainterToolbar.position) SPC + (getWord(PaintBrushSoftnessTextEditContainer, 1)) + 25; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "PaintBrushSoftnessTextEditContainer-->textEdit.setValue(mFloatLength( ($ThisControl.getValue()), 2 )); ETerrainEditor.setBrushSoftness( $ThisControl.value );"; + range = "0 1"; + ticks = "0"; + value = "0"; + }; +}; + diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/TerrainPainterWindow.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/TerrainPainterWindow.ed.gui new file mode 100644 index 000000000..a08c05841 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/TerrainPainterWindow.ed.gui @@ -0,0 +1,249 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TerrainPainterContainer,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(EPainter) { + canSaveDynamicFields = "0"; + internalName = "TerrainPainter"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 SPC getWord(EditorGuiToolbar.extent, 1)+249; + Extent = "210 446"; + MinExtent = "210 100"; + canSave = "1"; + isDecoy = "0"; + Visible = "0"; + hovertime = "1000"; + Docking = "None"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "152 300"; + closeCommand = "EPainter.parentGroup.setVisible(false);"; + EdgeSnap = "1"; + text = "Terrain Painter Material Selector"; + + new GuiScrollCtrl( EPainterScroll ) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 24"; + Extent = "202 418"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "3 1 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiStackControl( EPainterStack ) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "-2"; + canSaveDynamicFields = "0"; + internalName = "theMaterialList"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "200 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; + new GuiWindowCollapseCtrl(EPainterPreview) { + canSaveDynamicFields = "0"; + internalName = "TerrainPainterPreview"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord($pref::Video::mode, 0) - 209 SPC getWord(EditorGuiToolbar.extent, 1)-1; + Extent = "210 251"; + MinExtent = "210 251"; + canSave = "1"; + isDecoy = "0"; + Visible = "0"; + hovertime = "1000"; + Docking = "None"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "152 300"; + closeCommand = "EPainter.parentGroup.setVisible(false);"; + EdgeSnap = "1"; + text = "Terrain Painter Material Preview"; + + new GuiContainer(){ + Docking = "Client"; + Margin = "3 22 3 3"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 24"; + Extent = "202 202"; + + new GuiBitmapCtrl(ETerrainMaterialSelected) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 202"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + wrap = "0"; + bitmap= "tools/materialEditor/gui/unknownImage"; + }; + new GuiBitmapCtrl(ETerrainMaterialSelectedBorder) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 202"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/terrainpainter/terrain-painter-border-large"; + wrap = "0"; + }; + }; + new GuiButtonCtrl(ETerrainMaterialSelectedEdit) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "170 229"; + Extent = "36 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "0"; + Command = "TerrainMaterialDlg.show(ETerrainMaterialSelected.selectedMatIndex, ETerrainMaterialSelected.selectedMat, EPainter_TerrainMaterialUpdateCallback);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl(TerrainTextureText) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "5 230"; + Extent = "162 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "100 229"; + Extent = "50 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "autoLayers();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "Generate a layer mask for this material."; + hovertime = "1000"; + text = "AutoPaint"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/TimeAdjustGui.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/TimeAdjustGui.ed.gui new file mode 100644 index 000000000..8eaf11d4c --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/TimeAdjustGui.ed.gui @@ -0,0 +1,214 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TimeAdjustGui, EditorGuiGroup) { + isContainer = "1"; + Profile = "ToolsGuiModelessDialogProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl() { + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Time Adjust Gui"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "338 63"; + Extent = "462 84"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + closeCommand = "Canvas.popDialog(TimeAdjustGui);"; + + new GuiSliderCtrl(TimeAdjustSliderCtrl) { + range = "0 1"; + ticks = "100"; + value = "0.1"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "37 27"; + Extent = "389 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + altCommand = "$ThisControl.onAction();"; + }; + new GuiTextCtrl() { + text = "Sunrise"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "11 53"; + Extent = "59 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Sunset"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "206 53"; + Extent = "59 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Noon"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "108 53"; + Extent = "59 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Midnight"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "307 53"; + Extent = "59 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Sunrise"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextCenterProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "393 53"; + Extent = "59 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function TimeAdjustSliderCtrl::onAction(%this) +{ + // NOTE: Though this is a GuiControl which exists on the client-side + // we access and modify the server-side TimeOfDay object. This is acceptible + // because this is a "tools" gui which is not intended for a real-game + // or multiplayer situation. + + if ( !isObject( %this.tod ) ) + { + if ( isObject( MissionGroup ) ) + { + for ( %i = 0; %i < MissionGroup.getCount(); %i++ ) + { + %obj = MissionGroup.getObject( %i ); + + if ( %obj.getClassName() $= "TimeOfDay" ) + { + %this.tod = %obj; + break; + } + } + } + } + + if ( !isObject( %this.tod ) ) + return; + + %this.tod.time = %this.getValue(); +} + +function toggleTimeAdjustGui() +{ + if ( TimeAdjustGui.isAwake() ) + Canvas.popDialog( TimeAdjustGui ); + else + Canvas.pushDialog( TimeAdjustGui ); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/ConvexEditorPalette.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/ConvexEditorPalette.ed.gui new file mode 100644 index 000000000..e32cdfb4a --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/ConvexEditorPalette.ed.gui @@ -0,0 +1,102 @@ +%paletteId = new GuiControl(ConvexEditorPalette, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(ConvexEditorNoneModeBtn) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Select Arrow (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + Command = "GlobalGizmoProfile.mode = \"None\";"; + }; + + new GuiBitmapButtonCtrl(ConvexEditorMoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "28 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Move Selection (2)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/translate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + Command = "GlobalGizmoProfile.mode = \"Move\";"; + }; + + new GuiBitmapButtonCtrl(ConvexEditorRotateModeBtn) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "56 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Rotate Selection (3)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/rotate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + Command = "GlobalGizmoProfile.mode = \"Rotate\";"; + }; + + new GuiBitmapButtonCtrl(ConvexEditorScaleModeBtn) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "84 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Scale Selection (4)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/scale"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + Command = "GlobalGizmoProfile.mode = \"Scale\";"; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/DecalEditorPalette.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/DecalEditorPalette.ed.gui new file mode 100644 index 000000000..1e4053c8e --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/DecalEditorPalette.ed.gui @@ -0,0 +1,121 @@ +%paletteId = new GuiControl(DecalEditorPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(EDecalEditorSelectDecalBtn) { + canSaveDynamicFields = "0"; + internalName = "SelectDecalMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DecalEditorGui.setMode(\"SelectDecalMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Select Decal (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(EDecalEditorMoveDecalBtn) { + canSaveDynamicFields = "0"; + internalName = "MoveDecalMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DecalEditorGui.setMode(\"MoveDecalMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Move Decal (2)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/move-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EDecalEditorRotateDecalBtn) { + canSaveDynamicFields = "0"; + internalName = "RotateDecalMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DecalEditorGui.setMode(\"RotateDecalMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Rotate Decal (3)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/rotate-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EDecalEditorScaleDecalBtn) { + canSaveDynamicFields = "0"; + internalName = "ScaleDecalMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DecalEditorGui.setMode(\"ScaleDecalMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Scale Decal (4)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/scale-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EDecalEditorAddDecalBtn) { + canSaveDynamicFields = "0"; + internalName = "AddDecalMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "DecalEditorGui.setMode(\"AddDecalMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Add Decal (5)"; + hovertime = "1000"; + bitmap = "tools/decalEditor/add-decal"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/ForestEditorPalette.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/ForestEditorPalette.ed.gui new file mode 100644 index 000000000..a1cc96ef5 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/ForestEditorPalette.ed.gui @@ -0,0 +1,163 @@ +%paletteId = new GuiControl(ForestEditorPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(ForestEditorSelectModeBtn) { + canSaveDynamicFields = "0"; + internalName = "ForestEditorSelectMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.mode = \"None\"; ForestEditorGui.setActiveTool(ForestTools->SelectionTool);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Select Item (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ForestEditorMoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "ForestEditorMoveMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.mode = \"Move\"; ForestEditorGui.setActiveTool(ForestTools->SelectionTool);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Move Item (2)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/translate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ForestEditorRotateModeBtn) { + canSaveDynamicFields = "0"; + internalName = "ForestEditorRotateMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.mode = \"Rotate\"; ForestEditorGui.setActiveTool(ForestTools->SelectionTool);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Rotate Item (3)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/rotate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ForestEditorScaleModeBtn) { + canSaveDynamicFields = "0"; + internalName = "ForestEditorScaleMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.mode = \"Scale\"; ForestEditorGui.setActiveTool(ForestTools->SelectionTool);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Scale Item (4)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/scale"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ForestEditorPaintModeBtn) { + canSaveDynamicFields = "0"; + internalName = "ForestEditorPaintMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.setActiveTool( ForestTools->BrushTool ); ForestTools->BrushTool.mode = \"Paint\";"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Paint (5)"; + hovertime = "1000"; + bitmap = "tools/forestEditor/images/paint-forest-btn"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ForestEditorEraseModeBtn) { + canSaveDynamicFields = "0"; + internalName = "ForestEditorEraseMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.setActiveTool( ForestTools->BrushTool ); ForestTools->BrushTool.mode = \"Erase\";"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Erase (6)"; + hovertime = "1000"; + bitmap = "tools/forestEditor/images/erase-all-btn"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ForestEditorEraseSelectedModeBtn) { + canSaveDynamicFields = "0"; + internalName = "ForestEditorEraseSelectedMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ForestEditorGui.setActiveTool( ForestTools->BrushTool ); ForestTools->BrushTool.mode = \"EraseSelected\";"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Erase Selected (7)"; + hovertime = "1000"; + bitmap = "tools/forestEditor/images/erase-element-btn"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/MeshRoadEditorPalette.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/MeshRoadEditorPalette.ed.gui new file mode 100644 index 000000000..b005ac958 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/MeshRoadEditorPalette.ed.gui @@ -0,0 +1,163 @@ +%paletteId = new GuiControl(MeshRoadEditorPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(EMeshRoadEditorSelectModeBtn) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorSelectMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.prepSelectionMode();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Select Mesh Road (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(EMeshRoadEditorMoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorMoveMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.setMode(\"MeshRoadEditorMoveMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Move Point (2)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/move-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EMeshRoadEditorRotateModeBtn) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorRotateMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.setMode(\"MeshRoadEditorRotateMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Rotate Point (3)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/rotate-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EMeshRoadEditorScaleModeBtn) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorScaleMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.setMode(\"MeshRoadEditorScaleMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Scale Point (4)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/scale-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EMeshRoadEditorAddModeBtn) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorAddRoadMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.setMode(\"MeshRoadEditorAddRoadMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Create Road (5)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/add-mesh-road"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EMeshRoadEditorInsertModeBtn) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorInsertPointMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.setMode(\"MeshRoadEditorInsertPointMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Insert Point (+)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/add-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(EMeshRoadEditorRemoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "MeshRoadEditorRemovePointMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MeshRoadEditorGui.setMode(\"MeshRoadEditorRemovePointMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Remove Point (-)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/subtract-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/NavEditorPalette.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/NavEditorPalette.ed.gui new file mode 100644 index 000000000..506c525b2 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/NavEditorPalette.ed.gui @@ -0,0 +1,130 @@ +%paletteId = new GuiControl(NavEditorPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(ENavEditorSelectModeBtn) { + canSaveDynamicFields = "1"; + class = ENavEditorPaletteButton; + internalName = "NavEditorSelectMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "NavEditorGui.prepSelectionMode();"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "View NavMesh (1)."; + DetailedDesc = ""; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/visibility-toggle"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ENavEditorLinkModeBtn) { + canSaveDynamicFields = "1"; + class = ENavEditorPaletteButton; + internalName = "NavEditorLinkMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "NavEditorGui.setMode(\"LinkMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Create off-mesh links (2)."; + DetailedDesc = "Click to select/add. Shift-click to add multiple end points."; + hovertime = "1000"; + bitmap = "tools/navEditor/images/nav-link"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ENavEditorCoverModeBtn) { + canSaveDynamicFields = "1"; + class = ENavEditorPaletteButton; + internalName = "NavEditorCoverMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "NavEditorGui.setMode(\"CoverMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Edit cover (3)."; + DetailedDesc = ""; + hovertime = "1000"; + bitmap = "tools/navEditor/images/nav-cover"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ENavEditorTileModeBtn) { + canSaveDynamicFields = "1"; + class = ENavEditorPaletteButton; + internalName = "NavEditorTileMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "NavEditorGui.setMode(\"TileMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "View tiles (4)."; + DetailedDesc = "Click to select."; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/select-bounds"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ENavEditorTestModeBtn) { + canSaveDynamicFields = "1"; + class = ENavEditorPaletteButton; + internalName = "NavEditorTestMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "NavEditorGui.setMode(\"TestMode\");"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Test pathfinding (5)."; + DetailedDesc = "Click to select/move character, CTRL-click to spawn, SHIFT-click to deselect."; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/toolbar/3rd-person-camera"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/RiverEditorPalette.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/RiverEditorPalette.ed.gui new file mode 100644 index 000000000..5fea48b1b --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/RiverEditorPalette.ed.gui @@ -0,0 +1,163 @@ +%paletteId = new GuiControl(RiverEditorPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(ERiverEditorSelectModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RiverEditorSelectMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.prepSelectionMode();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Select River (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ERiverEditorMoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RiverEditorMoveMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.setMode(\"RiverEditorMoveMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Move Point (2)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/move-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ERiverEditorRotateModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RiverEditorRotateMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.setMode(\"RiverEditorRotateMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Rotate Point (3)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/rotate-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ERiverEditorScaleModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RiverEditorScaleMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.setMode(\"RiverEditorScaleMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Scale Point (4)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/scale-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ERiverEditorAddModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RiverEditorAddRiverMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.setMode(\"RiverEditorAddRiverMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Create River (5)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/add-river"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ERiverEditorInsertModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RiverEditorInsertPointMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.setMode(\"RiverEditorInsertPointMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Insert Point (+)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/add-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ERiverEditorRemoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RiverEditorRemovePointMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RiverEditorGui.setMode(\"RiverEditorRemovePointMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Remove Point (-)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/subtract-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/RoadEditorPalette.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/RoadEditorPalette.ed.gui new file mode 100644 index 000000000..712ea774f --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/RoadEditorPalette.ed.gui @@ -0,0 +1,144 @@ +%paletteId = new GuiControl(RoadEditorPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(ERoadEditorSelectModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RoadEditorSelectMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RoadEditorGui.prepSelectionMode();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Select Road (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ERoadEditorMoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RoadEditorMoveMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RoadEditorGui.setMode(\"RoadEditorMoveMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Move Point (2)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/move-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ERoadEditorScaleModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RoadEditorScaleMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RoadEditorGui.setMode(\"RoadEditorScaleMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Scale Point (4)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/scale-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ERoadEditorAddModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RoadEditorAddRoadMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RoadEditorGui.setMode(\"RoadEditorAddRoadMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Create Road (5)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/add-road-path"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl(ERoadEditorInsertModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RoadEditorInsertPointMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RoadEditorGui.setMode(\"RoadEditorInsertPointMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Insert Point (+)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/add-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ERoadEditorRemoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "RoadEditorRemovePointMode"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "RoadEditorGui.setMode(\"RoadEditorRemovePointMode\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Remove Point (-)"; + hovertime = "1000"; + bitmap = "tools/worldEditor/images/road-river/subtract-point"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/ShapeEditorPalette.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/ShapeEditorPalette.ed.gui new file mode 100644 index 000000000..e8dfaf0e9 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/ShapeEditorPalette.ed.gui @@ -0,0 +1,102 @@ +%paletteId = new GuiControl(ShapeEditorPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(ShapeEditorNoneModeBtn) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorSelectArrow"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.mode = \"None\";"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Select Arrow (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ShapeEditorMoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorMove"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "28 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.mode = \"Move\";"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Move Selection (2)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/translate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ShapeEditorRotateModeBtn) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorRotate"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "56 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.mode = \"Rotate\";"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Rotate Selection (3)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/rotate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(ShapeEditorSunModeBtn) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "84 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = "ShapeEdShapeView.editSun"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Rotate sun"; + hovertime = "1000"; + bitmap = "tools/shapeEditor/images/sun-btn"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/TerrainEditPalette.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/TerrainEditPalette.ed.gui new file mode 100644 index 000000000..8f776c932 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/TerrainEditPalette.ed.gui @@ -0,0 +1,235 @@ +%paletteId = new GuiControl(TerrainEditorPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "brushAdjustHeight"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( brushAdjustHeight );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Grab Terrain (1)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/brushAdjustHeight"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "raiseHeight"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( raiseHeight );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Raise Height (2)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/raiseHeight"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "lowerHeight"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "36 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( lowerHeight );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Lower Height (3)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/lowerHeight"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "smoothHeight"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "144 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( smoothHeight );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Smooth (4)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/smoothHeight"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "smoothSlope"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "144 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( smoothSlope );"; + tooltipprofile = "GuiToolTipProfile"; + ToolTip = "Smooth Slope (5)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/softCurve"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "paintNoise"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "72 36"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( paintNoise );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Paint Noise (6)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/brushPaintNoise"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "flattenHeight"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "108 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( flattenHeight );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Flatten (7)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/flattenHeight"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "setHeight"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "180 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( setHeight );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Set Height (8)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/setHeight"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "setEmpty"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 36"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( setEmpty );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Clear Terrain (9)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/setEmpty"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "clearEmpty"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "36 36"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "ETerrainEditor.switchAction( clearEmpty );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Restore Terrain (0)"; + hovertime = "750"; + text = "Button"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + bitmap = "tools/worldEditor/images/clearEmpty"; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/TerrainPainterPalette.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/TerrainPainterPalette.ed.gui new file mode 100644 index 000000000..091f7a1c0 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/TerrainPainterPalette.ed.gui @@ -0,0 +1,14 @@ +%paletteId = new GuiControl(TerrainPainterPalette,EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/WorldEditorPalette.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/WorldEditorPalette.ed.gui new file mode 100644 index 000000000..421b52fe4 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/WorldEditorPalette.ed.gui @@ -0,0 +1,98 @@ +%paletteId = new GuiControl(WorldEditorInspectorPalette, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(EWorldEditorNoneModeBtn) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorSelectArrow"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Select Arrow (1)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/arrow"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(EWorldEditorMoveModeBtn) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorMove"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "28 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Move Selection (2)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/translate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(EWorldEditorRotateModeBtn) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorRotate"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "56 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Rotate Selection (3)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/rotate"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(EWorldEditorScaleModeBtn) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorScale"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "84 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Scale Selection (4)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/scale"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/init.cs b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/init.cs new file mode 100644 index 000000000..637739745 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteGroups/init.cs @@ -0,0 +1,102 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function EWToolsPaletteWindow::loadToolsPalettes() +{ + %filespec = "tools/worldEditor/gui/ToolsPaletteGroups/*.ed.gui"; + + // were executing each gui file and adding them to the ToolsPaletteArray + for( %file = findFirstFile(%filespec); %file !$= ""; %file = findNextFile(%filespec)) + { + exec( %file ); + %paletteGroup = 0; + + %i = %paletteId.getCount(); + for( ; %i != 0; %i--) + { + %paletteId.getObject(0).visible = 0; + %paletteId.getObject(0).groupNum = %paletteGroup; + %paletteId.getObject(0).paletteName = %paletteId.getName(); + ToolsPaletteArray.addGuiControl(%paletteId.getObject(0)); + } + %paletteGroup++; + } + + %filespec = "tools/worldEditor/gui/ToolsPaletteGroups/*.ed.gui.edso"; + + // were executing each gui file and adding them to the ToolsPaletteArray + for( %file = findFirstFile(%filespec); %file !$= ""; %file = findNextFile(%filespec)) + { + exec( %file ); + %paletteGroup = 0; + + %i = %paletteId.getCount(); + for( ; %i != 0; %i--) + { + %paletteId.getObject(0).visible = 0; + %paletteId.getObject(0).groupNum = %paletteGroup; + %paletteId.getObject(0).paletteName = %paletteId.getName(); + ToolsPaletteArray.addGuiControl(%paletteId.getObject(0)); + } + %paletteGroup++; + } +} + +function EWToolsPaletteWindow::init() +{ + EWToolsPaletteWindow.loadToolsPalettes(); +} + +function EWToolsPaletteWindow::togglePalette(%this, %paletteName) +{ + // since the palette window ctrl auto adjusts to child ctrls being visible, + // loop through the array and pick out the children that belong to a certain tool + // and label them visible or not visible + + for( %i = 0; %i < ToolsPaletteArray.getCount(); %i++ ) + ToolsPaletteArray.getObject(%i).visible = 0; + + %windowMultiplier = 0; + %paletteNameWordCount = getWordCount( %paletteName ); + for(%pallateNum = 0; %pallateNum < %paletteNameWordCount; %pallateNum++) + { + %currentPalette = getWord(%paletteName, %pallateNum); + for( %i = 0; %i < ToolsPaletteArray.getCount(); %i++ ) + { + if( ToolsPaletteArray.getObject(%i).paletteName $= %currentPalette) + { + ToolsPaletteArray.getObject(%i).visible = 1; + %windowMultiplier++; + } + } + } + + // auto adjust the palette window extent according to how many + // children controls we found; if none found, the palette window becomes invisible + if( %windowMultiplier == 0 || %paletteName $= "") + EWToolsPaletteWindow.visible = 0; + else + { + EWToolsPaletteWindow.visible = 1; + EWToolsPaletteWindow.extent = getWord(EWToolsPaletteWindow.extent, 0) SPC (16 + 26 * %windowMultiplier); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteWindow.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteWindow.ed.gui new file mode 100644 index 000000000..b6b9c5507 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsPaletteWindow.ed.gui @@ -0,0 +1,68 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(EWToolsPaletteWindow) { + canSaveDynamicFields = "0"; + internalName = "ToolsPaletteWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiToolbarWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Extent = "36 24"; + MinExtent = "36 24"; + Position = "-1 63"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + EdgeSnap = false; + text = ""; + class = "EWToolsPaletteWindowClass"; + + new GuiDynamicCtrlArrayControl(ToolsPaletteArray) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "5 15"; + Extent = "35 514"; + MinExtent = "35 514"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + colCount = "1"; + colSize = "26"; + RowSize = "22"; + rowSpacing = "3"; + colSpacing = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/ToolsToolbar.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsToolbar.ed.gui new file mode 100644 index 000000000..f57c39be7 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/ToolsToolbar.ed.gui @@ -0,0 +1,72 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiContainer(EWToolsToolbar) { + canSaveDynamicFields = "0"; + Enabled = "0"; + internalName = "ToolsToolbar"; + isContainer = "1"; + Profile = "editorMenubarProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 31"; + Extent = "0 33"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + isClosed = "0"; + isDynamic = "0"; + + new GuiDynamicCtrlArrayControl(ToolsToolbarArray) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "4 3"; + Extent = "264 32"; + MinExtent = "1024 32"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + colCount = "1"; + colSize = "29"; + RowSize = "27"; + rowSpacing = "2"; + colSpacing = "4"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + internalName = "resizeArrow"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = getWord(EWToolsToolbar.Extent, 0) - 7 SPC "0"; + extent = "7 33"; + MinExtent = "7 2"; + canSave = "1"; + Visible = "1"; + Command = "EWToolsToolbar.ToggleSize();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Collapse Toolbar"; + hovertime = "750"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/collapse-toolbar"; + }; + new GuiDecoyCtrl(EWToolsToolbarDecoy) { + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "1 1"; + extent = "35 31"; + minExtent = "8 8"; + visible = "0"; + helpTag = "0"; + useMouseEvents = "1"; + isDecoy = "1"; + }; +}; + diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/TransformSelectionWindow.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/TransformSelectionWindow.ed.gui new file mode 100644 index 000000000..26324ea74 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/TransformSelectionWindow.ed.gui @@ -0,0 +1,1026 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TransformSelectionContainer, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiModelessDialogProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(ETransformSelection) { + internalName = "TransformSelectionWindow"; + Enabled = "1"; + isContainer = "1"; + profile = "ToolsGuiWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + resizeWidth = "1"; + resizeHeight = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + position = "40 70"; + extent = "180 508"; + MinExtent = "120 130"; + text = "Transform Selection"; + closeCommand = "ETransformSelection.hideDialog();"; + EdgeSnap = "0"; + canCollapse = "0"; + visible = "0"; + Margin = "5 5 5 5"; + Padding = "5 5 5 5"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 12"; + Extent = "156 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "5 5 5 4"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 2"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "5"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "140 300"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiControl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "140 106"; + MinExtent = "16 16"; + Visible = "1"; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "DoPosition"; + Enabled = "1"; + Profile = "ToolsGuiCheckBoxProfile"; + position = "1 0"; + Extent = "190 18"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Apply changes to position"; + text = "Position"; + Command = ""; + }; + + new GuiButtonCtrl() { + class = "ETransformSelectionButtonClass"; + internalName = "GetPosButton"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "100 0"; + Extent = "30 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ETransformSelection.getAbsPosition();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Get absolute position for selected objects"; + text = "Get"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 22"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "X:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "PosX"; + profile="ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 22"; + Extent = "90 18"; + text ="0.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 44"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Y:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "PosY"; + profile="ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 44"; + Extent = "90 18"; + text ="0.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 66"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Z:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "PosZ"; + profile="ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 66"; + Extent = "90 18"; + text ="0.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "PosRelative"; + Enabled = "1"; + Profile = "ToolsGuiCheckBoxProfile"; + position = "40 88"; + Extent = "120 18"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Add values to current position (checked) or set absolute position (unchecked)"; + text = "Relative"; + Command = ""; + }; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "0 0"; + Extent = "100 2"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-v.png"; + }; + + new GuiControl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "140 128"; + MinExtent = "16 16"; + Visible = "1"; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "DoRotation"; + Enabled = "1"; + Profile = "ToolsGuiCheckBoxProfile"; + position = "1 0"; + Extent = "190 18"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Apply changes to rotation"; + text = "Rotation"; + Command = ""; + }; + + new GuiButtonCtrl() { + class = "ETransformSelectionButtonClass"; + internalName = "GetRotButton"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "100 0"; + Extent = "30 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ETransformSelection.getAbsRotation();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Get absolute rotation for selected objects"; + text = "Get"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 22"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "H:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "Heading"; + profile="ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 22"; + Extent = "90 18"; + text ="0.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 44"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "P:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "Pitch"; + profile="ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 44"; + Extent = "90 18"; + text ="0.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 66"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "B:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "Bank"; + profile="ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 66"; + Extent = "90 18"; + text ="0.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "RotRelative"; + Enabled = "1"; + Profile = "ToolsGuiCheckBoxProfile"; + position = "40 88"; + Extent = "120 18"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Add values to current rotation (checked) or set absolute rotation (unchecked)"; + text = "Relative"; + Command = "ETransformSelection.RotRelativeChanged();"; + }; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "RotLocal"; + Enabled = "1"; + Profile = "ToolsGuiCheckBoxProfile"; + position = "40 110"; + Extent = "120 18"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Use object's local origin to rotate from"; + text = "Local Center"; + Command = "ETransformSelection.RotLocalChanged();"; + }; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "0 0"; + Extent = "100 2"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-v.png"; + }; + + new GuiTabBookCtrl() { + internalName = "ScaleTabBook"; + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "140 176"; + MinExtent = "16 16"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "3 2 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "0"; + MinTabWidth = "50"; + + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "140 156"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Scale"; + maxLength = "1024"; + + new GuiBitmapBorderCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTabBorderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "134 156"; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + hovertime = "1000"; + }; + + new GuiControl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "134 156"; + MinExtent = "16 16"; + Visible = "1"; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "DoScale"; + Enabled = "1"; + Profile = "ToolsGuiCheckBoxProfile"; + position = "2 4"; + Extent = "100 18"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Apply changes to scale"; + text = "Scale"; + Command = ""; + }; + + new GuiButtonCtrl() { + class = "ETransformSelectionButtonClass"; + internalName = "GetScaleButton"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "100 4"; + Extent = "30 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ETransformSelection.getAbsScale();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Get absolute scale for selected objects"; + text = "Get"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 26"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "X:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "ScaleX"; + profile="ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 26"; + Extent = "90 18"; + text ="1.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 48"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Y:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "ScaleY"; + profile="ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 48"; + Extent = "90 18"; + text ="1.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 70"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Z:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "ScaleZ"; + profile="ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 70"; + Extent = "90 18"; + text ="1.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "ScaleRelative"; + Enabled = "1"; + Profile = "ToolsGuiCheckBoxProfile"; + position = "40 92"; + Extent = "120 18"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Add values to current scale (checked) or set absolute scale (unchecked)"; + text = "Relative"; + Command = ""; + }; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "ScaleLocal"; + Enabled = "1"; + Profile = "ToolsGuiCheckBoxProfile"; + position = "40 114"; + Extent = "120 18"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Use object's local origin to scale from"; + text = "Local Center"; + Command = ""; + }; + + new GuiCheckBoxCtrl(ETransformSelectionScaleProportional){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "ScaleProportional"; + Enabled = "1"; + Profile = "ToolsGuiCheckBoxProfile"; + position = "40 136"; + Extent = "120 18"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Scale equally in all directions"; + text = "Constrain Proportions"; + Command = ""; + }; + }; + }; + + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "140 156"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Size"; + maxLength = "1024"; + + new GuiBitmapBorderCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTabBorderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "134 156"; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + hovertime = "1000"; + }; + + new GuiControl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "134 156"; + MinExtent = "16 16"; + Visible = "1"; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "DoSize"; + Enabled = "1"; + Profile = "ToolsGuiCheckBoxProfile"; + position = "2 4"; + Extent = "100 18"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Apply changes to size"; + text = "Size"; + Command = ""; + }; + + new GuiButtonCtrl() { + class = "ETransformSelectionButtonClass"; + internalName = "GetSizeButton"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "100 4"; + Extent = "30 18"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ETransformSelection.getAbsSize();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Get absolute size for selected objects"; + text = "Get"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 26"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "X:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "SizeX"; + profile="ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 26"; + Extent = "90 18"; + text ="1.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 48"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Y:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "SizeY"; + profile="ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 48"; + Extent = "90 18"; + text ="1.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "20 70"; + Extent = "20 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Z:"; + maxLength = "1024"; + }; + + new GuiTextEditCtrl() { + class = "ETransformSelectionTextEdit"; + internalName = "SizeZ"; + profile="ToolsGuiNumericTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "40 70"; + Extent = "90 18"; + text ="1.0"; + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "SizeRelative"; + Enabled = "1"; + Profile = "ToolsGuiCheckBoxProfile"; + position = "40 92"; + Extent = "120 18"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Add values to current size (checked) or set absolute size (unchecked)"; + text = "Relative"; + Command = ""; + }; + + new GuiCheckBoxCtrl(){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "SizeLocal"; + Enabled = "1"; + Profile = "ToolsGuiCheckBoxProfile"; + position = "40 114"; + Extent = "120 18"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Use object's local origin to size from"; + text = "Local Center"; + Command = ""; + }; + + new GuiCheckBoxCtrl(ETransformSelectionSizeProportional){ + class = "ETransformSelectionCheckBoxClass"; + internalName = "SizeProportional"; + Enabled = "1"; + Profile = "ToolsGuiCheckBoxProfile"; + position = "40 136"; + Extent = "120 18"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Size equally in all directions"; + text = "Constrain Proportions"; + Command = ""; + }; + }; + }; + }; + }; + }; + + new GuiContainer(){ + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "190 24"; + Docking = "Bottom"; + Margin = "5 5 5 5"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiButtonCtrl() { + class = "ETransformSelectionButtonClass"; + internalName = "ApplyButton"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "50 23"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ETransformSelection.apply();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Apply"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiButtonCtrl() { + class = "ETransformSelectionButtonClass"; + internalName = "CloseButton"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "140 0"; + Extent = "50 23"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "ETransformSelection.hideDialog();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Close"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/VisibilityLayerWindow.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/VisibilityLayerWindow.ed.gui new file mode 100644 index 000000000..3dbed5244 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/VisibilityLayerWindow.ed.gui @@ -0,0 +1,278 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(VisibilityLayerContainer, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiModelessDialogProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl(EVisibility) { + internalName = "VisibilityLayerWindow"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiToolbarWindowProfile"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + Position = getWord(visibilityToggleBtn.position, 0) SPC getWord(EditorGuiToolbar.extent, 1); + Extent = "161 250"; //175 696 = full length + MinExtent = "161 86"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + hovertime = "1000"; + Docking = "None"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "152 300"; + closeCommand = ""; + EdgeSnap = "1"; + text = ""; + + new GuiTabBookCtrl(EVisibilityTabBook) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Margin = "3 1 3 3"; + Position = "5 24"; + Extent = "170 226"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + TabPosition = "Top"; + TabHeight = "22"; + TabMargin = "7"; + MinTabWidth = "8"; + + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Margin = "-1 0 0 0"; + Position = "0 14"; + Extent = "164 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + text = "Visual"; + maxLength = "255"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Position = "4 12"; + Extent = "156 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "-2"; + canSaveDynamicFields = "0"; + internalName = "theVisOptionsList"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 0"; + Extent = "156 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Margin = "-1 0 0 0"; + Position = "0 14"; + Extent = "164 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + text = "Visible"; + maxLength = "255"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Position = "4 12"; + Extent = "156 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "-2"; + canSaveDynamicFields = "0"; + internalName = "theClassVisList"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 0"; + Extent = "156 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Margin = "-1 0 0 0"; + Position = "0 14"; + Extent = "164 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + text = "Select"; + maxLength = "255"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Docking = "Client"; + Position = "4 12"; + Extent = "156 190"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "2 0"; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "-2"; + canSaveDynamicFields = "0"; + internalName = "theClassSelList"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 0"; + Extent = "156 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + }; + }; + }; + }; + }; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/WorldEditorInspectorWindow.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/WorldEditorInspectorWindow.ed.gui new file mode 100644 index 000000000..2d429529d --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/WorldEditorInspectorWindow.ed.gui @@ -0,0 +1,143 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(EWInspectorWindow) { + canSaveDynamicFields = "0"; + internalName = "InspectorWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + Position = getWord($pref::Video::mode, 0) - 209 SPC + getWord(EditorGuiToolbar.extent, 1) + getWord(EWTreeWindow.extent, 1) - 2; + Extent = "210 373"; + MinExtent = "210 140"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "8 8 8 8"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + closeCommand = "EWInspectorWindow.setVisible(false);"; + minSize = "50 50"; + EdgeSnap = "1"; + text = "Inspector"; + + new GuiContainer() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "4 24"; + Extent = "202 304"; + MinExtent = "64 64"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "client"; + Margin = "3 41 3 3"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiEditorScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "202 304"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(Inspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "GuiInspectorProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "202 309"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + dividerMargin = "5"; + superClass = "EditorInspectorBase"; + }; + }; + }; + new GuiMLTextCtrl(FieldInfoControl) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorFieldInfoMLTextProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "1 328"; + Extent = "205 14"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + lineSpacing = "2"; + allowColorChars = "0"; + maxChars = "-1"; + useURLMouseCursor = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/WorldEditorToolbar.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/WorldEditorToolbar.ed.gui new file mode 100644 index 000000000..79f34211d --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/WorldEditorToolbar.ed.gui @@ -0,0 +1,673 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(EWorldEditorToolbar, EditorGuiGroup) { + canSaveDynamicFields = "0"; + internalName = "WorldEditorToolbar"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "306 0"; + Extent = "550" SPC getWord(EditorGuiToolbar.extent, 1); + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + + new GuiStackControl() { + StackingType = "Horizontal"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 3"; + Extent = "190 31"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + changeChildSizeToFit = false; + padding = "2"; + + new GuiBitmapButtonCtrl(FitToSelectionBtn) { + canSaveDynamicFields = "0"; + internalName = ""; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "2 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "commandToServer('EditorCameraAutoFit', EWorldEditor.getSelectionRadius()+1);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Fit View To Selection (F)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/fit-selection"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "34 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiTextCtrl() { + profile = "ToolsGuiTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "37 7"; + extent = "77 16"; + minExtent = "8 8"; + visible = "1"; + text = " World Settings"; + maxLength = "255"; + helpTag = "0"; + }; + + new GuiControl(SnapToBar){ + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + Position = "116 3"; + Extent = "123 27"; + Padding = "4"; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "snappingSettingsBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command ="ESnapOptions.ToggleVisibility();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Snapping Options"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + buttonMargin = "0 0"; + bitmap = "tools/gui/images/menubar/snapping-settings"; + + new GuiBitmapCtrl(){ + HorizSizing = "left"; + VertSizing = "top"; + Position = "23 21"; + Extent = "4 4"; + MinExtent = "4 4"; + bitmap = "tools/gui/images/dropdown-button-arrow"; + }; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "objectGridSnapBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "31 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "toggleSnappingOptions(\"grid\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggles grid snapping (G)"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "toggleButton"; + useMouseEvents = "0"; + groupNum = "-1"; + bitmap = "tools/gui/images/menubar/snap-grid"; + textMargin = "4"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "objectSnapDownBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "62 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "toggleSnappingOptions(\"terrain\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "All objects will snap to the terrain (T)"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "toggleButton"; + useMouseEvents = "0"; + groupNum = "-1"; + bitmap = "tools/gui/images/menubar/snap-terrain"; + textMargin = "4"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "objectSnapBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "93 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "toggleSnappingOptions(\"soft\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Soft object snapping to other objects (B)"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "toggleButton"; + useMouseEvents = "0"; + groupNum = "-1"; + bitmap = "tools/gui/images/menubar/snap-objects"; + textMargin = "4"; + }; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + internalName = "softSnapSizeTextEditContainer"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "178 5"; + Extent = "56 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "softSnapSizeTextEdit"; + isContainer = "0"; + HorizSizing = "right"; + profile="ToolsGuiNumericDropSliderTextProfile"; + VertSizing = "bottom"; + position = "0 2"; + Extent = "42 16"; + MinExtent = "8 16"; + canSave = "1"; + Visible = "1"; + AltCommand = "EWorldEditor.setSoftSnapSize( $ThisControl.getText() ); EWorldEditor.syncGui();"; + tooltip = "Object Snapping Distance"; + hovertime = "1000"; + text = "9"; + maxLength = "6"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "34 2"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "Canvas.pushDialog(softSnapSizeSliderCtrlContainer);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Changes size of the soft snap region"; + hovertime = "750"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/dropslider"; + }; + }; + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "269 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "boundingBoxColBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "274 3"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Variable = "EWorldEditor.boundingBoxCollision"; + Command = "EWorldEditor.boundingBoxCollision = $ThisControl.getValue();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Object bounds selection toggle (V)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/select-bounds"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "307 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiControl(ToggleButtonBar){ + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + Position = "313 3"; + Extent = "65 27"; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "centerObject"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "objectCenterDropdown.toggle();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggles object center (O) and bounds center (P)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/object-center"; + text = "Button"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + + new GuiBitmapCtrl(){ + HorizSizing = "left"; + VertSizing = "top"; + Position = "23 21"; + Extent = "4 4"; + MinExtent = "4 4"; + bitmap = "tools/gui/images/dropdown-button-arrow"; + }; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "objectTransform"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "31 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "objectTransformDropdown.toggle();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Toggles object transform (K) and world transform (L)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/world-transform"; + groupNum = "-1"; + buttonType = "ToggleButton"; + text = ""; + + new GuiBitmapCtrl(){ + HorizSizing = "left"; + VertSizing = "top"; + Position = "23 21"; + Extent = "4 4"; + MinExtent = "4 4"; + bitmap = "tools/gui/images/dropdown-button-arrow"; + }; + }; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "379 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiControl(ToggleNodeBar){ + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + Position = "386 3"; + Extent = "63 27"; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "renderHandleBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Variable = "EWorldEditor.renderObjHandle"; + Command = "EWorldEditor.renderObjHandle = $ThisControl.getValue();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Enables Render of Object Node Icons (N)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/object-node-icon"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "renderTextBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "33 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Variable = "EWorldEditor.renderObjText"; + Command = "EWorldEditor.renderObjText = $ThisControl.getValue();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Enables Render of Object Node Lables (SHIFT N)"; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/object-node-lable"; + text = ""; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + }; + }; + + new GuiBitmapCtrl() { + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + position = "379 3"; + Extent = "2 26"; + MinExtent = "1 1"; + bitmap = "tools/gui/images/separator-h.png"; + }; + + new GuiControl(PrefabBar){ + isContainer = "1"; + profile = "ToolsGuiDefaultProfile"; + Position = "386 3"; + Extent = "63 27"; + visible = true; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "makePrefabBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Variable = ""; + Command = "EditorMakePrefab();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Make the Selection a Prefab."; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/selection-to-prefab"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "explodePrefabBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "33 0"; + Extent = "29 27"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Variable = ""; + Command = "EditorExplodePrefab();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Explode the Selected Prefab."; + hovertime = "1000"; + bitmap = "tools/gui/images/menubar/explode-prefab"; + text = ""; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + }; + + new GuiContainer(objectCenterDropdown){ + Profile = "IconDropdownProfile"; + Position = getWord(EWorldEditorToolbar.position, 0)+getWord(ToggleButtonBar.Position, 0)+getWord(EWorldEditorToolbar-->centerObject.position, 0)-5 SPC getWord(EditorGuiToolbar.extent, 1)-1; + Extent = "132 62"; + isContainer = "1"; + visible = "0"; + + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "objectBoxBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 5"; + Extent = "122 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "EWorldEditor.objectsUseBoxCenter = 0; EWorldEditor.syncGui(); objectCenterDropdown.toggle(); "; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Use object defined center (O)"; + hovertime = "1000"; + iconBitmap = "tools/gui/images/menubar/object-center_n"; + text = "Object Center"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "objectBoundsBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 33 "; + Extent = "122 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "EWorldEditor.objectsUseBoxCenter = 1; EWorldEditor.syncGui(); objectCenterDropdown.toggle(); "; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Use bounding box center (P)"; + hovertime = "1000"; + iconBitmap = "tools/gui/images/menubar/bounds-center_n"; + text = "Bounds Center"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiDecoyCtrl(objectCenterDropdownDecoy) { + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "132 62"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + useMouseEvents = "1"; + isDecoy = "1"; + }; + }; + + new GuiContainer(objectTransformDropdown){ + Profile = "IconDropdownProfile"; + Position = getWord(EWorldEditorToolbar.position, 0)+getWord(ToggleButtonBar.position, 0)+getWord(EWorldEditorToolbar-->objectTransform.position, 0)-5 SPC getWord(EditorGuiToolbar.extent, 1)-1; + Extent = "147 62"; + isContainer = "1"; + visible ="0"; + + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "worldTransformBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiIconProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 5"; + Extent = "137 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.setFieldValue(alignment, World); EWorldEditor.syncGui(); objectTransformDropdown.toggle(); "; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Use world normal for transformations (L)"; + hovertime = "1000"; + iconBitmap = "tools/gui/images/menubar/world-transform_n"; + text = "World Transform"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiIconButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "objectTransformBtn"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiIconButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 33"; + Extent = "137 25"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "GlobalGizmoProfile.setFieldValue(alignment, Object); EWorldEditor.syncGui(); objectTransformDropdown.toggle(); "; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Use object normal for transformations (K)"; + hovertime = "1000"; + iconBitmap = "tools/gui/images/menubar/object-transform_n"; + text = "Object Transform"; + buttonMargin = "0 4"; + textMargin = "38"; + groupNum = "0"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + }; + + new GuiDecoyCtrl(objectTransformDropdownDecoy) { + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "147 62"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + useMouseEvents = "1"; + isDecoy = "1"; + }; + }; + }; +}; + +new GuiMouseEventCtrl(softSnapSizeSliderCtrlContainer, EditorGuiGroup) { + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "1024 768"; + minExtent = "8 8"; + visible = "1"; + helpTag = "0"; + class = "EditorDropdownSliderContainer"; + + new GuiSliderCtrl() { + canSaveDynamicFields = "0"; + internalName = "slider"; + isContainer = "0"; + Profile = "ToolsGuiSliderBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = firstWord(EWorldEditorToolbar-->softSnapSizeTextEdit.getGlobalPosition()) - 12 SPC + (getWord(EWorldEditorToolbar-->softSnapSizeTextEdit.getGlobalPosition(), 1)) + 18; + Extent = "112 20"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "softSnapSizeSliderCtrlContainer.onSliderChanged();"; + range = "0.01 10"; + ticks = "0"; + value = "0"; + }; +}; diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui new file mode 100644 index 000000000..9f8b496e0 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui @@ -0,0 +1,577 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCollapseCtrl(EWTreeWindow) { + canSaveDynamicFields = "0"; + internalName = "TreeWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + Position = firstWord($pref::Video::mode) - 209 + SPC getWord(EditorGuiToolbar.extent, 1) -1; + Extent = "210 324"; + MinExtent = "210 140"; + HorizSizing = "windowRelative"; + VertSizing = "windowRelative"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "8 8 8 8"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EWTreeWindow.setVisible(false);"; + EdgeSnap = "1"; + text = "Scene Tree"; + + new GuiTabBookCtrl(EditorTreeTabBook) { + canSaveDynamicFields = "0"; + isContainer = "1"; + internalName = "EditorTree"; + Profile = "ToolsGuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "6 27"; + Extent = "197 289"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "3 2 3 3"; + Docking = "client"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "0"; + MinTabWidth = "64"; + + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiEditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "197 271"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Scene"; + maxLength = "1024"; + + new GuiTextEditCtrl( EditorTreeFilter ) { + position = "2 4"; + extent = "175 18"; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + class = "GuiTreeViewFilterText"; + treeView = EditorTree; + }; + + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/clear-icon"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "180 5"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + class = "GuiTreeViewFilterClearButton"; + textCtrl = EditorTreeFilter; + }; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 25"; + Extent = "197 246"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiTreeViewCtrl(EditorTree) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "1 1"; + Extent = "193 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "1"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "1"; + showRoot = "1"; + useInspectorTooltips = "1"; + tooltipOnWidthOnly = "1"; + showObjectIds = "0"; + showClassNames = "0"; + showObjectNames = "1"; + showInternalNames = "1"; + showClassNameForUnnamedObjects = "1"; + }; + }; + }; + new GuiTabPageCtrl(EWCreatorWindow) { + canSaveDynamicFields = "0"; + internalName = "CreatorWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiEditorTabPage"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 19"; + Extent = "208 274"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Library"; + maxLength = "1024"; + + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "GuiInspectorProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "198 271"; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + }; + new GuiBitmapBorderCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTabBorderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "198 271"; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + hovertime = "1000"; + }; + new GuiBitmapBorderCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTabBorderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 25"; + Extent = "198 246"; + MinExtent = "8 2"; + canSave = "0"; + Visible = "1"; + hovertime = "1000"; + }; + new GuiContainer() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "-4 47"; + Extent = "206 228"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "4 4 4 4"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "EditorLightScrollProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 4"; + Extent = "198 220"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "alwaysOff"; + lockHorizScroll = "false"; + lockVertScroll = "true"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiDynamicCtrlArrayControl(CreatorIconArray) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "1 1"; + Extent = "197 218"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + colCount = "20"; + colSize = "64"; + rowCount = "0"; + RowSize = "32"; + rowSpacing = "4"; + colSpacing = "4"; + frozen = "0"; + autoCellSize = "1"; + fillRowFirst = "0"; + dynamicSize = "1"; + }; + }; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "-3 2"; + Extent = "202 55"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(CreatorNavUpButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 28"; + Extent = "20 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EWCreatorWindow.navigateUp();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + groupNum = "0"; + buttonType = "PushButton"; + + Bitmap = "tools/gui/images/folderUp"; + autoSize = "0"; + }; + new GuiPopUpMenuCtrl(CreatorPopupMenu) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "32 28"; + Extent = "163 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Objects"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiTabBookCtrl(CreatorTabBook) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "6 4"; + Extent = "198 21"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "4"; + MinTabWidth = "49"; + + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "0 0"; + MinExtent = "0 0"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Scripted"; + maxLength = "1024"; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "0 0"; + MinExtent = "0 0"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Meshes"; + maxLength = "1024"; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "0 0"; + MinExtent = "0 0"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Level"; + maxLength = "1024"; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "0 0"; + Extent = "0 0"; + MinExtent = "0 0"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Prefabs"; + maxLength = "1024"; + }; + }; + }; + }; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "LockSelection"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "157 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EWorldEditor.lockSelection(true); EditorTree.toggleLock();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Lock Selection"; + hovertime = "1000"; + bitmap = "tools/gui/images/lock"; + buttonType = "ToggleButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; + + new GuiBitmapButtonCtrl(EWAddSimGroupButton) { + canSaveDynamicFields = "0"; + internalName = "AddSimGroup"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "173 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Add Sim Group"; + hovertime = "1000"; + bitmap = "tools/gui/images/add-simgroup-btn"; + buttonType = "PushButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + useModifiers = "1"; + }; + + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = "DeleteSelection"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "189 26"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EditorMenuEditDelete();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Delete Selection"; + hovertime = "1000"; + bitmap = "tools/gui/images/delete"; + buttonType = "PushButton"; + groupNum = "-1"; + text = ""; + useMouseEvents = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/guiCreateNewTerrainGui.gui b/Templates/BaseGame/game/tools/worldEditor/gui/guiCreateNewTerrainGui.gui new file mode 100644 index 000000000..23d65e24a --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/guiCreateNewTerrainGui.gui @@ -0,0 +1,352 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(CreateNewTerrainGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiOverlayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "640 480"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "182 94"; + Extent = "250 140"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "1"; + AnchorLeft = "1"; + AnchorRight = "1"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "Canvas.popDialog( CreateNewTerrainGui );"; + EdgeSnap = "0"; + text = "Create New Terrain"; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "theName"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "68 30"; + Extent = "171 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + text = "myNewTerrain"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "32 31"; + Extent = "31 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Name:"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 108"; + Extent = "138 24"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "CreateNewTerrainGui.create();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Create New"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + accelerator = "return"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "159 108"; + Extent = "80 24"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "Canvas.popDialog( CreateNewTerrainGui );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + accelerator = "escape"; + }; + new GuiRadioCtrl() { + canSaveDynamicFields = "0"; + internalName = "flatRadio"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiRadioProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "155 80"; + Extent = "40 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Flat"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiRadioCtrl() { + canSaveDynamicFields = "0"; + internalName = "noiseRadio"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiRadioProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "195 80"; + Extent = "45 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Noise"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "23 56"; + Extent = "40 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Material: "; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "10 81"; + Extent = "52 16"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Resolution:"; + maxLength = "1024"; + }; + new GuiPopUpMenuCtrl() { + canSaveDynamicFields = "0"; + internalName = "theRezList"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "68 80"; + Extent = "57 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiPopUpMenuCtrl() { + canSaveDynamicFields = "0"; + internalName = "theMaterialList"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "68 55"; + Extent = "171 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + }; +}; +//--- OBJECT WRITE END --- +function CreateNewTerrainGui::onWake( %this ) +{ + %this-->theName.setText( "" ); + + %matList = %this-->theMaterialList; + %matList.clear(); + %count = TerrainMaterialSet.getCount(); + for ( %i=0; %i < %count; %i++ ) + %matList.add( TerrainMaterialSet.getObject( %i ).internalName, %i ); + %matList.setSelected( 0 ); + + %rezList = %this-->theRezList; + %rezList.clear(); + %rezList.add( "256", 256 ); + %rezList.add( "512", 512 ); + %rezList.add( "1024", 1024 ); + %rezList.add( "2048", 2048 ); + //%rezList.add( "4096", 4096 ); + %rezList.setSelected( 256 ); + + %this-->flatRadio.setStateOn( true ); +} + +function CreateNewTerrainGui::create( %this ) +{ + %terrainName = %this-->theName.getText(); + %resolution = %this-->theRezList.getSelected(); + %materialName = %this-->theMaterialList.getText(); + %genNoise = %this-->noiseRadio.getValue(); + + %obj = TerrainBlock::createNew( %terrainName, %resolution, %materialName, %genNoise ); + + if( %genNoise ) + ETerrainEditor.isDirty = true; + + if( isObject( %obj ) ) + { + // Submit an undo action. + MECreateUndoAction::submit(%obj); + + assert( isObject( EWorldEditor ), + "ObjectBuilderGui::processNewObject - EWorldEditor is missing!" ); + + // Select it in the editor. + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%obj); + + // When we drop the selection don't store undo + // state for it... the creation deals with it. + EWorldEditor.dropSelection( true ); + } + + Canvas.popDialog( %this ); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainEditorToolbar.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainEditorToolbar.ed.gui new file mode 100644 index 000000000..e69de29bb diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainExportGui.gui b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainExportGui.gui new file mode 100644 index 000000000..772d4d129 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainExportGui.gui @@ -0,0 +1,310 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TerrainExportGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Profile = "ToolsGuiOverlayProfile"; + Enabled = "1"; + isContainer = "1"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "1024 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(TerrainExportWindow) { + profile = "ToolsGuiWindowProfile"; + canSaveDynamicFields = "0"; + internalName = "TerrainExport"; + Enabled = "1"; + isContainer = "1"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "248 248"; + Extent = "290 235"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "1"; + AnchorLeft = "1"; + AnchorRight = "1"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "TerrainExportGui.close();"; + EdgeSnap = "0"; + canCollapse = "0"; + text = "Export Terrain"; + + new GuiScrollCtrl(TerrainSelectScroll) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 43"; + Extent = "272 112"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiListBoxCtrl(TerrainSelectListBox) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "2 2"; + Extent = "248 104"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + AllowMultipleSelections = "1"; + fitParentWidth = "1"; + }; + }; + new GuiTextCtrl(TerrainSelectText) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 25"; + Extent = "88 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Select Terrain(s):"; + maxLength = "1024"; + }; + new GuiTextEditCtrl(SelectFolderTextEdit) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 176"; + Extent = "195 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiButtonCtrl(SelectFolderButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "212 174"; + Extent = "69 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainExportGui.selectFolder();"; + hovertime = "1000"; + text = "Browse"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "174 202"; + Extent = "107 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainExportGui.close();"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl(ExportButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 202"; + Extent = "107 24"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainExportGui.export();"; + hovertime = "1000"; + text = "Export"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl(FolderText) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "9 159"; + Extent = "96 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Folder:"; + maxLength = "1024"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function TerrainExportGui::findAllTerrains( %this ) +{ + TerrainSelectListBox.clearItems(); + + if ( isObject( MegaTerrain ) ) + TerrainSelectListBox.addItem( "MegaTerrain" ); + + // Find all of the terrain files + initContainerTypeSearch( $TypeMasks::TerrainObjectType ); + + while ( (%terrainObject = containerSearchNext()) != 0 ) + { + %terrainId = %terrainObject.getId(); + %terrainName = %terrainObject.getName(); + if ( %terrainName $= "" ) + %terrainName = "Unnamed (" @ %terrainId @ ")"; + + TerrainSelectListBox.addItem( %terrainName, %terrainId ); + } +} + +function TerrainExportGui::init( %this ) +{ + %this.findAllTerrains(); +} + +function TerrainExportGui::export( %this ) +{ + %itemId = TerrainSelectListBox.getSelectedItem(); + %terrainObj = TerrainSelectListBox.getItemObject( %itemId ); + if ( !isObject( %terrainObj ) ) + { + MessageBoxOK( "Export failed", "Could not find the selected TerrainBlock!" ); + return; + } + + %filePath = SelectFolderTextEdit.getText(); + + %terrainName = %terrainObj.getName(); + if ( %terrainName $= "" ) + %terrainName = "Unnamed"; + + %fileName = %terrainName @ "_heightmap.png"; + %filePrefix = %terrainName @ "_layerMap"; + + %ret = %terrainObj.exportHeightMap( %filePath @ "/" @ %fileName, "png" ); + if ( %ret ) + %ret = %terrainObj.exportLayerMaps( %filePath @ "/" @ %filePrefix, "png" ); + + if ( %ret ) + %this.close(); +} + +function TerrainExportGui::onWake( %this ) +{ + TerrainExportGui.init(); +} + +function TerrainExportGui::close( %this ) +{ + Canvas.popDialog( %this ); +} + +function TerrainExportGui::showExportDialog( %this ) +{ + %this.findAllTerrains(); + + Canvas.pushDialog( %this ); +} + +function TerrainExportGui::openFolderCallback( %this, %path ) +{ + SelectFolderTextEdit.setText( %path ); +} + +function TerrainExportGui::selectFolder( %this ) +{ + %this.doOpenDialog( "", %this @ ".openFolderCallback" ); +} + +function TerrainExportGui::doOpenDialog( %this, %filter, %callback ) +{ + %dlg = new OpenFolderDialog() + { + Title = "Select Export Folder"; + Filters = %filter; + DefaultFile = %currentFile; + ChangePath = false; + MustExist = true; + MultipleFiles = false; + }; + + if(filePath( %currentFile ) !$= "") + %dlg.DefaultPath = filePath(%currentFile); + else + %dlg.DefaultPath = getMainDotCSDir(); + + if(%dlg.Execute()) + eval(%callback @ "(\"" @ %dlg.FileName @ "\");"); + + %dlg.delete(); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainImportGui.gui b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainImportGui.gui new file mode 100644 index 000000000..c82e82450 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainImportGui.gui @@ -0,0 +1,759 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TerrainImportGui, EditorGuiGroup) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiOverlayProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + internalName = "TerrainImport"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + Position = "119 84"; + Extent = "391 257"; + MinExtent = "391 257"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "1"; + AnchorLeft = "1"; + AnchorRight = "1"; + resizeWidth = "1"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "4 4"; + closeCommand = "Canvas.popDialog( TerrainImportGui );"; + EdgeSnap = "0"; + text = "Import Terrain Height Map"; + + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "HeightfieldFilename"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "10 85"; + Extent = "298 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = " "; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "11 66"; + Extent = "120 20"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Height Map Image:"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "316 83"; + Extent = "65 22"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "TerrainImportGui.browseForHeightfield();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Browse..."; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "MetersPerPixel"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "226 44"; + Extent = "82 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "1"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "226 26"; + Extent = "88 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Meters Per Pixel"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "316 26"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Height Scale:"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "HeightScale"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "316 44"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "256"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "10 112"; + Extent = "365 2"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + bitmap = "tools/gui/images/separator-v"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "top"; + Position = "14 123"; + Extent = "74 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "1"; + text = "Texture Map"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "341 142"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "TerrainImportGui.browseForOpacityMap();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "+"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "341 165"; + Extent = "18 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "TerrainImportGui.removeOpacitymap();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "-"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "195 225"; + Extent = "88 24"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "TerrainImportGui.import();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Import"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + internalName = "OpacityLayerScroll"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "10 142"; + Extent = "326 75"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiTextListCtrl() { + canSaveDynamicFields = "0"; + internalName = "OpacityLayerTextList"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTextListProfile"; + HorizSizing = "width"; + VertSizing = "top"; + Position = "1 1"; + Extent = "293 2"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + AltCommand = "TerrainImportGui.onOpacityListDblClick();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + enumerate = "0"; + resizeCell = "1"; + columns = "0 250 300"; + fitParentWidth = "1"; + clipColumnText = "1"; + }; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "264 123"; + Extent = "48 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Channels"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "11 26"; + Extent = "64 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Name:"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + canSaveDynamicFields = "0"; + internalName = "TerrainName"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "10 44"; + Extent = "206 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "theTerrain"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "341 199"; + Extent = "40 18"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "TerrainImportGui.onOpacityListDblClick();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + Position = "293 225"; + Extent = "88 24"; + MinExtent = "8 2"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + Command = "Canvas.popDialog( TerrainImportGui );"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiCheckBoxCtrl() { + text = " Flip Y axis?"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "12 222"; + extent = "140 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "FlipYAxis"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- + + +function TerrainImportGui::onWake( %this ) +{ + if ( !isObject( %this.namesArray ) ) + %this.namesArray = new ArrayObject(); + + if ( !isObject( %this.channelsArray ) ) + %this.channelsArray = new ArrayObject(); +} + +function TerrainImportGui::import( %this ) +{ + // Gather all the import settings. + + %heightMapPng = %this-->HeightfieldFilename.getText(); + + %metersPerPixel = %this-->MetersPerPixel.getText(); + %heightScale = %this-->HeightScale.getText(); + + %flipYAxis = %this-->FlipYAxis.isStateOn(); + + // Grab and validate terrain object name. + + %terrainName = %this-->TerrainName.getText(); + if( !( isObject( %terrainName ) && %terrainName.isMemberOfClass( "TerrainBlock" ) ) && + !Editor::validateObjectName( %terrainName ) ) + return; + + %opacityNames = ""; + %materialNames = ""; + + %opacityList = %this-->OpacityLayerTextList; + + for( %i = 0; %i < %opacityList.rowCount(); %i++ ) + { + %itemText = %opacityList.getRowTextById( %i ); + %opacityName = %this.namesArray.getValue( %i ); + + %channelInfo = %this.channelsArray.getValue( %i ); + %channel = getWord( %channelInfo, 0 ); + + %materialName = getField( %itemText, 2 ); + + %opacityNames = %opacityNames @ %opacityName TAB %channel @ "\n"; + %materialNames = %materialNames @ %materialName @ "\n"; + } + + %updated = nameToID( %terrainName ); + + // This will update an existing terrain with the name %terrainName, + // or create a new one if %terrainName isn't a TerrainBlock + %obj = TerrainBlock::import( %terrainName, + %heightMapPng, + %metersPerPixel, + %heightScale, + %opacityNames, + %materialNames, + %flipYAxis ); + + Canvas.popDialog( %this ); + + if ( isObject( %obj ) ) + { + if( %obj != %updated ) + { + // created a new TerrainBlock + // Submit an undo action. + MECreateUndoAction::submit(%obj); + } + + assert( isObject( EWorldEditor ), + "ObjectBuilderGui::processNewObject - EWorldEditor is missing!" ); + + // Select it in the editor. + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%obj); + + // When we drop the selection don't store undo + // state for it... the creation deals with it. + EWorldEditor.dropSelection( true ); + + ETerrainEditor.isDirty = true; + EPainter.updateLayers(); + } + else + { + MessageBox( "Import Terrain", + "Terrain import failed! Check console for error messages.", + "Ok", "Error" ); + } +} + +function TerrainImportGui::doOpenDialog( %this, %filter, %callback ) +{ + %dlg = new OpenFileDialog() + { + Filters = %filter; + DefaultFile = %currentFile; + ChangePath = false; + MustExist = true; + MultipleFiles = false; + }; + + if(filePath( %currentFile ) !$= "") + %dlg.DefaultPath = filePath(%currentFile); + else + %dlg.DefaultPath = getMainDotCSDir(); + + if(%dlg.Execute()) + eval(%callback @ "(\"" @ %dlg.FileName @ "\");"); + + + %dlg.delete(); +} + +function TerrainImportGui_SetHeightfield( %name ) +{ + TerrainImportGui-->HeightfieldFilename.setText( %name ); +} + +$TerrainImportGui::HeightFieldFilter = "Heightfield Files (*.png, *.bmp, *.jpg, *.gif)|*.png;*.bmp;*.jpg;*.gif|All Files (*.*)|*.*|"; +$TerrainImportGui::OpacityMapFilter = "Opacity Map Files (*.png, *.bmp, *.jpg, *.gif)|*.png;*.bmp;*.jpg;*.gif|All Files (*.*)|*.*|"; + +function TerrainImportGui::browseForHeightfield( %this ) +{ + %this.doOpenDialog( $TerrainImportGui::HeightFieldFilter, "TerrainImportGui_SetHeightfield" ); +} + +function TerrainImportGuiAddOpacityMap( %name ) +{ + // TODO: Need to actually look at + // the file here and figure + // out how many channels it has. + + %txt = makeRelativePath( %name, getWorkingDirectory() ); + + // Will need to do this stuff + // once per channel in the file + // currently it works with just grayscale. + %channelsTxt = "R" TAB "G" TAB "B" TAB "A"; + %bitmapInfo = getBitmapinfo( %name ); + + %channelCount = getWord( %bitmapInfo, 2 ); + + %opacityList = TerrainImportGui-->OpacityLayerTextList; + + for ( %i = 0; %i < %channelCount; %i++ ) + { + TerrainImportGui.namesArray.push_back( %txt, %name ); + TerrainImportGui.channelsArray.push_back( %txt, getWord( %channelsTxt, %i ) TAB %channelCount ); + + //TerrainImportGui.namesArray.echo(); + + %count = %opacityList.rowCount(); + %opacityList.addRow( %count, %txt TAB getWord( %channelsTxt, %i ) ); + } + + //OpacityMapListBox.addItem( %name ); +} + +function TerrainImportGui::browseForOpacityMap( %this ) +{ + TerrainImportGui.doOpenDialog( $TerrainImportGui::OpacityMapFilter, "TerrainImportGuiAddOpacityMap" ); +} + +function TerrainImportGui::removeOpacitymap( %this ) +{ + %opacityList = %this-->OpacityLayerTextList; + + //%itemIdx = OpacityMapListBox.getSelectedItem(); + %itemIdx = %opacityList.getSelectedId(); + if ( %itemIdx < 0 ) // -1 is no item selected + return; + + %this.namesArray.erase( %itemIdx ); + %this.channelsArray.erase( %itemIdx ); + + //%this.namesArray.echo(); + + %opacityList.removeRowById( %itemIdx ); + + //OpacityMapListBox.deleteItem( %itemIdx ); +} + +function TerrainImportGui::onOpacityListDblClick( %this ) +{ + %opacityList = %this-->OpacityLayerTextList; + + //echo( "Double clicked the opacity list control!" ); + %itemIdx = %opacityList.getSelectedId(); + if ( %itemIdx < 0 ) + return; + + %this.activeIdx = %itemIdx; + + %rowTxt = %opacityList.getRowTextById( %itemIdx ); + %matTxt = getField( %rowTxt, 2 ); + %matId = getField( %rowTxt, 3 ); + + TerrainMaterialDlg.showByObjectId( %matId, TerrainImportGui_TerrainMaterialApplyCallback ); +} + +function TerrainImportGui_TerrainMaterialApplyCallback( %mat, %matIndex ) +{ + // Skip over a bad selection. + if ( !isObject( %mat ) ) + return; + + %opacityList = TerrainImportGui-->OpacityLayerTextList; + + %itemIdx = TerrainImportGui.activeIdx; + + if ( %itemIdx < 0 || %itemIdx $= "" ) + return; + + %rowTxt = %opacityList.getRowTextById( %itemIdx ); + + %columntTxtCount = getFieldCount( %rowTxt ); + if ( %columntTxtCount > 2 ) + %rowTxt = getFields( %rowTxt, 0, 1 ); + + %opacityList.setRowById( %itemIdx, %rowTxt TAB %mat.internalName TAB %mat ); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui new file mode 100644 index 000000000..09a90ef26 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui @@ -0,0 +1,1392 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(TerrainMaterialDlg, EditorGuiGroup) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 768"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "center"; + VertSizing = "center"; + position = "221 151"; + Extent = "394 432"; + MinExtent = "358 432"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "4 4 4 4"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "TerrainMaterialDlg.dialogCancel();"; + EdgeSnap = "0"; + text = "Terrain Materials Editor"; + new GuiContainer(){ //Node Properties + isContainer = "1"; + Profile = "inspectorStyleRolloutDarkProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "6 25"; + Extent = "189 64"; + + new GuiTextCtrl(){ + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "5 0"; + Extent = "91 18"; + text = "Terrain Materials"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "160 2"; + Extent = "15 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.newMat();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/new"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "173 2"; + Extent = "15 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.deleteMat();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + }; + new GuiContainer() { + canSaveDynamicFields = "0"; + internalName = "matSettingsParent"; + isContainer = "1"; + Profile = "inspectorStyleRolloutProfile"; + HorizSizing = "left"; + VertSizing = "height"; + position = "202 26"; + Extent = "185 363"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "1 0"; + Extent = "183 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + bitmap = "core/art/gui/images/separator-v"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 22"; + Extent = "44 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiDefaultProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Name"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + internalName = "matNameCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "39 21"; + Extent = "143 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + altCommand = "TerrainMaterialDlg.setMaterialName( $ThisControl.getText() );"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiInspectorTitleTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "8 0"; + Extent = "117 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Material Properties"; + maxLength = "1024"; + }; + new GuiContainer() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "6 43"; + Extent = "185 75"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiCheckBoxCtrl() { + internalName = "sideProjectionCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "55 54"; + Extent = "119 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = " Use Side Projection"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiBitmapCtrl() { + internalName = "baseTexCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "47 47"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.changeBase();"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Change the Active Diffuse Map for this layer"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "39 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Diffuse"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "116 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "116 0"; + Extent = "40 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.changeBase();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "159 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg-->baseTexCtrl.setBitmap(\"tools/materialEditor/gui/unknownImage\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "132 35"; + Extent = "39 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + text = "Size"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + internalName = "baseSizeCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "94 34"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + }; + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "6 116"; + Extent = "175 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + bitmap = "tools/gui/images/separator-v"; + wrap = "0"; + }; + new GuiContainer() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "6 295"; + Extent = "185 50"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiBitmapCtrl() { + internalName = "normTexCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "47 47"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "39 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Normal"; + maxLength = "1024"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.changeNormal();"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Change the active Normal Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 15"; + Extent = "116 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "116 0"; + Extent = "40 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.changeNormal();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "159 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg-->normTexCtrl.setBitmap(\"tools/materialEditor/gui/unknownImage\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "92 34"; + Extent = "77 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Parallax Scale"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + internalName = "parallaxScaleCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "55 33"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + text = "0.00"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + }; + + new GuiBitmapCtrl() { + bitmap = "tools/gui/images/separator-v"; + wrap = "0"; + position = "6 288"; + extent = "175 2"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 122"; + extent = "185 72"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + position = "1 1"; + extent = "47 47"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "macroTexCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "1 1"; + extent = "48 48"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.changeMacro();"; + tooltipProfile = "ToolsGuiDefaultProfile"; + tooltip = "Change the active Macro Map for this layer."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Macro"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 -3"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "EditorTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "None"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 17"; + extent = "116 17"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "116 0"; + extent = "40 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.changeMacro();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "159 0"; + extent = "16 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg-->macroTexCtrl.setBitmap(\"tools/materialEditor/gui/unknownImage\");"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Size"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "132 33"; + extent = "39 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "94 32"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "macroSizeCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Strength"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "39 54"; + extent = "46 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "1 53"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "macroStrengthCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Distance"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "132 54"; + extent = "45 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "94 53"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "macroDistanceCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + + new GuiBitmapCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "6 200"; + Extent = "175 2"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + bitmap = "tools/gui/images/separator-v"; + wrap = "0"; + }; + new GuiContainer() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "6 206"; + Extent = "185 72"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiBitmapCtrl() { + internalName = "detailTexCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "47 47"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + bitmap = "tools/materialEditor/gui/unknownImage"; + wrap = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "48 48"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.changeDetail();"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Change the active Detail Map for this layer."; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "EditorTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "56 -3"; + Extent = "30 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Detail"; + maxLength = "1024"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "56 16"; + Extent = "116 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "None"; + maxLength = "1024"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "116 0"; + Extent = "40 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.changeDetail();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "159 0"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg-->detailTexCtrl.setBitmap(\"tools/materialEditor/gui/unknownImage\");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + bitmap = "tools/gui/images/delete"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "132 33"; + Extent = "39 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + text = "Size"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + internalName = "detSizeCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "94 32"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "39 54"; + Extent = "46 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + text = "Strength"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + internalName = "detStrengthCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 53"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "132 54"; + Extent = "45 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + text = "Distance"; + maxLength = "1024"; + }; + new GuiTextEditCtrl() { + internalName = "detDistanceCtrl"; + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "94 53"; + Extent = "34 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "0"; + AnchorBottom = "0"; + AnchorLeft = "0"; + AnchorRight = "0"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "*"; + }; + }; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "6 42"; + Extent = "189 373"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "189 374"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "false"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + + new GuiTreeViewCtrl() { + internalName = "matLibTree"; + canSaveDynamicFields = "0"; + class = "TerrainMaterialTreeCtrl"; + className = "TerrainMaterialTreeCtrl"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "1 1"; + Extent = "125 84"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "0"; + MultipleSelections = "0"; + DeleteObjectAllowed = "0"; + DragToItemAllowed = "0"; + ClearAllOnSingleSelection = "1"; + showRoot = "0"; + internalNamesOnly = "1"; + objectNamesOnly = "0"; + }; + }; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "202 394"; + Extent = "98 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.dialogApply();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Apply&Select"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "top"; + position = "307 394"; + Extent = "80 22"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "TerrainMaterialDlg.dialogCancel();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = "Cancel"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + + new GuiBitmapCtrl() { // inactive overlay + internalName = "inactiveOverlay"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "height"; + position = "199 23"; + Extent = "190 267"; + isContainer = true; + Visible = false; + bitmap = "tools/gui/images/inactive-overlay"; + + new GuiTextCtrl(){ + internalName = "inactiveOverlayDlg"; + Profile = "ToolsGuiTextCenterProfile"; + HorizSizing = "width"; + VertSizing = "center"; + position = "0 104"; + Extent = "190 64"; + text = "Inactive"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/guiWorldEditorCreatorWindow.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/guiWorldEditorCreatorWindow.ed.gui new file mode 100644 index 000000000..03a3d6d8a --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/guiWorldEditorCreatorWindow.ed.gui @@ -0,0 +1,286 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(WorldEditorCreatorWindowContainer) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiWindowCtrl(EWCreatorWindow) { + canSaveDynamicFields = "0"; + internalName = "CreatorWindow"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "38 36"; + Extent = "354 276"; + MinExtent = "354 207"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "30 30"; + EdgeSnap = "0"; + text = "Creator"; + + new GuiContainer() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "2 80"; + Extent = "348 195"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "4 4 4 4"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "EditorLightScrollProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 4"; + Extent = "340 187"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "Client"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "alwaysOff"; + lockHorizScroll = "false"; + lockVertScroll = "true"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiDynamicCtrlArrayControl(CreatorIconArray) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTransparentProfile"; + HorizSizing = "width"; + VertSizing = "height"; + Position = "2 2"; + Extent = "335 183"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + colCount = "9"; + colSize = "64"; + rowCount = "0"; + RowSize = "64"; + rowSpacing = "4"; + colSpacing = "4"; + frozen = "0"; + autoCellSize = "1"; + fillRowFirst = "0"; + dynamicSize = "1"; + }; + }; + }; + new GuiControl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 24"; + Extent = "348 55"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiBitmapButtonCtrl(CreatorNavUpButton) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + Position = "319 33"; + Extent = "20 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EWCreatorWindow.navigateUp();"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + groupNum = "-1"; + buttonType = "PushButton"; + + Bitmap = "tools/gui/images/folderUp.png"; + autoSize = "0"; + }; + new GuiPopUpMenuCtrl(CreatorPopupMenu) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 33"; + Extent = "308 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Objects"; + maxLength = "1024"; + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + }; + new GuiTabBookCtrl(CreatorTabBook) { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTabBookProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "4 4"; + Extent = "342 21"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Docking = "None"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + TabPosition = "Top"; + TabMargin = "7"; + MinTabWidth = "64"; + + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "0 0"; + MinExtent = "0 0"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Shapes"; + maxLength = "1024"; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "0 0"; + MinExtent = "0 0"; + canSave = "1"; + Visible = "0"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Geometry"; + maxLength = "1024"; + }; + new GuiTabPageCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiTabPageProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "0 0"; + MinExtent = "0 0"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "MissionObjects"; + maxLength = "1024"; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/guiWorldEditorMissionInspector.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/guiWorldEditorMissionInspector.ed.gui new file mode 100644 index 000000000..ab7bfe2f5 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/guiWorldEditorMissionInspector.ed.gui @@ -0,0 +1,299 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(WorldEditorMissionInspector,EditorGuiGroup) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "800 600"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiWindowCtrl(EWInspectorWindow) { + canSaveDynamicFields = "0"; + internalName = "InspectorWindow"; + isContainer = "1"; + Profile = "ToolsGuiWindowProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "333 26"; + Extent = "304 448"; + MinExtent = "304 448"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + text = "Mission Inspector"; + maxLength = "1024"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + closeCommand = "EWInspectorFrame.parentGroup.setVisible(false);"; + + new GuiFrameSetCtrl(EWInspectorFrame) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiFrameSetProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "8 32"; + Extent = "288 408"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + columns = "0"; + rows = "0 206"; + borderWidth = "0"; + borderColor = "84 12 136 1"; + borderEnable = "dynamic"; + borderMovable = "dynamic"; + autoBalance = "0"; + fudgeFactor = "0"; + + new GuiControl(EWTreePane) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "EditorDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "288 202"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "288 202"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "alwaysOff"; + vScrollBar = "dynamic"; + lockHorizScroll = "true"; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiTreeViewCtrl(EditorTree) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "226 21"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "1"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "1"; + }; + }; + }; + new GuiControl(EWCreatorInspectorPane) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "EditorDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 206"; + Extent = "288 202"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiScrollCtrl(EWCreatorPane) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "288 202"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "0"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiTreeViewCtrl(Creator) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiTreeViewProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "131 84"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + tabSize = "16"; + textOffset = "2"; + fullRowSelect = "0"; + itemHeight = "21"; + destroyTreeOnSleep = "1"; + MouseDragging = "1"; + MultipleSelections = "1"; + DeleteObjectAllowed = "1"; + DragToItemAllowed = "1"; + }; + }; + new GuiControl(EWInspectorPane) { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "EditorDefaultProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 0"; + Extent = "288 202"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiControl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiSolidDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "288 24"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + + new GuiButtonCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "40 20"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + Command = "EWorldEditor.isDirty = true;EWorldEditor.makeFirstResponder(true);"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Don\'t forget to hit Apply after making changes!"; + hovertime = "1000"; + text = "Apply"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + }; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiInspectorFieldProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "52 4"; + Extent = "42 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + text = "Name:"; + maxLength = "1024"; + }; + new GuiTextEditCtrl(InspectorNameEdit) { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "GuiInspectorBackgroundProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "97 4"; + Extent = "758 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + AltCommand = "EWorldEditor.isDirty = true;"; + hovertime = "1000"; + maxLength = "1024"; + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + }; + }; + new GuiScrollCtrl() { + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "ToolsGuiScrollProfile"; + HorizSizing = "width"; + VertSizing = "height"; + position = "0 24"; + Extent = "288 178"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = true; + lockVertScroll = "false"; + constantThumbHeight = "0"; + childMargin = "0 0"; + + new GuiInspector(Inspector) { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "1"; + canSaveDynamicFields = "0"; + isContainer = "1"; + Profile = "GuiInspectorBackgroundProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "266 8"; + MinExtent = "8 8"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + }; + }; + }; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui new file mode 100644 index 000000000..74f1200c6 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui @@ -0,0 +1,1156 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ObjectBuilderGui, EditorGuiGroup) { + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "800 600"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + + new GuiWindowCtrl(OBTargetWindow) { + profile = "ToolsGuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "384 205"; + extent = "256 282"; + minExtent = "256 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = "Create Object"; + + new GuiTextCtrl() { + profile = "GuiCenterTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "9 26"; + extent = "84 16"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + text = "Object Name:"; + }; + new GuiTextEditCtrl(OBObjectName) { + class = ObjectBuilderGuiTextEditCtrl; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "78 26"; + extent = "172 18"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + historySize = "0"; + }; + new GuiBitmapBorderCtrl(OBContentWindow) { + profile = "ToolsGuiGroupBorderProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "7 51"; + extent = "243 193"; + minExtent = "0 0"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + }; + new GuiButtonCtrl(OBOKButton) { + profile = "ToolsGuiButtonProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "7 250"; + extent = "156 24"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + command = "ObjectBuilderGui.onOK();"; + helpTag = "0"; + text = "Create New"; + Accelerator = "return"; + }; + new GuiButtonCtrl(OBCancelButton) { + profile = "ToolsGuiButtonProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "170 250"; + extent = "80 24"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + command = "ObjectBuilderGui.onCancel();"; + helpTag = "0"; + text = "Cancel"; + Accelerator = "escape"; + }; + }; +}; +//--- OBJECT WRITE END --- + +function ObjectBuilderGui::init(%this) +{ + %this.baseOffsetX = 5; + %this.baseOffsetY = 5; + %this.defaultObjectName = ""; + %this.defaultFieldStep = 22; + %this.columnOffset = 110; + + %this.fieldNameExtent = "105 18"; + %this.textEditExtent = "122 18"; + %this.checkBoxExtent = "13 18"; + %this.popupMenuExtent = "122 18"; + %this.fileButtonExtent = "122 18"; + %this.matButtonExtent = "17 18"; + + // + %this.numControls = 0; + + %this.lastPath = ""; + + %this.reset(); +} + +function ObjectBuilderGui::reset(%this) +{ + %this.objectGroup = ""; + %this.curXPos = %this.baseOffsetX; + %this.curYPos = %this.baseOffsetY; + %this.createFunction = ""; + %this.createCallback = ""; + %this.currentControl = 0; + + // + OBObjectName.setValue(%this.defaultObjectName); + + // + %this.newObject = 0; + %this.objectClassName = ""; + %this.numFields = 0; + + // + for(%i = 0; %i < %this.numControls; %i++) + { + %this.textControls[%i].delete(); + %this.controls[%i].delete(); + } + %this.numControls = 0; +} + +//------------------------------------------------------------------------------ + +function ObjectBuilderGui::createFileType(%this, %index) +{ + if(%index >= %this.numFields || %this.field[%index, name] $= "") + { + error("ObjectBuilderGui::createFileType: invalid field"); + return; + } + + // + if(%this.field[%index, text] $= "") + %name = %this.field[%index, name]; + else + %name = %this.field[%index, text]; + + // + %this.textControls[%this.numControls] = new GuiTextCtrl() { + profile = "ToolsGuiTextRightProfile"; + text = %name; + extent = %this.fieldNameExtent; + position = %this.curXPos @ " " @ %this.curYPos; + modal = "1"; + }; + + // + %this.controls[%this.numControls] = new GuiButtonCtrl() { + HorizSizing = "width"; + profile = "ToolsGuiButtonProfile"; + extent = %this.fileButtonExtent; + position = %this.curXPos + %this.columnOffset @ " " @ %this.curYPos; + modal = "1"; + command = %this @ ".getFileName(" @ %index @ ");"; + }; + + %val = %this.field[%index, value]; + %this.controls[%this.numControls].setValue(fileBase(%val) @ fileExt(%val)); + + %this.numControls++; + %this.curYPos += %this.defaultFieldStep; +} + +function ObjectBuilderGui::getFileName(%this, %index) +{ + if(%index >= %this.numFields || %this.field[%index, name] $= "") + { + error("ObjectBuilderGui::getFileName: invalid field"); + return; + } + + %val = %this.field[%index, ext]; + + //%path = filePath(%val); + //%ext = fileExt(%val); + + %this.currentControl = %index; + getLoadFilename( %val @ "|" @ %val, %this @ ".gotFileName", %this.lastPath ); +} + +function ObjectBuilderGui::gotFileName(%this, %name) +{ + %index = %this.currentControl; + + %name = makeRelativePath(%name,getWorkingDirectory()); + + %this.field[%index, value] = %name; + %this.controls[%this.currentControl].setText(fileBase(%name) @ fileExt(%name)); + + %this.lastPath = %name; + + // This doesn't work for button controls as getValue returns their state! + //%this.controls[%this.currentControl].setValue(%name); +} + +//------------------------------------------------------------------------------ + +function ObjectBuilderGui::createMaterialNameType(%this, %index) +{ + if(%index >= %this.numFields || %this.field[%index, name] $= "") + { + error("ObjectBuilderGui::createMaterialNameType: invalid field"); + return; + } + + // + if(%this.field[%index, text] $= "") + %name = %this.field[%index, name]; + else + %name = %this.field[%index, text]; + + // + %this.textControls[%this.numControls] = new GuiTextCtrl() { + profile = "ToolsGuiTextRightProfile"; + text = %name; + extent = %this.fieldNameExtent; + position = %this.curXPos @ " " @ %this.curYPos; + modal = "1"; + }; + + // + %this.controls[%this.numControls] = new GuiControl() { + HorizSizing = "width"; + profile = "ToolsGuiDefaultProfile"; + extent = %this.textEditExtent; + position = %this.curXPos + %this.columnOffset @ " " @ %this.curYPos; + modal = "1"; + }; + + %text = new GuiTextEditCtrl() { + class = ObjectBuilderGuiTextEditCtrl; + internalName = "MatText"; + HorizSizing = "width"; + profile = "ToolsGuiTextEditProfile"; + extent = getWord(%this.textEditExtent,0) - getWord(%this.matButtonExtent,0) - 2 @ " " @ getWord(%this.textEditExtent,1); + text = %this.field[%index, value]; + position = "0 0"; + modal = "1"; + }; + %this.controls[%this.numControls].addGuiControl(%text); + + %button = new GuiBitmapButtonCtrl() { + internalName = "MatButton"; + HorizSizing = "left"; + profile = "ToolsGuiButtonProfile"; + extent = %this.matButtonExtent; + position = getWord(%this.textEditExtent,0) - getWord(%this.matButtonExtent,0) @ " 0"; + modal = "1"; + command = %this @ ".getMaterialName(" @ %index @ ");"; + }; + %button.setBitmap("tools/materialEditor/gui/change-material-btn"); + %this.controls[%this.numControls].addGuiControl(%button); + + //%val = %this.field[%index, value]; + //%this.controls[%this.numControls].setValue(%val); + //%this.controls[%this.numControls].setBitmap("tools/materialEditor/gui/change-material-btn"); + + %this.numControls++; + %this.curYPos += %this.defaultFieldStep; +} + +function ObjectBuilderGui::getMaterialName(%this, %index) +{ + if(%index >= %this.numFields || %this.field[%index, name] $= "") + { + error("ObjectBuilderGui::getMaterialName: invalid field"); + return; + } + + %this.currentControl = %index; + materialSelector.showDialog(%this @ ".gotMaterialName", "name"); +} + +function ObjectBuilderGui::gotMaterialName(%this, %name) +{ + %index = %this.currentControl; + + %this.field[%index, value] = %name; + %this.controls[%index]-->MatText.setText(%name); +} + +//------------------------------------------------------------------------------ + +function ObjectBuilderGui::createDataBlockType(%this, %index) +{ + if(%index >= %this.numFields || %this.field[%index, name] $= "") + { + error("ObjectBuilderGui::createDataBlockType: invalid field"); + return; + } + + // + if(%this.field[%index, text] $= "") + %name = %this.field[%index, name]; + else + %name = %this.field[%index, text]; + + // + %this.textControls[%this.numControls] = new GuiTextCtrl() { + profile = "ToolsGuiTextRightProfile"; + text = %name; + extent = %this.fieldNameExtent; + position = %this.curXPos @ " " @ %this.curYPos; + modal = "1"; + }; + + // + %this.controls[%this.numControls] = new GuiPopupMenuCtrl() { + HorizSizing = "width"; + profile = "ToolsGuiPopUpMenuProfile"; + extent = %this.popupMenuExtent; + position = %this.curXPos + %this.columnOffset @ " " @ %this.curYPos; + modal = "1"; + maxPopupHeight = "200"; + }; + + %classname = getWord(%this.field[%index, value], 0); + %classname_alt = getWord(%this.field[%index, value], 1); + + %this.controls[%this.numControls].add("", -1); + + // add the datablocks + for(%i = 0; %i < DataBlockGroup.getCount(); %i++) + { + %obj = DataBlockGroup.getObject(%i); + if( isMemberOfClass( %obj.getClassName(), %classname ) || isMemberOfClass ( %obj.getClassName(), %classname_alt ) ) + %this.controls[%this.numControls].add(%obj.getName(), %i); + } + + %this.controls[%this.numControls].setValue(getWord(%this.field[%index, value], 1)); + + %this.numControls++; + %this.curYPos += %this.defaultFieldStep; +} + +function ObjectBuilderGui::createBoolType(%this, %index) +{ + if(%index >= %this.numFields || %this.field[%index, name] $= "") + { + error("ObjectBuilderGui::createBoolType: invalid field"); + return; + } + + // + if(%this.field[%index, value] $= "") + %value = 0; + else + %value = %this.field[%index, value]; + + // + if(%this.field[%index, text] $= "") + %name = %this.field[%index, name]; + else + %name = %this.field[%index, text]; + + // + %this.textControls[%this.numControls] = new GuiTextCtrl() { + profile = "ToolsGuiTextRightProfile"; + text = %name; + extent = %this.fieldNameExtent; + position = %this.curXPos @ " " @ %this.curYPos; + modal = "1"; + }; + + // + %this.controls[%this.numControls] = new GuiCheckBoxCtrl() { + profile = "ToolsGuiCheckBoxProfile"; + extent = %this.checkBoxExtent; + position = %this.curXPos + %this.columnOffset @ " " @ %this.curYPos; + modal = "1"; + }; + + %this.controls[%this.numControls].setValue(%value); + + %this.numControls++; + %this.curYPos += %this.defaultFieldStep; +} + +function ObjectBuilderGuiTextEditCtrl::onGainFirstResponder(%this) +{ + %this.selectAllText(); +} + +function ObjectBuilderGui::createStringType(%this, %index) +{ + if(%index >= %this.numFields || %this.field[%index, name] $= "") + { + error("ObjectBuilderGui::createStringType: invalid field"); + return; + } + + // + if(%this.field[%index, text] $= "") + %name = %this.field[%index, name]; + else + %name = %this.field[%index, text]; + + // + %this.textControls[%this.numControls] = new GuiTextCtrl() { + profile = "ToolsGuiTextRightProfile"; + text = %name; + extent = %this.fieldNameExtent; + position = %this.curXPos @ " " @ %this.curYPos; + modal = "1"; + }; + + // + %this.controls[%this.numControls] = new GuiTextEditCtrl() { + class = ObjectBuilderGuiTextEditCtrl; + HorizSizing = "width"; + profile = "ToolsGuiTextEditProfile"; + extent = %this.textEditExtent; + text = %this.field[%index, value]; + position = %this.curXPos + %this.columnOffset @ " " @ %this.curYPos; + modal = "1"; + }; + + %this.numControls++; + %this.curYPos += %this.defaultFieldStep; +} + +//------------------------------------------------------------------------------ + +function ObjectBuilderGui::adjustSizes(%this) +{ + if(%this.numControls == 0) + %this.curYPos = 0; + + OBTargetWindow.extent = getWord(OBTargetWindow.extent, 0) SPC %this.curYPos + 88; + OBContentWindow.extent = getWord(OBContentWindow.extent, 0) SPC %this.curYPos; + OBOKButton.position = getWord(OBOKButton.position, 0) SPC %this.curYPos + 57; + OBCancelButton.position = getWord(OBCancelButton.position, 0) SPC %this.curYPos + 57; +} + +function ObjectBuilderGui::process(%this) +{ + if(%this.objectClassName $= "") + { + error("ObjectBuilderGui::process: classname is not specified"); + return; + } + + OBTargetWindow.text = "Create Object: " @ %this.objectClassName; + + // + for(%i = 0; %i < %this.numFields; %i++) + { + switch$(%this.field[%i, type]) + { + case "TypeBool": + %this.createBoolType(%i); + + case "TypeDataBlock": + %this.createDataBlockType(%i); + + case "TypeFile": + %this.createFileType(%i); + + case "TypeMaterialName": + %this.createMaterialNameType(%i); + + default: + %this.createStringType(%i); + } + } + + // add the controls + for(%i = 0; %i < %this.numControls; %i++) + { + OBContentWindow.add(%this.textControls[%i]); + OBContentWindow.add(%this.controls[%i]); + } + + // + %this.adjustSizes(); + + // + Canvas.pushDialog(%this); +} + +function ObjectBuilderGui::processNewObject(%this, %obj) +{ + if ( %this.createCallback !$= "" ) + eval( %this.createCallback ); + + // Skip out if nothing was created. + if ( !isObject( %obj ) ) + return; + + // Add the object to the group. + if( %this.objectGroup !$= "" ) + %this.objectGroup.add( %obj ); + else + EWCreatorWindow.objectGroup.add( %obj ); + + // If we were given a callback to call after the + // object has been created, do so now. Also clear + // the callback to make sure it's valid only for + // a single invocation. + + %callback = %this.newObjectCallback; + %this.newObjectCallback = ""; + + if( %callback !$= "" ) + eval( %callback @ "( " @ %obj @ " );" ); +} + +function ObjectBuilderGui::onOK(%this) +{ + // Error out if the given object name is not valid or not unique. + %objectName = OBObjectName.getValue(); + if( !Editor::validateObjectName( %objectName, false )) + return; + + // get current values + for(%i = 0; %i < %this.numControls; %i++) + { + // uses button type where getValue returns button state! + if (%this.field[%i, type] $= "TypeFile") + { + if (strchr(%this.field[%i, value],"*") !$= "") + %this.field[%i, value] = ""; + + continue; + } + if (%this.field[%i, type] $= "TypeMaterialName") + { + %this.field[%i, value] = %this.controls[%i]-->MatText.getValue(); + continue; + } + %this.field[%i, value] = %this.controls[%i].getValue(); + } + + // If we have a special creation function then + // let it do the construction. + if ( %this.createFunction !$= "" ) + eval( %this.createFunction ); + + else + { + // Else we use the memento. + %memento = %this.buildMemento(); + eval( %memento ); + } + + if(%this.newObject != 0) + %this.processNewObject(%this.newObject); + + %this.reset(); + Canvas.popDialog(%this); +} + +function ObjectBuilderGui::onCancel(%this) +{ + %this.reset(); + Canvas.popDialog(%this); +} + +function ObjectBuilderGui::addField(%this, %name, %type, %text, %value, %ext) +{ + %this.field[%this.numFields, name] = %name; + %this.field[%this.numFields, type] = %type; + %this.field[%this.numFields, text] = %text; + %this.field[%this.numFields, value] = %value; + %this.field[%this.numFields, ext] = %ext; + + %this.numFields++; +} + +function ObjectBuilderGui::buildMemento(%this) +{ + // Build the object into a string. + %this.memento = %this @ ".newObject = new " @ %this.objectClassName @ "(" @ OBObjectName.getValue() @ ") { "; + for( %i = 0; %i < %this.numFields; %i++ ) + %this.memento = %this.memento @ %this.field[%i, name] @ " = \"" @ %this.field[%i, value] @ "\"; "; + %this.memento = %this.memento @ "};"; + + return %this.memento; +} + +//------------------------------------------------------------------------------ +// This function is used for objects that don't require any special +// fields/functionality when being built +//------------------------------------------------------------------------------ +function ObjectBuilderGui::buildObject(%this, %className) +{ + %this.objectClassName = %className; + %this.process(); +} + +//------------------------------------------------------------------------------ +// Environment +//------------------------------------------------------------------------------ + +function ObjectBuilderGui::buildScatterSky( %this, %dontWarnAboutSun ) +{ + if( !%dontWarnAboutSun ) + { + // Check for sun object already in the level. If there is one, + // warn the user. + + initContainerTypeSearch( $TypeMasks::EnvironmentObjectType ); + while( 1 ) + { + %object = containerSearchNext(); + if( !%object ) + break; + + if( %object.isMemberOfClass( "Sun" ) ) + { + MessageBoxYesNo( "Warning", + "A ScatterSky object will conflict with the Sun object that is already in the level." SPC + "Do you still want to create a ScatterSky object?", + %this @ ".buildScatterSky( true );" ); + return; + } + } + } + + %this.objectClassName = "ScatterSky"; + + %this.addField("rayleighScattering", "TypeFloat", "Rayleigh Scattering", "0.0035"); + %this.addField("mieScattering", "TypeFloat", "Mie Scattering", "0.0045"); + %this.addField("skyBrightness", "TypeFloat", "Sky Brightness", "25"); + + %this.process(); + + // This is a trick... any fields added after process won't show + // up as controls, but will be applied to the created object. + %this.addField( "flareType", "TypeLightFlareDataPtr", "Flare", "ScatterSkyFlareExample" ); + %this.addField( "moonMat", "TypeMaterialName", "Moon Material", "Moon_Glow_Mat" ); + %this.addField( "nightCubemap", "TypeCubemapName", "Night Cubemap", "NightCubemap" ); + %this.addField( "useNightCubemap", "TypeBool", "Use Night Cubemap", "true" ); + +} + +function ObjectBuilderGui::buildCloudLayer(%this) +{ + OBObjectName.setValue( "" ); + %this.objectClassName = "CloudLayer"; + %this.addField( "texture", "TypeImageFilename", "Texture", "art/skies/clouds/clouds_normal_displacement" ); + %this.process(); +} + +function ObjectBuilderGui::buildBasicClouds(%this) +{ + OBObjectName.setValue( "" ); + %this.objectClassName = "BasicClouds"; + %this.process(); + + // This is a trick... any fields added after process won't show + // up as controls, but will be applied to the created object. + %this.addField( "texture[0]", "TypeImageFilename", "Texture", "art/skies/clouds/cloud1" ); + %this.addField( "texture[1]", "TypeImageFilename", "Texture", "art/skies/clouds/cloud2" ); + %this.addField( "texture[2]", "TypeImageFilename", "Texture", "art/skies/clouds/cloud3" ); +} + +function ObjectBuilderGui::checkExists( %this, %classname ) +{ + for ( %i = 0; %i < EWCreatorWindow.objectGroup.getCount(); %i++ ) + { + %obj = EWCreatorWindow.objectGroup.getObject( %i ); + if ( %obj.getClassName() $= %classname ) + return true; + } + + return false; +} + +function ObjectBuilderGui::buildsgMissionLightingFilter(%this) +{ + %this.objectClassName = "sgMissionLightingFilter"; + %this.addField("dataBlock", "TypeDataBlock", "sgMissionLightingFilter Data", "sgMissionFilterData"); + %this.process(); +} + +function ObjectBuilderGui::buildsgDecalProjector(%this) +{ + %this.objectClassName = "sgDecalProjector"; + %this.addField("dataBlock", "TypeDataBlock", "DecalData Data", "DecalData"); + %this.process(); +} + +function ObjectBuilderGui::buildsgLightObject(%this) +{ + %this.objectClassName = "sgLightObject"; + %this.addField("dataBlock", "TypeDataBlock", "LightObject Data", "sgLightObjectData"); + %this.process(); +} + +function ObjectBuilderGui::buildSun( %this, %dontWarnAboutScatterSky ) +{ + if( !%dontWarnAboutScatterSky ) + { + // Check for scattersky object already in the level. If there is one, + // warn the user. + + initContainerTypeSearch( $TypeMasks::EnvironmentObjectType ); + while( 1 ) + { + %object = containerSearchNext(); + if( !%object ) + break; + + if( %object.isMemberOfClass( "ScatterSky" ) ) + { + MessageBoxYesNo( "Warning", + "A Sun object will conflict with the ScatterSky object that is already in the level." SPC + "Do you still want to create a Sun object?", + %this @ ".buildSun( true );" ); + return; + } + } + } + + %this.objectClassName = "Sun"; + + %this.addField("direction", "TypeVector", "Direction", "1 1 -1"); + %this.addField("color", "TypeColor", "Sun color", "0.8 0.8 0.8"); + %this.addField("ambient", "TypeColor", "Ambient color", "0.2 0.2 0.2"); + + %this.process(); + + // This is a trick... any fields added after process won't show + // up as controls, but will be applied to the created object. + %this.addField( "coronaMaterial", "TypeMaterialName", "Corona Material", "Corona_Mat" ); + %this.addField( "flareType", "TypeLightFlareDataPtr", "Flare", "SunFlareExample" ); +} + +function ObjectBuilderGui::buildLightning(%this) +{ + %this.objectClassName = "Lightning"; + + %this.addField("dataBlock", "TypeDataBlock", "Data block", "LightningData DefaultStorm"); + + %this.process(); +} + +function ObjectBuilderGui::addWaterObjectFields(%this) +{ + %this.addField("rippleDir[0]", "TypePoint2", "Ripple Direction", "0.000000 1.000000"); + %this.addField("rippleDir[1]", "TypePoint2", "Ripple Direction", "0.707000 0.707000"); + %this.addField("rippleDir[2]", "TypePoint2", "Ripple Direction", "0.500000 0.860000"); + %this.addField("rippleTexScale[0]", "TypePoint2", "Ripple Texture Scale", "7.140000 7.140000"); + %this.addField("rippleTexScale[1]", "TypePoint2", "Ripple Texture Scale", "6.250000 12.500000"); + %this.addField("rippleTexScale[2]", "TypePoint2", "Ripple Texture Scale", "50.000000 50.000000"); + %this.addField("rippleSpeed[0]", "TypeFloat", "Ripple Speed", "0.065"); + %this.addField("rippleSpeed[1]", "TypeFloat", "Ripple Speed", "0.09"); + %this.addField("rippleSpeed[2]", "TypeFloat", "Ripple Speed", "0.04"); + %this.addField("rippleMagnitude[0]", "TypeFloat", "Ripple Magnitude", "1.0"); + %this.addField("rippleMagnitude[1]", "TypeFloat", "Ripple Magnitude", "1.0"); + %this.addField("rippleMagnitude[2]", "TypeFloat", "Ripple Magnitude", "0.3"); + %this.addField("overallRippleMagnitude", "TypeFloat", "Overall Ripple Magnitude", "1.0"); + + %this.addField("waveDir[0]", "TypePoint2", "Wave Direction", "0.000000 1.000000"); + %this.addField("waveDir[1]", "TypePoint2", "Wave Direction", "0.707000 0.707000"); + %this.addField("waveDir[2]", "TypePoint2", "Wave Direction", "0.500000 0.860000"); + %this.addField("waveMagnitude[0]", "TypePoint2", "Wave Magnitude", "0.2"); + %this.addField("waveMagnitude[1]", "TypePoint2", "Wave Magnitude", "0.2"); + %this.addField("waveMagnitude[2]", "TypePoint2", "Wave Magnitude", "0.2"); + %this.addField("waveSpeed[0]", "TypeFloat", "Wave Speed", "1"); + %this.addField("waveSpeed[1]", "TypeFloat", "Wave Speed", "1"); + %this.addField("waveSpeed[2]", "TypeFloat", "Wave Speed", "1"); + %this.addField("overallWaveMagnitude", "TypeFloat", "Overall Wave Magnitude", "1.0"); + + %this.addField("rippleTex", "TypeImageFilename", "Ripple Texture", "art/water/ripple" ); + %this.addField("depthGradientTex", "TypeImageFilename", "Depth Gradient Texture", "art/water/depthcolor_ramp" ); + %this.addField("foamTex", "TypeImageFilename", "Foam Texture", "art/water/foam" ); +} + +function ObjectBuilderGui::buildWaterBlock(%this) +{ + %this.objectClassName = "WaterBlock"; + %this.addField( "baseColor", "TypeColorI", "Base Color", "45 108 171 255" ); + %this.process(); + + // This is a trick... any fields added after process won't show + // up as controls, but will be applied to the created object. + %this.addWaterObjectFields(); +} + +function ObjectBuilderGui::buildWaterPlane(%this) +{ + %this.objectClassName = "WaterPlane"; + %this.addField( "baseColor", "TypeColorI", "Base Color", "45 108 171 255" ); + %this.process(); + + // This is a trick... any fields added after process won't show + // up as controls, but will be applied to the created object. + %this.addWaterObjectFields(); +} + +function ObjectBuilderGui::buildTerrainBlock(%this) +{ + %this.objectClassName = "TerrainBlock"; + %this.createCallback = "ETerrainEditor.attachTerrain();"; + + %this.addField("terrainFile", "TypeFile", "Terrain file", "", "*.ter"); + %this.addField("squareSize", "TypeInt", "Square size", "8"); + + %this.process(); +} + +function ObjectBuilderGui::buildGroundCover( %this ) +{ + %this.objectClassName = "GroundCover"; + %this.addField( "material", "TypeMaterialName", "Material Name", "" ); + %this.addField( "shapeFilename[0]", "TypeFile", "Shape File [Optional]", "", "*.*"); + %this.process(); + + // This is a trick... any fields added after process won't show + // up as controls, but will be applied to the created object. + %this.addField( "probability[0]", "TypeFloat", "Probability", "1" ); +} + +function ObjectBuilderGui::buildPrecipitation(%this) +{ + %this.objectClassName = "Precipitation"; + %this.addField("dataBlock", "TypeDataBlock", "Precipitation data", "PrecipitationData"); + %this.process(); +} + +function ObjectBuilderGui::buildParticleEmitterNode(%this) +{ + %this.objectClassName = "ParticleEmitterNode"; + %this.addField("dataBlock", "TypeDataBlock", "datablock", "ParticleEmitterNodeData"); + %this.addField("emitter", "TypeDataBlock", "Particle data", "ParticleEmitterData"); + %this.process(); +} + +function ObjectBuilderGui::buildRibbonNode(%this) +{ + %this.objectClassName = "RibbonNode"; + %this.addField("dataBlock", "TypeDataBlock", "datablock", "RibbonNodeData"); + %this.addField("ribbon", "TypeDataBlock", "Ribbon data", "RibbonData"); + %this.process(); +} + +function ObjectBuilderGui::buildParticleSimulation(%this) +{ + %this.objectClassName = "ParticleSimulation"; + %this.addField("datablock", "TypeDataBlock", "datablock", "ParticleSimulationData"); + %this.process(); +} + +//------------------------------------------------------------------------------ +// Mission +//------------------------------------------------------------------------------ + +function ObjectBuilderGui::buildTrigger(%this) +{ + %this.objectClassName = "Trigger"; + %this.addField("dataBlock", "TypeDataBlock", "Data Block", "TriggerData defaultTrigger"); + %this.addField("polyhedron", "TypeTriggerPolyhedron", "Polyhedron", "-0.5 0.5 0.0 1.0 0.0 0.0 0.0 -1.0 0.0 0.0 0.0 1.0"); + %this.process(); +} + +function ObjectBuilderGui::buildPhysicalZone(%this) +{ + %this.objectClassName = "PhysicalZone"; + %this.addField("polyhedron", "TypeTriggerPolyhedron", "Polyhedron", "-0.5 0.5 0.0 1.0 0.0 0.0 0.0 -1.0 0.0 0.0 0.0 1.0"); + %this.process(); +} + +function ObjectBuilderGui::buildCamera(%this) +{ + %this.objectClassName = "Camera"; + + %this.addField("position", "TypePoint3", "Position", "0 0 0"); + %this.addField("rotation", "TypePoint4", "Rotation", "1 0 0 0"); + %this.addField("dataBlock", "TypeDataBlock", "Data block", "CameraData Observer"); + %this.addField("team", "TypeInt", "Team", "0"); + + %this.process(); +} + +function ObjectBuilderGui::buildLevelInfo(%this) +{ + if ( %this.checkExists( "LevelInfo" ) ) + { + GenericPromptDialog-->GenericPromptWindow.text = "Warning"; + GenericPromptDialog-->GenericPromptText.text = "There is already an existing LevelInfo in the scene."; + Canvas.pushDialog( GenericPromptDialog ); + return; + } + + OBObjectName.setValue( "theLevelInfo" ); + %this.objectClassName = "LevelInfo"; + %this.process(); +} + +function ObjectBuilderGui::buildTimeOfDay(%this) +{ + if ( %this.checkExists( "TimeOfDay" ) ) + { + GenericPromptDialog-->GenericPromptWindow.text = "Warning"; + GenericPromptDialog-->GenericPromptText.text = "There is already an existing TimeOfDay in the scene."; + Canvas.pushDialog( GenericPromptDialog ); + return; + } + + %this.objectClassName = "TimeOfDay"; + %this.process(); +} + +function ObjectBuilderGui::buildPlayerDropPoint(%this) +{ + %this.objectClassName = "SpawnSphere"; + %this.addField("dataBlock", "TypeDataBlock", "dataBlock", "MissionMarkerData SpawnSphereMarker"); + %this.addField("radius", "TypeFloat", "Radius", 1); + %this.addField("sphereWeight", "TypeFloat", "Sphere Weight", 1); + + %this.addField("spawnClass", "TypeString", "Spawn Class", "Player"); + %this.addField("spawnDatablock", "TypeDataBlock", "Spawn Data", "PlayerData DefaultPlayerData"); + + if( EWCreatorWindow.objectGroup.getID() == MissionGroup.getID() ) + { + if( !isObject("PlayerDropPoints") ) + MissionGroup.add( new SimGroup("PlayerDropPoints") ); + %this.objectGroup = "PlayerDropPoints"; + } + + %this.process(); +} + +function ObjectBuilderGui::buildObserverDropPoint(%this) +{ + %this.objectClassName = "SpawnSphere"; + %this.addField("dataBlock", "TypeDataBlock", "dataBlock", "MissionMarkerData SpawnSphereMarker"); + %this.addField("radius", "TypeFloat", "Radius", 1); + %this.addField("sphereWeight", "TypeFloat", "Sphere Weight", 1); + + %this.addField("spawnClass", "TypeString", "Spawn Class", "Camera"); + %this.addField("spawnDatablock", "TypeDataBlock", "Spawn Data", "CameraData Observer"); + + if( EWCreatorWindow.objectGroup.getID() == MissionGroup.getID() ) + { + if( !isObject("ObserverDropPoints") ) + MissionGroup.add( new SimGroup("ObserverDropPoints") ); + %this.objectGroup = "ObserverDropPoints"; + } + + %this.process(); +} + +//------------------------------------------------------------------------------ +// System +//------------------------------------------------------------------------------ +function ObjectBuilderGui::buildVolumetricFog(%this) +{ + // Change this if you want to default to another Folder + // Otherwise every time you want to add a Fog you will go this. + %defShape = "/art/environment/Fog_Cube.dts"; + %this.lastPath=getMainDotCsDir() @ %defShape; + OBObjectName.setValue( "" ); + %this.objectClassName = "VolumetricFog"; + %this.addField( "shapeName", "TypeFile", "Shape (Fog volume)", "", "*.dts;*.dae"); + %this.addField("Scale", "TypePoint3", "Scale", "1 1 1"); + %this.addField("FogColor", "TypeColorI", "FogColor", "200 200 200 255"); + %this.process(); +} +function ObjectBuilderGui::buildPhysicsEntity(%this) +{ + %this.objectClassName = "PhysicsEntity"; + %this.addField("dataBlock", "TypeDataBlock", "Data block", "PhysicsEntityData"); + %this.process(); +} + +//------------------------------------------------------------------------------ +// Functions to allow scripted/datablock objects to be instantiated +//------------------------------------------------------------------------------ + +function PhysicsEntityData::create(%data) +{ + %obj = new PhysicsEntity() { + dataBlock = %data; + parentGroup = EWCreatorWindow.objectGroup; + }; + return %obj; +} + +function StaticShapeData::create(%data) +{ + %obj = new StaticShape() { + dataBlock = %data; + parentGroup = EWCreatorWindow.objectGroup; + }; + return %obj; +} + +function MissionMarkerData::create(%block) +{ + switch$(%block) + { + case "WayPointMarker": + %obj = new WayPoint() { + dataBlock = %block; + parentGroup = EWCreatorWindow.objectGroup; + }; + return(%obj); + case "SpawnSphereMarker": + %obj = new SpawnSphere() { + datablock = %block; + parentGroup = EWCreatorWindow.objectGroup; + }; + return(%obj); + } + + return(-1); +} + +function ItemData::create(%data) +{ + %obj = new Item() + { + dataBlock = %data; + parentGroup = EWCreatorWindow.objectGroup; + static = true; + rotate = true; + }; + return %obj; +} + +function TurretShapeData::create(%block) +{ + %obj = new TurretShape() { + dataBlock = %block; + static = true; + respawn = true; + parentGroup = EWCreatorWindow.objectGroup; + }; + return %obj; +} + +function AITurretShapeData::create(%block) +{ + %obj = new AITurretShape() { + dataBlock = %block; + static = true; + respawn = true; + parentGroup = EWCreatorWindow.objectGroup; + }; + return %obj; +} + +function WheeledVehicleData::create(%block) +{ + %obj = new WheeledVehicle() { + dataBlock = %block; + parentGroup = EWCreatorWindow.objectGroup; + }; + return %obj; +} + +function FlyingVehicleData::create(%block) +{ + %obj = new FlyingVehicle() + { + dataBlock = %block; + parentGroup = EWCreatorWindow.objectGroup; + }; + return(%obj); +} + +function HoverVehicleData::create(%block) +{ + %obj = new HoverVehicle() + { + dataBlock = %block; + parentGroup = EWCreatorWindow.objectGroup; + }; + return(%obj); +} + +function RigidShapeData::create(%data) +{ + %obj = new RigidShape() { + dataBlock = %data; + parentGroup = EWCreatorWindow.objectGroup; + }; + return %obj; +} + +function PhysicsShapeData::create( %datablock ) +{ + %obj = new PhysicsShape() + { + dataBlock = %datablock; + parentGroup = EWCreatorWindow.objectGroup; + + invulnerable = false; + damageRadius = 0; + areaImpulse = 0; + radiusDamage = 0; + minDamageAmount = 0; + }; + + return %obj; +} + +function ProximityMineData::create( %datablock ) +{ + %obj = new ProximityMine() + { + dataBlock = %dataBlock; + parentGroup = EWCreatorWindow.objectGroup; + static = true; // mines created by the editor are static, and armed immediately + }; + + return %obj; +} + +function RibbonData::create( %datablock ) +{ + %obj = new RibbonNode() + { + dataBlock = DefaultRibbonNodeData; + ribbon = %datablock; + }; + + return %obj; +} diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/profiles.ed.cs b/Templates/BaseGame/game/tools/worldEditor/gui/profiles.ed.cs new file mode 100644 index 000000000..ac11fade3 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/profiles.ed.cs @@ -0,0 +1,126 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +singleton GuiControlProfile (EditorDefaultProfile) +{ + opaque = true; + category = "Editor"; +}; + +singleton GuiControlProfile (EditorToolButtonProfile) +{ + opaque = true; + border = 2; + category = "Editor"; +}; + +singleton GuiControlProfile (EditorTextProfile) +{ + fontType = "Arial Bold"; + fontColor = "0 0 0"; + autoSizeWidth = true; + autoSizeHeight = true; + category = "Editor"; +}; + +singleton GuiControlProfile (EditorTextProfileWhite) +{ + fontType = "Arial Bold"; + fontColor = "255 255 255"; + autoSizeWidth = true; + autoSizeHeight = true; + category = "Editor"; +}; + +singleton GuiControlProfile (WorldEditorProfile) +{ + canKeyFocus = true; + category = "Editor"; +}; + +singleton GuiControlProfile (EditorScrollProfile) +{ + opaque = true; + fillColor = "192 192 192 192"; + border = 3; + borderThickness = 2; + borderColor = "0 0 0"; + bitmap = "tools/gui/images/scrollBar"; + hasBitmapArray = true; + category = "Editor"; +}; + +singleton GuiControlProfile (GuiEditorClassProfile) +{ + opaque = true; + fillColor = "232 232 232"; + border = true; + borderColor = "0 0 0"; + borderColorHL = "127 127 127"; + fontColor = "0 0 0"; + fontColorHL = "50 50 50"; + fixedExtent = true; + justify = "center"; + bitmap = "tools/gui/images/scrollBar"; + hasBitmapArray = true; + category = "Editor"; +}; + +singleton GuiControlProfile( EPainterBitmapProfile ) +{ + opaque = false; + border = false; + borderColor ="243 242 241"; + Color ="230 230 230"; + category = "Editor"; +}; + +singleton GuiControlProfile( EPainterBorderButtonProfile : ToolsGuiDefaultProfile ) +{ + border = true; + borderColor = "0 0 0"; + borderThickness = 2; + + fontColorHL = "255 0 0"; + fontColorSEL = "0 0 255"; + category = "Editor"; +}; + +singleton GuiControlProfile( EPainterDragDropProfile ) +{ + justify = "center"; + fontColor = "0 0 0"; + border = 0; + textOffset = "0 0"; + opaque = true; + fillColor = "221 221 221 150"; + category = "Editor"; +}; + +singleton GizmoProfile( GlobalGizmoProfile ) +{ + // This isnt a GuiControlProfile but fits in well here. + // Don't really have to initialize this now because that will be done later + // based on the saved editor prefs. + screenLength = 100; + category = "Editor"; +}; diff --git a/Templates/BaseGame/game/tools/worldEditor/images/CUR_3darrow.png b/Templates/BaseGame/game/tools/worldEditor/images/CUR_3darrow.png new file mode 100644 index 000000000..1e06287e3 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/CUR_3darrow.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/CUR_3ddiagleft.png b/Templates/BaseGame/game/tools/worldEditor/images/CUR_3ddiagleft.png new file mode 100644 index 000000000..93e2af4d1 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/CUR_3ddiagleft.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/CUR_3ddiagright.png b/Templates/BaseGame/game/tools/worldEditor/images/CUR_3ddiagright.png new file mode 100644 index 000000000..59c09bcac Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/CUR_3ddiagright.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/CUR_3dleftright.png b/Templates/BaseGame/game/tools/worldEditor/images/CUR_3dleftright.png new file mode 100644 index 000000000..63c20e16a Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/CUR_3dleftright.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/CUR_3dupdown.png b/Templates/BaseGame/game/tools/worldEditor/images/CUR_3dupdown.png new file mode 100644 index 000000000..c0897e896 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/CUR_3dupdown.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/CUR_grab.png b/Templates/BaseGame/game/tools/worldEditor/images/CUR_grab.png new file mode 100644 index 000000000..7bab05a38 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/CUR_grab.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/CUR_hand.png b/Templates/BaseGame/game/tools/worldEditor/images/CUR_hand.png new file mode 100644 index 000000000..5e1073644 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/CUR_hand.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/CUR_rotate.png b/Templates/BaseGame/game/tools/worldEditor/images/CUR_rotate.png new file mode 100644 index 000000000..24c91b854 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/CUR_rotate.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/DefaultHandle.png b/Templates/BaseGame/game/tools/worldEditor/images/DefaultHandle.png new file mode 100644 index 000000000..c32ed3fb8 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/DefaultHandle.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/LockedHandle.png b/Templates/BaseGame/game/tools/worldEditor/images/LockedHandle.png new file mode 100644 index 000000000..37f2ddec4 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/LockedHandle.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/SelectHandle.png b/Templates/BaseGame/game/tools/worldEditor/images/SelectHandle.png new file mode 100644 index 000000000..941fcd9c8 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/SelectHandle.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/boxBrush_d.PNG b/Templates/BaseGame/game/tools/worldEditor/images/boxBrush_d.PNG new file mode 100644 index 000000000..8cb9baff5 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/boxBrush_d.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/boxBrush_h.PNG b/Templates/BaseGame/game/tools/worldEditor/images/boxBrush_h.PNG new file mode 100644 index 000000000..b380cf4a6 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/boxBrush_h.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/boxBrush_n.PNG b/Templates/BaseGame/game/tools/worldEditor/images/boxBrush_n.PNG new file mode 100644 index 000000000..fee5a9cf3 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/boxBrush_n.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/brushAdjustHeight_d.PNG b/Templates/BaseGame/game/tools/worldEditor/images/brushAdjustHeight_d.PNG new file mode 100644 index 000000000..056bae49e Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/brushAdjustHeight_d.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/brushAdjustHeight_h.PNG b/Templates/BaseGame/game/tools/worldEditor/images/brushAdjustHeight_h.PNG new file mode 100644 index 000000000..8b8f181e2 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/brushAdjustHeight_h.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/brushAdjustHeight_n.png b/Templates/BaseGame/game/tools/worldEditor/images/brushAdjustHeight_n.png new file mode 100644 index 000000000..d0d03edb5 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/brushAdjustHeight_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/brushPaintNoise_d.png b/Templates/BaseGame/game/tools/worldEditor/images/brushPaintNoise_d.png new file mode 100644 index 000000000..66a10bc37 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/brushPaintNoise_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/brushPaintNoise_h.png b/Templates/BaseGame/game/tools/worldEditor/images/brushPaintNoise_h.png new file mode 100644 index 000000000..921e03bc7 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/brushPaintNoise_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/brushPaintNoise_n.png b/Templates/BaseGame/game/tools/worldEditor/images/brushPaintNoise_n.png new file mode 100644 index 000000000..7d14ea43d Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/brushPaintNoise_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/brushThermalErosion.png b/Templates/BaseGame/game/tools/worldEditor/images/brushThermalErosion.png new file mode 100644 index 000000000..339ad47e8 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/brushThermalErosion.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/brushThermalErosion_d.png b/Templates/BaseGame/game/tools/worldEditor/images/brushThermalErosion_d.png new file mode 100644 index 000000000..89aaea06c Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/brushThermalErosion_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/brushThermalErosion_h.png b/Templates/BaseGame/game/tools/worldEditor/images/brushThermalErosion_h.png new file mode 100644 index 000000000..8d3dc826e Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/brushThermalErosion_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/circleBrush_d.PNG b/Templates/BaseGame/game/tools/worldEditor/images/circleBrush_d.PNG new file mode 100644 index 000000000..1c4d37bf5 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/circleBrush_d.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/circleBrush_h.PNG b/Templates/BaseGame/game/tools/worldEditor/images/circleBrush_h.PNG new file mode 100644 index 000000000..cfea7736f Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/circleBrush_h.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/circleBrush_n.PNG b/Templates/BaseGame/game/tools/worldEditor/images/circleBrush_n.PNG new file mode 100644 index 000000000..82a47b748 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/circleBrush_n.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/clearEmpty_d.PNG b/Templates/BaseGame/game/tools/worldEditor/images/clearEmpty_d.PNG new file mode 100644 index 000000000..cdbe87769 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/clearEmpty_d.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/clearEmpty_h.PNG b/Templates/BaseGame/game/tools/worldEditor/images/clearEmpty_h.PNG new file mode 100644 index 000000000..9b24adf90 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/clearEmpty_h.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/clearEmpty_n.PNG b/Templates/BaseGame/game/tools/worldEditor/images/clearEmpty_n.PNG new file mode 100644 index 000000000..6aed6c702 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/clearEmpty_n.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/flattenHeight_d.PNG b/Templates/BaseGame/game/tools/worldEditor/images/flattenHeight_d.PNG new file mode 100644 index 000000000..963c1d320 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/flattenHeight_d.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/flattenHeight_h.PNG b/Templates/BaseGame/game/tools/worldEditor/images/flattenHeight_h.PNG new file mode 100644 index 000000000..c9ce739da Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/flattenHeight_h.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/flattenHeight_n.PNG b/Templates/BaseGame/game/tools/worldEditor/images/flattenHeight_n.PNG new file mode 100644 index 000000000..d8d1931ad Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/flattenHeight_n.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/lowerHeight_d.PNG b/Templates/BaseGame/game/tools/worldEditor/images/lowerHeight_d.PNG new file mode 100644 index 000000000..79d2384d7 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/lowerHeight_d.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/lowerHeight_h.PNG b/Templates/BaseGame/game/tools/worldEditor/images/lowerHeight_h.PNG new file mode 100644 index 000000000..07e3dd25a Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/lowerHeight_h.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/lowerHeight_n.PNG b/Templates/BaseGame/game/tools/worldEditor/images/lowerHeight_n.PNG new file mode 100644 index 000000000..048615dcf Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/lowerHeight_n.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/maskBrush_d.PNG b/Templates/BaseGame/game/tools/worldEditor/images/maskBrush_d.PNG new file mode 100644 index 000000000..007650c79 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/maskBrush_d.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/maskBrush_h.PNG b/Templates/BaseGame/game/tools/worldEditor/images/maskBrush_h.PNG new file mode 100644 index 000000000..a7764100a Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/maskBrush_h.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/maskBrush_n.PNG b/Templates/BaseGame/game/tools/worldEditor/images/maskBrush_n.PNG new file mode 100644 index 000000000..99bafbcb4 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/maskBrush_n.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/raiseHeight_d.PNG b/Templates/BaseGame/game/tools/worldEditor/images/raiseHeight_d.PNG new file mode 100644 index 000000000..870db9d38 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/raiseHeight_d.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/raiseHeight_h.PNG b/Templates/BaseGame/game/tools/worldEditor/images/raiseHeight_h.PNG new file mode 100644 index 000000000..6c95d4f7f Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/raiseHeight_h.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/raiseHeight_n.PNG b/Templates/BaseGame/game/tools/worldEditor/images/raiseHeight_n.PNG new file mode 100644 index 000000000..e110a5247 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/raiseHeight_n.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-mesh-road_d.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-mesh-road_d.png new file mode 100644 index 000000000..e97d7edc9 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-mesh-road_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-mesh-road_h.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-mesh-road_h.png new file mode 100644 index 000000000..1dc2a5663 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-mesh-road_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-mesh-road_n.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-mesh-road_n.png new file mode 100644 index 000000000..717e60356 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-mesh-road_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-point_d.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-point_d.png new file mode 100644 index 000000000..4d3dfa759 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-point_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-point_h.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-point_h.png new file mode 100644 index 000000000..fbdac0f6e Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-point_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-point_n.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-point_n.png new file mode 100644 index 000000000..6e6dff3d7 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-point_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-river_d.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-river_d.png new file mode 100644 index 000000000..112d5dba6 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-river_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-river_h.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-river_h.png new file mode 100644 index 000000000..7c0261f25 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-river_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-river_n.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-river_n.png new file mode 100644 index 000000000..a283365dc Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-river_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-road-path_d.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-road-path_d.png new file mode 100644 index 000000000..96ecb99f0 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-road-path_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-road-path_h.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-road-path_h.png new file mode 100644 index 000000000..0e7556879 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-road-path_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-road-path_n.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-road-path_n.png new file mode 100644 index 000000000..6cecf08e0 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/add-road-path_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-spline_d.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-spline_d.png new file mode 100644 index 000000000..87e93b120 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-spline_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-spline_h.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-spline_h.png new file mode 100644 index 000000000..80baf68ba Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-spline_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-spline_n.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-spline_n.png new file mode 100644 index 000000000..81a0180b9 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-spline_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-texture_d.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-texture_d.png new file mode 100644 index 000000000..03fee8c42 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-texture_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-texture_h.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-texture_h.png new file mode 100644 index 000000000..92bac44dc Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-texture_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-texture_n.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-texture_n.png new file mode 100644 index 000000000..31601728f Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-texture_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-wireframe_d.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-wireframe_d.png new file mode 100644 index 000000000..c32ca6b94 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-wireframe_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-wireframe_h.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-wireframe_h.png new file mode 100644 index 000000000..bd8e7acba Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-wireframe_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-wireframe_n.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-wireframe_n.png new file mode 100644 index 000000000..099a142a8 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/menubar/show-wireframe_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/move-point_d.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/move-point_d.png new file mode 100644 index 000000000..dc89c1d98 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/move-point_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/move-point_h.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/move-point_h.png new file mode 100644 index 000000000..f863eafc8 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/move-point_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/move-point_n.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/move-point_n.png new file mode 100644 index 000000000..f3cadb7a1 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/move-point_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/rotate-point_d.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/rotate-point_d.png new file mode 100644 index 000000000..18297741a Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/rotate-point_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/rotate-point_h.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/rotate-point_h.png new file mode 100644 index 000000000..5e17a9c46 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/rotate-point_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/rotate-point_n.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/rotate-point_n.png new file mode 100644 index 000000000..9cdb0b3df Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/rotate-point_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/scale-point_d.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/scale-point_d.png new file mode 100644 index 000000000..4700cd3b3 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/scale-point_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/scale-point_h.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/scale-point_h.png new file mode 100644 index 000000000..5ac38959f Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/scale-point_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/scale-point_n.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/scale-point_n.png new file mode 100644 index 000000000..1206e08cb Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/scale-point_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/subtract-point_d.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/subtract-point_d.png new file mode 100644 index 000000000..9f0c31b5c Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/subtract-point_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/subtract-point_h.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/subtract-point_h.png new file mode 100644 index 000000000..b3cfb6aac Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/subtract-point_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/road-river/subtract-point_n.png b/Templates/BaseGame/game/tools/worldEditor/images/road-river/subtract-point_n.png new file mode 100644 index 000000000..3180edba4 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/road-river/subtract-point_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/setEmpty_d.PNG b/Templates/BaseGame/game/tools/worldEditor/images/setEmpty_d.PNG new file mode 100644 index 000000000..9a3194b24 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/setEmpty_d.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/setEmpty_h.PNG b/Templates/BaseGame/game/tools/worldEditor/images/setEmpty_h.PNG new file mode 100644 index 000000000..87118eea7 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/setEmpty_h.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/setEmpty_n.PNG b/Templates/BaseGame/game/tools/worldEditor/images/setEmpty_n.PNG new file mode 100644 index 000000000..7f1d4df67 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/setEmpty_n.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/setHeight_d.PNG b/Templates/BaseGame/game/tools/worldEditor/images/setHeight_d.PNG new file mode 100644 index 000000000..1422857fa Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/setHeight_d.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/setHeight_h.PNG b/Templates/BaseGame/game/tools/worldEditor/images/setHeight_h.PNG new file mode 100644 index 000000000..448612785 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/setHeight_h.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/setHeight_n.PNG b/Templates/BaseGame/game/tools/worldEditor/images/setHeight_n.PNG new file mode 100644 index 000000000..83196ea6e Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/setHeight_n.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/smoothHeight_d.PNG b/Templates/BaseGame/game/tools/worldEditor/images/smoothHeight_d.PNG new file mode 100644 index 000000000..05678ed31 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/smoothHeight_d.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/smoothHeight_h.PNG b/Templates/BaseGame/game/tools/worldEditor/images/smoothHeight_h.PNG new file mode 100644 index 000000000..bd5f71ec3 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/smoothHeight_h.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/smoothHeight_n.PNG b/Templates/BaseGame/game/tools/worldEditor/images/smoothHeight_n.PNG new file mode 100644 index 000000000..1bec2d18d Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/smoothHeight_n.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/softCurve_d.PNG b/Templates/BaseGame/game/tools/worldEditor/images/softCurve_d.PNG new file mode 100644 index 000000000..89679ff79 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/softCurve_d.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/softCurve_h.PNG b/Templates/BaseGame/game/tools/worldEditor/images/softCurve_h.PNG new file mode 100644 index 000000000..c04786d96 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/softCurve_h.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/softCurve_n.PNG b/Templates/BaseGame/game/tools/worldEditor/images/softCurve_n.PNG new file mode 100644 index 000000000..a1cf84d6a Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/softCurve_n.PNG differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/new_layer_icon.png b/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/new_layer_icon.png new file mode 100644 index 000000000..3589b8d20 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/new_layer_icon.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-large.png b/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-large.png new file mode 100644 index 000000000..84bc9be6b Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-large.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-new_h.png b/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-new_h.png new file mode 100644 index 000000000..a650fe2d9 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-new_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-new_n.png b/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-new_n.png new file mode 100644 index 000000000..ef1fa85c9 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border-new_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_d.png b/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_d.png new file mode 100644 index 000000000..edb9b29cc Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_h.png b/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_h.png new file mode 100644 index 000000000..cbe39f4da Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_n.png b/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_n.png new file mode 100644 index 000000000..f80943fb2 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/terrainpainter/terrain-painter-border_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/3rd-person-camera_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/3rd-person-camera_d.png new file mode 100644 index 000000000..c63ab98cf Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/3rd-person-camera_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/3rd-person-camera_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/3rd-person-camera_h.png new file mode 100644 index 000000000..def996838 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/3rd-person-camera_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/3rd-person-camera_n.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/3rd-person-camera_n.png new file mode 100644 index 000000000..e45cc4244 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/3rd-person-camera_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/camera_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/camera_d.png new file mode 100644 index 000000000..6500b92c5 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/camera_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/camera_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/camera_h.png new file mode 100644 index 000000000..0451a0e9c Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/camera_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/camera_n.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/camera_n.png new file mode 100644 index 000000000..516c0c00e Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/camera_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/datablock-editor_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/datablock-editor_d.png new file mode 100644 index 000000000..8911e14d7 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/datablock-editor_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/datablock-editor_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/datablock-editor_h.png new file mode 100644 index 000000000..cd2cfec3d Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/datablock-editor_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/datablock-editor_n.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/datablock-editor_n.png new file mode 100644 index 000000000..44d08018a Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/datablock-editor_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/gui.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/gui.png new file mode 100644 index 000000000..9971dc150 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/gui.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/gui_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/gui_d.png new file mode 100644 index 000000000..376b3f9d0 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/gui_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/gui_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/gui_h.png new file mode 100644 index 000000000..96e58de3f Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/gui_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/matterial-editor_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/matterial-editor_d.png new file mode 100644 index 000000000..e850a5873 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/matterial-editor_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/matterial-editor_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/matterial-editor_h.png new file mode 100644 index 000000000..93df1f2ac Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/matterial-editor_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/matterial-editor_n.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/matterial-editor_n.png new file mode 100644 index 000000000..326589e1f Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/matterial-editor_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/mesh-road-editor_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/mesh-road-editor_d.png new file mode 100644 index 000000000..125308927 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/mesh-road-editor_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/mesh-road-editor_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/mesh-road-editor_h.png new file mode 100644 index 000000000..45eabc320 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/mesh-road-editor_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/mesh-road-editor_n.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/mesh-road-editor_n.png new file mode 100644 index 000000000..1cb88dc8e Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/mesh-road-editor_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/missionarea-editor_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/missionarea-editor_d.png new file mode 100644 index 000000000..72457d069 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/missionarea-editor_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/missionarea-editor_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/missionarea-editor_h.png new file mode 100644 index 000000000..7bff1444f Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/missionarea-editor_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/missionarea-editor_n.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/missionarea-editor_n.png new file mode 100644 index 000000000..6a8533f5a Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/missionarea-editor_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/paint-terrain_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/paint-terrain_d.png new file mode 100644 index 000000000..144099429 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/paint-terrain_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/paint-terrain_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/paint-terrain_h.png new file mode 100644 index 000000000..9ca94ff58 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/paint-terrain_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/paint-terrain_n.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/paint-terrain_n.png new file mode 100644 index 000000000..b2d156044 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/paint-terrain_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/particleeditor_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/particleeditor_d.png new file mode 100644 index 000000000..9867911ed Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/particleeditor_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/particleeditor_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/particleeditor_h.png new file mode 100644 index 000000000..e7fd0b0fc Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/particleeditor_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/particleeditor_n.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/particleeditor_n.png new file mode 100644 index 000000000..d8c6266af Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/particleeditor_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/playbutton_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/playbutton_d.png new file mode 100644 index 000000000..08b3b8641 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/playbutton_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/playbutton_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/playbutton_h.png new file mode 100644 index 000000000..2059a23fb Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/playbutton_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/playbutton_n.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/playbutton_n.png new file mode 100644 index 000000000..24840940b Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/playbutton_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/player_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/player_d.png new file mode 100644 index 000000000..ad03e6c93 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/player_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/player_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/player_h.png new file mode 100644 index 000000000..fae070bdf Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/player_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/player_n.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/player_n.png new file mode 100644 index 000000000..15e7e5504 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/player_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/river-editor_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/river-editor_d.png new file mode 100644 index 000000000..1e9abf699 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/river-editor_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/river-editor_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/river-editor_h.png new file mode 100644 index 000000000..2d57d4a10 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/river-editor_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/river-editor_n.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/river-editor_n.png new file mode 100644 index 000000000..e7cb27a09 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/river-editor_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/road-path-editor_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/road-path-editor_d.png new file mode 100644 index 000000000..a0e961fc9 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/road-path-editor_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/road-path-editor_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/road-path-editor_h.png new file mode 100644 index 000000000..25b47ae25 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/road-path-editor_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/road-path-editor_n.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/road-path-editor_n.png new file mode 100644 index 000000000..9435692d9 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/road-path-editor_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/sculpt-terrain_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/sculpt-terrain_d.png new file mode 100644 index 000000000..72457d069 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/sculpt-terrain_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/sculpt-terrain_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/sculpt-terrain_h.png new file mode 100644 index 000000000..7bff1444f Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/sculpt-terrain_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/sculpt-terrain_n.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/sculpt-terrain_n.png new file mode 100644 index 000000000..6a8533f5a Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/sculpt-terrain_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/shape-editor_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/shape-editor_d.png new file mode 100644 index 000000000..5e1bfff7f Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/shape-editor_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/shape-editor_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/shape-editor_h.png new file mode 100644 index 000000000..c512a6ae4 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/shape-editor_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/shape-editor_n.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/shape-editor_n.png new file mode 100644 index 000000000..e583f2549 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/shape-editor_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/transform-objects_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/transform-objects_d.png new file mode 100644 index 000000000..5ee2faf47 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/transform-objects_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/transform-objects_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/transform-objects_h.png new file mode 100644 index 000000000..68c21d9e4 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/transform-objects_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/transform-objects_n.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/transform-objects_n.png new file mode 100644 index 000000000..51f81427f Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/transform-objects_n.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/world.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/world.png new file mode 100644 index 000000000..e08a1b89d Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/world.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/world_d.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/world_d.png new file mode 100644 index 000000000..da4cb5856 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/world_d.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/images/toolbar/world_h.png b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/world_h.png new file mode 100644 index 000000000..9f68f1bc0 Binary files /dev/null and b/Templates/BaseGame/game/tools/worldEditor/images/toolbar/world_h.png differ diff --git a/Templates/BaseGame/game/tools/worldEditor/main.cs b/Templates/BaseGame/game/tools/worldEditor/main.cs new file mode 100644 index 000000000..82b83701a --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/main.cs @@ -0,0 +1,136 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function initializeWorldEditor() +{ + echo(" % - Initializing World Editor"); + + // Load GUI + exec("./gui/profiles.ed.cs"); + exec("./scripts/cursors.ed.cs"); + + exec("./gui/guiCreateNewTerrainGui.gui" ); + exec("./gui/GenericPromptDialog.ed.gui" ); + exec("./gui/guiTerrainImportGui.gui" ); + exec("./gui/guiTerrainExportGui.gui" ); + exec("./gui/EditorGui.ed.gui"); + exec("./gui/objectBuilderGui.ed.gui"); + exec("./gui/TerrainEditorVSettingsGui.ed.gui"); + exec("./gui/EditorChooseLevelGui.ed.gui"); + exec("./gui/VisibilityLayerWindow.ed.gui"); + exec("./gui/ManageBookmarksWindow.ed.gui"); + exec("./gui/ManageSFXParametersWindow.ed.gui" ); + exec("./gui/TimeAdjustGui.ed.gui"); + exec("./gui/AddFMODProjectDlg.ed.gui"); + exec("./gui/SelectObjectsWindow.ed.gui"); + exec("./gui/ProceduralTerrainPainterGui.gui" ); + + // Load Scripts. + exec("./scripts/menus.ed.cs"); + exec("./scripts/menuHandlers.ed.cs"); + exec("./scripts/editor.ed.cs"); + exec("./scripts/editor.bind.ed.cs"); + exec("./scripts/undoManager.ed.cs"); + exec("./scripts/lighting.ed.cs"); + exec("./scripts/EditorGui.ed.cs"); + exec("./scripts/editorPrefs.ed.cs"); + exec("./scripts/editorRender.ed.cs"); + exec("./scripts/editorPlugin.ed.cs"); + exec("./scripts/EditorChooseLevelGui.ed.cs"); + exec("./scripts/visibilityLayer.ed.cs"); + exec("./scripts/cameraBookmarks.ed.cs"); + exec("./scripts/ManageSFXParametersWindow.ed.cs"); + exec("./scripts/AddFMODProjectDlg.ed.cs"); + exec("./scripts/SelectObjectsWindow.ed.cs"); + exec("./scripts/cameraCommands.ed.cs"); + + // Load Custom Editors + loadDirectory(expandFilename("./scripts/editors")); + loadDirectory(expandFilename("./scripts/interfaces")); + + // Create the default editor plugins before calling buildMenus. + + new ScriptObject( WorldEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = EWorldEditor; + }; + + // aka. The ObjectEditor. + new ScriptObject( WorldEditorInspectorPlugin ) + { + superClass = "WorldEditorPlugin"; + editorGui = EWorldEditor; + }; + + new ScriptObject( TerrainEditorPlugin ) + { + superClass = "EditorPlugin"; + editorGui = ETerrainEditor; + }; + + new ScriptObject( TerrainPainterPlugin ) + { + superClass = "EditorPlugin"; + editorGui = ETerrainEditor; + }; + + new ScriptObject( MaterialEditorPlugin ) + { + superClass = "WorldEditorPlugin"; + editorGui = EWorldEditor; + }; + + // Expose stock visibility/debug options. + EVisibility.addOption( "Render: Zones", "$Zone::isRenderable", "" ); + EVisibility.addOption( "Render: Portals", "$Portal::isRenderable", "" ); + EVisibility.addOption( "Render: Occlusion Volumes", "$OcclusionVolume::isRenderable", "" ); + EVisibility.addOption( "Render: Triggers", "$Trigger::renderTriggers", "" ); + EVisibility.addOption( "Render: PhysicalZones", "$PhysicalZone::renderZones", "" ); + EVisibility.addOption( "Render: Sound Emitters", "$SFXEmitter::renderEmitters", "" ); + EVisibility.addOption( "Render: Mission Area", "EWorldEditor.renderMissionArea", "" ); + EVisibility.addOption( "Render: Sound Spaces", "$SFXSpace::isRenderable", "" ); + EVisibility.addOption( "Wireframe Mode", "$gfx::wireframe", "" ); + EVisibility.addOption( "Debug Render: Player Collision", "$Player::renderCollision", "" ); + EVisibility.addOption( "Debug Render: Terrain", "TerrainBlock::debugRender", "" ); + EVisibility.addOption( "Debug Render: Decals", "$Decals::debugRender", "" ); + EVisibility.addOption( "Debug Render: Light Frustums", "$Light::renderLightFrustums", "" ); + EVisibility.addOption( "Debug Render: Bounding Boxes", "$Scene::renderBoundingBoxes", "" ); + EVisibility.addOption( "Debug Render: Physics World", "$PhysicsWorld::render", "togglePhysicsDebugViz" ); + EVisibility.addOption( "AL: Disable Shadows", "$Shadows::disable", "" ); + EVisibility.addOption( "AL: Light Color Viz", "$AL_LightColorVisualizeVar", "toggleLightColorViz" ); + EVisibility.addOption( "AL: Light Specular Viz", "$AL_LightSpecularVisualizeVar", "toggleLightSpecularViz" ); + EVisibility.addOption( "AL: Normals Viz", "$AL_NormalsVisualizeVar", "toggleNormalsViz" ); + EVisibility.addOption( "AL: Depth Viz", "$AL_DepthVisualizeVar", "toggleDepthViz" ); + EVisibility.addOption( "AL: Color Buffer", "$AL_ColorBufferShaderVar", "toggleColorBufferViz" ); + EVisibility.addOption( "AL: Spec Map", "$AL_SpecMapShaderVar", "toggleSpecMapViz"); + EVisibility.addOption( "AL: Backbuffer", "$AL_BackbufferVisualizeVar", "toggleBackbufferViz" ); + EVisibility.addOption( "AL: Glow Buffer", "$AL_GlowVisualizeVar", "toggleGlowViz" ); + EVisibility.addOption( "AL: PSSM Cascade Viz", "$AL::PSSMDebugRender", "" ); + EVisibility.addOption( "Frustum Lock", "$Scene::lockCull", "" ); + EVisibility.addOption( "Disable Zone Culling", "$Scene::disableZoneCulling", "" ); + EVisibility.addOption( "Disable Terrain Occlusion", "$Scene::disableTerrainOcclusion", "" ); +} + +function destroyWorldEditor() +{ +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/AddFMODProjectDlg.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/AddFMODProjectDlg.ed.cs new file mode 100644 index 000000000..a005ab4b3 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/AddFMODProjectDlg.ed.cs @@ -0,0 +1,253 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + + +//============================================================================= +// AddFMODProjectDlg. +//============================================================================= + +//----------------------------------------------------------------------------- + +function AddFMODProjectDlg::show( %this ) +{ + if( $platform $= "macos" ) + { + %fmodex = "libfmodex.dylib"; + %fmodevent = "libfmodevent.dylib"; + } + else + { + %fmodex = "fmodex.dll"; + %fmodevent = "fmod_event.dll"; + } + + // Make sure we have FMOD running. + + if( getField( sfxGetDeviceInfo(), $SFX::DEVICE_INFO_PROVIDER ) !$= "FMOD" ) + { + MessageBoxOK( "Error", + "You do not currently have FMOD selected as your sound system." NL + "" NL + "To install FMOD, place the FMOD DLLs (" @ %fmodex @ " and " @ %fmodevent @ ")" SPC + "in your game/ folder alongside your game executable" SPC + "and restart Torque." NL + "" NL + "To select FMOD as your sound system, choose it as the sound provider in" SPC + "the audio tab of the Game Options dialog." + ); + + return; + } + + // Make sure we have the FMOD Event DLL loaded. + + %deviceCaps = getField( sfxGetDeviceInfo(), $SFX::DEVICE_INFO_CAPS ); + if( !( %deviceCaps & $SFX::DEVICE_CAPS_FMODDESIGNER ) ) + { + MessageBoxOK( "Error", + "You do not have the requisite FMOD Event DLL in place." NL + "" NL + "Please copy " @ %fmodevent @ " into your game/ folder and restart Torque." + ); + return; + } + + // Show it. + + Canvas.pushDialog( %this, 0, true ); +} + +//----------------------------------------------------------------------------- + +function AddFMODProjectDlg::onWake( %this ) +{ + %this.persistenceMgr = new PersistenceManager(); +} + +//----------------------------------------------------------------------------- + +function AddFMODProjectDlg::onSleep( %this ) +{ + %this.persistenceMgr.delete(); +} + +//----------------------------------------------------------------------------- + +function AddFMODProjectDlg::onCancel( %this ) +{ + Canvas.popDialog( %this ); +} + +//----------------------------------------------------------------------------- + +function AddFMODProjectDlg::onOK( %this ) +{ + %objName = %this-->projectNameField.getText(); + %fileName = %this-->fileNameField.getText(); + %mediaPath = %this-->mediaPathField.getText(); + + // Make sure the object name is valid. + if( !Editor::validateObjectName( %objName, true )) + return; + + // Make sure the .fev file exists. + + if( %fileName $= "" ) + { + MessageBoxOK( "Error", + "Please enter a project file name." + ); + return; + } + if( !isFile( %fileName ) ) + { + MessageBoxOK( "Error", + "'" @ %fileName @ "' is not a valid file." + ); + return; + } + + // Make sure the media path exists. + + if( !isDirectory( %mediaPath ) ) + { + MessageBoxOK( "Error", + "'" @ %mediaPath @ "' is not a valid directory." + ); + return; + } + + // If an event script exists from a previous instantiation, + // delete it first. + + %eventFileName = %fileName @ ".cs"; + if( isFile( %eventFileName ) ) + fileDelete( %eventFileName ); + + // Create the FMOD project object. + + pushInstantGroup(); + eval( "new SFXFMODProject( " @ %objName @ ") {" NL + "fileName = \"" @ %fileName @ "\";" NL + "mediaPath = \"" @ %mediaPath @ "\";" NL + "};" ); + popInstantGroup(); + + if( !isObject( %objName ) ) + { + MessageBoxOK( "Error", + "Failed to create the object. Please take a look at the log for details." + ); + return; + } + else + { + // Save the object. + + %objName.setFileName( "scripts/client/audioData.cs" ); + %this.persistenceMgr.setDirty( %objName ); + %this.persistenceMgr.saveDirty(); + } + + Canvas.popDialog( %this ); + + // Trigger a reinit on the datablock editor, just in case. + + if( isObject( DatablockEditorPlugin ) ) + DatablockEditorPlugin.populateTrees(); +} + +//----------------------------------------------------------------------------- + +function AddFMODProjectDlg::onSelectFile( %this ) +{ + if( $pref::WorldEditor::AddFMODProjectDlg::lastPath $= "" ) + $pref::WorldEditor::AddFMODProjectDlg::lastPath = getMainDotCsDir(); + + %dlg = new OpenFileDialog() + { + Title = "Select Compiled FMOD Designer Event File..."; + Filters = "Compiled Event Files (*.fev)|*.fev|All Files (*.*)|*.*|"; + DefaultPath = $pref::WorldEditor::AddFMODProjectDlg::lastPath; + DefaultFile = fileName( %this-->fileNameField.getText() ); + MustExit = true; + ChangePath = false; + }; + + %ret = %dlg.execute(); + if( %ret ) + { + %file = %dlg.fileName; + $pref::WorldEditor::AddFMODProjectDlg::lastPath = filePath( %file ); + } + + %dlg.delete(); + + if( !%ret ) + return; + + %file = makeRelativePath( %file, getMainDotCsDir() ); + %this-->fileNameField.setText( %file ); + + if( %this-->projectNameField.getText() $= "" ) + { + %projectName = "fmod" @ fileBase( %file ); + if( isValidObjectName( %projectName ) ) + %this-->projectNameField.setText( %projectName ); + } +} + +//----------------------------------------------------------------------------- + +function AddFMODProjectDlg::onSelectMediaPath( %this ) +{ + %defaultPath = %this-->mediaPathField.getText(); + if( %defaultPath $= "" ) + { + %defaultPath = filePath( %this-->fileNameField.getText() ); + if( %defaultPath $= "" ) + %defaultPath = getMainDotCsDir(); + else + %defaultPath = makeFullPath( %defaultPath ); + } + + %dlg = new OpenFolderDialog() + { + Title = "Select Media Path..."; + DefaultPath = %defaultPath; + MustExit = true; + ChangePath = false; + }; + + %ret = %dlg.execute(); + if( %ret ) + %file = %dlg.fileName; + + %dlg.delete(); + + if( !%ret ) + return; + + %file = makeRelativePath( %file, getMainDotCsDir() ); + %this-->mediaPathField.setText( %file ); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorChooseLevelGui.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorChooseLevelGui.ed.cs new file mode 100644 index 000000000..01c6d9fbe --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorChooseLevelGui.ed.cs @@ -0,0 +1,155 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function EditorChooseLevelGui::onWake() +{ + // first check if we have a level file to load, then we'll bypass this + if ($levelToLoad !$= "") + { + // First try using the file path raw... it may already be good. + %file = findFirstFile( $levelToLoad ); + if ( %file $= "" ) + { + %levelFile = "levels/"; + %ext = getSubStr($levelToLoad, strlen($levelToLoad) - 3, 3); + if(%ext !$= "mis") + %levelFile = %levelFile @ $levelToLoad @ ".mis"; + else + %levelFile = %levelFile @ $levelToLoad; + + // let's make sure the file exists + %file = findFirstFile(%levelFile); + } + + // Clear out the $levelToLoad so we don't attempt to load the level again + // later on. + $levelToLoad = ""; + + if(%file !$= "") + { + WE_EditLevel(%file); + return; + } + } + + //If no valid name, then push the level chooser + Canvas.pushDialog(EditorChooseLevelContainer); +} + +function EditorChooseLevelContainer::onWake(%this) +{ + // Build the text lists + WE_LevelList.clear(); + WE_TemplateList.clear(); + + %leveltext = "<linkcolor:0000FF><linkcolorhl:FF0000>"; + %templatetext = "<linkcolor:0000FF><linkcolorhl:FF0000>"; + for(%file = findFirstFile($Server::MissionFileSpec); %file !$= ""; %file = findNextFile($Server::MissionFileSpec)) + { + %name = getLevelDisplayName(%file); + %n = strlwr(%name); + if(strstr(%n, "template") == -1) + { + %leveltext = %leveltext @ "<a:gamelink:" @ %file @ ">" @ %name @ "</a><br>"; + } + else + { + %templatetext = %templatetext @ "<a:gamelink:" @ %file @ ">" @ %name @ "</a><br>"; + } + } + + WE_LevelList.setText(%leveltext); + WE_LevelList.forceReflow(); + WE_LevelList.scrollToTop(); + + WE_TemplateList.setText(%templatetext); + WE_TemplateList.forceReflow(); + WE_TemplateList.scrollToTop(); +} + +function WE_EditLevel(%levelFile) +{ + EditorOpenMission( %levelFile ); +} + +function WE_ReturnToMainMenu() +{ + loadMainMenu(); +} + +function WE_LevelList::onURL(%this, %url) +{ + // Remove 'gamelink:' from front + %levelFile = getSubStr(%url, 9, 1024); + WE_EditLevel(%levelFile); +} + +function WE_TemplateList::onURL(%this, %url) +{ + // Remove 'gamelink:' from front + %levelFile = getSubStr(%url, 9, 1024); + WE_EditLevel(%levelFile); + EditorGui.saveAs = true; +} + +function getLevelDisplayName( %levelFile ) +{ + %file = new FileObject(); + + %MissionInfoObject = ""; + + if ( %file.openForRead( %levelFile ) ) { + %inInfoBlock = false; + + while ( !%file.isEOF() ) { + %line = %file.readLine(); + %line = trim( %line ); + + if( %line $= "new ScriptObject(MissionInfo) {" ) + %inInfoBlock = true; + else if( %line $= "new LevelInfo(theLevelInfo) {" ) + %inInfoBlock = true; + else if( %inInfoBlock && %line $= "};" ) { + %inInfoBlock = false; + %MissionInfoObject = %MissionInfoObject @ %line; + break; + } + + if( %inInfoBlock ) + %MissionInfoObject = %MissionInfoObject @ %line @ " "; + } + + %file.close(); + } + %MissionInfoObject = "%MissionInfoObject = " @ %MissionInfoObject; + eval( %MissionInfoObject ); + + %file.delete(); + if( %MissionInfoObject.levelName !$= "" ) + %name = %MissionInfoObject.levelName; + else + %name = fileBase(%levelFile); + + %MissionInfoObject.delete(); + + return %name; +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs new file mode 100644 index 000000000..31f794d17 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs @@ -0,0 +1,2825 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function EditorGui::init(%this) +{ + EWorldEditor.isDirty = false; + ETerrainEditor.isDirty = false; + ETerrainEditor.isMissionDirty = false; + + if( %this.isInitialized ) + return; + + %this.readWorldEditorSettings(); + + $SelectedOperation = -1; + $NextOperationId = 1; + $HeightfieldDirtyRow = -1; + + if( !isObject( %this-->ToolsPaletteWindow ) ) + { + // Load Creator/Inspector GUI + exec("~/worldEditor/gui/ToolsPaletteGroups/init.cs"); + exec("~/worldEditor/gui/ToolsPaletteWindow.ed.gui"); + + if( isObject( EWToolsPaletteWindow ) ) + { + %this.add( EWToolsPaletteWindow ); + EWToolsPaletteWindow.init(); + EWToolsPaletteWindow.setVisible( false ); + } + } + + if( !isObject( %this-->TreeWindow ) ) + { + // Load Creator/Inspector GUI + exec("~/worldEditor/gui/WorldEditorTreeWindow.ed.gui"); + if( isObject( EWTreeWindow ) ) + { + %this.add( EWTreeWindow ); + EWTreeWindow-->EditorTree.selectPage( 0 ); + EWTreeWindow.setVisible( false ); + } + } + + if( !isObject( %this-->InspectorWindow ) ) + { + // Load Creator/Inspector GUI + exec("~/worldEditor/gui/WorldEditorInspectorWindow.ed.gui"); + //EWInspectorWindow.resize(getWord(EWInspectorWindow.Position, 0), getWord(EWInspectorWindow.Position, 1), getWord(EWInspectorWindow.extent, 0), getWord(EWInspectorWindow.extent, 1)); + if( isObject( EWInspectorWindow ) ) + { + %this.add( EWInspectorWindow ); + EWInspectorWindow.setVisible( false ); + } + } + + if( !isObject( %this-->WorldEditorToolbar ) ) + { + // Load Creator/Inspector GUI + exec("~/worldEditor/gui/WorldEditorToolbar.ed.gui"); + if( isObject( EWorldEditorToolbar ) ) + { + %this.add( EWorldEditorToolbar ); + EWorldEditorToolbar.setVisible( false ); + } + } + + if ( !isObject( %this-->TerrainEditToolbar ) ) + { + // Load Terrain Edit GUI + exec("~/worldEditor/gui/TerrainEditToolbar.ed.gui"); + if( isObject( EWTerrainEditToolbar ) ) + { + %this.add( EWTerrainEditToolbar ); + EWTerrainEditToolbar.setVisible( false ); + } + } + + if( !isObject( %this-->TerrainPainter ) ) + { + // Load Terrain Painter GUI + exec("~/worldEditor/gui/TerrainPainterWindow.ed.gui"); + if( isObject( %guiContent ) ){ + %this.add( %guiContent->TerrainPainter ); + %this.add( %guiContent->TerrainPainterPreview ); + } + + exec("~/worldEditor/gui/guiTerrainMaterialDlg.ed.gui"); + exec("~/worldEditor/gui/TerrainBrushSoftnessCurveDlg.ed.gui"); + } + if ( !isObject( %this-->TerrainPainterToolbar) ) + { + // Load Terrain Edit GUI + exec("~/worldEditor/gui/TerrainPainterToolbar.ed.gui"); + if( isObject( EWTerrainPainterToolbar ) ) + { + %this.add( EWTerrainPainterToolbar ); + EWTerrainPainterToolbar.setVisible( false ); + } + } + + if( !isObject( %this-->ToolsToolbar ) ) + { + // Load Creator/Inspector GUI + exec("~/worldEditor/gui/ToolsToolbar.ed.gui"); + if( isObject( EWToolsToolbar ) ) + { + %this.add( EWToolsToolbar ); + EWToolsToolbar.setVisible( true ); + + } + } + + // Visibility Layer Window + if( !isObject( %this-->VisibilityLayerWindow ) ) + { + %this.add( EVisibility ); + EVisibility.setVisible(false); + EVisibilityTabBook.selectPage(0); + } + + // Editor Settings Window + if( !isObject( %this-->EditorSettingsWindow ) ) + { + exec("~/worldEditor/gui/EditorSettingsWindow.ed.gui"); + exec("~/worldEditor/scripts/editorSettingsWindow.ed.cs"); + %this.add( ESettingsWindow ); + ESettingsWindow.setVisible(false); + + // Start the standard settings tabs pages + exec( "~/worldEditor/gui/GeneralSettingsTab.ed.gui" ); + ESettingsWindow.addTabPage( EGeneralSettingsPage ); + exec("~/worldEditor/gui/ObjectEditorSettingsTab.ed.gui"); + ESettingsWindow.addTabPage( EObjectEditorSettingsPage ); + exec("~/worldEditor/gui/AxisGizmoSettingsTab.ed.gui"); + ESettingsWindow.addTabPage( EAxisGizmoSettingsPage ); + exec("~/worldEditor/gui/TerrainEditorSettingsTab.ed.gui"); + ESettingsWindow.addTabPage( ETerrainEditorSettingsPage ); + exec("~/worldEditor/gui/CameraSettingsTab.ed.gui"); + ESettingsWindow.addTabPage( ECameraSettingsPage ); + } + + // Object Snap Options Window + if( !isObject( %this-->SnapOptionsWindow ) ) + { + exec("~/worldEditor/gui/ObjectSnapOptionsWindow.ed.gui"); + exec("~/worldEditor/scripts/objectSnapOptions.ed.cs"); + %this.add( ESnapOptions ); + ESnapOptions.setVisible(false); + ESnapOptionsTabBook.selectPage(0); + } + + // Transform Selection Window + if( !isObject( %this-->TransformSelectionWindow ) ) + { + exec("~/worldEditor/gui/TransformSelectionWindow.ed.gui"); + exec("~/worldEditor/scripts/transformSelection.ed.cs"); + %this.add( ETransformSelection ); + ETransformSelection.setVisible(false); + } + + // Manage Bookmarks Window + if( !isObject( %this-->ManageBookmarksWindow ) ) + { + %this.add( EManageBookmarks ); + EManageBookmarks.setVisible(false); + } + + // Manage SFXParameters Window + if( !isObject( %this-->ManageSFXParametersWindow ) ) + { + %this.add( EManageSFXParameters ); + EManageSFXParameters.setVisible( false ); + } + + // Select Objects Window + if( !isObject( %this->SelectObjectsWindow ) ) + { + %this.add( ESelectObjectsWindow ); + ESelectObjectsWindow.setVisible( false ); + } + + EWorldEditor.init(); + ETerrainEditor.init(); + + //Creator.init(); + EWCreatorWindow.init(); + ObjectBuilderGui.init(); + + %this.setMenuDefaultState(); + + EWorldEditorToggleCamera.setBitmap("tools/worldEditor/images/toolbar/player"); + + /* + EWorldEditorCameraSpeed.clear(); + EWorldEditorCameraSpeed.add("Slowest - Camera 1",0); + EWorldEditorCameraSpeed.add("Slow - Camera 2",1); + EWorldEditorCameraSpeed.add("Slower - Camera 3",2); + EWorldEditorCameraSpeed.add("Normal - Camera 4",3); + EWorldEditorCameraSpeed.add("Faster - Camera 5",4); + EWorldEditorCameraSpeed.add("Fast - Camera 6",5); + EWorldEditorCameraSpeed.add("Fastest - Camera 7",6); + EWorldEditorCameraSpeed.setSelected(3); + */ + + EWorldEditorAlignPopup.clear(); + EWorldEditorAlignPopup.add("World",0); + EWorldEditorAlignPopup.add("Object",1); + EWorldEditorAlignPopup.setSelected(0); + + + // sync camera gui + EditorGui.syncCameraGui(); + + // this will brind CameraTypesDropdown to front so that it goes over the menubar + EditorGui.pushToBack(CameraTypesDropdown); + EditorGui.pushToBack(VisibilityDropdown); + + // dropdowns out so that they display correctly in editor gui + objectTransformDropdown.parentGroup = editorGui; + objectCenterDropdown.parentGroup = editorGui; + objectSnapDropdown.parentGroup = editorGui; + + // make sure to show the default world editor guis + EditorGui.bringToFront( EWorldEditor ); + EWorldEditor.setVisible( false ); + + // Call the startup callback on the editor plugins. + for ( %i = 0; %i < EditorPluginSet.getCount(); %i++ ) + { + %obj = EditorPluginSet.getObject( %i ); + %obj.onWorldEditorStartup(); + } + + // With everything loaded, start up the settings window + ESettingsWindow.startup(); + + // Start up initial editor plugin. + + %initialEditor = %this.currentEditor; // Read from prefs. + %this.currentEditor = ""; + + if( %initialEditor $= "" ) + %initialEditor = "WorldEditorInspectorPlugin"; + %this.setEditor( %initialEditor, true, true ); + + // Done. + + %this.isInitialized = true; +} + +//------------------------------------------------------------------------------ +// Editor Gui's interactions with Camera Settings + +function EditorGui::setupDefaultCameraSettings( %this ) +{ + EditorSettings.beginGroup( "LevelInformation/levels/" @ %this.levelName ); + + EditorSettings.setDefaultValue( "cameraSpeedMin", "5" ); + EditorSettings.setDefaultValue( "cameraSpeedMax", "200" ); + + EditorSettings.endGroup(); +} + +function EditorGui::readCameraSettings( %this, %levelName ) +{ + if( %levelName !$= %this.levelName ) + return; + + EditorCameraSpeedOptions.setupGuiControls(); +} + +function EditorGui::writeCameraSettings( %this ) +{ + EditorSettings.beginGroup( "LevelInformation/levels/" @ %this.levelName ); + + EditorSettings.setValue( "cameraSpeed", $Camera::movementSpeed ); + + EditorSettings.endGroup(); +} + +//------------------------------------------------------------------------------ + +function EditorGui::shutdown( %this ) +{ + // Store settings. + %this.writeWorldEditorSettings(); + + // Deactivate current editor. + %this.setEditor( "" ); + + // Call the shutdown callback on the editor plugins. + foreach( %plugin in EditorPluginSet ) + %plugin.onWorldEditorShutdown(); +} + +/// This is used to add an editor to the Editors menu which +/// will take over the default world editor window. +function EditorGui::addToEditorsMenu( %this, %displayName, %accel, %newPlugin ) +{ + %windowMenu = %this.findMenu( "Editors" ); + %count = %windowMenu.getItemCount(); + + + %alreadyExists = false; + for ( %i = 0; %i < %count; %i++ ) + { + %existingPlugins = getField(%windowMenu.Item[%i], 2); + + if(%newPlugin $= %existingPlugins) + %alreadyExists = true; + } + + if( %accel $= "" && %count < 9 ) + %accel = "F" @ %count + 1; + else + %accel = ""; + + if(!%alreadyExists) + %windowMenu.addItem( %count, %displayName TAB %accel TAB %newPlugin ); + + return %accel; +} + +function EditorGui::addToToolsToolbar( %this, %pluginName, %internalName, %bitmap, %tooltip ) +{ + %count = ToolsToolbarArray.getCount(); + + %alreadyExists = false; + for ( %i = 0; %i < %count; %i++ ) + { + %existingInternalName = ToolsToolbarArray.getObject(%i).getFieldValue("internalName"); + + if(%internalName $= %existingInternalName) + { + %alreadyExists = true; + break; + } + } + + if(!%alreadyExists) + { + %button = new GuiBitmapButtonCtrl() { + canSaveDynamicFields = "0"; + internalName = %internalName; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "180 0"; + Extent = "25 19"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "EditorGui.setEditor(" @ %pluginName @ ");"; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = %tooltip; + hovertime = "750"; + bitmap = %bitmap; + buttonType = "RadioButton"; + groupNum = "0"; + useMouseEvents = "0"; + }; + ToolsToolbarArray.add(%button); + EWToolsToolbar.setExtent((25 + 8) * (%count + 1) + 12 SPC "33"); + } +} + +//----------------------------------------------------------------------------- + +function EditorGui::setDisplayType( %this, %type ) +{ + %gui = %this.currentEditor.editorGui; + if( !isObject( %gui ) ) + return; + + %this.viewTypeMenu.checkRadioItem( 0, 7, %type ); + + // Store the current camera rotation so we can restore it correctly when + // switching back to perspective view + if ( %gui.getDisplayType() == $EditTSCtrl::DisplayTypePerspective ) + %this.lastPerspectiveCamRotation = LocalClientConnection.camera.getRotation(); + + %gui.setDisplayType( %type ); + + if ( %gui.getDisplayType() == $EditTSCtrl::DisplayTypePerspective ) + LocalClientConnection.camera.setRotation( %this.lastPerspectiveCamRotation ); + + %this.currentDisplayType = %type; +} + +//----------------------------------------------------------------------------- + +function EditorGui::setEditor( %this, %newEditor, %dontActivate ) +{ + if ( isObject( %this.currentEditor ) ) + { + if( isObject( %newEditor ) && %this.currentEditor.getId() == %newEditor.getId() ) + return; + + if( %this.currentEditor.isActivated ) + %this.currentEditor.onDeactivated(); + + if( isObject( %this.currentEditor.editorGui ) ) + %this.currentOrthoFOV = %this.currentEditor.editorGui.getOrthoFOV(); + } + + if( !isObject( %newEditor ) ) + { + %this.currentEditor = ""; + return; + } + + // If we have a special set editor function, run that instead + if( %newEditor.isMethod( "setEditorFunction" ) ) + { + if( %newEditor.setEditorFunction() ) + { + %this.syncEditor( %newEditor ); + %this.currentEditor = %newEditor; + + if (!%dontActivate) + %this.currentEditor.onActivated(); + } + else + { + // if were falling back and were the same editor, why are we going to just shove ourself + // into the editor position again? opt for a fallback + if( !isObject( %this.currentEditor ) ) + %this.currentEditor = "WorldEditorInspectorPlugin"; + else if( %this.currentEditor.getId() == %newEditor.getId() ) + %this.currentEditor = "WorldEditorInspectorPlugin"; + + %this.syncEditor( %this.currentEditor, true ); + + if( !%dontActivate ) + %this.currentEditor.onActivated(); + } + } + else + { + %this.syncEditor( %newEditor ); + %this.currentEditor = %newEditor; + + if( !%dontActivate ) + %this.currentEditor.onActivated(); + } + + // Sync display type. + + %gui = %this.currentEditor.editorGui; + if( isObject( %gui ) ) + { + %gui.setDisplayType( %this.currentDisplayType ); + %gui.setOrthoFOV( %this.currentOrthoFOV ); + EditorGui.syncCameraGui(); + } +} + +function EditorGui::syncEditor( %this, %newEditor, %newEditorFailed ) +{ + // Sync with menu bar + %menu = %this.findMenu( "Editors" ); + %count = %menu.getItemCount(); + for ( %i = 0; %i < %count; %i++ ) + { + %pluginObj = getField( %menu.item[%i], 2 ); + if ( %pluginObj $= %newEditor ) + { + %menu.checkRadioItem( 0, %count, %i ); + break; + } + } + + // In order to hook up a palette, the word Palette must be able to be + // switched out in order to read correctly, if not, no palette will be used + %paletteName = strreplace(%newEditor, "Plugin", "Palette"); + + // Sync with ToolsToolbar + for ( %i = 0; %i < ToolsToolbarArray.getCount(); %i++ ) + { + %toolbarButton = ToolsToolbarArray.getObject(%i).internalName; + if( %paletteName $= %toolbarButton ) + { + ToolsToolbarArray.getObject(%i).setStateOn(1); + break; + } + } + + // Handles quit game and gui editor changes in wierd scenarios + if( %newEditorFailed && EWToolsToolbar.isDynamic ) + { + if( EWToolsToolbar.isClosed ) + EWToolsToolbar.reset(); + EWToolsToolbar.toggleSize(); + } + + // Toggle the editor specific palette; we define special cases here + switch$ ( %paletteName ) + { + case "MaterialEditorPalette": + %paletteName = "WorldEditorInspectorPalette"; + case "DatablockEditorPalette": + %paletteName = "WorldEditorInspectorPalette"; + case "ParticleEditorPalette": + %paletteName = "WorldEditorInspectorPalette"; + } + + %this-->ToolsPaletteWindow.togglePalette(%paletteName); +} + +function EditorGui::onWake( %this ) +{ + EHWorldEditor.setStateOn( 1 ); + + // Notify the editor plugins that the editor has started. + + foreach( %plugin in EditorPluginSet ) + %plugin.onEditorWake(); + + // Push the ActionMaps in the order that we want to have them + // before activating an editor plugin, so that if the plugin + // installs an ActionMap, it will be highest on the stack. + + MoveMap.push(); + EditorMap.push(); + + // Active the current editor plugin. + + if( !%this.currentEditor.isActivated ) + %this.currentEditor.onActivated(); + + %slashPos = 0; + while( strpos( $Server::MissionFile, "/", %slashPos ) != -1 ) + { + %slashPos = strpos( $Server::MissionFile, "/", %slashPos ) + 1; + } + %levelName = getSubStr( $Server::MissionFile , %slashPos , 99 ); + + if( %levelName !$= %this.levelName ) + %this.onNewLevelLoaded( %levelName ); +} + +function EditorGui::onSleep( %this ) +{ + // Deactivate the current editor plugin. + + if( %this.currentEditor.isActivated ) + %this.currentEditor.onDeactivated(); + + // Remove the editor's ActionMaps. + + EditorMap.pop(); + MoveMap.pop(); + + // Notify the editor plugins that the editor will be closing. + + foreach( %plugin in EditorPluginSet ) + %plugin.onEditorSleep(); + + if(isObject($Server::CurrentScene)) + $Server::CurrentScene.open(); +} + +function EditorGui::onNewLevelLoaded( %this, %levelName ) +{ + %this.levelName = %levelName; + %this.setupDefaultCameraSettings(); + ECameraSettingsPage.init(); + EditorCameraSpeedOptions.setupDefaultState(); + + new ScriptObject( EditorMissionCleanup ) + { + parentGroup = "MissionCleanup"; + }; +} + +function EditorMissionCleanup::onRemove( %this ) +{ + EditorGui.levelName = ""; + foreach( %plugin in EditorPluginSet ) + %plugin.onExitMission(); +} + +//----------------------------------------------------------------------------- + +// Called when we have been set as the content and onWake has been called +function EditorGui::onSetContent(%this, %oldContent) +{ + %this.attachMenus(); +} + +// Called before onSleep when the canvas content is changed +function EditorGui::onUnsetContent(%this, %newContent) +{ + %this.detachMenus(); +} + +//------------------------------------------------------------------------------ + +function EditorGui::toggleSFXParametersWindow( %this ) +{ + %window = %this-->ManageSFXParametersWindow; + %window.setVisible( !%window.isVisible() ); +} + +//------------------------------------------------------------------------------ + +function EditorGui::addCameraBookmark( %this, %name ) +{ + %obj = new CameraBookmark() { + datablock = CameraBookmarkMarker; + internalName = %name; + }; + + // Place into correct group + if( !isObject(CameraBookmarks) ) + { + %grp = new SimGroup(CameraBookmarks); + MissionGroup.add(%grp); + } + CameraBookmarks.add( %obj ); + + %cam = LocalClientConnection.camera.getTransform(); + %obj.setTransform( %cam ); + + EWorldEditor.isDirty = true; + EditorTree.buildVisibleTree(true); +} + +function EditorGui::removeCameraBookmark( %this, %name ) +{ + if( !isObject(CameraBookmarks) ) + return; + + %mark = CameraBookmarks.findObjectByInternalName( %name, true ); + if( %mark == 0 ) + return; + + MEDeleteUndoAction::submit( %mark ); + EWorldEditor.isDirty = true; + EditorTree.buildVisibleTree(true); +} + +function EditorGui::removeCameraBookmarkIndex( %this, %index ) +{ + if( !isObject(CameraBookmarks) ) + return; + + if( %index < 0 || %index >= CameraBookmarks.getCount() ) + return; + + %obj = CameraBookmarks.getObject( %index ); + MEDeleteUndoAction::submit( %obj ); + EWorldEditor.isDirty = true; + EditorTree.buildVisibleTree(true); +} + +function EditorGui::jumpToBookmark( %this, %name ) +{ + if( !isObject(CameraBookmarks) ) + return; + + %mark = CameraBookmarks.findObjectByInternalName( %name, true ); + if( %mark == 0 ) + return; + + LocalClientConnection.camera.setTransform( %mark.getTransform() ); + return; +} + +function EditorGui::jumpToBookmarkIndex( %this, %index ) +{ + if( !isObject(CameraBookmarks) ) + return; + + if( %index < 0 || %index >= CameraBookmarks.getCount() ) + return; + + %trans = CameraBookmarks.getObject( %index ).getTransform(); + LocalClientConnection.camera.setTransform( %trans ); +} + +function EditorGui::addCameraBookmarkByGui( %this ) +{ + // look for a NewCamera name to grab + for(%i = 0; ; %i++){ + %name = "NewCamera_" @ %i; + if( !CameraBookmarks.findObjectByInternalName(%name) ){ + break; + } + } + EditorGui.addCameraBookmark( %name ); +} + +function EditorGui::toggleCameraBookmarkWindow( %this ) +{ + EManageBookmarks.ToggleVisibility(); +} + +function EditorGui::toggleObjectSelectionsWindow( %this ) +{ + ESelectObjectsWindow.toggleVisibility(); +} + +function EditorGui::toggleOrthoGrid( %this ) +{ + EWorldEditor.renderOrthoGrid = !EWorldEditor.renderOrthoGrid; +} + +//------------------------------------------------------------------------------ + +function EditorGui::syncCameraGui( %this ) +{ + if( !EditorIsActive() ) + return; + + // Sync projection type + %displayType = %this.currentEditor.editorGui.getDisplayType(); + %this.viewTypeMenu.checkRadioItem( 0, 7, %displayType ); + + // Set the camera object's mode and rotation so that it moves correctly + // based on the current editor mode + if( %displayType != $EditTSCtrl::DisplayTypePerspective ) + { + switch( %displayType ) + { + case $EditTSCtrl::DisplayTypeTop: %name = "Top View"; %camRot = "0 0 0"; + case $EditTSCtrl::DisplayTypeBottom: %name = "Bottom View"; %camRot = "3.14159 0 0"; + case $EditTSCtrl::DisplayTypeLeft: %name = "Left View"; %camRot = "-1.571 0 1.571"; + case $EditTSCtrl::DisplayTypeRight: %name = "Right View"; %camRot = "-1.571 0 -1.571"; + case $EditTSCtrl::DisplayTypeFront: %name = "Front View"; %camRot = "-1.571 0 3.14159"; + case $EditTSCtrl::DisplayTypeBack: %name = "Back View"; %camRot = "-1.571 0 0"; + case $EditTSCtrl::DisplayTypeIsometric: %name = "Isometric View"; %camRot = "0 0 0"; + } + + LocalClientConnection.camera.controlMode = "Fly"; + LocalClientConnection.camera.setRotation( %camRot ); + EditorGuiStatusBar.setCamera( %name ); + return; + } + + // Sync camera settings. + %flyModeRadioItem = -1; + if(LocalClientConnection.getControlObject() != LocalClientConnection.player) + { + %mode = LocalClientConnection.camera.getMode(); + + if(%mode $= "Fly" && LocalClientConnection.camera.newtonMode) + { + if(LocalClientConnection.camera.newtonRotation == true) + { + EditorGui-->NewtonianRotationCamera.setStateOn(true); + EWorldEditorToggleCamera.setBitmap("tools/gui/images/menubar/smooth-cam-rot"); + %flyModeRadioItem = 4; + EditorGuiStatusBar.setCamera("Smooth Rot Camera"); + } + else + { + EditorGui-->NewtonianCamera.setStateOn(true); + EWorldEditorToggleCamera.setBitmap("tools/gui/images/menubar/smooth-cam"); + %flyModeRadioItem = 3; + EditorGuiStatusBar.setCamera("Smooth Camera"); + } + } + else if(%mode $= "EditOrbit") + { + EditorGui-->OrbitCamera.setStateOn(true); + EWorldEditorToggleCamera.setBitmap("tools/gui/images/menubar/orbit-cam"); + %flyModeRadioItem = 1; + EditorGuiStatusBar.setCamera("Orbit Camera"); + } + else // default camera mode + { + EditorGui-->StandardCamera.setStateOn(true); + EWorldEditorToggleCamera.setBitmap("tools/worldEditor/images/toolbar/camera"); + %flyModeRadioItem = 0; + EditorGuiStatusBar.setCamera("Standard Camera"); + } + + //quick way select menu bar options + %this.findMenu( "Camera" ).checkRadioItem( 0, 1, 0 ); + EditorFreeCameraTypeOptions.checkRadioItem( 0, 4, %flyModeRadioItem); + EditorPlayerCameraTypeOptions.checkRadioItem( 0, 4, -1); + } + else if (!$isFirstPersonVar) // if 3rd person + { + EditorGui-->trdPersonCamera.setStateOn(true); + EWorldEditorToggleCamera.setBitmap("tools/worldEditor/images/toolbar/3rd-person-camera"); + %flyModeRadioItem = 1; + //quick way select menu bar options + %this.findMenu( "Camera" ).checkRadioItem( 0, 1, 1 ); + EditorPlayerCameraTypeOptions.checkRadioItem( 0, 2, %flyModeRadioItem); + EditorGuiStatusBar.setCamera("3rd Person Camera"); + } + else if ($isFirstPersonVar) // if 1st Person + { + EditorGui-->PlayerCamera.setStateOn(true); + EWorldEditorToggleCamera.setBitmap("tools/worldEditor/images/toolbar/player"); + %flyModeRadioItem = 0; + //quick way select menu bar options + %this.findMenu( "Camera" ).checkRadioItem( 0, 1, 1 ); + EditorPlayerCameraTypeOptions.checkRadioItem( 0, 2, %flyModeRadioItem); + EditorFreeCameraTypeOptions.checkRadioItem( 0, 4, -1); + EditorGuiStatusBar.setCamera("1st Person Camera"); + } + } + +/// @name EditorPlugin Methods +/// @{ + +//------------------------------------------------------------------------------ +// WorldEditorPlugin +//------------------------------------------------------------------------------ + +function WorldEditorPlugin::onActivated( %this ) +{ + EditorGui.bringToFront( EWorldEditor ); + EWorldEditor.setVisible(true); + EditorGui.menuBar.insert( EditorGui.worldMenu, EditorGui.menuBar.dynamicItemInsertPos ); + EWorldEditor.makeFirstResponder(true); + EditorTree.open(MissionGroup,true); + EWCreatorWindow.setNewObjectGroup(MissionGroup); + + EWorldEditor.syncGui(); + + EditorGuiStatusBar.setSelectionObjectsByCount(EWorldEditor.getSelectionSize()); + + // Should the Transform Selection window open? + if( EWorldEditor.ETransformSelectionDisplayed ) + { + ETransformSelection.setVisible(true); + } + + Parent::onActivated(%this); +} + +function WorldEditorPlugin::onDeactivated( %this ) +{ + // Hide the Transform Selection window from other editors + ETransformSelection.setVisible(false); + + EWorldEditor.setVisible( false ); + EditorGui.menuBar.remove( EditorGui.worldMenu ); + + Parent::onDeactivated(%this); +} + +//------------------------------------------------------------------------------ +// WorldEditorInspectorPlugin +//------------------------------------------------------------------------------ + +function WorldEditorInspectorPlugin::onWorldEditorStartup( %this ) +{ + Parent::onWorldEditorStartup( %this ); + + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Object Editor", "", WorldEditorInspectorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Object Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "WorldEditorInspectorPlugin", "WorldEditorInspectorPalette", expandFilename("tools/worldEditor/images/toolbar/transform-objects"), %tooltip ); + + //connect editor windows + GuiWindowCtrl::attach( EWInspectorWindow, EWTreeWindow); + + %map = new ActionMap(); + %map.bindCmd( keyboard, "1", "EWorldEditorNoneModeBtn.performClick();", "" ); // Select + %map.bindCmd( keyboard, "2", "EWorldEditorMoveModeBtn.performClick();", "" ); // Move + %map.bindCmd( keyboard, "3", "EWorldEditorRotateModeBtn.performClick();", "" ); // Rotate + %map.bindCmd( keyboard, "4", "EWorldEditorScaleModeBtn.performClick();", "" ); // Scale + %map.bindCmd( keyboard, "f", "FitToSelectionBtn.performClick();", "" );// Fit Camera to Selection + %map.bindCmd( keyboard, "z", "EditorGuiStatusBar.setCamera(\"Standard Camera\");", "" );// Free camera + %map.bindCmd( keyboard, "n", "ToggleNodeBar->renderHandleBtn.performClick();", "" );// Render Node + %map.bindCmd( keyboard, "shift n", "ToggleNodeBar->renderTextBtn.performClick();", "" );// Render Node Text + %map.bindCmd( keyboard, "g", "ESnapOptions-->GridSnapButton.performClick();" ); // Grid Snappping + %map.bindCmd( keyboard, "t", "SnapToBar->objectSnapDownBtn.performClick();", "" );// Terrain Snapping + %map.bindCmd( keyboard, "b", "SnapToBar-->objectSnapBtn.performClick();" ); // Soft Snappping + %map.bindCmd( keyboard, "v", "EWorldEditorToolbar->boundingBoxColBtn.performClick();", "" );// Bounds Selection + %map.bindCmd( keyboard, "o", "objectCenterDropdown->objectBoxBtn.performClick(); objectCenterDropdown.toggle();", "" );// Object Center + %map.bindCmd( keyboard, "p", "objectCenterDropdown->objectBoundsBtn.performClick(); objectCenterDropdown.toggle();", "" );// Bounds Center + %map.bindCmd( keyboard, "k", "objectTransformDropdown->objectTransformBtn.performClick(); objectTransformDropdown.toggle();", "" );// Object Transform + %map.bindCmd( keyboard, "l", "objectTransformDropdown->worldTransformBtn.performClick(); objectTransformDropdown.toggle();", "" );// World Transform + + WorldEditorInspectorPlugin.map = %map; +} + +function WorldEditorInspectorPlugin::onActivated( %this ) +{ + Parent::onActivated( %this ); + + EditorGui-->InspectorWindow.setVisible( true ); + EditorGui-->TreeWindow.setVisible( true ); + EditorGui-->WorldEditorToolbar.setVisible( true ); + %this.map.push(); +} + +function WorldEditorInspectorPlugin::onDeactivated( %this ) +{ + Parent::onDeactivated( %this ); + + EditorGui-->InspectorWindow.setVisible( false ); + EditorGui-->TreeWindow.setVisible( false ); + EditorGui-->WorldEditorToolbar.setVisible( false ); + %this.map.pop(); +} + +function WorldEditorInspectorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %canCutCopy = EWorldEditor.getSelectionSize() > 0; + %editMenu.enableItem( 3, %canCutCopy ); // Cut + %editMenu.enableItem( 4, %canCutCopy ); // Copy + %editMenu.enableItem( 5, EWorldEditor.canPasteSelection() ); // Paste + + %selSize = EWorldEditor.getSelectionSize(); + %lockCount = EWorldEditor.getSelectionLockCount(); + %hideCount = EWorldEditor.getSelectionHiddenCount(); + %editMenu.enableItem( 6, %selSize > 0 && %lockCount != %selSize ); // Delete Selection + + %editMenu.enableItem( 8, %canCutCopy ); // Deselect +} + +function WorldEditorInspectorPlugin::handleDelete( %this ) +{ + // The tree handles deletion and notifies the + // world editor to clear its selection. + // + // This is because non-SceneObject elements like + // SimGroups also need to be destroyed. + // + // See EditorTree::onObjectDeleteCompleted(). + %selSize = EWorldEditor.getSelectionSize(); + if( %selSize > 0 ) + EditorTree.deleteSelection(); +} + +function WorldEditorInspectorPlugin::handleDeselect() +{ + EWorldEditor.clearSelection(); +} + +function WorldEditorInspectorPlugin::handleCut() +{ + EWorldEditor.cutSelection(); +} + +function WorldEditorInspectorPlugin::handleCopy() +{ + EWorldEditor.copySelection(); +} + +function WorldEditorInspectorPlugin::handlePaste() +{ + EWorldEditor.pasteSelection(); +} + +//------------------------------------------------------------------------------ +// TerrainEditorPlugin +//------------------------------------------------------------------------------ + +function TerrainEditorPlugin::onWorldEditorStartup( %this ) +{ + Parent::onWorldEditorStartup( %this ); + + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Terrain Editor", "", TerrainEditorPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Terrain Editor (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "TerrainEditorPlugin", "TerrainEditorPalette", expandFilename("tools/worldEditor/images/toolbar/sculpt-terrain"), %tooltip ); + + %map = new ActionMap(); + %map.bindCmd( keyboard, "1", "ToolsPaletteArray->brushAdjustHeight.performClick();", "" ); //Grab Terrain + %map.bindCmd( keyboard, "2", "ToolsPaletteArray->raiseHeight.performClick();", "" ); // Raise Height + %map.bindCmd( keyboard, "3", "ToolsPaletteArray->lowerHeight.performClick();", "" ); // Lower Height + %map.bindCmd( keyboard, "4", "ToolsPaletteArray->smoothHeight.performClick();", "" ); // Average Height + %map.bindCmd( keyboard, "5", "ToolsPaletteArray->smoothSlope.performClick();", "" ); // Smooth Slope + %map.bindCmd( keyboard, "6", "ToolsPaletteArray->paintNoise.performClick();", "" ); // Noise + %map.bindCmd( keyboard, "7", "ToolsPaletteArray->flattenHeight.performClick();", "" ); // Flatten + %map.bindCmd( keyboard, "8", "ToolsPaletteArray->setHeight.performClick();", "" ); // Set Height + %map.bindCmd( keyboard, "9", "ToolsPaletteArray->setEmpty.performClick();", "" ); // Clear Terrain + %map.bindCmd( keyboard, "0", "ToolsPaletteArray->clearEmpty.performClick();", "" ); // Restore Terrain + %map.bindCmd( keyboard, "v", "EWTerrainEditToolbarBrushType->ellipse.performClick();", "" );// Circle Brush + %map.bindCmd( keyboard, "b", "EWTerrainEditToolbarBrushType->box.performClick();", "" );// Box Brush + %map.bindCmd( keyboard, "=", "TerrainEditorPlugin.keyboardModifyBrushSize(1);", "" );// +1 Brush Size + %map.bindCmd( keyboard, "+", "TerrainEditorPlugin.keyboardModifyBrushSize(1);", "" );// +1 Brush Size + %map.bindCmd( keyboard, "-", "TerrainEditorPlugin.keyboardModifyBrushSize(-1);", "" );// -1 Brush Size + %map.bindCmd( keyboard, "[", "TerrainEditorPlugin.keyboardModifyBrushSize(-5);", "" );// -5 Brush Size + %map.bindCmd( keyboard, "]", "TerrainEditorPlugin.keyboardModifyBrushSize(5);", "" );// +5 Brush Size + /*%map.bindCmd( keyboard, "]", "TerrainBrushPressureTextEditContainer->textEdit.text += 5", "" );// +5 Pressure + %map.bindCmd( keyboard, "[", "TerrainBrushPressureTextEditContainer->textEdit.text -= 5", "" );// -5 Pressure + %map.bindCmd( keyboard, "'", "TerrainBrushSoftnessTextEditContainer->textEdit.text += 5", "" );// +5 Softness + %map.bindCmd( keyboard, ";", "TerrainBrushSoftnessTextEditContainer->textEdit.text -= 5", "" );// -5 Softness*/ + + TerrainEditorPlugin.map = %map; + + %this.terrainMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + + barTitle = "Terrain"; + + item[0] = "Smooth Heightmap" TAB "" TAB "ETerrainEditor.onSmoothHeightmap();"; + }; +} + +function TerrainEditorPlugin::onActivated( %this ) +{ + Parent::onActivated( %this ); + + EditorGui.readTerrainEditorSettings(); + + %action = EditorSettings.value("TerrainEditor/currentAction"); + ETerrainEditor.switchAction( %action ); + ToolsPaletteArray.findObjectByInternalName( %action, true ).setStateOn( true ); + + EWTerrainEditToolbarBrushType->ellipse.performClick(); // Circle Brush + + EditorGui.menuBar.insert( %this.terrainMenu, EditorGui.menuBar.dynamicItemInsertPos ); + + EditorGui.bringToFront( ETerrainEditor ); + ETerrainEditor.setVisible( true ); + ETerrainEditor.attachTerrain(); + ETerrainEditor.makeFirstResponder( true ); + + EWTerrainEditToolbar.setVisible( true ); + ETerrainEditor.onBrushChanged(); + ETerrainEditor.setup(); + TerrainEditorPlugin.syncBrushInfo(); + + EditorGuiStatusBar.setSelection(""); + %this.map.push(); +} + +function TerrainEditorPlugin::onDeactivated( %this ) +{ + Parent::onDeactivated( %this ); + + endToolTime("TerrainEditor"); + EditorGui.writeTerrainEditorSettings(); + + EWTerrainEditToolbar.setVisible( false ); + ETerrainEditor.setVisible( false ); + + EditorGui.menuBar.remove( %this.terrainMenu ); + + %this.map.pop(); +} + +function TerrainEditorPlugin::syncBrushInfo( %this ) +{ + // Update gui brush info + TerrainBrushSizeTextEditContainer-->textEdit.text = getWord(ETerrainEditor.getBrushSize(), 0); + TerrainBrushPressureTextEditContainer-->textEdit.text = ETerrainEditor.getBrushPressure()*100; + TerrainBrushSoftnessTextEditContainer-->textEdit.text = ETerrainEditor.getBrushSoftness()*100; + TerrainSetHeightTextEditContainer-->textEdit.text = ETerrainEditor.setHeightVal; + + %brushType = ETerrainEditor.getBrushType(); + eval( "EWTerrainEditToolbar-->" @ %brushType @ ".setStateOn(1);" ); +} + +function TerrainEditorPlugin::validateBrushSize( %this ) +{ + %minBrushSize = 1; + %maxBrushSize = getWord(ETerrainEditor.maxBrushSize, 0); + + %val = $ThisControl.getText(); + if(%val < %minBrushSize) + $ThisControl.setValue(%minBrushSize); + else if(%val > %maxBrushSize) + $ThisControl.setValue(%maxBrushSize); +} + +function TerrainEditorPlugin::keyboardModifyBrushSize( %this, %amt) +{ + %val = TerrainBrushSizeTextEditContainer-->textEdit.getText(); + %val += %amt; + TerrainBrushSizeTextEditContainer-->textEdit.setValue(%val); + TerrainBrushSizeTextEditContainer-->textEdit.forceValidateText(); + ETerrainEditor.setBrushSize( TerrainBrushSizeTextEditContainer-->textEdit.getText() ); +} + +//------------------------------------------------------------------------------ +// TerrainTextureEditorTool +//------------------------------------------------------------------------------ + +function TerrainTextureEditorTool::onActivated( %this ) +{ + EditorGui.bringToFront( ETerrainEditor ); + ETerrainEditor.setVisible( true ); + ETerrainEditor.attachTerrain(); + ETerrainEditor.makeFirstResponder( true ); + + EditorGui-->TextureEditor.setVisible(true); + + EditorGuiStatusBar.setSelection(""); +} + +function TerrainTextureEditorTool::onDeactivated( %this ) +{ + EditorGui-->TextureEditor.setVisible(false); + + ETerrainEditor.setVisible( false ); +} + +//------------------------------------------------------------------------------ +// TerrainPainterPlugin +//------------------------------------------------------------------------------ + +function TerrainPainterPlugin::onWorldEditorStartup( %this ) +{ + Parent::onWorldEditorStartup( %this ); + + // Add ourselves to the window menu. + %accel = EditorGui.addToEditorsMenu( "Terrain Painter", "", TerrainPainterPlugin ); + + // Add ourselves to the ToolsToolbar + %tooltip = "Terrain Painter (" @ %accel @ ")"; + EditorGui.addToToolsToolbar( "TerrainPainterPlugin", "TerrainPainterPalette", expandFilename("tools/worldEditor/images/toolbar/paint-terrain"), %tooltip ); + + %map = new ActionMap(); + %map.bindCmd( keyboard, "v", "EWTerrainPainterToolbarBrushType->ellipse.performClick();", "" );// Circle Brush + %map.bindCmd( keyboard, "b", "EWTerrainPainterToolbarBrushType->box.performClick();", "" );// Box Brush + %map.bindCmd( keyboard, "=", "TerrainPainterPlugin.keyboardModifyBrushSize(1);", "" );// +1 Brush Size + %map.bindCmd( keyboard, "+", "TerrainPainterPlugin.keyboardModifyBrushSize(1);", "" );// +1 Brush Size + %map.bindCmd( keyboard, "-", "TerrainPainterPlugin.keyboardModifyBrushSize(-1);", "" );// -1 Brush Size + %map.bindCmd( keyboard, "[", "TerrainPainterPlugin.keyboardModifyBrushSize(-5);", "" );// -5 Brush Size + %map.bindCmd( keyboard, "]", "TerrainPainterPlugin.keyboardModifyBrushSize(5);", "" );// +5 Brush Size + /*%map.bindCmd( keyboard, "]", "PaintBrushSlopeControl->SlopeMinAngle.text += 5", "" );// +5 SlopeMinAngle + %map.bindCmd( keyboard, "[", "PaintBrushSlopeControl->SlopeMinAngle.text -= 5", "" );// -5 SlopeMinAngle + %map.bindCmd( keyboard, "'", "PaintBrushSlopeControl->SlopeMaxAngle.text += 5", "" );// +5 SlopeMaxAngle + %map.bindCmd( keyboard, ";", "PaintBrushSlopeControl->SlopeMaxAngle.text -= 5", "" );// -5 Softness*/ + + for(%i=1; %i<10; %i++) + { + %map.bindCmd( keyboard, %i, "TerrainPainterPlugin.keyboardSetMaterial(" @ (%i-1) @ ");", "" ); + } + %map.bindCmd( keyboard, 0, "TerrainPainterPlugin.keyboardSetMaterial(10);", "" ); + + TerrainPainterPlugin.map = %map; + GuiWindowCtrl::attach( EPainter, EPainterPreview); +} + +function TerrainPainterPlugin::onActivated( %this ) +{ + Parent::onActivated( %this ); + + EditorGui.readTerrainEditorSettings(); + + EWTerrainPainterToolbarBrushType->ellipse.performClick();// Circle Brush + %this.map.push(); + + EditorGui.bringToFront( ETerrainEditor ); + ETerrainEditor.setVisible( true ); + ETerrainEditor.attachTerrain(); + ETerrainEditor.makeFirstResponder( true ); + + EditorGui-->TerrainPainter.setVisible(true); + EditorGui-->TerrainPainterPreview.setVisible(true); + EWTerrainPainterToolbar.setVisible(true); + ETerrainEditor.onBrushChanged(); + EPainter.setup(); + TerrainPainterPlugin.syncBrushInfo(); + + EditorGuiStatusBar.setSelection(""); +} + +function TerrainPainterPlugin::onDeactivated( %this ) +{ + Parent::onDeactivated( %this ); + + EditorGui.writeTerrainEditorSettings(); + + %this.map.pop(); + EditorGui-->TerrainPainter.setVisible(false); + EditorGui-->TerrainPainterPreview.setVisible(false); + EWTerrainPainterToolbar.setVisible(false); + ETerrainEditor.setVisible( false ); +} + +function TerrainPainterPlugin::syncBrushInfo( %this ) +{ + // Update gui brush info + PaintBrushSizeTextEditContainer-->textEdit.text = getWord(ETerrainEditor.getBrushSize(), 0); + PaintBrushSlopeControl-->SlopeMinAngle.text = ETerrainEditor.getSlopeLimitMinAngle(); + PaintBrushSlopeControl-->SlopeMaxAngle.text = ETerrainEditor.getSlopeLimitMaxAngle(); + PaintBrushPressureTextEditContainer-->textEdit.text = ETerrainEditor.getBrushPressure()*100; + %brushType = ETerrainEditor.getBrushType(); + eval( "EWTerrainPainterToolbar-->" @ %brushType @ ".setStateOn(1);" ); +} + +function TerrainPainterPlugin::validateBrushSize( %this ) +{ + %minBrushSize = 1; + %maxBrushSize = getWord(ETerrainEditor.maxBrushSize, 0); + + %val = $ThisControl.getText(); + if(%val < %minBrushSize) + $ThisControl.setValue(%minBrushSize); + else if(%val > %maxBrushSize) + $ThisControl.setValue(%maxBrushSize); +} + +function TerrainPainterPlugin::validateSlopeMaxAngle( %this ) +{ + %maxval = ETerrainEditor.getSlopeLimitMaxAngle(); + PaintBrushSlopeControl-->SlopeMaxAngle.setText(%maxval); +} + +function TerrainPainterPlugin::validateSlopeMinAngle( %this ) +{ + %minval = ETerrainEditor.getSlopeLimitMinAngle(); + PaintBrushSlopeControl-->SlopeMinAngle.setText(%minval); +} + +function TerrainPainterPlugin::keyboardModifyBrushSize( %this, %amt) +{ + %val = PaintBrushSizeTextEditContainer-->textEdit.getText(); + %val += %amt; + PaintBrushSizeTextEditContainer-->textEdit.setValue(%val); + PaintBrushSizeTextEditContainer-->textEdit.forceValidateText(); + ETerrainEditor.setBrushSize( PaintBrushSizeTextEditContainer-->textEdit.getText() ); +} + +function TerrainPainterPlugin::keyboardSetMaterial( %this, %mat) +{ + %name = "EPainterMaterialButton" @ %mat; + %ctrl = EPainter.findObjectByInternalName(%name, true); + if(%ctrl) + { + %ctrl.performClick(); + } +} + +/// @} End of EditorPlugin Methods + + +function objectTransformDropdown::toggle() +{ + if ( objectTransformDropdown.visible ) + { + EWorldEditorToolbar-->objectTransform.setStateOn(false); + objectTransformDropdownDecoy.setVisible(false); + objectTransformDropdownDecoy.setActive(false); + objectTransformDropdown.setVisible(false); + } + else + { + EWorldEditorToolbar-->objectTransform.setStateOn(true); + objectTransformDropdown.setVisible(true); + objectTransformDropdownDecoy.setActive(true); + objectTransformDropdownDecoy.setVisible(true); + } +} + +function CameraTypesDropdownToggle() +{ + if ( CameraTypesDropdown.visible ) + { + EWorldEditorToggleCamera.setStateOn(0); + CameraTypesDropdownDecoy.setVisible(false); + CameraTypesDropdownDecoy.setActive(false); + CameraTypesDropdown.setVisible(false); + } + else + { + CameraTypesDropdown.setVisible(true); + CameraTypesDropdownDecoy.setVisible(true); + CameraTypesDropdownDecoy.setActive(true); + EWorldEditorToggleCamera.setStateOn(1); + } +} + +function VisibilityDropdownToggle() +{ + if ( EVisibility.visible ) + { + EVisibility.setVisible(false); + visibilityToggleBtn.setStateOn(0); + } + else + { + EVisibility.setVisible(true); + visibilityToggleBtn.setStateOn(1); + } +} + +function CameraTypesDropdownDecoy::onMouseLeave() +{ + CameraTypesDropdownToggle(); +} + +//----------------------------------------------------------------------------- + +function EWorldEditor::getGridSnap( %this ) +{ + return %this.gridSnap; +} + +function EWorldEditor::setGridSnap( %this, %value ) +{ + %this.gridSnap = %value; + GlobalGizmoProfile.snapToGrid = %value; + %this.syncGui(); +} + +function EWorldEditor::getGridSize( %this ) +{ + return %this.gridSize; +} + +function EWorldEditor::setGridSize( %this, %value ) +{ + GlobalGizmoProfile.gridSize = %value SPC %value SPC %value; + %this.gridSize = %value; + + %this.syncGui(); +} + +//----------------------------------------------------------------------------- + +function EWorldEditor::areAllSelectedObjectsOfType( %this, %className ) +{ + %activeSelection = %this.getActiveSelection(); + if( !isObject( %activeSelection ) ) + return false; + + %count = %activeSelection.getCount(); + for( %i = 0; %i < %count; %i ++ ) + { + %obj = %activeSelection.getObject( %i ); + if( !%obj.isMemberOfClass( %className ) ) + return false; + } + + return true; +} + +//----------------------------------------------------------------------------- +function EWorldEditorToggleCamera::toggleBitmap(%this) +{ + %currentImage = %this.bitmap; + + if ( %currentImage $= "tools/worldEditor/images/toolbar/player" ) + %image = "tools/worldEditor/images/toolbar/camera"; + else + %image = "tools/worldEditor/images/toolbar/player"; + + %this.setBitmap( %image ); +} + +function EWorldEditorCameraSpeed::updateMenuBar(%this, %editorBarCtrl) +{ + // Update Toolbar TextEdit + if( %editorBarCtrl.getId() == CameraSpeedDropdownCtrlContainer-->slider.getId() ) + { + %value = %editorBarCtrl.getValue(); + EWorldEditorCameraSpeed.setText( %value ); + $Camera::movementSpeed = %value; + } + + // Update Toolbar Slider + if( %editorBarCtrl.getId() == EWorldEditorCameraSpeed.getId() ) + { + %value = %editorBarCtrl.getText(); + if ( %value !$= "" ) + { + if ( %value <= 0 ) // camera speed must be >= 0 + { + %value = 1; + %editorBarCtrl.setText( %value ); + } + CameraSpeedDropdownCtrlContainer-->slider.setValue( %value ); + $Camera::movementSpeed = %value; + } + } + + // Update Editor + EditorCameraSpeedOptions.checkRadioItem(0, 6, -1); +} + +//----------------------------------------------------------------------------- + +function EWorldEditorAlignPopup::onSelect(%this, %id, %text) +{ + if ( GlobalGizmoProfile.mode $= "Scale" && %text $= "World" ) + { + EWorldEditorAlignPopup.setSelected(1); + return; + } + + GlobalGizmoProfile.alignment = %text; +} + +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- + +function EWorldEditorNoneModeBtn::onClick(%this) +{ + GlobalGizmoProfile.mode = "None"; + + EditorGuiStatusBar.setInfo("Selection arrow."); +} + +function EWorldEditorMoveModeBtn::onClick(%this) +{ + GlobalGizmoProfile.mode = "Move"; + + %cmdCtrl = "CTRL"; + if( $platform $= "macos" ) + %cmdCtrl = "CMD"; + + EditorGuiStatusBar.setInfo( "Move selection. SHIFT while dragging duplicates objects. " @ %cmdCtrl @ " to toggle soft snap. ALT to toggle grid snap." ); +} + +function EWorldEditorRotateModeBtn::onClick(%this) +{ + GlobalGizmoProfile.mode = "Rotate"; + + EditorGuiStatusBar.setInfo("Rotate selection."); +} + +function EWorldEditorScaleModeBtn::onClick(%this) +{ + GlobalGizmoProfile.mode = "Scale"; + + EditorGuiStatusBar.setInfo("Scale selection."); +} + +//----------------------------------------------------------------------------- + +function EditorTree::onDeleteSelection( %this ) +{ + %this.undoDeleteList = ""; +} + +function EditorTree::onDeleteObject( %this, %object ) +{ + // Don't delete locked objects + if( %object.locked ) + return true; + + if( %object == EWCreatorWindow.objectGroup ) + EWCreatorWindow.setNewObjectGroup( MissionGroup ); + + // Append it to our list. + %this.undoDeleteList = %this.undoDeleteList TAB %object; + + // We're gonna delete this ourselves in the + // completion callback. + return true; +} + +function EditorTree::onObjectDeleteCompleted( %this ) +{ + // This can be called when a deletion is attempted but nothing was + // actually deleted ( cannot delete the root of the tree ) so only submit + // the undo if we really deleted something. + if ( %this.undoDeleteList !$= "" ) + MEDeleteUndoAction::submit( %this.undoDeleteList ); + + // Let the world editor know to + // clear its selection. + EWorldEditor.clearSelection(); + EWorldEditor.isDirty = true; +} + +function EditorTree::onClearSelected(%this) +{ + WorldEditor.clearSelection(); +} + +function EditorTree::onInspect(%this, %obj) +{ + Inspector.inspect(%obj); +} + +function EditorTree::toggleLock( %this ) +{ + if( EWTreeWindow-->LockSelection.command $= "EWorldEditor.lockSelection(true); EditorTree.toggleLock();" ) + { + EWTreeWindow-->LockSelection.command = "EWorldEditor.lockSelection(false); EditorTree.toggleLock();"; + EWTreeWindow-->DeleteSelection.command = ""; + } + else + { + EWTreeWindow-->LockSelection.command = "EWorldEditor.lockSelection(true); EditorTree.toggleLock();"; + EWTreeWindow-->DeleteSelection.command = "EditorMenuEditDelete();"; + } +} + +function EditorTree::onAddSelection(%this, %obj, %isLastSelection) +{ + EWorldEditor.selectObject( %obj ); + + %selSize = EWorldEditor.getSelectionSize(); + %lockCount = EWorldEditor.getSelectionLockCount(); + + if( %lockCount < %selSize ) + { + EWTreeWindow-->LockSelection.setStateOn(0); + EWTreeWindow-->LockSelection.command = "EWorldEditor.lockSelection(true); EditorTree.toggleLock();"; + } + else if ( %lockCount > 0 ) + { + EWTreeWindow-->LockSelection.setStateOn(1); + EWTreeWindow-->LockSelection.command = "EWorldEditor.lockSelection(false); EditorTree.toggleLock();"; + } + + if( %selSize > 0 && %lockCount == 0 ) + EWTreeWindow-->DeleteSelection.command = "EditorMenuEditDelete();"; + else + EWTreeWindow-->DeleteSelection.command = ""; + + if( %isLastSelection ) + Inspector.addInspect( %obj ); + else + Inspector.addInspect( %obj, false ); + +} +function EditorTree::onRemoveSelection(%this, %obj) +{ + EWorldEditor.unselectObject(%obj); + Inspector.removeInspect( %obj ); +} +function EditorTree::onSelect(%this, %obj) +{ +} + +function EditorTree::onUnselect(%this, %obj) +{ + EWorldEditor.unselectObject(%obj); +} + +function EditorTree::onDragDropped(%this) +{ + EWorldEditor.isDirty = true; +} + +function EditorTree::onAddGroupSelected(%this, %group) +{ + EWCreatorWindow.setNewObjectGroup(%group); +} + +function EditorTree::onRightMouseUp( %this, %itemId, %mouse, %obj ) +{ + %haveObjectEntries = false; + %haveLockAndHideEntries = true; + + // Handle multi-selection. + if( %this.getSelectedItemsCount() > 1 ) + { + %popup = ETMultiSelectionContextPopup; + if( !isObject( %popup ) ) + %popup = new PopupMenu( ETMultiSelectionContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Delete" TAB "" TAB "EditorMenuEditDelete();"; + item[ 1 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; + }; + } + + // Open context menu if this is a CameraBookmark + else if( %obj.isMemberOfClass( "CameraBookmark" ) ) + { + %popup = ETCameraBookmarkContextPopup; + if( !isObject( %popup ) ) + %popup = new PopupMenu( ETCameraBookmarkContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Go To Bookmark" TAB "" TAB "EditorGui.jumpToBookmark( %this.bookmark.getInternalName() );"; + + bookmark = -1; + }; + + ETCameraBookmarkContextPopup.bookmark = %obj; + } + + // Open context menu if this is set CameraBookmarks group. + else if( %obj.name $= "CameraBookmarks" ) + { + %popup = ETCameraBookmarksGroupContextPopup; + if( !isObject( %popup ) ) + %popup = new PopupMenu( ETCameraBookmarksGroupContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Add Camera Bookmark" TAB "" TAB "EditorGui.addCameraBookmarkByGui();"; + }; + } + + // Open context menu if this is a SimGroup + else if( !%obj.isMemberOfClass( "SceneObject" ) ) + { + %popup = ETSimGroupContextPopup; + if( !isObject( %popup ) ) + %popup = new PopupMenu( ETSimGroupContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Rename" TAB "" TAB "EditorTree.showItemRenameCtrl( EditorTree.findItemByObjectId( %this.object ) );"; + item[ 1 ] = "Delete" TAB "" TAB "EWorldEditor.deleteMissionObject( %this.object );"; + item[ 2 ] = "Inspect" TAB "" TAB "inspectObject( %this.object );"; + item[ 3 ] = "-"; + item[ 4 ] = "Toggle Lock Children" TAB "" TAB "EWorldEditor.toggleLockChildren( %this.object );"; + item[ 5 ] = "Toggle Hide Children" TAB "" TAB "EWorldEditor.toggleHideChildren( %this.object );"; + item[ 6 ] = "-"; + item[ 7 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; + item[ 8 ] = "-"; + item[ 9 ] = "Add New Objects Here" TAB "" TAB "EWCreatorWindow.setNewObjectGroup( %this.object );"; + item[ 10 ] = "Add Children to Selection" TAB "" TAB "EWorldEditor.selectAllObjectsInSet( %this.object, false );"; + item[ 11 ] = "Remove Children from Selection" TAB "" TAB "EWorldEditor.selectAllObjectsInSet( %this.object, true );"; + + object = -1; + }; + + %popup.object = %obj; + + %hasChildren = %obj.getCount() > 0; + %popup.enableItem( 10, %hasChildren ); + %popup.enableItem( 11, %hasChildren ); + + %haveObjectEntries = true; + %haveLockAndHideEntries = false; + } + + // Open generic context menu. + else + { + %popup = ETContextPopup; + if( !isObject( %popup ) ) + %popup = new PopupMenu( ETContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Rename" TAB "" TAB "EditorTree.showItemRenameCtrl( EditorTree.findItemByObjectId( %this.object ) );"; + item[ 1 ] = "Delete" TAB "" TAB "EWorldEditor.deleteMissionObject( %this.object );"; + item[ 2 ] = "Inspect" TAB "" TAB "inspectObject( %this.object );"; + item[ 3 ] = "-"; + item[ 4 ] = "Locked" TAB "" TAB "%this.object.setLocked( !%this.object.locked ); EWorldEditor.syncGui();"; + item[ 5 ] = "Hidden" TAB "" TAB "EWorldEditor.hideObject( %this.object, !%this.object.hidden ); EWorldEditor.syncGui();"; + item[ 6 ] = "-"; + item[ 7 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; + + object = -1; + }; + + if(%obj.isMemberOfClass("Entity")) + { + %popup = ETEntityContextPopup; + if( !isObject( %popup ) ) + %popup = new PopupMenu( ETEntityContextPopup : ETSimGroupContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 12 ] = "-"; + item[ 13 ] = "Convert to Game Object" TAB "" TAB "EWorldEditor.createGameObject( %this.object );"; + }; + } + + // Specialized version for ConvexShapes. + else if( %obj.isMemberOfClass( "ConvexShape" ) ) + { + %popup = ETConvexShapeContextPopup; + if( !isObject( %popup ) ) + %popup = new PopupMenu( ETConvexShapeContextPopup : ETContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 8 ] = "-"; + item[ 9 ] = "Convert to Zone" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"Zone\" );"; + item[ 10 ] = "Convert to Portal" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"Portal\" );"; + item[ 11 ] = "Convert to Occluder" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"OcclusionVolume\" );"; + item[ 12 ] = "Convert to Sound Space" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"SFXSpace\" );"; + }; + } + + // Specialized version for polyhedral objects. + else if( %obj.isMemberOfClass( "Zone" ) || + %obj.isMemberOfClass( "Portal" ) || + %obj.isMemberOfClass( "OcclusionVolume" ) || + %obj.isMemberOfClass( "SFXSpace" ) ) + { + %popup = ETPolyObjectContextPopup; + if( !isObject( %popup ) ) + %popup = new PopupMenu( ETPolyObjectContextPopup : ETContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 8 ] = "-"; + item[ 9 ] = "Convert to ConvexShape" TAB "" TAB "EWorldEditor.convertSelectionToConvexShape();"; + }; + } + + %popup.object = %obj; + %haveObjectEntries = true; + } + + if( %haveObjectEntries ) + { + %popup.enableItem( 0, %obj.isNameChangeAllowed() && %obj.getName() !$= "MissionGroup" ); + %popup.enableItem( 1, %obj.getName() !$= "MissionGroup" ); + if( %haveLockAndHideEntries ) + { + %popup.checkItem( 4, %obj.locked ); + %popup.checkItem( 5, %obj.hidden ); + } + %popup.enableItem( 7, %this.isItemSelected( %itemId ) ); + } + + %popup.showPopup( Canvas ); +} + +function EditorTree::positionContextMenu( %this, %menu ) +{ + if( (getWord(%menu.position, 0) + getWord(%menu.extent, 0)) > getWord(EWorldEditor.extent, 0) ) + { + %posx = getWord(%menu.position, 0); + %offset = getWord(EWorldEditor.extent, 0) - (%posx + getWord(%menu.extent, 0)) - 5; + %posx += %offset; + %menu.position = %posx @ " " @ getWord(%menu.position, 1); + } +} + +function EditorTree::isValidDragTarget( %this, %id, %obj ) +{ + if( %obj.isMemberOfClass( "Path" ) ) + return EWorldEditor.areAllSelectedObjectsOfType( "Marker" ); + if( %obj.name $= "CameraBookmarks" ) + return EWorldEditor.areAllSelectedObjectsOfType( "CameraBookmark" ); + else + return ( %obj.getClassName() $= "SimGroup" ); +} + +function EditorTree::onBeginReparenting( %this ) +{ + if( isObject( %this.reparentUndoAction ) ) + %this.reparentUndoAction.delete(); + + %action = UndoActionReparentObjects::create( %this ); + + %this.reparentUndoAction = %action; +} + +function EditorTree::onReparent( %this, %obj, %oldParent, %newParent ) +{ + %this.reparentUndoAction.add( %obj, %oldParent, %newParent ); +} + +function EditorTree::onEndReparenting( %this ) +{ + %action = %this.reparentUndoAction; + %this.reparentUndoAction = ""; + + if( %action.numObjects > 0 ) + { + if( %action.numObjects == 1 ) + %action.actionName = "Reparent Object"; + else + %action.actionName = "Reparent Objects"; + + %action.addToManager( Editor.getUndoManager() ); + + EWorldEditor.syncGui(); + } + else + %action.delete(); +} + +function EditorTree::update( %this ) +{ + %this.buildVisibleTree( false ); +} + +//------------------------------------------------------------------------------ + +// Tooltip for TSStatic +function EditorTree::GetTooltipTSStatic( %this, %obj ) +{ + return "Shape: " @ %obj.shapeName; +} + +// Tooltip for ShapeBase +function EditorTree::GetTooltipShapeBase( %this, %obj ) +{ + return "Datablock: " @ %obj.dataBlock; +} + +// Tooltip for StaticShape +function EditorTree::GetTooltipStaticShape( %this, %obj ) +{ + return "Datablock: " @ %obj.dataBlock; +} + +// Tooltip for Item +function EditorTree::GetTooltipItem( %this, %obj ) +{ + return "Datablock: " @ %obj.dataBlock; +} + +// Tooltip for RigidShape +function EditorTree::GetTooltipRigidShape( %this, %obj ) +{ + return "Datablock: " @ %obj.dataBlock; +} + +// Tooltip for Prefab +function EditorTree::GetTooltipPrefab( %this, %obj ) +{ + return "File: " @ %obj.filename; +} + +// Tooltip for GroundCover +function EditorTree::GetTooltipGroundCover( %this, %obj ) +{ + %text = "Material: " @ %obj.material; + for(%i=0; %i<8; %i++) + { + if(%obj.probability[%i] > 0 && %obj.shapeFilename[%i] !$= "") + { + %text = %text NL "Shape " @ %i @ ": " @ %obj.shapeFilename[%i]; + } + } + return %text; +} + +// Tooltip for SFXEmitter +function EditorTree::GetTooltipSFXEmitter( %this, %obj ) +{ + if(%obj.fileName $= "") + return "Track: " @ %obj.track; + else + return "File: " @ %obj.fileName; +} + +// Tooltip for ParticleEmitterNode +function EditorTree::GetTooltipParticleEmitterNode( %this, %obj ) +{ + %text = "Datablock: " @ %obj.dataBlock; + %text = %text NL "Emitter: " @ %obj.emitter; + return %text; +} + +// Tooltip for WorldEditorSelection +function EditorTree::GetTooltipWorldEditorSelection( %this, %obj ) +{ + %text = "Objects: " @ %obj.getCount(); + + if( !%obj.getCanSave() ) + %text = %text NL "Persistent: No"; + else + %text = %text NL "Persistent: Yes"; + + return %text; +} + +//------------------------------------------------------------------------------ + +function EditorTreeTabBook::onTabSelected( %this ) +{ + if( EditorTreeTabBook.getSelectedPage() == 0) + { + EWTreeWindow-->DeleteSelection.visible = true; + EWTreeWindow-->LockSelection.visible = true; + EWTreeWindow-->AddSimGroup.visible = true; + } + else + { + EWTreeWindow-->DeleteSelection.visible = false; + EWTreeWindow-->LockSelection.visible = false; + EWTreeWindow-->AddSimGroup.visible = false; + } +} + +//------------------------------------------------------------------------------ + +function Editor::open(%this) +{ + // prevent the mission editor from opening while the GuiEditor is open. + if(Canvas.getContent() == GuiEditorGui.getId()) + return; + + EditorGui.buildMenus(); + + if( !EditorGui.isInitialized ) + EditorGui.init(); + + %this.editorEnabled(); + Canvas.setContent(EditorGui); + EditorGui.syncCameraGui(); +} + +function Editor::close(%this, %gui) +{ + %this.editorDisabled(); + Canvas.setContent(%gui); + if(isObject(MessageHud)) + MessageHud.close(); + EditorGui.writeCameraSettings(); + + EditorGui.onDestroyMenu(); +} + +function EditorGui::onDestroyMenu(%this) +{ + if( !isObject( %this.menuBar ) ) + return; + + // Destroy menus + while( %this.menuBar.getCount() != 0 ) + %this.menuBar.getObject( 0 ).delete(); + + %this.menuBar.removeFromCanvas(); + %this.menuBar.delete(); +} + +$RelightCallback = ""; + +function EditorLightingComplete() +{ + $lightingMission = false; + RelightStatus.visible = false; + + if ($RelightCallback !$= "") + { + eval($RelightCallback); + } + + $RelightCallback = ""; +} + +function updateEditorLightingProgress() +{ + RelightProgress.setValue(($SceneLighting::lightingProgress)); + if ($lightingMission) + $lightingProgressThread = schedule(1, 0, "updateEditorLightingProgress"); +} + +function Editor::lightScene(%this, %callback, %forceAlways) +{ + if ($lightingMission) + return; + + $lightingMission = true; + $RelightCallback = %callback; + RelightStatus.visible = true; + RelightProgress.setValue(0); + Canvas.repaint(); + lightScene("EditorLightingComplete", %forceAlways); + updateEditorLightingProgress(); +} + +//------------------------------------------------------------------------------ + +function EditorGui::handleEscape( %this ) +{ + %result = false; + if ( isObject( %this.currentEditor ) ) + %result = %this.currentEditor.handleEscape(); + + if ( !%result ) + { + Editor.close("PlayGui"); + } +} + +function EditTSCtrl::updateGizmoMode( %this, %mode ) +{ + // Called when the gizmo mode is changed from C++ + + if ( %mode $= "None" ) + EditorGuiToolbar->NoneModeBtn.performClick(); + else if ( %mode $= "Move" ) + EditorGuiToolbar->MoveModeBtn.performClick(); + else if ( %mode $= "Rotate" ) + EditorGuiToolbar->RotateModeBtn.performClick(); + else if ( %mode $= "Scale" ) + EditorGuiToolbar->ScaleModeBtn.performClick(); +} + +//------------------------------------------------------------------------------ + +function EWorldEditor::syncGui( %this ) +{ + %this.syncToolPalette(); + + EditorTree.update(); + Editor.getUndoManager().updateUndoMenu( EditorGui.menuBar-->EditMenu ); + EditorGuiStatusBar.setSelectionObjectsByCount( %this.getSelectionSize() ); + + EWTreeWindow-->LockSelection.setStateOn( %this.getSelectionLockCount() > 0 ); + + EWorldEditorToolbar-->boundingBoxColBtn.setStateOn( EWorldEditor.boundingBoxCollision ); + + if( EWorldEditor.objectsUseBoxCenter ) + { + EWorldEditorToolbar-->centerObject.setBitmap("tools/gui/images/menubar/bounds-center"); + objectCenterDropdown-->objectBoundsBtn.setStateOn( 1 ); + } + else + { + EWorldEditorToolbar-->centerObject.setBitmap("tools/gui/images/menubar/object-center"); + objectCenterDropdown-->objectBoxBtn.setStateOn( 1 ); + } + + if( GlobalGizmoProfile.getFieldValue(alignment) $= "Object" ) + { + EWorldEditorToolbar-->objectTransform.setBitmap("tools/gui/images/menubar/object-transform"); + objectTransformDropdown-->objectTransformBtn.setStateOn( 1 ); + + } + else + { + EWorldEditorToolbar-->objectTransform.setBitmap("tools/gui/images/menubar/world-transform"); + objectTransformDropdown-->worldTransformBtn.setStateOn( 1 ); + } + + EWorldEditorToolbar-->renderHandleBtn.setStateOn( EWorldEditor.renderObjHandle ); + EWorldEditorToolbar-->renderTextBtn.setStateOn( EWorldEditor.renderObjText ); + + SnapToBar-->objectSnapBtn.setStateOn( EWorldEditor.getSoftSnap() ); + EWorldEditorToolbar-->softSnapSizeTextEdit.setText( EWorldEditor.getSoftSnapSize() ); + ESnapOptions-->SnapSize.setText( EWorldEditor.getSoftSnapSize() ); + ESnapOptions-->GridSize.setText( EWorldEditor.getGridSize() ); + + ESnapOptions-->GridSnapButton.setStateOn( %this.getGridSnap() ); + SnapToBar-->objectGridSnapBtn.setStateOn( %this.getGridSnap() ); + ESnapOptions-->NoSnapButton.setStateOn( !%this.stickToGround && !%this.getSoftSnap() && !%this.getGridSnap() ); +} + +function EWorldEditor::syncToolPalette( %this ) +{ + switch$ ( GlobalGizmoProfile.mode ) + { + case "None": + EWorldEditorNoneModeBtn.performClick(); + case "Move": + EWorldEditorMoveModeBtn.performClick(); + case "Rotate": + EWorldEditorRotateModeBtn.performClick(); + case "Scale": + EWorldEditorScaleModeBtn.performClick(); + } +} + +function EWorldEditor::addSimGroup( %this, %groupCurrentSelection ) +{ + %activeSelection = %this.getActiveSelection(); + if ( %activeSelection.getObjectIndex( MissionGroup ) != -1 ) + { + MessageBoxOK( "Error", "Cannot add MissionGroup to a new SimGroup" ); + return; + } + + // Find our parent. + + %parent = MissionGroup; + if( !%groupCurrentSelection && isObject( %activeSelection ) && %activeSelection.getCount() > 0 ) + { + %firstSelectedObject = %activeSelection.getObject( 0 ); + if( %firstSelectedObject.isMemberOfClass( "SimGroup" ) ) + %parent = %firstSelectedObject; + else if( %firstSelectedObject.getId() != MissionGroup.getId() ) + %parent = %firstSelectedObject.parentGroup; + } + + // If we are about to do a group-selected as well, + // starting recording an undo compound. + + if( %groupCurrentSelection ) + Editor.getUndoManager().pushCompound( "Group Selected" ); + + // Create the SimGroup. + + %object = new SimGroup() + { + parentGroup = %parent; + }; + MECreateUndoAction::submit( %object ); + + // Put selected objects into the group, if requested. + + if( %groupCurrentSelection && isObject( %activeSelection ) ) + { + %undo = UndoActionReparentObjects::create( EditorTree ); + + %numObjects = %activeSelection.getCount(); + for( %i = 0; %i < %numObjects; %i ++ ) + { + %sel = %activeSelection.getObject( %i ); + %undo.add( %sel, %sel.parentGroup, %object ); + %object.add( %sel ); + } + + %undo.addToManager( Editor.getUndoManager() ); + } + + // Stop recording for group-selected. + + if( %groupCurrentSelection ) + Editor.getUndoManager().popCompound(); + + // When not grouping selection, make the newly created SimGroup the + // current selection. + + if( !%groupCurrentSelection ) + { + EWorldEditor.clearSelection(); + EWorldEditor.selectObject( %object ); + } + + // Refresh the Gui. + + %this.syncGui(); +} + +function EWorldEditor::toggleLockChildren( %this, %simGroup ) +{ + foreach( %child in %simGroup ) + { + if( %child.class $= "SimGroup" ) + { + %this.toggleHideChildren( %child ); + } + if( %child.isMemberOfClass( "SimGroup" ) ) + { + %this.toggleHideChildren( %child ); + %child.setLocked( !%child.locked ); + } + else + { + %child.setLocked( !%child.locked ); + } + } + + EWorldEditor.syncGui(); +} + +function EWorldEditor::toggleHideChildren( %this, %simGroup ) +{ + foreach( %child in %simGroup ) + { + if( %child.class $= "SimGroup" ) + { + %this.toggleHideChildren( %child ); + } + if( %child.isMemberOfClass( "SimGroup" ) ) + { + %this.toggleHideChildren( %child ); + %this.hideObject( %child, !%child.hidden ); + } + else + { + %this.hideObject( %child, !%child.hidden ); + } + } + + EWorldEditor.syncGui(); +} + +function EWorldEditor::convertSelectionToPolyhedralObjects( %this, %className ) +{ + %group = %this.getNewObjectGroup(); + %undoManager = Editor.getUndoManager(); + + %activeSelection = %this.getActiveSelection(); + while( %activeSelection.getCount() != 0 ) + { + %oldObject = %activeSelection.getObject( 0 ); + %newObject = %this.createPolyhedralObject( %className, %oldObject ); + if( isObject( %newObject ) ) + { + %undoManager.pushCompound( "Convert ConvexShape to " @ %className ); + %newObject.parentGroup = %oldObject.parentGroup; + MECreateUndoAction::submit( %newObject ); + MEDeleteUndoAction::submit( %oldObject ); + %undoManager.popCompound(); + } + } +} + +function EWorldEditor::convertSelectionToConvexShape( %this ) +{ + %group = %this.getNewObjectGroup(); + %undoManager = Editor.getUndoManager(); + + %activeSelection = %this.getActiveSelection(); + while( %activeSelection.getCount() != 0 ) + { + %oldObject = %activeSelection.getObject( 0 ); + %newObject = %this.createConvexShapeFrom( %oldObject ); + if( isObject( %newObject ) ) + { + %undoManager.pushCompound( "Convert " @ %oldObject.getClassName() @ " to ConvexShape" ); + %newObject.parentGroup = %oldObject.parentGroup; + MECreateUndoAction::submit( %newObject ); + MEDeleteUndoAction::submit( %oldObject ); + %undoManager.popCompound(); + } + } +} + +function EWorldEditor::getNewObjectGroup( %this ) +{ + return EWCreatorWindow.getNewObjectGroup(); +} + +function EWorldEditor::deleteMissionObject( %this, %object ) +{ + // Unselect in editor tree. + + %id = EditorTree.findItemByObjectId( %object ); + EditorTree.selectItem( %id, false ); + + // Delete object. + + MEDeleteUndoAction::submit( %object ); + EWorldEditor.isDirty = true; + EditorTree.buildVisibleTree( true ); +} + +function EWorldEditor::createGameObject( %this, %entity ) +{ + if(!isObject(GameObjectBuilder)) + { + new GuiControl(GameObjectBuilder, EditorGuiGroup) { + profile = "ToolsGuiDefaultProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "0 0"; + extent = "800 600"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + + new GuiWindowCtrl(GameObjectBuilderTargetWindow) { + profile = "ToolsGuiWindowProfile"; + horizSizing = "center"; + vertSizing = "center"; + position = "384 205"; + extent = "256 102"; + minExtent = "256 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + resizeWidth = "1"; + resizeHeight = "1"; + canMove = "1"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + minSize = "50 50"; + text = "Create Object"; + + new GuiTextCtrl() { + profile = "GuiCenterTextProfile"; + horizSizing = "right"; + vertSizing = "bottom"; + position = "9 26"; + extent = "84 16"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + text = "Object Name:"; + }; + new GuiTextEditCtrl(GameObjectBuilderObjectName) { + class = ObjectBuilderGuiTextEditCtrl; + profile = "ToolsGuiTextEditProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "78 26"; + extent = "172 18"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + historySize = "0"; + }; + new GuiButtonCtrl(GameObjectBuilderOKButton) { + profile = "ToolsGuiButtonProfile"; + horizSizing = "width"; + vertSizing = "bottom"; + position = "7 250"; + extent = "156 24"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + command = "EWorldEditor.buildGameObject();"; + helpTag = "0"; + text = "Create New"; + Accelerator = "return"; + }; + new GuiButtonCtrl(GameObjectBuilderCancelButton) { + profile = "ToolsGuiButtonProfile"; + horizSizing = "left"; + vertSizing = "bottom"; + position = "170 250"; + extent = "80 24"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + command = "Canvas.popDialog(GameObjectBuilder);"; + helpTag = "0"; + text = "Cancel"; + Accelerator = "escape"; + }; + }; + }; + + GameObjectBuilderTargetWindow.extent = getWord(GameObjectBuilderTargetWindow.extent, 0) SPC 88; + GameObjectBuilderOKButton.position = getWord(GameObjectBuilderOKButton.position, 0) SPC 57; + GameObjectBuilderCancelButton.position = getWord(GameObjectBuilderCancelButton.position, 0) SPC 57; + } + + GameObjectBuilderObjectName.text = ""; + GameObjectBuilder.selectedEntity = %entity; + + Canvas.pushDialog(GameObjectBuilder); +} + +function EWorldEditor::buildGameObject(%this) +{ + if(GameObjectBuilderObjectName.getText() $= "") + { + error("Attempted to make a new Game Object with no name!"); + Canvas.popDialog(GameObjectBuilder); + return; + } + + %path = EditorSettings.value( "WorldEditor/newGameObjectDir" ); + %className = GameObjectBuilderObjectName.getText(); + GameObjectBuilder.selectedEntity.class = %className; + Inspector.inspect(GameObjectBuilder.selectedEntity); + + %file = new FileObject(); + + if(%file.openForWrite(%path @ "\\" @ %className @ ".cs")) + { + %file.writeline("function " @ %className @ "::onAdd(%this)\n{\n\n}\n"); + %file.writeline("function " @ %className @ "::onRemove(%this)\n{\n\n}\n"); + + //todo, pre-write any event functions of interest + + %file.close(); + } + + //set up the paths + %tamlPath = %path @ "/" @ %className @ ".taml"; + %scriptPath = %path @ "/" @ %className @ ".cs"; + saveGameObject(%className, %tamlPath, %scriptPath); + + //reload it + execGameObjects(); + + //now, add the script file and a ref to the taml into our SGO manifest so we can readily spawn it later. + TamlWrite(GameObjectBuilder.selectedEntity, %tamlpath); + + GameObjectBuilder.selectedEntity = ""; + + Canvas.popDialog(GameObjectBuilder); +} + +function EWorldEditor::selectAllObjectsInSet( %this, %set, %deselect ) +{ + if( !isObject( %set ) ) + return; + + foreach( %obj in %set ) + { + if( %deselect ) + %this.unselectObject( %obj ); + else + %this.selectObject( %obj ); + } +} + +function toggleSnappingOptions( %var ) +{ + if( SnapToBar->objectSnapDownBtn.getValue() && SnapToBar->objectSnapBtn.getValue() ) + { + if( %var $= "terrain" ) + { + EWorldEditor.stickToGround = 1; + EWorldEditor.setSoftSnap(false); + ESnapOptionsTabBook.selectPage(0); + SnapToBar->objectSnapBtn.setStateOn(0); + } + else + { + // soft snapping + EWorldEditor.stickToGround = 0; + EWorldEditor.setSoftSnap(true); + ESnapOptionsTabBook.selectPage(1); + SnapToBar->objectSnapDownBtn.setStateOn(0); + } + } + else if( %var $= "terrain" && EWorldEditor.stickToGround == 0 ) + { + // Terrain Snapping + EWorldEditor.stickToGround = 1; + EWorldEditor.setSoftSnap(false); + ESnapOptionsTabBook.selectPage(0); + SnapToBar->objectSnapDownBtn.setStateOn(1); + SnapToBar->objectSnapBtn.setStateOn(0); + + } + else if( %var $= "soft" && EWorldEditor.getSoftSnap() == false ) + { + // Object Snapping + EWorldEditor.stickToGround = 0; + EWorldEditor.setSoftSnap(true); + ESnapOptionsTabBook.selectPage(1); + SnapToBar->objectSnapBtn.setStateOn(1); + SnapToBar->objectSnapDownBtn.setStateOn(0); + + } + else if( %var $= "grid" ) + { + EWorldEditor.setGridSnap( !EWorldEditor.getGridSnap() ); + } + else + { + // No snapping. + + EWorldEditor.stickToGround = false; + EWorldEditor.setGridSnap( false ); + EWorldEditor.setSoftSnap( false ); + + SnapToBar->objectSnapDownBtn.setStateOn(0); + SnapToBar->objectSnapBtn.setStateOn(0); + } + + EWorldEditor.syncGui(); +} + +function objectCenterDropdown::toggle() +{ + if ( objectCenterDropdown.visible ) + { + EWorldEditorToolbar-->centerObject.setStateOn(false); + objectCenterDropdownDecoy.setVisible(false); + objectCenterDropdownDecoy.setActive(false); + objectCenterDropdown.setVisible(false); + } + else + { + EWorldEditorToolbar-->centerObject.setStateOn(true); + objectCenterDropdown.setVisible(true); + objectCenterDropdownDecoy.setActive(true); + objectCenterDropdownDecoy.setVisible(true); + } +} + +function objectTransformDropdown::toggle() +{ + if ( objectTransformDropdown.visible ) + { + EWorldEditorToolbar-->objectTransform.setStateOn(false); + objectTransformDropdownDecoy.setVisible(false); + objectTransformDropdownDecoy.setActive(false); + objectTransformDropdown.setVisible(false); + } + else + { + EWorldEditorToolbar-->objectTransform.setStateOn(true); + objectTransformDropdown.setVisible(true); + objectTransformDropdownDecoy.setActive(true); + objectTransformDropdownDecoy.setVisible(true); + } +} + +function objectSnapDropdownDecoy::onMouseLeave() +{ + objectSnapDropdown.toggle(); +} + +function objectCenterDropdownDecoy::onMouseLeave() +{ + objectCenterDropdown.toggle(); +} + +function objectTransformDropdownDecoy::onMouseLeave() +{ + objectTransformDropdown.toggle(); +} + +//------------------------------------------------------------------------------ + +function EWAddSimGroupButton::onDefaultClick( %this ) +{ + EWorldEditor.addSimGroup(); +} + +function EWAddSimGroupButton::onCtrlClick( %this ) +{ + EWorldEditor.addSimGroup( true ); +} + +//------------------------------------------------------------------------------ + +function EWToolsToolbar::reset( %this ) +{ + %count = ToolsToolbarArray.getCount(); + for( %i = 0 ; %i < %count; %i++ ) + ToolsToolbarArray.getObject(%i).setVisible(true); + + %this.setExtent((29 + 4) * %count + 12, 33); + %this.isClosed = 0; + EWToolsToolbar.isDynamic = 0; + + EWToolsToolbarDecoy.setVisible(false); + EWToolsToolbarDecoy.setExtent((29 + 4) * %count + 4, 31); + + %this-->resizeArrow.setBitmap( "tools/gui/images/collapse-toolbar" ); +} + +function EWToolsToolbar::toggleSize( %this, %useDynamics ) +{ + // toggles the size of the tooltoolbar. also goes through + // and hides each control not currently selected. we hide the controls + // in a very neat, spiffy way + + if ( %this.isClosed == 0 ) + { + %image = "tools/gui/images/expand-toolbar"; + + for( %i = 0 ; %i < ToolsToolbarArray.getCount(); %i++ ) + { + if( ToolsToolbarArray.getObject(%i).getValue() != 1 ) + ToolsToolbarArray.getObject(%i).setVisible(false); + } + + %this.setExtent(43, 33); + %this.isClosed = 1; + + if(!%useDynamics) + { + EWToolsToolbarDecoy.setVisible(true); + EWToolsToolbar.isDynamic = 1; + } + + EWToolsToolbarDecoy.setExtent(35, 31); + } + else + { + %image = "tools/gui/images/collapse-toolbar"; + + %count = ToolsToolbarArray.getCount(); + for( %i = 0 ; %i < %count; %i++ ) + ToolsToolbarArray.getObject(%i).setVisible(true); + + %this.setExtent((29 + 4) * %count + 12, 33); + %this.isClosed = 0; + + if(!%useDynamics) + { + EWToolsToolbarDecoy.setVisible(false); + EWToolsToolbar.isDynamic = 0; + } + + EWToolsToolbarDecoy.setExtent((29 + 4) * %count + 4, 32); + } + + %this-->resizeArrow.setBitmap( %image ); + +} + +function EWToolsToolbarDecoy::onMouseEnter( %this ) +{ + EWToolsToolbar.toggleSize(true); +} + +function EWToolsToolbarDecoy::onMouseLeave( %this ) +{ + EWToolsToolbar.toggleSize(true); +} + +//------------------------------------------------------------------------------ + +function EditorGuiStatusBar::reset( %this ) +{ + EWorldEditorStatusBarInfo.clearInfo(); +} + +function EditorGuiStatusBar::getInfo( %this ) +{ + return EWorldEditorStatusBarInfo.getValue(); +} + +function EditorGuiStatusBar::setInfo( %this, %text ) +{ + EWorldEditorStatusBarInfo.setText(%text); +} + +function EditorGuiStatusBar::clearInfo( %this ) +{ + EWorldEditorStatusBarInfo.setText(""); +} + +function EditorGuiStatusBar::getSelection( %this ) +{ + return EWorldEditorStatusBarSelection.getValue(); +} + +function EditorGuiStatusBar::setSelection( %this, %text ) +{ + EWorldEditorStatusBarSelection.setText(%text); +} + +function EditorGuiStatusBar::setSelectionObjectsByCount( %this, %count ) +{ + %text = " objects selected"; + if(%count == 1) + %text = " object selected"; + + EWorldEditorStatusBarSelection.setText(%count @ %text); +} + +function EditorGuiStatusBar::clearSelection( %this ) +{ + EWorldEditorStatusBarSelection.setText(""); +} + +function EditorGuiStatusBar::getCamera( %this ) +{ + return EWorldEditorStatusBarCamera.getText(); +} + +function EditorGuiStatusBar::setCamera( %this, %text ) +{ + %id = EWorldEditorStatusBarCamera.findText( %text ); + if( %id != -1 ) + { + if ( EWorldEditorStatusBarCamera.getSelected() != %id ) + EWorldEditorStatusBarCamera.setSelected( %id, true ); + } +} + +function EWorldEditorStatusBarCamera::onWake( %this ) +{ + %this.add( "Standard Camera" ); + %this.add( "1st Person Camera" ); + %this.add( "3rd Person Camera" ); + %this.add( "Orbit Camera" ); + %this.add( "Top View" ); + %this.add( "Bottom View" ); + %this.add( "Left View" ); + %this.add( "Right View" ); + %this.add( "Front View" ); + %this.add( "Back View" ); + %this.add( "Isometric View" ); + %this.add( "Smooth Camera" ); + %this.add( "Smooth Rot Camera" ); +} + +function EWorldEditorStatusBarCamera::onSelect( %this, %id, %text ) +{ + switch$( %text ) + { + case "Top View": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeTop ); + + case "Bottom View": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeBottom ); + + case "Left View": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeLeft ); + + case "Right View": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeRight ); + + case "Front View": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeFront ); + + case "Back View": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeBack ); + + case "Isometric View": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypeIsometric ); + + case "Standard Camera": + commandToServer( 'SetEditorCameraStandard' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); + + case "1st Person Camera": + commandToServer( 'SetEditorCameraPlayer' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); + + case "3rd Person Camera": + commandToServer( 'SetEditorCameraPlayerThird' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); + + case "Orbit Camera": + commandToServer( 'SetEditorOrbitCamera' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); + + case "Smooth Camera": + commandToServer( 'SetEditorCameraNewton' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); + + case "Smooth Rot Camera": + commandToServer( 'SetEditorCameraNewtonDamped' ); + EditorGui.setDisplayType( $EditTsCtrl::DisplayTypePerspective ); + } +} + +//------------------------------------------------------------------------------------ +// Each a gui slider bar is pushed on the editor gui, it maps itself with value +// located in its connected text control +//------------------------------------------------------------------------------------ +function softSnapSizeSliderCtrlContainer::onWake(%this) +{ + %this-->slider.setValue(EWorldEditorToolbar-->softSnapSizeTextEdit.getValue()); +} +function softSnapSizeSliderCtrlContainer::onSliderChanged(%this) +{ + EWorldEditor.setSoftSnapSize( %this-->slider.value ); + EWorldEditor.syncGui(); +} +//------------------------------------------------------------------------------------ + +function PaintBrushSizeSliderCtrlContainer::onWake(%this) +{ + %this-->slider.range = "1" SPC getWord(ETerrainEditor.maxBrushSize, 0); + %this-->slider.setValue(PaintBrushSizeTextEditContainer-->textEdit.getValue()); +} + +function PaintBrushPressureSliderCtrlContainer::onWake(%this) +{ + %this-->slider.setValue(PaintBrushPressureTextEditContainer-->textEdit.getValue() / 100); +} + +function PaintBrushSoftnessSliderCtrlContainer::onWake(%this) +{ + %this-->slider.setValue(PaintBrushSoftnessTextEditContainer-->textEdit.getValue() / 100); +} + +//------------------------------------------------------------------------------------ + +function TerrainBrushSizeSliderCtrlContainer::onWake(%this) +{ + %this-->slider.range = "1" SPC getWord(ETerrainEditor.maxBrushSize, 0); + %this-->slider.setValue(TerrainBrushSizeTextEditContainer-->textEdit.getValue()); +} + +function TerrainBrushPressureSliderCtrlContainer::onWake(%this) +{ + %this-->slider.setValue(TerrainBrushPressureTextEditContainer-->textEdit.getValue() / 100.0); +} + +function TerrainBrushSoftnessSliderCtrlContainer::onWake(%this) +{ + %this-->slider.setValue(TerrainBrushSoftnessTextEditContainer-->textEdit.getValue() / 100.0); +} + +function TerrainSetHeightSliderCtrlContainer::onWake(%this) +{ + %this-->slider.setValue(TerrainSetHeightTextEditContainer-->textEdit.getValue()); +} +//------------------------------------------------------------------------------------ +function CameraSpeedDropdownCtrlContainer::onWake(%this) +{ + %this-->slider.setValue(CameraSpeedDropdownContainer-->textEdit.getText()); +} + +//------------------------------------------------------------------------------------ +// Callbacks to close the dropdown slider controls like the camera speed, +// that are marked with this class name. + +function EditorDropdownSliderContainer::onMouseDown(%this) +{ + Canvas.popDialog(%this); +} + +function EditorDropdownSliderContainer::onRightMouseDown(%this) +{ + Canvas.popDialog(%this); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/ManageSFXParametersWindow.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/ManageSFXParametersWindow.ed.cs new file mode 100644 index 000000000..5e1134d38 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/ManageSFXParametersWindow.ed.cs @@ -0,0 +1,847 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +//============================================================================= +// Constants. +//============================================================================= + +/// File to save newly created SFXParameters in by default. +$SFX_PARAMETER_FILE = "scripts/client/audioData.cs"; + +$SFX_PARAMETER_CHANNELS[ 0 ] = "Volume"; +$SFX_PARAMETER_CHANNELS[ 1 ] = "Pitch"; +$SFX_PARAMETER_CHANNELS[ 2 ] = "Priority"; +$SFX_PARAMETER_CHANNELS[ 3 ] = "MinDistance"; +$SFX_PARAMETER_CHANNELS[ 4 ] = "MaxDistance"; +$SFX_PARAMETER_CHANNELS[ 5 ] = "ConeInsideAngle"; +$SFX_PARAMETER_CHANNELS[ 6 ] = "ConeOutsideAngle"; +$SFX_PARAMETER_CHANNELS[ 7 ] = "ConeOutsideVolume"; +$SFX_PARAMETER_CHANNELS[ 8 ] = "PositionX"; +$SFX_PARAMETER_CHANNELS[ 9 ] = "PositionY"; +$SFX_PARAMETER_CHANNELS[ 10 ] = "PositionZ"; +$SFX_PARAMETER_CHANNELS[ 11 ] = "RotationX"; +$SFX_PARAMETER_CHANNELS[ 12 ] = "RotationY"; +$SFX_PARAMETER_CHANNELS[ 13 ] = "RotationZ"; +$SFX_PARAMETER_CHANNELS[ 14 ] = "VelocityX"; +$SFX_PARAMETER_CHANNELS[ 15 ] = "VelocityY"; +$SFX_PARAMETER_CHANNELS[ 16 ] = "VelocityZ"; +$SFX_PARAMETER_CHANNELS[ 17 ] = "Cursor"; +$SFX_PARAMETER_CHANNELS[ 18 ] = "User0"; +$SFX_PARAMETER_CHANNELS[ 19 ] = "User1"; +$SFX_PARAMETER_CHANNELS[ 20 ] = "User2"; +$SFX_PARAMETER_CHANNELS[ 21 ] = "User3"; + +$SFX_PARAMETER_CHANNELS_COUNT = 22; + +/// Interval (in milliseconds) between GUI updates. Each update +/// syncs the displayed values to the actual parameter states. +$SFX_PARAMETERS_UPDATE_INTERVAL = 50; + +//============================================================================= +// EManageSFXParameters. +//============================================================================= + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::createNewParameter( %this, %name ) +{ + %parameter = new SFXParameter() + { + internalName = %name; + }; + + if( !isObject( %parameter ) ) + return; + + %parameter.setFilename( $SFX_PARAMETER_FILE ); + %this.persistenceMgr.setDirty( %parameter ); + %this.persistenceMgr.saveDirty(); + + %this.addParameter( %parameter ); +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::showDeleteParameterDlg( %this, %parameter ) +{ + MessageBoxOkCancel( "Confirmation", + "Really delete '" @ %parameter.getInternalName() @ "'?" NL + "" NL + "The parameter will be removed from the file '" @ %parameter.getFileName() @ "'.", + %this @ ".deleteParameter( " @ %parameter @ " );" + ); +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::deleteParameter( %this, %parameter ) +{ + %this.removeParameter( %parameter ); + if( %parameter.getFilename() !$= "" ) + %this.persistenceMgr.removeObjectFromFile( %parameter ); + + %parameter.delete(); +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::saveParameter( %this, %parameter ) +{ + if( %parameter.getFilename() !$= "" ) + { + if( !%this.persistenceMgr.isDirty( %parameter ) ) + %this.persistenceMgr.setDirty( %parameter ); + + %this.persistenceMgr.saveDirty(); + } +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::onWake( %this ) +{ + // If the parameter list is empty, add all SFXParameters in the + // SFXParameterGroup to the list. + + if( %this-->SFXParametersStack.getCount() == 0 ) + %this.initList(); + + if( !isObject( %this.persistenceMgr ) ) + %this.persistenceMgr = new PersistenceManager(); +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::onVisible( %this, %value ) +{ + if( %value ) + { + // Schedule an update. + + %this.schedule( %SFX_PARAMETERS_UPDATE_INTERVAL, "update" ); + } +} + +//----------------------------------------------------------------------------- + +/// Populate the parameter list with the currently defined SFXParameters. +function EManageSFXParameters::initList( %this, %filter ) +{ + // Clear the current lists. + + %this-->SFXParametersStack.clear(); + + // Add each SFXParameter in SFXParameterGroup. + + foreach( %obj in SFXParameterGroup ) + { + if( !isMemberOfClass( %obj.getClassName(), "SFXParameter" ) ) + continue; + + // If we have a filter, search for it in the parameter's + // categories. + + %matchesFilter = true; + if( %filter !$= "" ) + { + %matchesFilter = false; + + for( %idx = 0; %obj.categories[ %idx ] !$= ""; %idx ++ ) + { + if( %obj.categories[ %idx ] $= %filter ) + { + %matchesFilter = true; + break; + } + } + } + + if( %matchesFilter ) + %this.addParameter( %obj ); + } + + // Init the filters. + + %this.initFilterList( %filter ); +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::initFilterList( %this, %selectFilter ) +{ + %filterList = %this-->SFXParameterFilter; + %filterList.clear(); + %filterList.add( "", 0 ); + + foreach( %obj in SFXParameterGroup ) + { + if( !isMemberOfClass( %obj.getClassName(), "SFXParameter" ) ) + continue; + + for( %idx = 0; %obj.categories[ %idx ] !$= ""; %idx ++ ) + { + %category = %obj.categories[ %idx ]; + if( %filterList.findText( %category ) == -1 ) + %filterList.add( %category, %filterList.size() ); + } + } + + // Sort the filters. + + %filterList.sort(); + %filterList.setSelected( %filterList.findText( %selectFilter ), false ); +} + +//----------------------------------------------------------------------------- + +/// Parse the categories for the parameter from the given comma-separated list. +function EManageSFXParameters::updateParameterCategories( %this, %parameter, %list ) +{ + %this.persistenceMgr.setDirty( %parameter ); + + // Parse the list. + + %len = strlen( %list ); + %pos = 0; + + %idx = 0; + while( %pos < %len ) + { + %startPos = %pos; + %pos = strchrpos( %list, ",", %pos ); + if( %pos == -1 ) + %pos = %len; + + if( %pos > %startPos ) + { + %category = getSubStr( %list, %startPos, %pos - %startPos ); + %category = trim( %category ); + %parameter.categories[ %idx ] = %category; + %idx ++; + } + + %pos ++; + } + + // Clear out excess categories existing from before. + + while( %parameter.categories[ %idx ] !$= "" ) + { + %parameter.categories[ %idx ] = ""; + %this.persistenceMgr.removeField( %parameter, "categories" @ %idx ); + %idx ++; + } + + // Save the parameter. + + %this.saveParameter( %parameter ); + + // Re-initialize the filter list. + + %this.initFilterList( %this-->SFXParameterFilter.getText() ); +} + +//----------------------------------------------------------------------------- + +/// Add a new SFXParameter to the list. +function EManageSFXParameters::addParameter( %this, %parameter ) +{ + %ctrl = new GuiRolloutCtrl() { + Margin = "0 0 0 0"; + DefaultHeight = "40"; + Expanded = "1"; + ClickCollapse = "1"; + HideHeader = "0"; + isContainer = "1"; + Profile = "GuiRolloutProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 0"; + Extent = "421 114"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + caption = %parameter.getInternalName(); + + new GuiControl() { + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "0 17"; + Extent = "421 94"; + MinExtent = "421 94"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Value"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 4"; + Extent = "27 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Channel"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 27"; + Extent = "45 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Comment"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 50"; + Extent = "47 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Tags"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiAutoSizeTextProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "7 73"; + Extent = "25 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Min"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiAutoSizeTextProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "205 27"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Max"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiAutoSizeTextProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "271 27"; + Extent = "21 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Initial"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiAutoSizeTextProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "340 27"; + Extent = "24 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + canSaveDynamicFields = "0"; + }; + new GuiSliderCtrl() { + range = "0 1"; + ticks = "0"; + snap = "0"; + value = "0.5"; + isContainer = "0"; + Profile = "ToolsGuiSliderProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "65 5"; + Extent = "263 15"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "valueSlider"; + canSaveDynamicFields = "0"; + command = %parameter @ ".value = $thisControl.getValue();"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "336 4"; + Extent = "39 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "valueField"; + canSaveDynamicFields = "0"; + altCommand = %parameter @ ".value = $thisControl.getValue();"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/reset-icon"; + autoFit = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "381 4"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "resetButton"; + canSaveDynamicFields = "0"; + command = %parameter @ ".reset();"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + autoFit = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "398 4"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "deleteButton"; + canSaveDynamicFields = "0"; + command = "EManageSFXParameters.showDeleteParameterDlg( " @ %parameter @ ");"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "65 26"; + Extent = "135 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "channelDropdown"; + canSaveDynamicFields = "0"; + command = %parameter @ ".channel = $ThisControl.getText(); EManageSFXParameters.saveParameter( " @ %parameter @ ");"; //RDTODO: update range + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "65 50"; + Extent = "350 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "descriptionField"; + canSaveDynamicFields = "0"; + altCommand = %parameter @ ".description = $ThisControl.getText(); EManageSFXParameters.saveParameter( " @ %parameter @ ");"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "65 73"; + Extent = "230 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "tagsField"; + canSaveDynamicFields = "0"; + altCommand = "EManageSFXParameters.updateParameterCategories( " @ %parameter @ ", $ThisControl.getText() );"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "372 27"; + Extent = "43 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "defaultField"; + canSaveDynamicFields = "0"; + command = %parameter @ ".defaultValue = $ThisControl.getValue(); EManageSFXParameters.saveParameter( " @ %parameter @ ");"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "297 27"; + Extent = "39 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "rangeMaxField"; + canSaveDynamicFields = "0"; + altCommand = %parameter @ ".range = " @ %parameter @ ".range.x SPC $ThisControl.getValue(); $ThisControl.parentGroup-->valueSlider.range = " @ %parameter @ ".range; EManageSFXParameters.saveParameter( " @ %parameter @ ");"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + password = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + passwordMask = "•"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiTextEditProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "229 27"; + Extent = "39 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "rangeMinField"; + canSaveDynamicFields = "0"; + altCommand = %parameter @ ".range = $ThisControl.getValue() SPC " @ %parameter @ ".range.y; $ThisControl.parentGroup-->valueSlider.range = " @ %parameter @ ".range; EManageSFXParameters.saveParameter( " @ %parameter @ ");"; + }; + new GuiCheckBoxCtrl() { + useInactiveState = "0"; + text = "Local"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "302 73"; + Extent = "45 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "localCheckbox"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiPopUpMenuProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "349 73"; + Extent = "64 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + internalName = "sourceDropdown"; + canSaveDynamicFields = "0"; + }; + }; + }; + + %ctrl.sfxParameter = %parameter; + + // Deactivate the per-source controls for now as these are not + // yet implemented in SFX. + + %ctrl-->localCheckbox.setActive( false ); + %ctrl-->sourceDropdown.setActive( false ); + + // Set the fields to reflect the parameter's current settings. + + %ctrl-->valueField.setValue( %paramter.value ); + %ctrl-->rangeMinField.setText( %parameter.range.x ); + %ctrl-->rangeMaxField.setText( %parameter.range.y ); + %ctrl-->defaultField.setValue( %parameter.defaultValue ); + %ctrl-->descriptionField.setText( %parameter.description ); + + %ctrl-->valueSlider.range = %parameter.range; + %ctrl-->valueSlider.setValue( %parameter.value ); + + // Set up the channels dropdown. + + %list = %ctrl-->channelDropdown; + for( %i = 0; %i < $SFX_PARAMETER_CHANNELS_COUNT; %i ++ ) + %list.add( $SFX_PARAMETER_CHANNELS[ %i ], %i ); + %list.sort(); + %list.setSelected( %list.findText( %parameter.channel ) ); + + %this-->SFXParametersStack.addGuiControl( %ctrl ); + + // Fill tagging field. + + %tags = ""; + %isFirst = true; + for( %i = 0; %parameter.categories[ %i ] !$= ""; %i ++ ) + { + if( !%isFirst ) + %tags = %tags @ ", "; + + %tags = %tags @ %parameter.categories[ %i ]; + + %isFirst = false; + } + + %ctrl-->tagsField.setText( %tags ); +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::removeParameter( %this, %parameter ) +{ + foreach( %ctrl in %this-->SFXParametersStack ) + { + if( %ctrl.sfxParameter == %parameter ) + { + %ctrl.delete(); + break; + } + } +} + +//----------------------------------------------------------------------------- + +function EManageSFXParameters::update( %this ) +{ + foreach( %ctrl in %this-->SFXParametersStack ) + { + // If either the value field or the slider are currently being + // edited, don't update the value in order to not interfere with + // user editing. + + if( %ctrl-->valueField.isFirstResponder() || %ctrl-->valueSlider.isThumbBeingDragged() ) + continue; + + %parameter = %ctrl.sfxParameter; + + %ctrl-->valueField.setValue( %parameter.value ); + %ctrl-->valueSlider.setValue( %parameter.value ); + } + + // If the control is still awake, schedule another + // update. + + if( %this.isVisible() ) + %this.schedule( $SFX_PARAMETERS_UPDATE_INTERVAL, "update" ); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/SelectObjectsWindow.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/SelectObjectsWindow.ed.cs new file mode 100644 index 000000000..2c436f74f --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/SelectObjectsWindow.ed.cs @@ -0,0 +1,178 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +singleton SimGroup( EWorldEditorSelectionFilters ); + + +//--------------------------------------------------------------------------------------------- + +function ESelectObjectsWindow::toggleVisibility( %this ) +{ + if( %this.isVisible() ) + %this.setVisible( false ); + else + %this.setVisible( true ); +} + +//--------------------------------------------------------------------------------------------- + +/// Function called by EObjectSelection::onSelectObjects to determine where +/// to start searching for objects. +function ESelectObjectsWindow::getRootGroup( %this ) +{ + return MissionGroup; +} + +//--------------------------------------------------------------------------------------------- + +/// Function called by EObjectSelection::initFilterList to retrieve the set of +/// filter objects. +function ESelectObjectsWindow::getFilterSet( %this ) +{ + return EWorldEditorSelectionFilters; +} + +//--------------------------------------------------------------------------------------------- + +/// Method called by EObjectSelection::initClassList to determine if the given +/// class should be included in the class list. +function ESelectObjectsWindow::includeClass( %this, %className ) +{ + if( isMemberOfClass( %className, "SceneObject" ) + || %className $= "SimGroup" + || %className $= "LevelInfo" ) // Derived directly from NetObject. + return true; + + return false; +} + +//--------------------------------------------------------------------------------------------- + +/// Method called by the EObjectSelection machinery when an object has been +/// matched against the given criteria. +function ESelectObjectsWindow::selectObject( %this, %object, %val ) +{ + if( %this.selectionSet ) + { + if( %val ) + %this.selectionSet.add( %object ); + else + %this.selectionSet.remove( %object ); + } + else + { + if( %val ) + EWorldEditor.selectObject( %object ); + else + EWorldEditor.unselectObject( %object ); + } +} + +//--------------------------------------------------------------------------------------------- + +function ESelectObjectsWindow::clearSelection( %this ) +{ + if( %this.selectionSet ) + %this.selectionSet.clear(); + else + EWorldEditor.clearSelection(); +} + +//============================================================================================= +// Events. +//============================================================================================= + +//--------------------------------------------------------------------------------------------- + +function ESelectObjectsWindow::onWake( %this ) +{ + if( !%this.isInitialized ) + { + %this.init(); + %this.isInitialized = true; + } + + // Re-initialize the group list on each wake. + + %this.initGroupList(); +} + +//--------------------------------------------------------------------------------------------- + +function ESelectObjectsWindow::onSelectObjects( %this, %val, %reuseExistingSet ) +{ + // See if we should create an independent selection set. + + if( %this-->createSelectionSet.isStateOn() ) + { + %name = %this-->selectionSetName.getText(); + + // See if we should create or re-use a set. + + if( isObject( %name ) ) + { + if( !%name.isMemberOfClass( "WorldEditorSelection" ) ) + { + MessageBoxOk( "Error", + "An object called '" @ %name @ "' already exists and is not a selection." NL + "" NL + "Please choose a different name." ); + return; + } + else if( !%reuseExistingSet ) + { + MessageBoxYesNo( "Question", + "A selection called '" @ %name @ "' already exists. Modify the existing selection?", + %this @ ".onSelectObjects( " @ %val @ ", true );" ); + return; + } + else + %sel = %name; + } + else + { + // Make sure the name is valid. + if( !Editor::validateObjectName( %name, false ) ) + return; + + // Create a new selection set. + eval( "%sel = new WorldEditorSelection( " @ %name @ " ) { parentGroup = Selections; canSave = true; };" ); + if( !isObject( %sel ) ) + { + MessageBoxOk( "Error", + "Could not create the selection set. Please look at the console.log for details." ); + return; + } + } + + %this.selectionSet = %sel; + } + else + %this.selectionSet = ""; + + Parent::onSelectObjects( %this, %val ); + + // Refresh editor tree just in case. + + EditorTree.buildVisibleTree(); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/cameraBookmarks.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/cameraBookmarks.ed.cs new file mode 100644 index 000000000..59a08803d --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/cameraBookmarks.ed.cs @@ -0,0 +1,360 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// CameraBookmark class methods. Located here so they won't fire without +// the tools in place. + +function CameraBookmark::onAdd( %this ) +{ +} + +function CameraBookmark::onRemove( %this ) +{ + if( isObject(EditorCameraBookmarks) ) + { + %pos = CameraBookmarks.getObjectIndex( %this ); + if( %pos != -1 ) + { + EditorCameraBookmarks.deleteItem( %pos ); + EManageBookmarks.deleteBookmark( %this, %pos ); + } + } +} + +function CameraBookmark::onGroupAdd( %this ) +{ + // If we're added to the CameraBookmarks group, then also add us + // to the menu and Manage Bookmarks window. + if( isObject(CameraBookmarks) ) + { + %pos = CameraBookmarks.getObjectIndex( %this ); + if( %pos != -1 ) + { + EditorCameraBookmarks.addItem( %pos, %this.internalName ); + EManageBookmarks.addBookmark( %this, %pos ); + } + } +} + +function CameraBookmark::onGroupRemove( %this ) +{ + // If we're part of the CameraBookmarks group, then also remove us from + // the menu and Manage Bookmarks window. + if( isObject(CameraBookmarks) ) + { + %pos = CameraBookmarks.getObjectIndex( %this ); + if( %pos != -1 ) + { + EditorCameraBookmarks.deleteItem( %pos ); + EManageBookmarks.deleteBookmark( %this, %pos ); + } + } +} + +function CameraBookmark::onInspectPostApply( %this ) +{ + EditorCameraBookmarks.rebuildBookmarks(); +} + +//----------------------------------------------------------------------------- + +function EditorCameraBookmarksMenu::onAdd( %this ) +{ + if(! isObject(%this.canvas)) + %this.canvas = Canvas; + + // Add any existing bookmarks + %this.rebuildBookmarks(); +} + +function EditorCameraBookmarksMenu::addItem( %this, %pos, %name ) +{ + if( %this.NoneItem == true ) + { + %this.NoneItem = false; + %this.removeItem( 0 ); + } + + %accel = ""; + %this.insertItem(%pos, %name !$= "-" ? %name : "", %accel); +} + +function EditorCameraBookmarksMenu::deleteItem( %this, %pos ) +{ + %this.removeItem( %pos ); + if( %this.getItemCount() == 0 && %this.NoneItem != true ) + { + %this.addItem( 0, "None" ); + %this.enableItem( 0, false ); + %this.NoneItem = true; + } +} + +function EditorCameraBookmarksMenu::onSelectItem( %this, %pos, %text ) +{ + if( %pos >= 0 && %pos < CameraBookmarks.getCount() ) + { + %mark = CameraBookmarks.getObject( %pos ); + EditorGui.jumpToBookmark( %mark.internalName ); + return true; + } + + return false; +} + +function EditorCameraBookmarksMenu::rebuildBookmarks( %this ) +{ + // Delete all current items + while( %this.getItemCount() > 0) + { + %this.removeItem( 0 ); + } + + // Add back in all of the bookmarks + if( isObject(CameraBookmarks) && CameraBookmarks.getCount() > 0 ) + { + for( %i=0; %i<CameraBookmarks.getCount(); %i++ ) + { + %mark = CameraBookmarks.getObject( %i ); + %this.addItem( %i, %mark.internalName ); + } + %this.NoneItem = false; + } + else + { + %this.addItem( 0, "None" ); + %this.enableItem( 0, false ); + %this.NoneItem = true; + } +} + +//----------------------------------------------------------------------------- + +function ManageBookmarksContainer::onOK( %this ) +{ + %name = EAddBookmarkWindowName.getText(); + EAddBookmarkWindowName.clearFirstResponder(); + + if( %name $= "" ) + { + // look for a NewCamera name to grab + for(%i = 0; ; %i++){ + %name = "NewCamera_" @ %i; + if( !CameraBookmarks.findObjectByInternalName(%name) ){ + break; + } + } + } + + // Check if the new bookmark name already exists + if( isObject(CameraBookmarks) && CameraBookmarks.findObjectByInternalName(%name) ) + { + %userName = %name; + for(%i = 0; ; %i++){ + %name = %userName @ "_" @ %i; + if( !CameraBookmarks.findObjectByInternalName(%name) ){ + break; + } + } + } + + EditorGui.addCameraBookmark( %name ); + EAddBookmarkWindowName.text = ""; + //%this.CloseWindow(); +} + +function EAddBookmarkWindowName::onReturn( %this ) +{ + // Same as clicking the Create Bookmark button + ManageBookmarksContainer.onOK(); +} + +//----------------------------------------------------------------------------- + +function EManageBookmarks::hideDialog( %this ) +{ + %this.setVisible(false); +} + +function EManageBookmarks::ToggleVisibility( %this ) +{ + if ( %this.visible ) + { + %this.setVisible(false); + EWorldEditor.EManageBookmarksDisplayed = false; + } + else + { + %this.setVisible(true); + %this.selectWindow(); + %this.setCollapseGroup(false); + EWorldEditor.EManageBookmarksDisplayed = true; + } +} + +function EManageBookmarks::addBookmark( %this, %mark, %index ) +{ + %gui = new GuiControl() { + internalName = %mark.getInternalName(); + Enabled = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "300 20"; + MinExtent = "78 20"; + Visible = "1"; + Bookmark = %mark; + + new GuiBitmapButtonCtrl() { + class = "EManageBookmarksGoToButton"; + bitmap = "tools/gui/images/camera-btn"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "2 2"; + Extent = "17 17"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Go to bookmark"; + hovertime = "1000"; + internalName = "goToBookmark"; + canSaveDynamicFields = "0"; + }; + + new GuiTextEditCtrl() { + class = "EManageBookmarksTextEdit"; + internalName = "BookmarkName"; + profile="ToolsGuiTextEditProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + position = "22 2"; + Extent = "260 18"; + text = %mark.getInternalName(); + maxLength = "1024"; + AltCommand = ""; + }; + + new GuiBitmapButtonCtrl() { + class = "EManageBookmarksDeleteButton"; + bitmap = "tools/gui/images/delete"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "284 3"; + Extent = "16 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = ""; + tooltipprofile = "ToolsGuiToolTipProfile"; + ToolTip = "Delete camera bookmark"; + hovertime = "1000"; + internalName = "deleteBookmark"; + canSaveDynamicFields = "0"; + }; + }; + + EManageBookmarks-->ManageBookmarksWindowStack.addGuiControl( %gui ); +} + +function EManageBookmarks::deleteBookmark( %this, %mark, %index ) +{ + %gui = EManageBookmarks-->ManageBookmarksWindowStack.findObjectByInternalName( %mark.getInternalName() ); + if( %gui != 0 ) + %gui.delete(); + else + warn("EManageBookmarks::deleteBookmark(): Could not find bookmark " @ %mark @ " at index " @ %index); +} + +function EManageBookmarksGoToButton::onClick( %this ) +{ + %mark = %this.getParent().Bookmark; + EditorGui.jumpToBookmark( %mark.getInternalName() ); +} + +function EManageBookmarksDeleteButton::onClick( %this ) +{ + %mark = %this.getParent().Bookmark; + EditorGui.schedule( 0, removeCameraBookmark, %mark.getInternalName() ); +} + +function EManageBookmarksTextEdit::onGainFirstResponder( %this ) +{ + if( %this.isActive() ) + { + %this.selectAllText(); + } +} + +function EManageBookmarksTextEdit::onReturn( %this ) +{ + %this.onValidate(); +} + +function EManageBookmarksTextEdit::onValidate( %this ) +{ + %mark = %this.getParent().Bookmark; + %oldname = %mark.getInternalName(); + %newname = %this.getText(); + + // If the new name is the same as the old, do nothing + if( %newname $= %oldname ) + return; + + // Make sure the new name doesn't conflict with a current bookmark + if( isObject(CameraBookmarks) && CameraBookmarks.findObjectByInternalName(%newname) ) + { + %id = %this.getId(); + %callback = %id @ ".setText(\"" @ %oldname @ "\"); " @ %id @ ".makeFirstResponder(true); " @ %id @ ".selectAllText();"; + MessageBoxOK("Create Bookmark", "You must provide a unique name for the new bookmark.", %callback); + return; + } + + // Rename the bookmark and update + %this.getParent().setInternalName( %newname ); + %mark.setInternalName( %newname ); + if( Inspector.getInspectObject() == %mark.getId() ) + { + Inspector.inspect( %mark ); + Inspector.apply(); + } + else + { + // User is not inspecting the bookmark, so manually + // update the menu. + %mark.onInspectPostApply(); + } + +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/cameraCommands.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/cameraCommands.ed.cs new file mode 100644 index 000000000..c842b77c1 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/cameraCommands.ed.cs @@ -0,0 +1,200 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Sync the Camera and the EditorGui +function clientCmdSyncEditorGui() +{ + if (isObject(EditorGui)) + EditorGui.syncCameraGui(); +} + +//---------------------------------------------------------------------------- +// Camera commands +//---------------------------------------------------------------------------- +function serverCmdTogglePathCamera(%client, %val) +{ + if(%val) + { + %control = %client.PathCamera; + } + else + { + %control = %client.camera; + } + %client.setControlObject(%control); + clientCmdSyncEditorGui(); +} +function serverCmdToggleCamera(%client) +{ + if (%client.getControlObject() == %client.player) + { + %client.camera.setVelocity("0 0 0"); + %control = %client.camera; + } + else + { + %client.player.setVelocity("0 0 0"); + %control = %client.player; + } + %client.setControlObject(%control); + clientCmdSyncEditorGui(); +} + +function serverCmdSetEditorCameraPlayer(%client) +{ + // Switch to Player Mode + %client.player.setVelocity("0 0 0"); + %client.setControlObject(%client.player); + ServerConnection.setFirstPerson(1); + $isFirstPersonVar = 1; + + clientCmdSyncEditorGui(); +} + +function serverCmdSetEditorCameraPlayerThird(%client) +{ + // Swith to Player Mode + %client.player.setVelocity("0 0 0"); + %client.setControlObject(%client.player); + ServerConnection.setFirstPerson(0); + $isFirstPersonVar = 0; + + clientCmdSyncEditorGui(); +} + +function serverCmdDropPlayerAtCamera(%client) +{ + // If the player is mounted to something (like a vehicle) drop that at the + // camera instead. The player will remain mounted. + %obj = %client.player.getObjectMount(); + if (!isObject(%obj)) + %obj = %client.player; + + %obj.setTransform(%client.camera.getTransform()); + %obj.setVelocity("0 0 0"); + + %client.setControlObject(%client.player); + clientCmdSyncEditorGui(); +} + +function serverCmdDropCameraAtPlayer(%client) +{ + %client.camera.setTransform(%client.player.getEyeTransform()); + %client.camera.setVelocity("0 0 0"); + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); +} + +function serverCmdCycleCameraFlyType(%client) +{ + if(%client.camera.getMode() $= "Fly") + { + if(%client.camera.newtonMode == false) // Fly Camera + { + // Switch to Newton Fly Mode without rotation damping + %client.camera.newtonMode = "1"; + %client.camera.newtonRotation = "0"; + %client.camera.setVelocity("0 0 0"); + } + else if(%client.camera.newtonRotation == false) // Newton Camera without rotation damping + { + // Switch to Newton Fly Mode with damped rotation + %client.camera.newtonMode = "1"; + %client.camera.newtonRotation = "1"; + %client.camera.setAngularVelocity("0 0 0"); + } + else // Newton Camera with rotation damping + { + // Switch to Fly Mode + %client.camera.newtonMode = "0"; + %client.camera.newtonRotation = "0"; + } + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); + } +} + +function serverCmdSetEditorCameraStandard(%client) +{ + // Switch to Fly Mode + %client.camera.setFlyMode(); + %client.camera.newtonMode = "0"; + %client.camera.newtonRotation = "0"; + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); +} + +function serverCmdSetEditorCameraNewton(%client) +{ + // Switch to Newton Fly Mode without rotation damping + %client.camera.setFlyMode(); + %client.camera.newtonMode = "1"; + %client.camera.newtonRotation = "0"; + %client.camera.setVelocity("0 0 0"); + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); +} + +function serverCmdSetEditorCameraNewtonDamped(%client) +{ + // Switch to Newton Fly Mode with damped rotation + %client.camera.setFlyMode(); + %client.camera.newtonMode = "1"; + %client.camera.newtonRotation = "1"; + %client.camera.setAngularVelocity("0 0 0"); + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); +} + +function serverCmdSetEditorOrbitCamera(%client) +{ + %client.camera.setEditOrbitMode(); + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); +} + +function serverCmdSetEditorFlyCamera(%client) +{ + %client.camera.setFlyMode(); + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); +} + +function serverCmdEditorOrbitCameraSelectChange(%client, %size, %center) +{ + if(%size > 0) + { + %client.camera.setValidEditOrbitPoint(true); + %client.camera.setEditOrbitPoint(%center); + } + else + { + %client.camera.setValidEditOrbitPoint(false); + } +} + +function serverCmdEditorCameraAutoFit(%client, %radius) +{ + %client.camera.autoFitRadius(%radius); + %client.setControlObject(%client.camera); + clientCmdSyncEditorGui(); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/cursors.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/cursors.ed.cs new file mode 100644 index 000000000..f281b653a --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/cursors.ed.cs @@ -0,0 +1,79 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Editor Cursors +//------------------------------------------------------------------------------ + +new GuiCursor(EditorHandCursor) +{ + hotSpot = "7 0"; + bitmapName = "~/worldEditor/images/CUR_hand.png"; +}; + +new GuiCursor(EditorRotateCursor) +{ + hotSpot = "11 18"; + bitmapName = "~/worldEditor/images/CUR_rotate.png"; +}; + +new GuiCursor(EditorMoveCursor) +{ + hotSpot = "9 13"; + bitmapName = "~/worldEditor/images/CUR_grab.png"; +}; + +new GuiCursor(EditorArrowCursor) +{ + hotSpot = "0 0"; + bitmapName = "~/worldEditor/images/CUR_3darrow.png"; +}; + +new GuiCursor(EditorUpDownCursor) +{ + hotSpot = "5 10"; + bitmapName = "~/worldEditor/images/CUR_3dupdown"; +}; +new GuiCursor(EditorLeftRightCursor) +{ + hotSpot = "9 5"; + bitmapName = "~/worldEditor/images/CUR_3dleftright"; +}; + +new GuiCursor(EditorDiagRightCursor) +{ + hotSpot = "8 8"; + bitmapName = "~/worldEditor/images/CUR_3ddiagright"; +}; + +new GuiCursor(EditorDiagLeftCursor) +{ + hotSpot = "8 8"; + bitmapName = "~/worldEditor/images/CUR_3ddiagleft"; +}; + +new GuiControl(EmptyControl) +{ + profile = "ToolsGuiButtonProfile"; +}; + + diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editor.bind.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editor.bind.ed.cs new file mode 100644 index 000000000..0c5b78a73 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editor.bind.ed.cs @@ -0,0 +1,84 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Mission Editor Manager +new ActionMap(EditorMap); + +function mouseWheelScroll( %val ) +{ + //$Camera::speedCurveTime += $Camera::scrollStepSize * ( (%val>0.0) ? 1 : -1 ); + //$Camera::speedCurveTime = mClamp( $Camera::speedCurveTime, 0.0, 1.0 ); + //calculateCameraSpeed(); + //EditorGui-->CameraSpeedSpinner.setText( $Camera::movementSpeed ); + + %rollAdj = getMouseAdjustAmount(%val); + %rollAdj = mClamp(%rollAdj, -mPi()+0.01, mPi()-0.01); + $mvRoll += %rollAdj; +} + +function editorYaw(%val) +{ + %yawAdj = getMouseAdjustAmount(%val); + + if(ServerConnection.isControlObjectRotDampedCamera() || EWorldEditor.isMiddleMouseDown()) + { + // Clamp and scale + %yawAdj = mClamp(%yawAdj, -m2Pi()+0.01, m2Pi()-0.01); + %yawAdj *= 0.5; + } + + if( EditorSettings.value( "Camera/invertXAxis" ) ) + %yawAdj *= -1; + + $mvYaw += %yawAdj; +} + +function editorPitch(%val) +{ + %pitchAdj = getMouseAdjustAmount(%val); + + if(ServerConnection.isControlObjectRotDampedCamera() || EWorldEditor.isMiddleMouseDown()) + { + // Clamp and scale + %pitchAdj = mClamp(%pitchAdj, -m2Pi()+0.01, m2Pi()-0.01); + %pitchAdj *= 0.5; + } + + if( EditorSettings.value( "Camera/invertYAxis" ) ) + %pitchAdj *= -1; + + $mvPitch += %pitchAdj; +} + +function editorWheelFadeScroll( %val ) +{ + EWorldEditor.fadeIconsDist += %val * 0.1; + if( EWorldEditor.fadeIconsDist < 0 ) + EWorldEditor.fadeIconsDist = 0; +} + +EditorMap.bind( mouse, xaxis, editorYaw ); +EditorMap.bind( mouse, yaxis, editorPitch ); +EditorMap.bind( mouse, zaxis, mouseWheelScroll ); + +EditorMap.bind( mouse, "alt zaxis", editorWheelFadeScroll ); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editor.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editor.ed.cs new file mode 100644 index 000000000..8545c9d67 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editor.ed.cs @@ -0,0 +1,201 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------ +// Hard coded images referenced from C++ code +//------------------------------------------------------------------------------ + +// editor/SelectHandle.png +// editor/DefaultHandle.png +// editor/LockedHandle.png + + +//------------------------------------------------------------------------------ +// Functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Mission Editor +//------------------------------------------------------------------------------ + +function Editor::create() +{ + // Not much to do here, build it and they will come... + // Only one thing... the editor is a gui control which + // expect the Canvas to exist, so it must be constructed + // before the editor. + new EditManager(Editor) + { + profile = "GuiContentProfile"; + horizSizing = "right"; + vertSizing = "top"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + helpTag = "0"; + open = false; + }; +} + +function Editor::getUndoManager(%this) +{ + if ( !isObject( %this.undoManager ) ) + { + /// This is the global undo manager used by all + /// of the mission editor sub-editors. + %this.undoManager = new UndoManager( EUndoManager ) + { + numLevels = 200; + }; + } + return %this.undoManager; +} + +function Editor::setUndoManager(%this, %undoMgr) +{ + %this.undoManager = %undoMgr; +} + +function Editor::onAdd(%this) +{ + // Ignore Replicated fxStatic Instances. + EWorldEditor.ignoreObjClass("fxShapeReplicatedStatic"); +} + +function Editor::checkActiveLoadDone() +{ + if(isObject(EditorGui) && EditorGui.loadingMission) + { + Canvas.setContent(EditorGui); + EditorGui.loadingMission = false; + return true; + } + return false; +} + +//------------------------------------------------------------------------------ +function toggleEditor(%make) +{ + if (%make) + { + %timerId = startPrecisionTimer(); + + if( GuiEditorIsActive() ) + toggleGuiEditor(1); + + if( !$missionRunning ) + { + // Flag saying, when level is chosen, launch it with the editor open. + ChooseLevelDlg.launchInEditor = true; + Canvas.pushDialog( ChooseLevelDlg ); + } + else + { + pushInstantGroup(); + + if ( !isObject( Editor ) ) + { + Editor::create(); + MissionCleanup.add( Editor ); + MissionCleanup.add( Editor.getUndoManager() ); + } + + if( EditorIsActive() ) + { + if (theLevelInfo.type $= "DemoScene") + { + commandToServer('dropPlayerAtCamera'); + Editor.close("SceneGui"); + } + else + { + Editor.close("PlayGui"); + } + } + else + { + canvas.pushDialog( EditorLoadingGui ); + canvas.repaint(); + + Editor.open(); + + // Cancel the scheduled event to prevent + // the level from cycling after it's duration + // has elapsed. + cancel($Game::Schedule); + + if (theLevelInfo.type $= "DemoScene") + commandToServer('dropCameraAtPlayer', true); + + canvas.popDialog(EditorLoadingGui); + } + + popInstantGroup(); + } + + %elapsed = stopPrecisionTimer( %timerId ); + warn( "Time spent in toggleEditor() : " @ %elapsed / 1000.0 @ " s" ); + } +} + +//------------------------------------------------------------------------------ +// The editor action maps are defined in editor.bind.cs +GlobalActionMap.bind(keyboard, "f11", toggleEditor); + + +// The scenario: +// The editor is open and the user closes the level by any way other than +// the file menu ( exit level ), eg. typing disconnect() in the console. +// +// The problem: +// Editor::close() is not called in this scenario which means onEditorDisable +// is not called on objects which hook into it and also gEditingMission will no +// longer be valid. +// +// The solution: +// Override the stock disconnect() function which is in game scripts from here +// in tools so we avoid putting our code in there. +// +// Disclaimer: +// If you think of a better way to do this feel free. The thing which could +// be dangerous about this is that no one will ever realize this code overriding +// a fairly standard and core game script from a somewhat random location. +// If it 'did' have unforscene sideeffects who would ever find it? + +package EditorDisconnectOverride +{ + function disconnect() + { + if ( isObject( Editor ) && Editor.isEditorEnabled() ) + { + if (isObject( MainMenuGui )) + Editor.close("MainMenuGui"); + } + + Parent::disconnect(); + } +}; +activatePackage( EditorDisconnectOverride ); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editor.keybinds.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editor.keybinds.cs new file mode 100644 index 000000000..92ac42d8c --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editor.keybinds.cs @@ -0,0 +1,80 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +if ( isObject( editorMoveMap ) ) + editorMoveMap.delete(); + +new ActionMap(editorMoveMap); + +//------------------------------------------------------------------------------ +// Non-remapable binds +//------------------------------------------------------------------------------ +editorMoveMap.bindCmd(keyboard, "escape", "", "Canvas.pushDialog(PauseMenu);"); + +//------------------------------------------------------------------------------ +// Movement Keys +//------------------------------------------------------------------------------ +editorMoveMap.bind( keyboard, a, editorMoveleft ); +editorMoveMap.bind( keyboard, d, editorMoveright ); +editorMoveMap.bind( keyboard, left, editorMoveleft ); +editorMoveMap.bind( keyboard, right, editorMoveright ); + +editorMoveMap.bind( keyboard, w, editorMoveforward ); +editorMoveMap.bind( keyboard, s, editorMovebackward ); +editorMoveMap.bind( keyboard, up, editorMoveforward ); +editorMoveMap.bind( keyboard, down, editorMovebackward ); + +editorMoveMap.bind( keyboard, e, editorMoveup ); +editorMoveMap.bind( keyboard, c, editorMovedown ); + +editorMoveMap.bind( mouse, xaxis, editorYaw ); +editorMoveMap.bind( mouse, yaxis, editorPitch ); + +//------------------------------------------------------------------------------ +// Mouse Trigger +//------------------------------------------------------------------------------ +editorMoveMap.bind( mouse, button0, editorClick ); +editorMoveMap.bind( mouse, button1, editorRClick ); + +//------------------------------------------------------------------------------ +// Camera & View functions +//------------------------------------------------------------------------------ +editorMoveMap.bind(keyboard, "alt c", toggleCamera); + +//------------------------------------------------------------------------------ +// Helper Functions +//------------------------------------------------------------------------------ +editorMoveMap.bind(keyboard, "F8", dropCameraAtPlayer); +editorMoveMap.bind(keyboard, "F7", dropPlayerAtCamera); + +//------------------------------------------------------------------------------ +// Debugging Functions +//------------------------------------------------------------------------------ +GlobalActionMap.bind(keyboard, "ctrl F2", showMetrics); +GlobalActionMap.bind(keyboard, "ctrl F3", doProfile); + +//------------------------------------------------------------------------------ +// Misc. +//------------------------------------------------------------------------------ +GlobalActionMap.bind(keyboard, "tilde", toggleConsole); + +editorMoveMap.bind( mouse, "alt zaxis", editorWheelFadeScroll ); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editorInputCommands.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editorInputCommands.cs new file mode 100644 index 000000000..aa6f8d8b6 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editorInputCommands.cs @@ -0,0 +1,181 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Non-remapable binds +//------------------------------------------------------------------------------ +function escapeFromGame() +{ + disconnect(); +} + +//------------------------------------------------------------------------------ +// Movement Keys +//------------------------------------------------------------------------------ +function editorMoveleft(%val) +{ + $mvLeftAction = %val * $Camera::movementSpeed; +} + +function editorMoveright(%val) +{ + $mvRightAction = %val * $Camera::movementSpeed; +} + +function editorMoveforward(%val) +{ + $mvForwardAction = %val * $Camera::movementSpeed; +} + +function editorMovebackward(%val) +{ + $mvBackwardAction = %val * $Camera::movementSpeed; +} + +function editorMoveup(%val) +{ + %object = ServerConnection.getControlObject(); + + if(%object.isInNamespaceHierarchy("Camera")) + $mvUpAction = %val * $Camera::movementSpeed; +} + +function editorMovedown(%val) +{ + %object = ServerConnection.getControlObject(); + + if(%object.isInNamespaceHierarchy("Camera")) + $mvDownAction = %val * $Camera::movementSpeed; +} + +function getEditorMouseAdjustAmount(%val) +{ + return(%val * ($cameraFov / 90) * 0.01); +} + +function editorYaw(%val) +{ + %yawAdj = getEditorMouseAdjustAmount(%val); + if(ServerConnection.isControlObjectRotDampedCamera()) + { + // Clamp and scale + %yawAdj = mClamp(%yawAdj, -m2Pi()+0.01, m2Pi()-0.01); + %yawAdj *= 0.5; + } + + $mvYaw += %yawAdj; +} + +function editorPitch(%val) +{ + %pitchAdj = getEditorMouseAdjustAmount(%val); + if(ServerConnection.isControlObjectRotDampedCamera()) + { + // Clamp and scale + %pitchAdj = mClamp(%pitchAdj, -m2Pi()+0.01, m2Pi()-0.01); + %pitchAdj *= 0.5; + } + + $mvPitch += %pitchAdj; +} + +//------------------------------------------------------------------------------ +// Mouse Trigger +//------------------------------------------------------------------------------ +function editorClick(%val) +{ + $mvTriggerCount0++; +} + +function editorRClick(%val) +{ + $mvTriggerCount1++; +} + +//------------------------------------------------------------------------------ +// Camera & View functions +//------------------------------------------------------------------------------ +function toggleCamera(%val) +{ + if (%val) + commandToServer('ToggleCamera'); +} + +//------------------------------------------------------------------------------ +// Helper Functions +//------------------------------------------------------------------------------ +function dropCameraAtPlayer(%val) +{ + if (%val) + commandToServer('dropCameraAtPlayer'); +} + +function dropPlayerAtCamera(%val) +{ + if (%val) + commandToServer('DropPlayerAtCamera'); +} + +//------------------------------------------------------------------------------ +// Debugging Functions +//------------------------------------------------------------------------------ +function showMetrics(%val) +{ + if(%val) + { + if(!Canvas.isMember(FrameOverlayGui)) + metrics("fps gfx shadow sfx terrain groundcover forest net"); + else + metrics(""); + } +} + +//------------------------------------------------------------------------------ +// +// Start profiler by pressing ctrl f3 +// ctrl f3 - starts profile that will dump to console and file +// +function doProfile(%val) +{ + if (%val) + { + // key down -- start profile + echo("Starting profile session..."); + profilerReset(); + profilerEnable(true); + } + else + { + // key up -- finish off profile + echo("Ending profile session..."); + + profilerDumpToFile("profilerDumpToFile" @ getSimTime() @ ".txt"); + profilerEnable(false); + } +} + +function editorWheelFadeScroll( %val ) +{ + EWorldEditor.fadeIconsDist += %val * 0.1; + if( EWorldEditor.fadeIconsDist < 0 ) + EWorldEditor.fadeIconsDist = 0; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editorPlugin.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editorPlugin.ed.cs new file mode 100644 index 000000000..7bafa3838 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editorPlugin.ed.cs @@ -0,0 +1,203 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +/// +/// This is used to register editor extensions and tools. +/// +/// There are various callbacks you can overload to hook in your +/// own functionality without changing the core editor code. +/// +/// At the moment this is primarily for the World/Mission +/// Editor and the callbacks mostly make sense in that context. +/// +/// Example: +/// +/// %obj = new ScriptObject() +/// { +/// superclass = "EditorPlugin"; +/// class = "RoadEditor"; +/// }; +/// +/// EditorPlugin::register( %obj ); +/// +/// For an a full example see: tools/roadEditor/main.cs +/// or: tools/riverEditor/main.cs +/// or: tools/decalEditor/main.cs +/// + +/// It is not intended for the user to overload this method. +/// If you do make sure you call the parent. +function EditorPlugin::onAdd( %this ) +{ + EditorPluginSet.add( %this ); +} + + +/// Callback when the world editor is first started. It +/// is a good place to insert menus and menu items as well as +/// preparing guis. +function EditorPlugin::onWorldEditorStartup( %this ) +{ +} + +/// Callback when the world editor is about to be totally deleted. +/// At the time of this writing this occurs when the engine is shut down +/// and the editor had been initialized. +function EditorPlugin::onWorldEditorShutdown( %this ) +{ +} + +/// Callback right before the editor is opened. +function EditorPlugin::onEditorWake( %this ) +{ +} + +/// Callback right before the editor is closed. +function EditorPlugin::onEditorSleep( %this ) +{ +} + +/// Callback when the tool is 'activated' by the WorldEditor +/// Push Gui's, stuff like that +function EditorPlugin::onActivated( %this ) +{ + %this.isActivated = true; +} + +/// Callback when the tool is 'deactivated' / closed by the WorldEditor +/// Pop Gui's, stuff like that +function EditorPlugin::onDeactivated( %this ) +{ + %this.isActivated = false; +} + +/// Callback when tab is pressed. +/// Used by the WorldEditor to toggle between inspector/creator, for example. +function EditorPlugin::onToggleToolWindows( %this ) +{ +} + +/// Callback when the edit menu is clicked or prior to handling an accelerator +/// key event mapped to an edit menu item. +/// It is up to the active editor to determine if these actions are +/// appropriate in the current state. +function EditorPlugin::onEditMenuSelect( %this, %editMenu ) +{ + %editMenu.enableItem( 3, false ); // Cut + %editMenu.enableItem( 4, false ); // Copy + %editMenu.enableItem( 5, false ); // Paste + %editMenu.enableItem( 6, false ); // Delete + %editMenu.enableItem( 8, false ); // Deselect +} + +/// If this tool keeps track of changes that necessitate resaving the mission +/// return true in that case. +function EditorPlugin::isDirty( %this ) +{ + return false; +} + +/// This gives tools a chance to clear whatever internal variables keep track of changes +/// since the last save. +function EditorPlugin::clearDirty( %this ) +{ +} + +/// This gives tools chance to save data out when the mission is being saved. +/// This will only be called if the tool says it is dirty. +function EditorPlugin::onSaveMission( %this, %missionFile ) +{ +} + +/// Called when during mission cleanup to notify plugins. +function EditorPlugin::onExitMission( %this ) +{ +} + +/// Called on the active plugin when a SceneObject is selected. +/// +/// @param object The object being selected. +function EditorPlugin::onObjectSelected( %this, %object ) +{ +} + +/// Called on the active plugin when a SceneObject is deselected. +/// +/// @param object The object being deselected. +function EditorPlugin::onObjectDeselected( %this, %object ) +{ +} + +/// Called on the active plugin when the selection of SceneObjects is cleared. +function EditorPlugin::onSelectionCleared( %this ) +{ +} + +/// Callback when the the delete item of the edit menu is selected or its +/// accelerator is pressed. +function EditorPlugin::handleDelete( %this ) +{ + warn( "EditorPlugin::handleDelete( " @ %this.getName() @ " )" NL + "Was not implemented in child namespace, yet menu item was enabled." ); +} + +/// Callback when the the deselect item of the edit menu is selected or its +/// accelerator is pressed. +function EditorPlugin::handleDeselect( %this ) +{ + warn( "EditorPlugin::handleDeselect( " @ %this.getName() @ " )" NL + "Was not implemented in child namespace, yet menu item was enabled." ); +} + +/// Callback when the the cut item of the edit menu is selected or its +/// accelerator is pressed. +function EditorPlugin::handleCut( %this ) +{ + warn( "EditorPlugin::handleCut( " @ %this.getName() @ " )" NL + "Was not implemented in child namespace, yet menu item was enabled." ); +} + +/// Callback when the the copy item of the edit menu is selected or its +/// accelerator is pressed. +function EditorPlugin::handleCopy( %this ) +{ + warn( "EditorPlugin::handleCopy( " @ %this.getName() @ " )" NL + "Was not implemented in child namespace, yet menu item was enabled." ); +} + +/// Callback when the the paste item of the edit menu is selected or its +/// accelerator is pressed. +function EditorPlugin::handlePaste( %this ) +{ + warn( "EditorPlugin::handlePaste( " @ %this.getName() @ " )" NL + "Was not implemented in child namespace, yet menu item was enabled." ); +} + +/// Callback when the escape key is pressed. +/// Return true if this tool has handled the key event in a custom way. +/// If false is returned the WorldEditor default behavior is to return +/// to the ObjectEditor. +function EditorPlugin::handleEscape( %this ) +{ + return false; +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editorPrefs.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editorPrefs.ed.cs new file mode 100644 index 000000000..1704e06ad --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editorPrefs.ed.cs @@ -0,0 +1,435 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Provide default values for all World Editor settings. These make use of +// the EditorSettings instance of the Settings class, as defined in the Tools +// package onStart(). + +EditorSettings.beginGroup( "WorldEditor", true ); +EditorSettings.setDefaultValue( "currentEditor", "WorldEditorInspectorPlugin" ); +EditorSettings.setDefaultValue( "dropType", "screenCenter" ); +EditorSettings.setDefaultValue( "undoLimit", "40" ); +EditorSettings.setDefaultValue( "forceLoadDAE", "0" ); +EditorSettings.setDefaultValue( "displayType", $EditTsCtrl::DisplayTypePerspective ); +EditorSettings.setDefaultValue( "orthoFOV", "50" ); +EditorSettings.setDefaultValue( "orthoShowGrid", "1" ); +EditorSettings.setDefaultValue( "currentEditor", "WorldEditorInspectorPlugin" ); +EditorSettings.setDefaultValue( "newLevelFile", "tools/levels/BlankRoom.mis" ); +EditorSettings.setDefaultValue( "newGameObjectDir", "scripts/server/gameObjects" ); + +if( isFile( "C:/Program Files/Torsion/Torsion.exe" ) ) + EditorSettings.setDefaultValue( "torsionPath", "C:/Program Files/Torsion/Torsion.exe" ); +else if( isFile( "C:/Program Files (x86)/Torsion/Torsion.exe" ) ) + EditorSettings.setDefaultValue( "torsionPath", "C:/Program Files (x86)/Torsion/Torsion.exe" ); +else + EditorSettings.setDefaultValue( "torsionPath", "" ); + +EditorSettings.beginGroup( "ObjectIcons" ); +EditorSettings.setDefaultValue( "fadeIcons", "1" ); +EditorSettings.setDefaultValue( "fadeIconsStartDist", "8" ); +EditorSettings.setDefaultValue( "fadeIconsEndDist", "20" ); +EditorSettings.setDefaultValue( "fadeIconsStartAlpha", "255" ); +EditorSettings.setDefaultValue( "fadeIconsEndAlpha", "0" ); +EditorSettings.endGroup(); + +EditorSettings.beginGroup( "Grid" ); +EditorSettings.setDefaultValue( "gridSize", "1" ); +EditorSettings.setDefaultValue( "gridSnap", "0" ); +EditorSettings.setDefaultValue( "gridColor", "102 102 102 100" ); +EditorSettings.setDefaultValue( "gridOriginColor", "255 255 255 100" ); +EditorSettings.setDefaultValue( "gridMinorColor", "51 51 51 100" ); +EditorSettings.endGroup(); + +EditorSettings.beginGroup( "Tools" ); +EditorSettings.setDefaultValue( "snapGround", "0" ); +EditorSettings.setDefaultValue( "snapSoft", "0" ); +EditorSettings.setDefaultValue( "snapSoftSize", "2.0" ); +EditorSettings.setDefaultValue( "boundingBoxCollision", "0" ); +EditorSettings.setDefaultValue( "objectsUseBoxCenter", "1" ); +EditorSettings.setDefaultValue( "dropAtScreenCenterScalar","1.0" ); +EditorSettings.setDefaultValue( "dropAtScreenCenterMax", "100.0" ); +EditorSettings.endGroup(); + +EditorSettings.beginGroup( "Render" ); +EditorSettings.setDefaultValue( "renderObjHandle", "1" ); +EditorSettings.setDefaultValue( "renderObjText", "1" ); +EditorSettings.setDefaultValue( "renderPopupBackground", "1" ); +EditorSettings.setDefaultValue( "renderSelectionBox", "1" ); //<-- Does not currently render +EditorSettings.setDefaultValue( "showMousePopupInfo", "1" ); +//EditorSettings.setDefaultValue( "visibleDistanceScale", "1" ); +EditorSettings.endGroup(); + +EditorSettings.beginGroup( "Color" ); +EditorSettings.setDefaultValue( "dragRectColor", "255 255 0 255" ); +EditorSettings.setDefaultValue( "objectTextColor", "255 255 255 255" ); +EditorSettings.setDefaultValue( "objMouseOverColor", "0 255 0 255" ); //<-- Currently ignored by editor (always white) +EditorSettings.setDefaultValue( "objMouseOverSelectColor", "0 0 255 255" ); //<-- Currently ignored by editor (always white) +EditorSettings.setDefaultValue( "objSelectColor", "255 0 0 255" ); //<-- Currently ignored by editor (always white) +EditorSettings.setDefaultValue( "popupBackgroundColor", "100 100 100 255" ); +EditorSettings.setDefaultValue( "popupTextColor", "255 255 0 255" ); +EditorSettings.setDefaultValue( "raceSelectColor", "0 0 100 100" ); //<-- What is this used for? +EditorSettings.setDefaultValue( "selectionBoxColor", "255 255 0 255" ); //<-- Does not currently render +EditorSettings.setDefaultValue( "uvEditorHandleColor", "1" ); //<-- Index into color popup +EditorSettings.endGroup(); + +EditorSettings.beginGroup( "Images" ); +EditorSettings.setDefaultValue( "defaultHandle", "tools/worldEditor/images/DefaultHandle" ); +EditorSettings.setDefaultValue( "lockedHandle", "tools/worldEditor/images/LockedHandle" ); +EditorSettings.setDefaultValue( "selectHandle", "tools/worldEditor/images/SelectHandle" ); +EditorSettings.endGroup(); + +EditorSettings.beginGroup( "Docs" ); +EditorSettings.setDefaultValue( "documentationLocal", "../../../Documentation/Official Documentation.html" ); +EditorSettings.setDefaultValue( "documentationReference", "../../../Documentation/Torque 3D - Script Manual.chm"); +EditorSettings.setDefaultValue( "documentationURL", "http://www.garagegames.com/products/torque-3d/documentation/user" ); +EditorSettings.setDefaultValue( "forumURL", "http://www.garagegames.com/products/torque-3d/forums" ); +EditorSettings.endGroup(); + +EditorSettings.endGroup(); // WorldEditor + +//------------------------------------- + +// After setting up the default value, this field should be altered immediately +// after successfully using such functionality such as Open... or Save As... +EditorSettings.beginGroup( "LevelInformation" ); +EditorSettings.setDefaultValue( "levelsDirectory", "levels" ); +EditorSettings.endGroup(); + +//------------------------------------- + +EditorSettings.beginGroup( "AxisGizmo", true ); + +EditorSettings.setDefaultValue( "axisGizmoMaxScreenLen", "100" ); //<-- What is this used for? +EditorSettings.setDefaultValue( "rotationSnap", "15" ); //<-- Not currently used +EditorSettings.setDefaultValue( "snapRotations", "0" ); //<-- Not currently used +EditorSettings.setDefaultValue( "mouseRotateScalar", "0.8" ); +EditorSettings.setDefaultValue( "mouseScaleScalar", "0.8" ); +EditorSettings.setDefaultValue( "renderWhenUsed", "0" ); +EditorSettings.setDefaultValue( "renderInfoText", "1" ); + +EditorSettings.beginGroup( "Grid" ); +EditorSettings.setDefaultValue( "gridColor", "255 255 255 20" ); +EditorSettings.setDefaultValue( "gridSize", "10 10 10" ); +EditorSettings.setDefaultValue( "snapToGrid", "0" ); //<-- Not currently used +EditorSettings.setDefaultValue( "renderPlane", "0" ); +EditorSettings.setDefaultValue( "renderPlaneHashes", "0" ); +EditorSettings.setDefaultValue( "planeDim", "500" ); +EditorSettings.endGroup(); + +EditorSettings.endGroup(); + +//------------------------------------- + +EditorSettings.beginGroup( "TerrainEditor", true ); + +EditorSettings.setDefaultValue( "currentAction", "raiseHeight" ); + +EditorSettings.beginGroup( "Brush" ); +EditorSettings.setDefaultValue( "maxBrushSize", "40 40" ); +EditorSettings.setDefaultValue( "brushSize", "1 1" ); +EditorSettings.setDefaultValue( "brushType", "box" ); +EditorSettings.setDefaultValue( "brushPressure", "1" ); +EditorSettings.setDefaultValue( "brushSoftness", "1" ); +EditorSettings.endGroup(); + +EditorSettings.beginGroup( "ActionValues" ); +EditorSettings.setDefaultValue( "adjustHeightVal", "10" ); +EditorSettings.setDefaultValue( "setHeightVal", "100" ); +EditorSettings.setDefaultValue( "scaleVal", "1" ); //<-- Tool not currently implemented +EditorSettings.setDefaultValue( "smoothFactor", "0.1" ); +EditorSettings.setDefaultValue( "noiseFactor", "1.0" ); +EditorSettings.setDefaultValue( "softSelectRadius", "50" ); +EditorSettings.setDefaultValue( "softSelectFilter", "1.000000 0.833333 0.666667 0.500000 0.333333 0.166667 0.000000" ); +EditorSettings.setDefaultValue( "softSelectDefaultFilter", "1.000000 0.833333 0.666667 0.500000 0.333333 0.166667 0.000000" ); +EditorSettings.setDefaultValue( "slopeMinAngle", "0" ); +EditorSettings.setDefaultValue( "slopeMaxAngle", "90" ); +EditorSettings.endGroup(); + +EditorSettings.endGroup(); + +//------------------------------------- + +EditorSettings.beginGroup( "TerrainPainter", true ); +EditorSettings.endGroup(); + +//------------------------------------- + +//TODO: this doesn't belong here +function setDefault( %name, %value ) +{ + if( !isDefined( %name ) ) + eval( %name SPC "=" SPC "\"" @ %value @ "\";" ); +} + +setDefault( "$pref::WorldEditor::visibleDistanceScale", "1" ); // DAW: Keep this around for now as is used by EditTSCtrl + +// JCF: Couldn't some or all of these be exposed +// from WorldEditor::ConsoleInit via Con::AddVariable() +// and do away with this file? + +function EditorGui::readWorldEditorSettings(%this) +{ + EditorSettings.beginGroup( "WorldEditor", true ); + EWorldEditor.dropType = EditorSettings.value( "dropType" ); //$pref::WorldEditor::dropType; + EWorldEditor.undoLimit = EditorSettings.value( "undoLimit" ); //$pref::WorldEditor::undoLimit; + EWorldEditor.forceLoadDAE = EditorSettings.value( "forceLoadDAE" ); //$pref::WorldEditor::forceLoadDAE; + %this.currentDisplayType = EditorSettings.value( "displayType" ); + %this.currentOrthoFOV = EditorSettings.value( "orthoFOV" ); + EWorldEditor.renderOrthoGrid = EditorSettings.value( "orthoShowGrid" ); + %this.currentEditor = EditorSettings.value( "currentEditor" ); + %this.torsionPath = EditorSettings.value( "torsionPath" ); + + EditorSettings.beginGroup( "ObjectIcons" ); + EWorldEditor.fadeIcons = EditorSettings.value( "fadeIcons" ); + EWorldEditor.fadeIconsStartDist = EditorSettings.value( "fadeIconsStartDist" ); + EWorldEditor.fadeIconsEndDist = EditorSettings.value( "fadeIconsEndDist" ); + EWorldEditor.fadeIconsStartAlpha = EditorSettings.value( "fadeIconsStartAlpha" ); + EWorldEditor.fadeIconsEndAlpha = EditorSettings.value( "fadeIconsEndAlpha" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Grid" ); + EWorldEditor.gridSize = EditorSettings.value( "gridSize" ); + EWorldEditor.gridSnap = EditorSettings.value( "gridSnap" ); + EWorldEditor.gridColor = EditorSettings.value( "gridColor" ); + EWorldEditor.gridOriginColor = EditorSettings.value( "gridOriginColor" ); + EWorldEditor.gridMinorColor = EditorSettings.value( "gridMinorColor" ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Tools" ); + EWorldEditor.stickToGround = EditorSettings.value("snapGround"); //$pref::WorldEditor::snapGround; + EWorldEditor.setSoftSnap( EditorSettings.value("snapSoft") ); //$pref::WorldEditor::snapSoft + EWorldEditor.setSoftSnapSize( EditorSettings.value("snapSoftSize") ); //$pref::WorldEditor::snapSoftSize + EWorldEditor.boundingBoxCollision = EditorSettings.value("boundingBoxCollision"); //$pref::WorldEditor::boundingBoxCollision; + EWorldEditor.objectsUseBoxCenter = EditorSettings.value("objectsUseBoxCenter"); //$pref::WorldEditor::objectsUseBoxCenter; + EWorldEditor.dropAtScreenCenterScalar = EditorSettings.value("dropAtScreenCenterScalar"); + EWorldEditor.dropAtScreenCenterMax = EditorSettings.value("dropAtScreenCenterMax"); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Render" ); + EWorldEditor.renderObjHandle = EditorSettings.value("renderObjHandle"); //$pref::WorldEditor::renderObjHandle; + EWorldEditor.renderObjText = EditorSettings.value("renderObjText"); //$pref::WorldEditor::renderObjText; + EWorldEditor.renderPopupBackground = EditorSettings.value("renderPopupBackground"); //$pref::WorldEditor::renderPopupBackground; + EWorldEditor.renderSelectionBox = EditorSettings.value("renderSelectionBox"); //$pref::WorldEditor::renderSelectionBox; + EWorldEditor.showMousePopupInfo = EditorSettings.value("showMousePopupInfo"); //$pref::WorldEditor::showMousePopupInfo; + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Color" ); + EWorldEditor.dragRectColor = EditorSettings.value("dragRectColor"); //$pref::WorldEditor::dragRectColor; + EWorldEditor.objectTextColor = EditorSettings.value("objectTextColor"); //$pref::WorldEditor::objectTextColor; + EWorldEditor.objMouseOverColor = EditorSettings.value("objMouseOverColor"); //$pref::WorldEditor::objMouseOverColor; + EWorldEditor.objMouseOverSelectColor = EditorSettings.value("objMouseOverSelectColor"); //$pref::WorldEditor::objMouseOverSelectColor; + EWorldEditor.objSelectColor = EditorSettings.value("objSelectColor"); //$pref::WorldEditor::objSelectColor; + EWorldEditor.popupBackgroundColor = EditorSettings.value("popupBackgroundColor"); //$pref::WorldEditor::popupBackgroundColor; + EWorldEditor.popupTextColor = EditorSettings.value("popupTextColor"); //$pref::WorldEditor::popupTextColor; + EWorldEditor.selectionBoxColor = EditorSettings.value("selectionBoxColor"); //$pref::WorldEditor::selectionBoxColor; + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Images" ); + EWorldEditor.defaultHandle = EditorSettings.value("defaultHandle"); //$pref::WorldEditor::defaultHandle; + EWorldEditor.lockedHandle = EditorSettings.value("lockedHandle"); //$pref::WorldEditor::lockedHandle; + EWorldEditor.selectHandle = EditorSettings.value("selectHandle"); //$pref::WorldEditor::selectHandle; + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Docs" ); + EWorldEditor.documentationLocal = EditorSettings.value( "documentationLocal" ); + EWorldEditor.documentationURL = EditorSettings.value( "documentationURL" ); + EWorldEditor.documentationReference = EditorSettings.value( "documentationReference" ); + EWorldEditor.forumURL = EditorSettings.value( "forumURL" ); + EditorSettings.endGroup(); + + //EWorldEditor.planarMovement = $pref::WorldEditor::planarMovement; //<-- What is this used for? + + EditorSettings.endGroup(); // WorldEditor + + EditorSettings.beginGroup( "AxisGizmo", true ); + GlobalGizmoProfile.screenLength = EditorSettings.value("axisGizmoMaxScreenLen"); //$pref::WorldEditor::axisGizmoMaxScreenLen; + GlobalGizmoProfile.rotationSnap = EditorSettings.value("rotationSnap"); //$pref::WorldEditor::rotationSnap; + GlobalGizmoProfile.snapRotations = EditorSettings.value("snapRotations"); //$pref::WorldEditor::snapRotations; + GlobalGizmoProfile.rotateScalar = EditorSettings.value("mouseRotateScalar"); //$pref::WorldEditor::mouseRotateScalar; + GlobalGizmoProfile.scaleScalar = EditorSettings.value("mouseScaleScalar"); //$pref::WorldEditor::mouseScaleScalar; + GlobalGizmoProfile.renderWhenUsed = EditorSettings.value("renderWhenUsed"); + GlobalGizmoProfile.renderInfoText = EditorSettings.value("renderInfoText"); + + EditorSettings.beginGroup( "Grid" ); + GlobalGizmoProfile.gridColor = EditorSettings.value("gridColor"); //$pref::WorldEditor::gridColor; + GlobalGizmoProfile.gridSize = EditorSettings.value("gridSize"); //$pref::WorldEditor::gridSize; + GlobalGizmoProfile.snapToGrid = EditorSettings.value("snapToGrid"); //$pref::WorldEditor::snapToGrid; + GlobalGizmoProfile.renderPlane = EditorSettings.value("renderPlane"); //$pref::WorldEditor::renderPlane; + GlobalGizmoProfile.renderPlaneHashes = EditorSettings.value("renderPlaneHashes"); //$pref::WorldEditor::renderPlaneHashes; + GlobalGizmoProfile.planeDim = EditorSettings.value("planeDim"); //$pref::WorldEditor::planeDim; + EditorSettings.endGroup(); + + EditorSettings.endGroup(); // AxisGizmo +} + +function EditorGui::writeWorldEditorSettings(%this) +{ + EditorSettings.beginGroup( "WorldEditor", true ); + EditorSettings.setValue( "dropType", EWorldEditor.dropType ); //$pref::WorldEditor::dropType + EditorSettings.setValue( "undoLimit", EWorldEditor.undoLimit ); //$pref::WorldEditor::undoLimit + EditorSettings.setValue( "forceLoadDAE", EWorldEditor.forceLoadDAE ); //$pref::WorldEditor::forceLoadDAE + EditorSettings.setValue( "displayType", %this.currentDisplayType ); + EditorSettings.setValue( "orthoFOV", %this.currentOrthoFOV ); + EditorSettings.setValue( "orthoShowGrid", EWorldEditor.renderOrthoGrid ); + EditorSettings.setValue( "currentEditor", %this.currentEditor ); + EditorSettings.setvalue( "torsionPath", %this.torsionPath ); + + EditorSettings.beginGroup( "ObjectIcons" ); + EditorSettings.setValue( "fadeIcons", EWorldEditor.fadeIcons ); + EditorSettings.setValue( "fadeIconsStartDist", EWorldEditor.fadeIconsStartDist ); + EditorSettings.setValue( "fadeIconsEndDist", EWorldEditor.fadeIconsEndDist ); + EditorSettings.setValue( "fadeIconsStartAlpha", EWorldEditor.fadeIconsStartAlpha ); + EditorSettings.setValue( "fadeIconsEndAlpha", EWorldEditor.fadeIconsEndAlpha ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Grid" ); + EditorSettings.setValue( "gridSize", EWorldEditor.gridSize ); + EditorSettings.setValue( "gridSnap", EWorldEditor.gridSnap ); + EditorSettings.setValue( "gridColor", EWorldEditor.gridColor ); + EditorSettings.setValue( "gridOriginColor", EWorldEditor.gridOriginColor ); + EditorSettings.setValue( "gridMinorColor", EWorldEditor.gridMinorColor ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Tools" ); + EditorSettings.setValue( "snapGround", EWorldEditor.stickToGround ); //$Pref::WorldEditor::snapGround + EditorSettings.setValue( "snapSoft", EWorldEditor.getSoftSnap() ); //$Pref::WorldEditor::snapSoft + EditorSettings.setValue( "snapSoftSize", EWorldEditor.getSoftSnapSize() ); //$Pref::WorldEditor::snapSoftSize + EditorSettings.setValue( "boundingBoxCollision", EWorldEditor.boundingBoxCollision ); //$Pref::WorldEditor::boundingBoxCollision + EditorSettings.setValue( "objectsUseBoxCenter", EWorldEditor.objectsUseBoxCenter ); //$Pref::WorldEditor::objectsUseBoxCenter + EditorSettings.setValue( "dropAtScreenCenterScalar", EWorldEditor.dropAtScreenCenterScalar ); + EditorSettings.setValue( "dropAtScreenCenterMax", EWorldEditor.dropAtScreenCenterMax ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Render" ); + EditorSettings.setValue( "renderObjHandle", EWorldEditor.renderObjHandle ); //$Pref::WorldEditor::renderObjHandle + EditorSettings.setValue( "renderObjText", EWorldEditor.renderObjText ); //$Pref::WorldEditor::renderObjText + EditorSettings.setValue( "renderPopupBackground", EWorldEditor.renderPopupBackground ); //$Pref::WorldEditor::renderPopupBackground + EditorSettings.setValue( "renderSelectionBox", EWorldEditor.renderSelectionBox ); //$Pref::WorldEditor::renderSelectionBox + EditorSettings.setValue( "showMousePopupInfo", EWorldEditor.showMousePopupInfo ); //$Pref::WorldEditor::showMousePopupInfo + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Color" ); + EditorSettings.setValue( "dragRectColor", EWorldEditor.dragRectColor ); //$Pref::WorldEditor::dragRectColor + EditorSettings.setValue( "objectTextColor", EWorldEditor.objectTextColor ); //$Pref::WorldEditor::objectTextColor + EditorSettings.setValue( "objMouseOverColor", EWorldEditor.objMouseOverColor ); //$Pref::WorldEditor::objMouseOverColor + EditorSettings.setValue( "objMouseOverSelectColor",EWorldEditor.objMouseOverSelectColor );//$Pref::WorldEditor::objMouseOverSelectColor + EditorSettings.setValue( "objSelectColor", EWorldEditor.objSelectColor ); //$Pref::WorldEditor::objSelectColor + EditorSettings.setValue( "popupBackgroundColor", EWorldEditor.popupBackgroundColor ); //$Pref::WorldEditor::popupBackgroundColor + EditorSettings.setValue( "selectionBoxColor", EWorldEditor.selectionBoxColor ); //$Pref::WorldEditor::selectionBoxColor + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Images" ); + EditorSettings.setValue( "defaultHandle", EWorldEditor.defaultHandle ); //$Pref::WorldEditor::defaultHandle + EditorSettings.setValue( "selectHandle", EWorldEditor.selectHandle ); //$Pref::WorldEditor::selectHandle + EditorSettings.setValue( "lockedHandle", EWorldEditor.lockedHandle ); //$Pref::WorldEditor::lockedHandle + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "Docs" ); + EditorSettings.setValue( "documentationLocal", EWorldEditor.documentationLocal ); + EditorSettings.setValue( "documentationReference", EWorldEditor.documentationReference ); + EditorSettings.setValue( "documentationURL", EWorldEditor.documentationURL ); + EditorSettings.setValue( "forumURL", EWorldEditor.forumURL ); + EditorSettings.endGroup(); + + EditorSettings.endGroup(); // WorldEditor + + EditorSettings.beginGroup( "AxisGizmo", true ); + + EditorSettings.setValue( "axisGizmoMaxScreenLen", GlobalGizmoProfile.screenLength ); //$Pref::WorldEditor::axisGizmoMaxScreenLen + EditorSettings.setValue( "rotationSnap", GlobalGizmoProfile.rotationSnap ); //$Pref::WorldEditor::rotationSnap + EditorSettings.setValue( "snapRotations", GlobalGizmoProfile.snapRotations ); //$Pref::WorldEditor::snapRotations + EditorSettings.setValue( "mouseRotateScalar", GlobalGizmoProfile.rotateScalar ); //$Pref::WorldEditor::mouseRotateScalar + EditorSettings.setValue( "mouseScaleScalar", GlobalGizmoProfile.scaleScalar ); //$Pref::WorldEditor::mouseScaleScalar + EditorSettings.setValue( "renderWhenUsed", GlobalGizmoProfile.renderWhenUsed ); + EditorSettings.setValue( "renderInfoText", GlobalGizmoProfile.renderInfoText ); + + EditorSettings.beginGroup( "Grid" ); + EditorSettings.setValue( "gridColor", GlobalGizmoProfile.gridColor ); //$Pref::WorldEditor::gridColor + EditorSettings.setValue( "gridSize", GlobalGizmoProfile.gridSize ); //$Pref::WorldEditor::gridSize + EditorSettings.setValue( "snapToGrid", GlobalGizmoProfile.snapToGrid ); //$Pref::WorldEditor::snapToGrid + EditorSettings.setValue( "renderPlane", GlobalGizmoProfile.renderPlane ); //$Pref::WorldEditor::renderPlane + EditorSettings.setValue( "renderPlaneHashes", GlobalGizmoProfile.renderPlaneHashes );//$Pref::WorldEditor::renderPlaneHashes + EditorSettings.setValue( "planeDim", GlobalGizmoProfile.planeDim ); //$Pref::WorldEditor::planeDim + EditorSettings.endGroup(); + + EditorSettings.endGroup(); // AxisGizmo +} + +function EditorGui::readTerrainEditorSettings(%this) +{ + EditorSettings.beginGroup( "TerrainEditor", true ); + + ETerrainEditor.savedAction = EditorSettings.value("currentAction"); + + EditorSettings.beginGroup( "Brush" ); + ETerrainEditor.maxBrushSize = EditorSettings.value("maxBrushSize"); + ETerrainEditor.setBrushSize( EditorSettings.value("brushSize") ); + ETerrainEditor.setBrushType( EditorSettings.value("brushType") ); + ETerrainEditor.setBrushPressure( EditorSettings.value("brushPressure") ); + ETerrainEditor.setBrushSoftness( EditorSettings.value("brushSoftness") ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "ActionValues" ); + ETerrainEditor.adjustHeightVal = EditorSettings.value("adjustHeightVal"); + ETerrainEditor.setHeightVal = EditorSettings.value("setHeightVal"); + ETerrainEditor.scaleVal = EditorSettings.value("scaleVal"); + ETerrainEditor.smoothFactor = EditorSettings.value("smoothFactor"); + ETerrainEditor.noiseFactor = EditorSettings.value("noiseFactor"); + ETerrainEditor.softSelectRadius = EditorSettings.value("softSelectRadius"); + ETerrainEditor.softSelectFilter = EditorSettings.value("softSelectFilter"); + ETerrainEditor.softSelectDefaultFilter = EditorSettings.value("softSelectDefaultFilter"); + ETerrainEditor.setSlopeLimitMinAngle( EditorSettings.value("slopeMinAngle") ); + ETerrainEditor.setSlopeLimitMaxAngle( EditorSettings.value("slopeMaxAngle") ); + EditorSettings.endGroup(); + + EditorSettings.endGroup(); +} + +function EditorGui::writeTerrainEditorSettings(%this) +{ + EditorSettings.beginGroup( "TerrainEditor", true ); + + EditorSettings.setValue( "currentAction", ETerrainEditor.savedAction ); + + EditorSettings.beginGroup( "Brush" ); + EditorSettings.setValue( "maxBrushSize", ETerrainEditor.maxBrushSize ); + EditorSettings.setValue( "brushSize", ETerrainEditor.getBrushSize() ); + EditorSettings.setValue( "brushType", ETerrainEditor.getBrushType() ); + EditorSettings.setValue( "brushPressure", ETerrainEditor.getBrushPressure() ); + EditorSettings.setValue( "brushSoftness", ETerrainEditor.getBrushSoftness() ); + EditorSettings.endGroup(); + + EditorSettings.beginGroup( "ActionValues" ); + EditorSettings.setValue( "adjustHeightVal", ETerrainEditor.adjustHeightVal ); + EditorSettings.setValue( "setHeightVal", ETerrainEditor.setHeightVal ); + EditorSettings.setValue( "scaleVal", ETerrainEditor.scaleVal ); + EditorSettings.setValue( "smoothFactor", ETerrainEditor.smoothFactor ); + EditorSettings.setValue( "noiseFactor", ETerrainEditor.noiseFactor ); + EditorSettings.setValue( "softSelectRadius", ETerrainEditor.softSelectRadius ); + EditorSettings.setValue( "softSelectFilter", ETerrainEditor.softSelectFilter ); + EditorSettings.setValue( "softSelectDefaultFilter",ETerrainEditor.softSelectDefaultFilter ); + EditorSettings.setValue( "slopeMinAngle", ETerrainEditor.getSlopeLimitMinAngle() ); + EditorSettings.setValue( "slopeMaxAngle", ETerrainEditor.getSlopeLimitMaxAngle() ); + EditorSettings.endGroup(); + + EditorSettings.endGroup(); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editorRender.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editorRender.ed.cs new file mode 100644 index 000000000..4fae4d11c --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editorRender.ed.cs @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Console onEditorRender functions: +//------------------------------------------------------------------------------ +// Functions: +// - renderSphere([pos], [radius], <sphereLevel>); +// - renderCircle([pos], [normal], [radius], <segments>); +// - renderTriangle([pnt], [pnt], [pnt]); +// - renderLine([start], [end], <thickness>); +// +// Variables: +// - consoleFrameColor - line prims are rendered with this +// - consoleFillColor +// - consoleSphereLevel - level of polyhedron subdivision +// - consoleCircleSegments +// - consoleLineWidth +//------------------------------------------------------------------------------ + +function SpawnSphere::onEditorRender(%this, %editor, %selected, %expanded) +{ + if(%selected $= "true") + { + %editor.consoleFrameColor = "255 0 0"; + %editor.consoleFillColor = "0 160 0 95"; + %editor.renderSphere(%this.getWorldBoxCenter(), %this.radius, 1); + } +} + +//function Item::onEditorRender(%this, %editor, %selected, %expanded) +//{ +// if(%this.getDataBlock().getName() $= "MineDeployed") +// { +// %editor.consoleFillColor = "0 0 0 0"; +// %editor.consoleFrameColor = "255 0 0"; +// %editor.renderSphere(%this.getWorldBoxCenter(), 6, 1); +// } +//} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editorSettingsWindow.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editorSettingsWindow.ed.cs new file mode 100644 index 000000000..3af447854 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editorSettingsWindow.ed.cs @@ -0,0 +1,142 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function ESettingsWindow::startup( %this ) +{ + ESettingsWindowTabBook.selectPage( 0 ); + ESettingsWindowList.setSelectedById( 0 ); +} + +function ESettingsWindow::onWake( %this ) +{ +} + +function ESettingsWindow::hideDialog( %this ) +{ + %this.setVisible(false); +} + +function ESettingsWindow::ToggleVisibility() +{ + if ( ESettingsWindow.visible ) + { + ESettingsWindow.setVisible(false); + } + else + { + ESettingsWindow.setVisible(true); + ESettingsWindow.selectWindow(); + ESettingsWindow.setCollapseGroup(false); + } +} + +function ESettingsWindow::addTabPage( %this, %page ) +{ + ESettingsWindowTabBook.add( %page ); + ESettingsWindowList.addRow( ESettingsWindowTabBook.getSelectedPage(), %page.text ); + ESettingsWindowList.sort(0); +} + +//----------------------------------------------------------------------------- + +function ESettingsWindowList::onSelect( %this, %id, %text ) +{ + ESettingsWindowTabBook.selectPage( %id ); +} + +//----------------------------------------------------------------------------- +// Standard settings GUI classes. Editors may define their own methods of +// working with settings and are not required to use these. +//----------------------------------------------------------------------------- + +function ESettingsWindowCheckbox::onWake( %this ) +{ + %this.setStateOn( EditorSettings.value( %this.editorSettingsValue )); +} + +function ESettingsWindowCheckbox::onClick( %this ) +{ + EditorSettings.setValue( %this.editorSettingsValue, %this.getValue() ); + eval(%this.editorSettingsRead); +} + +//----------------------------------------------------------------------------- + +function ESettingsWindowTextEdit::onWake( %this ) +{ + %this.setText( EditorSettings.value( %this.editorSettingsValue )); +} + +function ESettingsWindowTextEdit::onValidate( %this ) +{ + EditorSettings.setValue( %this.editorSettingsValue, %this.getValue() ); + eval(%this.editorSettingsRead); +} + +function ESettingsWindowTextEdit::onGainFirstResponder( %this ) +{ + %this.selectAllText(); +} + +//----------------------------------------------------------------------------- + +function ESettingsWindowColor::apply( %this, %color ) +{ + EditorSettings.setValue( %this.editorSettingsValue, %color ); + eval(%this.editorSettingsRead); + + %this.findObjectByInternalName("ColorEdit", true).setText( %color); + %this.findObjectByInternalName("ColorButton", true).color = ColorIntToFloat( %color ); +} + +function ESettingsWindowColorEdit::onWake( %this ) +{ + %this.setText( EditorSettings.value( %this.getParent().editorSettingsValue )); +} + +function ESettingsWindowColorEdit::onValidate( %this ) +{ + %this.getParent().apply( %this.getValue() ); +} + +function ESettingsWindowColorEdit::onGainFirstResponder( %this ) +{ + %this.selectAllText(); +} + +function ESettingsWindowColorButton::onWake( %this ) +{ + %this.color = ColorIntToFloat( EditorSettings.value( %this.getParent().editorSettingsValue ) ); +} + +function ESettingsWindowColorButton::onClick( %this ) +{ + getColorI( ColorFloatToInt( %this.color ), %this.getId() @ ".apply", %this.getRoot() ); + //EditorSettings.setValue( %this.editorSettingsValue, %this.getValue() ); + //eval(%this.editorSettingsRead); +} + +function ESettingsWindowColorButton::apply( %this, %color ) +{ + %this.getParent().apply(%color); + echo("ESettingsWindowColorButton::apply(): " @ %color); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.cs new file mode 100644 index 000000000..0e2813d57 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.cs @@ -0,0 +1,823 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +function EWCreatorWindow::init( %this ) +{ + // Just so we can recall this method for testing changes + // without restarting. + if ( isObject( %this.array ) ) + %this.array.delete(); + + %this.array = new ArrayObject(); + %this.array.caseSensitive = true; + %this.setListView( true ); + + %this.beginGroup( "Environment" ); + + // Removed Prefab as there doesn't really seem to be a point in creating a blank one + //%this.registerMissionObject( "Prefab", "Prefab" ); + %this.registerMissionObject( "SkyBox", "Sky Box" ); + %this.registerMissionObject( "CloudLayer", "Cloud Layer" ); + %this.registerMissionObject( "BasicClouds", "Basic Clouds" ); + %this.registerMissionObject( "ScatterSky", "Scatter Sky" ); + %this.registerMissionObject( "Sun", "Basic Sun" ); + %this.registerMissionObject( "Lightning" ); + %this.registerMissionObject( "WaterBlock", "Water Block" ); + %this.registerMissionObject( "SFXEmitter", "Sound Emitter" ); + %this.registerMissionObject( "Precipitation" ); + %this.registerMissionObject( "ParticleEmitterNode", "Particle Emitter" ); + %this.registerMissionObject( "VolumetricFog", "Volumetric Fog" ); + %this.registerMissionObject( "RibbonNode", "Ribbon" ); + + // Legacy features. Users should use Ground Cover and the Forest Editor. + //%this.registerMissionObject( "fxShapeReplicator", "Shape Replicator" ); + //%this.registerMissionObject( "fxFoliageReplicator", "Foliage Replicator" ); + + %this.registerMissionObject( "PointLight", "Point Light" ); + %this.registerMissionObject( "SpotLight", "Spot Light" ); + %this.registerMissionObject( "GroundCover", "Ground Cover" ); + %this.registerMissionObject( "TerrainBlock", "Terrain Block" ); + %this.registerMissionObject( "GroundPlane", "Ground Plane" ); + %this.registerMissionObject( "WaterPlane", "Water Plane" ); + %this.registerMissionObject( "PxCloth", "Cloth" ); + %this.registerMissionObject( "ForestWindEmitter", "Wind Emitter" ); + + %this.registerMissionObject( "DustEmitter", "Dust Emitter" ); + %this.registerMissionObject( "DustSimulation", "Dust Simulation" ); + %this.registerMissionObject( "DustEffecter", "Dust Effecter" ); + + %this.endGroup(); + + %this.beginGroup( "Level" ); + + %this.registerMissionObject( "MissionArea", "Mission Area" ); + %this.registerMissionObject( "Path" ); + %this.registerMissionObject( "Marker", "Path Node" ); + %this.registerMissionObject( "Trigger" ); + %this.registerMissionObject( "PhysicalZone", "Physical Zone" ); + %this.registerMissionObject( "Camera" ); + %this.registerMissionObject( "LevelInfo", "Level Info" ); + %this.registerMissionObject( "TimeOfDay", "Time of Day" ); + %this.registerMissionObject( "Zone", "Zone" ); + %this.registerMissionObject( "Portal", "Zone Portal" ); + %this.registerMissionObject( "SpawnSphere", "Player Spawn Sphere", "PlayerDropPoint" ); + %this.registerMissionObject( "SpawnSphere", "Observer Spawn Sphere", "ObserverDropPoint" ); + %this.registerMissionObject( "SFXSpace", "Sound Space" ); + %this.registerMissionObject( "OcclusionVolume", "Occlusion Volume" ); + %this.registerMissionObject( "AccumulationVolume", "Accumulation Volume" ); + %this.registerMissionObject( "Entity", "Entity" ); + + %this.endGroup(); + + %this.beginGroup( "System" ); + + %this.registerMissionObject( "SimGroup" ); + + %this.endGroup(); + + %this.beginGroup( "ExampleObjects" ); + + %this.registerMissionObject( "RenderObjectExample" ); + %this.registerMissionObject( "RenderMeshExample" ); + %this.registerMissionObject( "RenderShapeExample" ); + + %this.endGroup(); +} + +function EWCreatorWindow::onWake( %this ) +{ + CreatorTabBook.selectPage( 0 ); + CreatorTabBook.onTabSelected( "Scripted" ); +} + +function EWCreatorWindow::beginGroup( %this, %group ) +{ + %this.currentGroup = %group; +} + +function EWCreatorWindow::endGroup( %this, %group ) +{ + %this.currentGroup = ""; +} + +function EWCreatorWindow::getCreateObjectPosition() +{ + %focusPoint = LocalClientConnection.getControlObject().getLookAtPoint(); + if( %focusPoint $= "" ) + return "0 0 0"; + else + return getWord( %focusPoint, 1 ) SPC getWord( %focusPoint, 2 ) SPC getWord( %focusPoint, 3 ); +} + +function EWCreatorWindow::registerMissionObject( %this, %class, %name, %buildfunc, %group ) +{ + if( !isClass(%class) ) + return; + + if ( %name $= "" ) + %name = %class; + if ( %this.currentGroup !$= "" && %group $= "" ) + %group = %this.currentGroup; + + if ( %class $= "" || %group $= "" ) + { + warn( "EWCreatorWindow::registerMissionObject, invalid parameters!" ); + return; + } + + %args = new ScriptObject(); + %args.val[0] = %class; + %args.val[1] = %name; + %args.val[2] = %buildfunc; + + %this.array.push_back( %group, %args ); +} + +function EWCreatorWindow::getNewObjectGroup( %this ) +{ + return %this.objectGroup; +} + +function EWCreatorWindow::setNewObjectGroup( %this, %group ) +{ + if( %this.objectGroup ) + { + %oldItemId = EditorTree.findItemByObjectId( %this.objectGroup ); + if( %oldItemId > 0 ) + EditorTree.markItem( %oldItemId, false ); + } + + %group = %group.getID(); + %this.objectGroup = %group; + %itemId = EditorTree.findItemByObjectId( %group ); + EditorTree.markItem( %itemId ); +} + +function EWCreatorWindow::createStatic( %this, %file ) +{ + if ( !$missionRunning ) + return; + + if( !isObject(%this.objectGroup) ) + %this.setNewObjectGroup( MissionGroup ); + + %objId = new TSStatic() + { + shapeName = %file; + position = %this.getCreateObjectPosition(); + parentGroup = %this.objectGroup; + }; + + %this.onObjectCreated( %objId ); +} + +function EWCreatorWindow::createPrefab( %this, %file ) +{ + if ( !$missionRunning ) + return; + + if( !isObject(%this.objectGroup) ) + %this.setNewObjectGroup( MissionGroup ); + + %objId = new Prefab() + { + filename = %file; + position = %this.getCreateObjectPosition(); + parentGroup = %this.objectGroup; + }; + + %this.onObjectCreated( %objId ); +} + +function EWCreatorWindow::createObject( %this, %cmd ) +{ + if ( !$missionRunning ) + return; + + if( !isObject(%this.objectGroup) ) + %this.setNewObjectGroup( MissionGroup ); + + pushInstantGroup(); + %objId = eval(%cmd); + popInstantGroup(); + + if( isObject( %objId ) ) + %this.onFinishCreateObject( %objId ); + + return %objId; +} + +function EWCreatorWindow::onFinishCreateObject( %this, %objId ) +{ + %this.objectGroup.add( %objId ); + + if( %objId.isMemberOfClass( "SceneObject" ) ) + { + %objId.position = %this.getCreateObjectPosition(); + + //flush new position + %objId.setTransform( %objId.getTransform() ); + } + + %this.onObjectCreated( %objId ); +} + +function EWCreatorWindow::onObjectCreated( %this, %objId ) +{ + // Can we submit an undo action? + if ( isObject( %objId ) ) + MECreateUndoAction::submit( %objId ); + + EditorTree.clearSelection(); + EWorldEditor.clearSelection(); + EWorldEditor.selectObject( %objId ); + + // When we drop the selection don't store undo + // state for it... the creation deals with it. + EWorldEditor.dropSelection( true ); +} + +function CreatorTabBook::onTabSelected( %this, %text, %idx ) +{ + if ( %this.isAwake() ) + { + EWCreatorWindow.tab = %text; + EWCreatorWindow.navigate( "" ); + } +} + +function EWCreatorWindow::navigate( %this, %address ) +{ + CreatorIconArray.frozen = true; + CreatorIconArray.clear(); + CreatorPopupMenu.clear(); + + if ( %this.tab $= "Scripted" ) + { + %category = getWord( %address, 1 ); + %dataGroup = "DataBlockGroup"; + + for ( %i = 0; %i < %dataGroup.getCount(); %i++ ) + { + %obj = %dataGroup.getObject(%i); + // echo ("Obj: " @ %obj.getName() @ " - " @ %obj.category ); + + if ( %obj.category $= "" && %obj.category == 0 ) + continue; + + // Add category to popup menu if not there already + if ( CreatorPopupMenu.findText( %obj.category ) == -1 ) + CreatorPopupMenu.add( %obj.category ); + + if ( %address $= "" ) + { + %ctrl = %this.findIconCtrl( %obj.category ); + if ( %ctrl == -1 ) + { + %this.addFolderIcon( %obj.category ); + } + } + else if ( %address $= %obj.category ) + { + %ctrl = %this.findIconCtrl( %obj.getName() ); + if ( %ctrl == -1 ) + %this.addShapeIcon( %obj ); + } + } + + //Add a separate folder for Game Objects + if(isClass("Entity")) + { + if(%address $= "") + { + %this.addFolderIcon("GameObjects"); + } + else + { + //find all GameObjectAssets + %assetQuery = new AssetQuery(); + if(!AssetDatabase.findAssetType(%assetQuery, "GameObjectAsset")) + return 0; //if we didn't find ANY, just exit + + %count = %assetQuery.getCount(); + + for(%i=0; %i < %count; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + %gameObjectAsset = AssetDatabase.acquireAsset(%assetId); + + if(isFile(%gameObjectAsset.TAMLFilePath)) + { + %this.addGameObjectIcon( %gameObjectAsset.gameObjectName ); + } + } + } + } + } + + if ( %this.tab $= "Meshes" ) + { + %fullPath = findFirstFileMultiExpr( getFormatExtensions() ); + + while ( %fullPath !$= "" ) + { + if (strstr(%fullPath, "cached.dts") != -1) + { + %fullPath = findNextFileMultiExpr( getFormatExtensions() ); + continue; + } + + %fullPath = makeRelativePath( %fullPath, getMainDotCSDir() ); + %splitPath = strreplace( %fullPath, " ", "_" ); + %splitPath = strreplace( %splitPath, "/", " " ); + if( getWord(%splitPath, 0) $= "tools" ) + { + %fullPath = findNextFileMultiExpr( getFormatExtensions() ); + continue; + } + + %dirCount = getWordCount( %splitPath ) - 1; + + %pathFolders = getWords( %splitPath, 0, %dirCount - 1 ); + + // Add this file's path (parent folders) to the + // popup menu if it isn't there yet. + %temp = strreplace( %pathFolders, " ", "/" ); + %temp = strreplace( %temp, "_", " " ); + %r = CreatorPopupMenu.findText( %temp ); + if ( %r == -1 ) + { + CreatorPopupMenu.add( %temp ); + } + + // Is this file in the current folder? + if ( stricmp( %pathFolders, %address ) == 0 ) + { + %this.addStaticIcon( %fullPath ); + } + // Then is this file in a subfolder we need to add + // a folder icon for? + else + { + %wordIdx = 0; + %add = false; + + if ( %address $= "" ) + { + %add = true; + %wordIdx = 0; + } + else + { + for ( ; %wordIdx < %dirCount; %wordIdx++ ) + { + %temp = getWords( %splitPath, 0, %wordIdx ); + if ( stricmp( %temp, %address ) == 0 ) + { + %add = true; + %wordIdx++; + break; + } + } + } + + if ( %add == true ) + { + %folder = getWord( %splitPath, %wordIdx ); + + %ctrl = %this.findIconCtrl( %folder ); + if ( %ctrl == -1 ) + %this.addFolderIcon( %folder ); + } + } + + %fullPath = findNextFileMultiExpr( getFormatExtensions() ); + } + } + + if ( %this.tab $= "Level" ) + { + // Add groups to popup menu + %array = %this.array; + %array.sortk(); + + %count = %array.count(); + + if ( %count > 0 ) + { + %lastGroup = ""; + + for ( %i = 0; %i < %count; %i++ ) + { + %group = %array.getKey( %i ); + + if ( %group !$= %lastGroup ) + { + CreatorPopupMenu.add( %group ); + + if ( %address $= "" ) + %this.addFolderIcon( %group ); + } + + if ( %address $= %group ) + { + %args = %array.getValue( %i ); + %class = %args.val[0]; + %name = %args.val[1]; + %func = %args.val[2]; + + %this.addMissionObjectIcon( %class, %name, %func ); + } + + %lastGroup = %group; + } + } + } + + if ( %this.tab $= "Prefabs" ) + { + %expr = "*.prefab"; + %fullPath = findFirstFile( %expr ); + + while ( %fullPath !$= "" ) + { + %fullPath = makeRelativePath( %fullPath, getMainDotCSDir() ); + %splitPath = strreplace( %fullPath, " ", "_" ); + %splitPath = strreplace( %splitPath, "/", " " ); + if( getWord(%splitPath, 0) $= "tools" ) + { + %fullPath = findNextFile( %expr ); + continue; + } + + %dirCount = getWordCount( %splitPath ) - 1; + + %pathFolders = getWords( %splitPath, 0, %dirCount - 1 ); + + // Add this file's path (parent folders) to the + // popup menu if it isn't there yet. + %temp = strreplace( %pathFolders, " ", "/" ); + %temp = strreplace( %temp, "_", " " ); + %r = CreatorPopupMenu.findText( %temp ); + if ( %r == -1 ) + { + CreatorPopupMenu.add( %temp ); + } + + // Is this file in the current folder? + if ( (%dirCount == 0 && %address $= "") || stricmp( %pathFolders, %address ) == 0 ) + { + %this.addPrefabIcon( %fullPath ); + } + // Then is this file in a subfolder we need to add + // a folder icon for? + else + { + %wordIdx = 0; + %add = false; + + if ( %address $= "" ) + { + %add = true; + %wordIdx = 0; + } + else + { + for ( ; %wordIdx < %dirCount; %wordIdx++ ) + { + %temp = getWords( %splitPath, 0, %wordIdx ); + if ( stricmp( %temp, %address ) == 0 ) + { + %add = true; + %wordIdx++; + break; + } + } + } + + if ( %add == true ) + { + %folder = getWord( %splitPath, %wordIdx ); + + %ctrl = %this.findIconCtrl( %folder ); + if ( %ctrl == -1 ) + %this.addFolderIcon( %folder ); + } + } + + %fullPath = findNextFile( %expr ); + } + } + + CreatorIconArray.sort( "alphaIconCompare" ); + + for ( %i = 0; %i < CreatorIconArray.getCount(); %i++ ) + { + CreatorIconArray.getObject(%i).autoSize = false; + } + + CreatorIconArray.frozen = false; + CreatorIconArray.refresh(); + + // Recalculate the array for the parent guiScrollCtrl + CreatorIconArray.getParent().computeSizes(); + + %this.address = %address; + + CreatorPopupMenu.sort(); + + %str = strreplace( %address, " ", "/" ); + %r = CreatorPopupMenu.findText( %str ); + if ( %r != -1 ) + CreatorPopupMenu.setSelected( %r, false ); + else + CreatorPopupMenu.setText( %str ); + CreatorPopupMenu.tooltip = %str; +} + +function EWCreatorWindow::navigateDown( %this, %folder ) +{ + if ( %this.address $= "" ) + %address = %folder; + else + %address = %this.address SPC %folder; + + // Because this is called from an IconButton::onClick command + // we have to wait a tick before actually calling navigate, else + // we would delete the button out from under itself. + %this.schedule( 1, "navigate", %address ); +} + +function EWCreatorWindow::navigateUp( %this ) +{ + %count = getWordCount( %this.address ); + + if ( %count == 0 ) + return; + + if ( %count == 1 ) + %address = ""; + else + %address = getWords( %this.address, 0, %count - 2 ); + + %this.navigate( %address ); +} + +function EWCreatorWindow::setListView( %this, %noupdate ) +{ + //CreatorIconArray.clear(); + //CreatorIconArray.setVisible( false ); + + CreatorIconArray.setVisible( true ); + %this.contentCtrl = CreatorIconArray; + %this.isList = true; + + if ( %noupdate == true ) + %this.navigate( %this.address ); +} + +//function EWCreatorWindow::setIconView( %this ) +//{ + //echo( "setIconView" ); + // + //CreatorIconStack.clear(); + //CreatorIconStack.setVisible( false ); + // + //CreatorIconArray.setVisible( true ); + //%this.contentCtrl = CreatorIconArray; + //%this.isList = false; + // + //%this.navigate( %this.address ); +//} + +function EWCreatorWindow::findIconCtrl( %this, %name ) +{ + for ( %i = 0; %i < %this.contentCtrl.getCount(); %i++ ) + { + %ctrl = %this.contentCtrl.getObject( %i ); + if ( %ctrl.text $= %name ) + return %ctrl; + } + + return -1; +} + +function EWCreatorWindow::createIcon( %this ) +{ + %ctrl = new GuiIconButtonCtrl() + { + profile = "GuiCreatorIconButtonProfile"; + buttonType = "radioButton"; + groupNum = "-1"; + }; + + if ( %this.isList ) + { + %ctrl.iconLocation = "Left"; + %ctrl.textLocation = "Right"; + %ctrl.extent = "348 19"; + %ctrl.textMargin = 8; + %ctrl.buttonMargin = "2 2"; + %ctrl.autoSize = true; + } + else + { + %ctrl.iconLocation = "Center"; + %ctrl.textLocation = "Bottom"; + %ctrl.extent = "40 40"; + } + + return %ctrl; +} + +function EWCreatorWindow::addFolderIcon( %this, %text ) +{ + %ctrl = %this.createIcon(); + + %ctrl.altCommand = "EWCreatorWindow.navigateDown(\"" @ %text @ "\");"; + %ctrl.iconBitmap = "tools/gui/images/folder.png"; + %ctrl.text = %text; + %ctrl.tooltip = %text; + %ctrl.class = "CreatorFolderIconBtn"; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + %this.contentCtrl.addGuiControl( %ctrl ); +} + +function EWCreatorWindow::addMissionObjectIcon( %this, %class, %name, %buildfunc ) +{ + %ctrl = %this.createIcon(); + + // If we don't find a specific function for building an + // object then fall back to the stock one + %method = "build" @ %buildfunc; + if( !ObjectBuilderGui.isMethod( %method ) ) + %method = "build" @ %class; + + if( !ObjectBuilderGui.isMethod( %method ) ) + %cmd = "return new " @ %class @ "();"; + else + %cmd = "ObjectBuilderGui." @ %method @ "();"; + + %ctrl.altCommand = "ObjectBuilderGui.newObjectCallback = \"EWCreatorWindow.onFinishCreateObject\"; EWCreatorWindow.createObject( \"" @ %cmd @ "\" );"; + %ctrl.iconBitmap = EditorIconRegistry::findIconByClassName( %class ); + %ctrl.text = %name; + %ctrl.class = "CreatorMissionObjectIconBtn"; + %ctrl.tooltip = %class; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + %this.contentCtrl.addGuiControl( %ctrl ); +} + +function EWCreatorWindow::addShapeIcon( %this, %datablock ) +{ + %ctrl = %this.createIcon(); + + %name = %datablock.getName(); + %class = %datablock.getClassName(); + %cmd = %class @ "::create(" @ %name @ ");"; + + %shapePath = ( %datablock.shapeFile !$= "" ) ? %datablock.shapeFile : %datablock.shapeName; + + %createCmd = "EWCreatorWindow.createObject( \\\"" @ %cmd @ "\\\" );"; + %ctrl.altCommand = "ColladaImportDlg.showDialog( \"" @ %shapePath @ "\", \"" @ %createCmd @ "\" );"; + + %ctrl.iconBitmap = EditorIconRegistry::findIconByClassName( %class ); + %ctrl.text = %name; + %ctrl.class = "CreatorShapeIconBtn"; + %ctrl.tooltip = %name; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + %this.contentCtrl.addGuiControl( %ctrl ); +} + +function EWCreatorWindow::addStaticIcon( %this, %fullPath ) +{ + %ctrl = %this.createIcon(); + + %ext = fileExt( %fullPath ); + %file = fileBase( %fullPath ); + %fileLong = %file @ %ext; + %tip = %fileLong NL + "Size: " @ fileSize( %fullPath ) / 1000.0 SPC "KB" NL + "Date Created: " @ fileCreatedTime( %fullPath ) NL + "Last Modified: " @ fileModifiedTime( %fullPath ); + + %createCmd = "EWCreatorWindow.createStatic( \\\"" @ %fullPath @ "\\\" );"; + %ctrl.altCommand = "ColladaImportDlg.showDialog( \"" @ %fullPath @ "\", \"" @ %createCmd @ "\" );"; + + %ctrl.iconBitmap = ( ( %ext $= ".dts" ) ? EditorIconRegistry::findIconByClassName( "TSStatic" ) : "tools/gui/images/iconCollada" ); + %ctrl.text = %file; + %ctrl.class = "CreatorStaticIconBtn"; + %ctrl.tooltip = %tip; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + %this.contentCtrl.addGuiControl( %ctrl ); +} + +function EWCreatorWindow::addPrefabIcon( %this, %fullPath ) +{ + %ctrl = %this.createIcon(); + + %ext = fileExt( %fullPath ); + %file = fileBase( %fullPath ); + %fileLong = %file @ %ext; + %tip = %fileLong NL + "Size: " @ fileSize( %fullPath ) / 1000.0 SPC "KB" NL + "Date Created: " @ fileCreatedTime( %fullPath ) NL + "Last Modified: " @ fileModifiedTime( %fullPath ); + + %ctrl.altCommand = "EWCreatorWindow.createPrefab( \"" @ %fullPath @ "\" );"; + %ctrl.iconBitmap = EditorIconRegistry::findIconByClassName( "Prefab" ); + %ctrl.text = %file; + %ctrl.class = "CreatorPrefabIconBtn"; + %ctrl.tooltip = %tip; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + %this.contentCtrl.addGuiControl( %ctrl ); +} + +function EWCreatorWindow::addGameObjectIcon( %this, %gameObjectName ) +{ + %ctrl = %this.createIcon(); + + %ctrl.altCommand = "spawnGameObject( \"" @ %gameObjectName @ "\", true );"; + %ctrl.iconBitmap = EditorIconRegistry::findIconByClassName( "Prefab" ); + %ctrl.text = %gameObjectName; + %ctrl.class = "CreatorGameObjectIconBtn"; + %ctrl.tooltip = "Spawn the " @ %gameObjectName @ " GameObject"; + + %ctrl.buttonType = "radioButton"; + %ctrl.groupNum = "-1"; + + %this.contentCtrl.addGuiControl( %ctrl ); +} + +function CreatorPopupMenu::onSelect( %this, %id, %text ) +{ + %split = strreplace( %text, "/", " " ); + EWCreatorWindow.navigate( %split ); +} + +function alphaIconCompare( %a, %b ) +{ + if ( %a.class $= "CreatorFolderIconBtn" ) + if ( %b.class !$= "CreatorFolderIconBtn" ) + return -1; + + if ( %b.class $= "CreatorFolderIconBtn" ) + if ( %a.class !$= "CreatorFolderIconBtn" ) + return 1; + + %result = stricmp( %a.text, %b.text ); + return %result; +} + +// Generic create object helper for use from the console. + +function genericCreateObject( %class ) +{ + if ( !isClass( %class ) ) + { + warn( "createObject( " @ %class @ " ) - Was not a valid class." ); + return; + } + + %cmd = "return new " @ %class @ "();"; + + %obj = EWCreatorWindow.createObject( %cmd ); + + // In case the caller wants it. + return %obj; +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/missionArea.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/missionArea.ed.cs new file mode 100644 index 000000000..a2b3f90a9 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/missionArea.ed.cs @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function AreaEditor::onUpdate(%this, %area) +{ + AreaEditingText.setValue( "X: " @ getWord(%area,0) @ " Y: " @ getWord(%area,1) @ " W: " @ getWord(%area,2) @ " H: " @ getWord(%area,3)); +} + +function AreaEditor::onWorldOffset(%this, %offset) +{ +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs new file mode 100644 index 000000000..63d185541 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/terrainEditor.ed.cs @@ -0,0 +1,479 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +/// The texture filename filter used with OpenFileDialog. +$TerrainEditor::TextureFileSpec = "Image Files (*.png, *.jpg, *.dds)|*.png;*.jpg;*.dds|All Files (*.*)|*.*|"; + +function TerrainEditor::init( %this ) +{ + %this.attachTerrain(); + %this.setBrushSize( 9, 9 ); + + new PersistenceManager( ETerrainPersistMan ); +} + +/// +function EPainter_TerrainMaterialUpdateCallback( %mat, %matIndex ) +{ + // Skip over a bad selection. + if ( %matIndex == -1 || !isObject( %mat ) ) + return; + + // Update the material and the UI. + ETerrainEditor.updateMaterial( %matIndex, %mat.getInternalName() ); + EPainter.setup( %matIndex ); +} + +function EPainter_TerrainMaterialAddCallback( %mat, %matIndex ) +{ + // Ignore bad materials. + if ( !isObject( %mat ) ) + return; + + // Add it and update the UI. + ETerrainEditor.addMaterial( %mat.getInternalName() ); + EPainter.setup( %matIndex ); +} + +function TerrainEditor::setPaintMaterial( %this, %matIndex, %terrainMat ) +{ + assert( isObject( %terrainMat ), "TerrainEditor::setPaintMaterial - Got bad material!" ); + + ETerrainEditor.paintIndex = %matIndex; + ETerrainMaterialSelected.selectedMatIndex = %matIndex; + ETerrainMaterialSelected.selectedMat = %terrainMat; + ETerrainMaterialSelected.bitmap = %terrainMat.diffuseMap; + ETerrainMaterialSelectedEdit.Visible = isObject(%terrainMat); + TerrainTextureText.text = %terrainMat.getInternalName(); + ProceduralTerrainPainterDescription.text = "Generate "@ %terrainMat.getInternalName() @" layer"; +} + +function TerrainEditor::setup( %this ) +{ + %action = %this.savedAction; + %desc = %this.savedActionDesc; + if ( %this.savedAction $= "" ) + { + %action = brushAdjustHeight; + } + + %this.switchAction( %action ); +} + +function EPainter::updateLayers( %this, %matIndex ) +{ + // Default to whatever was selected before. + if ( %matIndex $= "" ) + %matIndex = ETerrainEditor.paintIndex; + + // The material string is a newline seperated string of + // TerrainMaterial internal names which we can use to find + // the actual material data in TerrainMaterialSet. + + %mats = ETerrainEditor.getMaterials(); + + %matList = %this-->theMaterialList; + %matList.deleteAllObjects(); + %listWidth = getWord( %matList.getExtent(), 0 ); + + for( %i = 0; %i < getRecordCount( %mats ); %i++ ) + { + %matInternalName = getRecord( %mats, %i ); + %mat = TerrainMaterialSet.findObjectByInternalName( %matInternalName ); + + // Is there no material info for this slot? + if ( !isObject( %mat ) ) + continue; + + %index = %matList.getCount(); + %command = "ETerrainEditor.setPaintMaterial( " @ %index @ ", " @ %mat @ " );"; + %altCommand = "TerrainMaterialDlg.show( " @ %index @ ", " @ %mat @ ", EPainter_TerrainMaterialUpdateCallback );"; + + %ctrl = new GuiIconButtonCtrl() + { + class = "EPainterIconBtn"; + internalName = "EPainterMaterialButton" @ %i; + profile = "GuiCreatorIconButtonProfile"; + iconLocation = "Left"; + textLocation = "Right"; + extent = %listWidth SPC "46"; + textMargin = 5; + buttonMargin = "4 4"; + buttonType = "RadioButton"; + sizeIconToButton = true; + makeIconSquare = true; + tooltipprofile = "ToolsGuiToolTipProfile"; + command = %command; + altCommand = %altCommand; + useMouseEvents = true; + + new GuiBitmapButtonCtrl() + { + bitmap = "tools/gui/images/delete"; + buttonType = "PushButton"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = ( %listwidth - 20 ) SPC "26"; + Extent = "17 17"; + command = "EPainter.showMaterialDeleteDlg( " @ %matInternalName @ " );"; + }; + }; + + %ctrl.setText( %matInternalName ); + %ctrl.setBitmap( %mat.diffuseMap ); + + %tooltip = %matInternalName; + if(%i < 9) + %tooltip = %tooltip @ " (" @ (%i+1) @ ")"; + else if(%i == 9) + %tooltip = %tooltip @ " (0)"; + %ctrl.tooltip = %tooltip; + + %matList.add( %ctrl ); + } + + %matCount = %matList.getCount(); + + // Add one more layer as the 'add new' layer. + %ctrl = new GuiIconButtonCtrl() + { + profile = "GuiCreatorIconButtonProfile"; + iconBitmap = "~/worldEditor/images/terrainpainter/new_layer_icon"; + iconLocation = "Left"; + textLocation = "Right"; + extent = %listWidth SPC "46"; + textMargin = 5; + buttonMargin = "4 4"; + buttonType = "PushButton"; + sizeIconToButton = true; + makeIconSquare = true; + tooltipprofile = "ToolsGuiToolTipProfile"; + text = "New Layer"; + tooltip = "New Layer"; + command = "TerrainMaterialDlg.show( " @ %matCount @ ", 0, EPainter_TerrainMaterialAddCallback );"; + }; + %matList.add( %ctrl ); + + // Make sure our selection is valid and that we're + // not selecting the 'New Layer' button. + + if( %matIndex < 0 ) + return; + if( %matIndex >= %matCount ) + %matIndex = 0; + + // To make things simple... click the paint material button to + // active it and initialize other state. + %ctrl = %matList.getObject( %matIndex ); + %ctrl.performClick(); +} + +function EPainter::showMaterialDeleteDlg( %this, %matInternalName ) +{ + MessageBoxYesNo( "Confirmation", + "Really remove material '" @ %matInternalName @ "' from the terrain?", + %this @ ".removeMaterial( " @ %matInternalName @ " );", "" ); +} + +function EPainter::removeMaterial( %this, %matInternalName ) +{ + %selIndex = ETerrainEditor.paintIndex - 1; + + // Remove the material from the terrain. + + %index = ETerrainEditor.getMaterialIndex( %matInternalName ); + if( %index != -1 ) + ETerrainEditor.removeMaterial( %index ); + + // Update the material list. + + %this.updateLayers( %selIndex ); +} + +function EPainter::setup( %this, %matIndex ) +{ + // Update the layer listing. + %this.updateLayers( %matIndex ); + + // Automagically put us into material paint mode. + ETerrainEditor.currentMode = "paint"; + ETerrainEditor.selectionHidden = true; + ETerrainEditor.currentAction = paintMaterial; + ETerrainEditor.currentActionDesc = "Paint material on terrain"; + ETerrainEditor.setAction( ETerrainEditor.currentAction ); + EditorGuiStatusBar.setInfo(ETerrainEditor.currentActionDesc); + ETerrainEditor.renderVertexSelection = true; +} + +function onNeedRelight() +{ + if( RelightMessage.visible == false ) + RelightMessage.visible = true; +} + +function TerrainEditor::onGuiUpdate(%this, %text) +{ + %minHeight = getWord(%text, 1); + %avgHeight = getWord(%text, 2); + %maxHeight = getWord(%text, 3); + + %mouseBrushInfo = " (Mouse) #: " @ getWord(%text, 0) @ " avg: " @ %avgHeight @ " " @ ETerrainEditor.currentAction; + %selectionInfo = " (Selected) #: " @ getWord(%text, 4) @ " avg: " @ getWord(%text, 5); + + TEMouseBrushInfo.setValue(%mouseBrushInfo); + TEMouseBrushInfo1.setValue(%mouseBrushInfo); + TESelectionInfo.setValue(%selectionInfo); + TESelectionInfo1.setValue(%selectionInfo); + + EditorGuiStatusBar.setSelection("min: " @ %minHeight @ " avg: " @ %avgHeight @ " max: " @ %maxHeight); +} + +function TerrainEditor::onBrushChanged( %this ) +{ + EditorGui.currentEditor.syncBrushInfo(); +} + +function TerrainEditor::toggleBrushType( %this, %brush ) +{ + %this.setBrushType( %brush.internalName ); +} + +function TerrainEditor::offsetBrush(%this, %x, %y) +{ + %curPos = %this.getBrushPos(); + %this.setBrushPos(getWord(%curPos, 0) + %x, getWord(%curPos, 1) + %y); +} + +function TerrainEditor::onActiveTerrainChange(%this, %newTerrain) +{ + // Need to refresh the terrain painter. + if ( EditorGui.currentEditor.getId() == TerrainPainterPlugin.getId() ) + EPainter.setup(ETerrainEditor.paintIndex); +} + +function TerrainEditor::getActionDescription( %this, %action ) +{ + switch$( %action ) + { + case "brushAdjustHeight": + return "Adjust terrain height up or down."; + + case "raiseHeight": + return "Raise terrain height."; + + case "lowerHeight": + return "Lower terrain height."; + + case "smoothHeight": + return "Smooth terrain."; + + case "paintNoise": + return "Modify terrain height using noise."; + + case "flattenHeight": + return "Flatten terrain."; + + case "setHeight": + return "Set terrain height to defined value."; + + case "setEmpty": + return "Remove terrain collision."; + + case "clearEmpty": + return "Add back terrain collision."; + + default: + return ""; + } +} + +/// This is only ment for terrain editing actions and not +/// processed actions or the terrain material painting action. +function TerrainEditor::switchAction( %this, %action ) +{ + %actionDesc = %this.getActionDescription(%action); + + %this.currentMode = "paint"; + %this.selectionHidden = true; + %this.currentAction = %action; + %this.currentActionDesc = %actionDesc; + %this.savedAction = %action; + %this.savedActionDesc = %actionDesc; + + if ( %action $= "setEmpty" || + %action $= "clearEmpty" || + %action $= "setHeight" ) + %this.renderSolidBrush = true; + else + %this.renderSolidBrush = false; + + EditorGuiStatusBar.setInfo(%actionDesc); + + %this.setAction( %this.currentAction ); +} + +function TerrainEditor::onSmoothHeightmap( %this ) +{ + if ( !%this.getActiveTerrain() ) + return; + + // Show the dialog first and let the user + // set the smoothing parameters. + + + + // Now create the terrain smoothing action to + // get the work done and perform later undos. + %action = new TerrainSmoothAction(); + %action.smooth( %this.getActiveTerrain(), 1.0, 1 ); + %action.addToManager( Editor.getUndoManager() ); +} + +function TerrainEditor::onMaterialUndo( %this ) +{ + // Update the gui to reflect the current materials. + EPainter.updateLayers(); +} + +//------------------------------------------------------------------------------ +// Functions +//------------------------------------------------------------------------------ + +function TerrainEditorSettingsGui::onWake(%this) +{ + TESoftSelectFilter.setValue(ETerrainEditor.softSelectFilter); +} + +function TerrainEditorSettingsGui::onSleep(%this) +{ + ETerrainEditor.softSelectFilter = TESoftSelectFilter.getValue(); +} + +function TESettingsApplyButton::onAction(%this) +{ + ETerrainEditor.softSelectFilter = TESoftSelectFilter.getValue(); + ETerrainEditor.resetSelWeights(true); + ETerrainEditor.processAction("softSelect"); +} + +function getPrefSetting(%pref, %default) +{ + // + if(%pref $= "") + return(%default); + else + return(%pref); +} + +function TerrainEditorPlugin::setEditorFunction(%this) +{ + %terrainExists = parseMissionGroup( "TerrainBlock" ); + + if( %terrainExists == false ) + MessageBoxYesNoCancel("No Terrain","Would you like to create a New Terrain?", "Canvas.pushDialog(CreateNewTerrainGui);"); + + return %terrainExists; +} + +function TerrainPainterPlugin::setEditorFunction(%this, %overrideGroup) +{ + %terrainExists = parseMissionGroup( "TerrainBlock" ); + + if( %terrainExists == false ) + MessageBoxYesNoCancel("No Terrain","Would you like to create a New Terrain?", "Canvas.pushDialog(CreateNewTerrainGui);"); + + return %terrainExists; +} + +function EPainterIconBtn::onMouseDragged( %this ) +{ + %payload = new GuiControl() + { + profile = GuiCreatorIconButtonProfile; + position = "0 0"; + extent = %this.extent.x SPC "5"; + dragSourceControl = %this; + }; + + %xOffset = getWord( %payload.extent, 0 ) / 2; + %yOffset = getWord( %payload.extent, 1 ) / 2; + %cursorpos = Canvas.getCursorPos(); + %xPos = getWord( %cursorpos, 0 ) - %xOffset; + %yPos = getWord( %cursorpos, 1 ) - %yOffset; + + // Create the drag control. + + %ctrl = new GuiDragAndDropControl() + { + canSaveDynamicFields = "0"; + Profile = EPainterDragDropProfile; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = %xPos SPC %yPos; + extent = %payload.extent; + MinExtent = "4 4"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + deleteOnMouseUp = true; + }; + + %ctrl.add( %payload ); + + Canvas.getContent().add( %ctrl ); + %ctrl.startDragging( %xOffset, %yOffset ); +} + +function EPainterIconBtn::onControlDragged( %this, %payload ) +{ + %payload.getParent().position = %this.getGlobalPosition(); +} + +function EPainterIconBtn::onControlDropped( %this, %payload ) +{ + %srcBtn = %payload.dragSourceControl; + %dstBtn = %this; + %stack = %this.getParent(); + + // Not dropped on a valid Button. + // Really this shouldnt happen since we are in a callback on our specialized + // EPainterIconBtn namespace. + if ( %stack != %dstBtn.getParent() || %stack != EPainterStack.getId() ) + { + echo( "Not dropped on valid control" ); + return; + } + + // Dropped on the original control, no order change. + // Simulate a click on the control, instead of a drag/drop. + if ( %srcBtn == %dstBtn ) + { + %dstBtn.performClick(); + return; + } + + %dstIndex = %stack.getObjectIndex( %dstBtn ); + ETerrainEditor.reorderMaterial( %stack.getObjectIndex( %srcBtn ), %dstIndex ); + + // select the button/material we just reordered. + %stack.getObject( %dstIndex ).performClick(); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/worldEditor.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/worldEditor.ed.cs new file mode 100644 index 000000000..eb89d1a30 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/worldEditor.ed.cs @@ -0,0 +1,486 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function WorldEditor::onSelect( %this, %obj ) +{ + EditorTree.addSelection( %obj ); + + _setShadowVizLight( %obj ); + + //Inspector.inspect( %obj ); + + if ( isObject( %obj ) && %obj.isMethod( "onEditorSelect" ) ) + %obj.onEditorSelect( %this.getSelectionSize() ); + + EditorGui.currentEditor.onObjectSelected( %obj ); + + // Inform the camera + commandToServer('EditorOrbitCameraSelectChange', %this.getSelectionSize(), %this.getSelectionCentroid()); + + EditorGuiStatusBar.setSelectionObjectsByCount(%this.getSelectionSize()); + + // Update the materialEditorList + $Tools::materialEditorList = %obj.getId(); + + // Used to help the Material Editor( the M.E doesn't utilize its own TS control ) + // so this dirty extension is used to fake it + if ( MaterialEditorPreviewWindow.isVisible() ) + MaterialEditorGui.prepareActiveObject(); + + // Update the Transform Selection window + ETransformSelection.onSelectionChanged(); +} + +function WorldEditor::onMultiSelect( %this, %set ) +{ + // This is called when completing a drag selection ( on3DMouseUp ) + // so we can avoid calling onSelect for every object. We can only + // do most of this stuff, like inspecting, on one object at a time anyway. + + %count = %set.getCount(); + %i = 0; + + foreach( %obj in %set ) + { + if ( %obj.isMethod( "onEditorSelect" ) ) + %obj.onEditorSelect( %count ); + + %i ++; + EditorTree.addSelection( %obj, %i == %count ); + EditorGui.currentEditor.onObjectSelected( %obj ); + } + + // Inform the camera + commandToServer( 'EditorOrbitCameraSelectChange', %count, %this.getSelectionCentroid() ); + + EditorGuiStatusBar.setSelectionObjectsByCount( EWorldEditor.getSelectionSize() ); + + // Update the Transform Selection window, if it is + // visible. + + if( ETransformSelection.isVisible() ) + ETransformSelection.onSelectionChanged(); +} + +function WorldEditor::onUnSelect( %this, %obj ) +{ + if ( isObject( %obj ) && %obj.isMethod( "onEditorUnselect" ) ) + %obj.onEditorUnselect(); + + EditorGui.currentEditor.onObjectDeselected( %obj ); + + Inspector.removeInspect( %obj ); + EditorTree.removeSelection(%obj); + + // Inform the camera + commandToServer('EditorOrbitCameraSelectChange', %this.getSelectionSize(), %this.getSelectionCentroid()); + + EditorGuiStatusBar.setSelectionObjectsByCount(%this.getSelectionSize()); + + // Update the Transform Selection window + ETransformSelection.onSelectionChanged(); +} + +function WorldEditor::onClearSelection( %this ) +{ + EditorGui.currentEditor.onSelectionCleared(); + + EditorTree.clearSelection(); + + // Inform the camera + commandToServer('EditorOrbitCameraSelectChange', %this.getSelectionSize(), %this.getSelectionCentroid()); + + EditorGuiStatusBar.setSelectionObjectsByCount(%this.getSelectionSize()); + + // Update the Transform Selection window + ETransformSelection.onSelectionChanged(); +} + +function WorldEditor::onSelectionCentroidChanged( %this ) +{ + // Inform the camera + commandToServer('EditorOrbitCameraSelectChange', %this.getSelectionSize(), %this.getSelectionCentroid()); + + // Refresh inspector. + Inspector.refresh(); +} + +////////////////////////////////////////////////////////////////////////// + +function WorldEditor::init(%this) +{ + // add objclasses which we do not want to collide with + %this.ignoreObjClass(Sky); + + // editing modes + %this.numEditModes = 3; + %this.editMode[0] = "move"; + %this.editMode[1] = "rotate"; + %this.editMode[2] = "scale"; + + // context menu + new GuiControl(WEContextPopupDlg, EditorGuiGroup) + { + profile = "ToolsGuiModelessDialogProfile"; + horizSizing = "width"; + vertSizing = "height"; + position = "0 0"; + extent = "640 480"; + minExtent = "8 8"; + visible = "1"; + setFirstResponder = "0"; + modal = "1"; + + new GuiPopUpMenuCtrl(WEContextPopup) + { + profile = "ToolsGuiScrollProfile"; + position = "0 0"; + extent = "0 0"; + minExtent = "0 0"; + maxPopupHeight = "200"; + command = "canvas.popDialog(WEContextPopupDlg);"; + }; + }; + WEContextPopup.setVisible(false); + + // Make sure we have an active selection set. + if( !%this.getActiveSelection() ) + %this.setActiveSelection( new WorldEditorSelection( EWorldEditorSelection ) ); +} + +//------------------------------------------------------------------------------ + +function WorldEditor::onDblClick(%this, %obj) +{ + // Commented out because making someone double click to do this is stupid + // and has the possibility of moving hte object + + //Inspector.inspect(%obj); + //InspectorNameEdit.setValue(%obj.getName()); +} + +function WorldEditor::onClick( %this, %obj ) +{ + Inspector.inspect( %obj ); +} + +function WorldEditor::onEndDrag( %this, %obj ) +{ + Inspector.inspect( %obj ); + Inspector.apply(); +} + +//------------------------------------------------------------------------------ + +function WorldEditor::export(%this) +{ + getSaveFilename("~/editor/*.mac|mac file", %this @ ".doExport", "selection.mac"); +} + +function WorldEditor::doExport(%this, %file) +{ + missionGroup.save("~/editor/" @ %file, true); +} + +function WorldEditor::import(%this) +{ + getLoadFilename("~/editor/*.mac|mac file", %this @ ".doImport"); +} + +function WorldEditor::doImport(%this, %file) +{ + exec("~/editor/" @ %file); +} + +function WorldEditor::onGuiUpdate(%this, %text) +{ +} + +function WorldEditor::getSelectionLockCount(%this) +{ + %ret = 0; + for(%i = 0; %i < %this.getSelectionSize(); %i++) + { + %obj = %this.getSelectedObject(%i); + if(%obj.locked) + %ret++; + } + return %ret; +} + +function WorldEditor::getSelectionHiddenCount(%this) +{ + %ret = 0; + for(%i = 0; %i < %this.getSelectionSize(); %i++) + { + %obj = %this.getSelectedObject(%i); + if(%obj.hidden) + %ret++; + } + return %ret; +} + +function WorldEditor::dropCameraToSelection(%this) +{ + if(%this.getSelectionSize() == 0) + return; + + %pos = %this.getSelectionCentroid(); + %cam = LocalClientConnection.camera.getTransform(); + + // set the pnt + %cam = setWord(%cam, 0, getWord(%pos, 0)); + %cam = setWord(%cam, 1, getWord(%pos, 1)); + %cam = setWord(%cam, 2, getWord(%pos, 2)); + + LocalClientConnection.camera.setTransform(%cam); +} + +/// Pastes the selection at the same place (used to move obj from a group to another) +function WorldEditor::moveSelectionInPlace(%this) +{ + %saveDropType = %this.dropType; + %this.dropType = "atCentroid"; + %this.copySelection(); + %this.deleteSelection(); + %this.pasteSelection(); + %this.dropType = %saveDropType; +} + +function WorldEditor::addSelectionToAddGroup(%this) +{ + for(%i = 0; %i < %this.getSelectionSize(); %i++) + { + %obj = %this.getSelectedObject(%i); + $InstantGroup.add(%obj); + } +} + +// resets the scale and rotation on the selection set +function WorldEditor::resetTransforms(%this) +{ + %this.addUndoState(); + + for(%i = 0; %i < %this.getSelectionSize(); %i++) + { + %obj = %this.getSelectedObject(%i); + %transform = %obj.getTransform(); + + %transform = setWord(%transform, 3, "0"); + %transform = setWord(%transform, 4, "0"); + %transform = setWord(%transform, 5, "1"); + %transform = setWord(%transform, 6, "0"); + + // + %obj.setTransform(%transform); + %obj.setScale("1 1 1"); + } +} + + +function WorldEditorToolbarDlg::init(%this) +{ + WorldEditorInspectorCheckBox.setValue( WorldEditorToolFrameSet.isMember( "EditorToolInspectorGui" ) ); + WorldEditorMissionAreaCheckBox.setValue( WorldEditorToolFrameSet.isMember( "EditorToolMissionAreaGui" ) ); + WorldEditorTreeCheckBox.setValue( WorldEditorToolFrameSet.isMember( "EditorToolTreeViewGui" ) ); + WorldEditorCreatorCheckBox.setValue( WorldEditorToolFrameSet.isMember( "EditorToolCreatorGui" ) ); +} + +function WorldEditor::onAddSelected(%this,%obj) +{ + EditorTree.addSelection(%obj); +} + +function WorldEditor::onWorldEditorUndo( %this ) +{ + Inspector.refresh(); +} + +function Inspector::onInspectorFieldModified( %this, %object, %fieldName, %arrayIndex, %oldValue, %newValue ) +{ + // The instant group will try to add our + // UndoAction if we don't disable it. + pushInstantGroup(); + + %nameOrClass = %object.getName(); + if ( %nameOrClass $= "" ) + %nameOrClass = %object.getClassname(); + + %action = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ %fieldName @ " Change"; + + objectId = %object.getId(); + fieldName = %fieldName; + fieldValue = %oldValue; + arrayIndex = %arrayIndex; + + inspectorGui = %this; + }; + + // If it's a datablock, initiate a retransmit. Don't do so + // immediately so as the actual field value will only be set + // by the inspector code after this method has returned. + + if( %object.isMemberOfClass( "SimDataBlock" ) ) + %object.schedule( 1, "reloadOnLocalClient" ); + + // Restore the instant group. + popInstantGroup(); + + %action.addToManager( Editor.getUndoManager() ); + EWorldEditor.isDirty = true; + + // Update the selection + if(EWorldEditor.getSelectionSize() > 0 && (%fieldName $= "position" || %fieldName $= "rotation" || %fieldName $= "scale")) + { + EWorldEditor.invalidateSelectionCentroid(); + } +} + +function Inspector::onFieldSelected( %this, %fieldName, %fieldTypeStr, %fieldDoc ) +{ + FieldInfoControl.setText( "<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc ); +} + +// The following three methods are for fields that edit field value live and thus cannot record +// undo information during edits. For these fields, undo information is recorded in advance and +// then either queued or disarded when the field edit is finished. + +function Inspector::onInspectorPreFieldModification( %this, %fieldName, %arrayIndex ) +{ + pushInstantGroup(); + %undoManager = Editor.getUndoManager(); + + %numObjects = %this.getNumInspectObjects(); + if( %numObjects > 1 ) + %action = %undoManager.pushCompound( "Multiple Field Edit" ); + + for( %i = 0; %i < %numObjects; %i ++ ) + { + %object = %this.getInspectObject( %i ); + + %nameOrClass = %object.getName(); + if ( %nameOrClass $= "" ) + %nameOrClass = %object.getClassname(); + + %undo = new InspectorFieldUndoAction() + { + actionName = %nameOrClass @ "." @ %fieldName @ " Change"; + + objectId = %object.getId(); + fieldName = %fieldName; + fieldValue = %object.getFieldValue( %fieldName, %arrayIndex ); + arrayIndex = %arrayIndex; + + inspectorGui = %this; + }; + + if( %numObjects > 1 ) + %undo.addToManager( %undoManager ); + else + { + %action = %undo; + break; + } + } + + %this.currentFieldEditAction = %action; + popInstantGroup(); +} + +function Inspector::onInspectorPostFieldModification( %this ) +{ + if( %this.currentFieldEditAction.isMemberOfClass( "CompoundUndoAction" ) ) + { + // Finish multiple field edit. + Editor.getUndoManager().popCompound(); + } + else + { + // Queue single field undo. + %this.currentFieldEditAction.addToManager( Editor.getUndoManager() ); + } + + %this.currentFieldEditAction = ""; + EWorldEditor.isDirty = true; +} + +function Inspector::onInspectorDiscardFieldModification( %this ) +{ + %this.currentFieldEditAction.undo(); + + if( %this.currentFieldEditAction.isMemberOfClass( "CompoundUndoAction" ) ) + { + // Multiple field editor. Pop and discard. + Editor.getUndoManager().popCompound( true ); + } + else + { + // Single field edit. Just kill undo action. + %this.currentFieldEditAction.delete(); + } + + %this.currentFieldEditAction = ""; +} + +function Inspector::inspect( %this, %obj ) +{ + //echo( "inspecting: " @ %obj ); + + %name = ""; + if ( isObject( %obj ) ) + %name = %obj.getName(); + else + FieldInfoControl.setText( "" ); + + //InspectorNameEdit.setValue( %name ); + Parent::inspect( %this, %obj ); +} + +function Inspector::onBeginCompoundEdit( %this ) +{ + Editor.getUndoManager().pushCompound( "Multiple Field Edit" ); +} + +function Inspector::onEndCompoundEdit( %this ) +{ + Editor.getUndoManager().popCompound(); +} + +function Inspector::onCancelCompoundEdit( %this ) +{ + Editor.getUndoManager().popCompound( true ); +} + +function foCollaps (%this, %tab){ + switch$ (%tab){ + case "container0": + %tab.visible = "0"; + buttxon1.position = getWord(buttxon0.position, 0)+32 SPC getWord(buttxon1.position, 1); + buttxon2.position = getWord(buttxon1.position, 0)+32 SPC getWord(buttxon2.position, 1); + case "container1": + %tab.visible = "0"; + case "container2": + %tab.visible = "0"; + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/levelInfoEditor.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/levelInfoEditor.ed.cs new file mode 100644 index 000000000..903f14dcf --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/levelInfoEditor.ed.cs @@ -0,0 +1,27 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +// Define the field types for objects that link to the namespace LevelInfo +function LevelInfo::onDefineFieldTypes( %this ) +{ + %this.setFieldType("Desc", "TypeString"); + %this.setFieldType("DescLines", "TypeS32"); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/simObjectEditor.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/simObjectEditor.ed.cs new file mode 100644 index 000000000..57826ae77 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/simObjectEditor.ed.cs @@ -0,0 +1,26 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +// Define the field types for objects that link to the namespace MissionInfo +function SimObject::onDefineFieldTypes( %this ) +{ + %this.setFieldType("Locked", "TypeBool"); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs new file mode 100644 index 000000000..2ec8e17f3 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs @@ -0,0 +1,625 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::show( %this, %matIndex, %terrMat, %onApplyCallback ) +{ + Canvas.pushDialog( %this ); + + %this.matIndex = %matIndex; + %this.onApplyCallback = %onApplyCallback; + + %matLibTree = %this-->matLibTree; + %item = %matLibTree.findItemByObjectId( %terrMat ); + if ( %item != -1 ) + { + %matLibTree.selectItem( %item ); + %matLibTree.scrollVisible( %item ); + } + else + { + for( %i = 1; %i < %matLibTree.getItemCount(); %i++ ) + { + %terrMat = TerrainMaterialDlg-->matLibTree.getItemValue(%i); + if( %terrMat.getClassName() $= "TerrainMaterial" ) + { + %matLibTree.selectItem( %i, true ); + %matLibTree.scrollVisible( %i ); + break; + } + } + } +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::showByObjectId( %this, %matObjectId, %onApplyCallback ) +{ + Canvas.pushDialog( %this ); + + %this.matIndex = -1; + %this.onApplyCallback = %onApplyCallback; + + %matLibTree = %this-->matLibTree; + %matLibTree.clearSelection(); + %item = %matLibTree.findItemByObjectId( %matObjectId ); + if ( %item != -1 ) + { + %matLibTree.selectItem( %item ); + %matLibTree.scrollVisible( %item ); + } +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::onWake( %this ) +{ + if( !isObject( ETerrainMaterialPersistMan ) ) + new PersistenceManager( ETerrainMaterialPersistMan ); + + if( !isObject( TerrainMaterialDlgNewGroup ) ) + new SimGroup( TerrainMaterialDlgNewGroup ); + if( !isObject( TerrainMaterialDlgDeleteGroup ) ) + new SimGroup( TerrainMaterialDlgDeleteGroup ); + + // Snapshot the materials. + %this.snapshotMaterials(); + + // Refresh the material list. + %matLibTree = %this-->matLibTree; + %matLibTree.clear(); + + %matLibTree.open( TerrainMaterialSet, false ); + + %matLibTree.buildVisibleTree( true ); + %item = %matLibTree.getFirstRootItem(); + %matLibTree.expandItem( %item ); + + %this.activateMaterialCtrls( true ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::onSleep( %this ) +{ + if( isObject( TerrainMaterialDlgSnapshot ) ) + TerrainMaterialDlgSnapshot.delete(); + + %this-->matLibTree.clear(); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::dialogApply( %this ) +{ + // Move all new materials we have created to the root group. + + %newCount = TerrainMaterialDlgNewGroup.getCount(); + for( %i = 0; %i < %newCount; %i ++ ) + RootGroup.add( TerrainMaterialDlgNewGroup.getObject( %i ) ); + + // Finalize deletion of all removed materials. + + %deletedCount = TerrainMaterialDlgDeleteGroup.getCount(); + for( %i = 0; %i < %deletedCount; %i ++ ) + { + %mat = TerrainMaterialDlgDeleteGroup.getObject( %i ); + ETerrainMaterialPersistMan.removeObjectFromFile( %mat ); + + %matIndex = ETerrainEditor.getMaterialIndex( %mat.internalName ); + if( %matIndex != -1 ) + { + ETerrainEditor.removeMaterial( %matIndex ); + EPainter.updateLayers(); + } + + %mat.delete(); + } + + // Make sure we save any changes to the current selection. + %this.saveDirtyMaterial( %this.activeMat ); + + // Save all changes. + ETerrainMaterialPersistMan.saveDirty(); + + // Delete the snapshot. + TerrainMaterialDlgSnapshot.delete(); + + // Remove ourselves from the canvas. + Canvas.popDialog( TerrainMaterialDlg ); + + call( %this.onApplyCallback, %this.activeMat, %this.matIndex ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::dialogCancel( %this ) +{ + // Restore material properties we have changed. + + %this.restoreMaterials(); + + // Clear the persistence manager state. + + ETerrainMaterialPersistMan.clearAll(); + + // Delete all new object we have created. + + TerrainMaterialDlgNewGroup.clear(); + + // Restore materials we have marked for deletion. + + %deletedCount = TerrainMaterialDlgDeleteGroup.getCount(); + for( %i = 0; %i < %deletedCount; %i ++ ) + { + %mat = TerrainMaterialDlgDeleteGroup.getObject( %i ); + %mat.parentGroup = RootGroup; + TerrainMaterialSet.add( %mat ); + } + + Canvas.popDialog( TerrainMaterialDlg ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::setMaterialName( %this, %newName ) +{ + %mat = %this.activeMat; + + if( %mat.internalName !$= %newName ) + { + %existingMat = TerrainMaterialSet.findObjectByInternalName( %newName ); + if( isObject( %existingMat ) ) + { + MessageBoxOK( "Error", + "There already is a terrain material called '" @ %newName @ "'.", "", "" ); + } + else + { + %mat.setInternalName( %newName ); + %this-->matLibTree.buildVisibleTree( false ); + } + } +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::changeBase( %this ) +{ + %ctrl = %this-->baseTexCtrl; + %file = %ctrl.bitmap; + if( getSubStr( %file, 0 , 6 ) $= "tools/" ) + %file = ""; + + %file = TerrainMaterialDlg._selectTextureFileDialog( %file ); + if( %file $= "" ) + { + if( %ctrl.bitmap !$= "" ) + %file = %ctrl.bitmap; + else + %file = "tools/materialEditor/gui/unknownImage"; + } + + %file = makeRelativePath( %file, getMainDotCsDir() ); + %ctrl.setBitmap( %file ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::changeDetail( %this ) +{ + %ctrl = %this-->detailTexCtrl; + %file = %ctrl.bitmap; + if( getSubStr( %file, 0 , 6 ) $= "tools/" ) + %file = ""; + + %file = TerrainMaterialDlg._selectTextureFileDialog( %file ); + if( %file $= "" ) + { + if( %ctrl.bitmap !$= "" ) + %file = %ctrl.bitmap; + else + %file = "tools/materialEditor/gui/unknownImage"; + } + + %file = makeRelativePath( %file, getMainDotCsDir() ); + %ctrl.setBitmap( %file ); +} + +//---------------------------------------------------------------------------- + +function TerrainMaterialDlg::changeMacro( %this ) +{ + %ctrl = %this-->macroTexCtrl; + %file = %ctrl.bitmap; + if( getSubStr( %file, 0 , 6 ) $= "tools/" ) + %file = ""; + + %file = TerrainMaterialDlg._selectTextureFileDialog( %file ); + if( %file $= "" ) + { + if( %ctrl.bitmap !$= "" ) + %file = %ctrl.bitmap; + else + %file = "tools/materialEditor/gui/unknownImage"; + } + + %file = makeRelativePath( %file, getMainDotCsDir() ); + %ctrl.setBitmap( %file ); +} + + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::changeNormal( %this ) +{ + %ctrl = %this-->normTexCtrl; + %file = %ctrl.bitmap; + if( getSubStr( %file, 0 , 6 ) $= "tools/" ) + %file = ""; + + %file = TerrainMaterialDlg._selectTextureFileDialog( %file ); + if( %file $= "" ) + { + if( %ctrl.bitmap !$= "" ) + %file = %ctrl.bitmap; + else + %file = "tools/materialEditor/gui/unknownImage"; + } + + %file = makeRelativePath( %file, getMainDotCsDir() ); + %ctrl.setBitmap( %file ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::newMat( %this ) +{ + // Create a unique material name. + %matName = getUniqueInternalName( "newMaterial", TerrainMaterialSet, true ); + + // Create the new material. + %newMat = new TerrainMaterial() + { + internalName = %matName; + parentGroup = TerrainMaterialDlgNewGroup; + }; + %newMat.setFileName( "art/terrains/materials.cs" ); + + // Mark it as dirty and to be saved in the default location. + ETerrainMaterialPersistMan.setDirty( %newMat, "art/terrains/materials.cs" ); + + %matLibTree = %this-->matLibTree; + %matLibTree.buildVisibleTree( true ); + %item = %matLibTree.findItemByObjectId( %newMat ); + %matLibTree.selectItem( %item ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::deleteMat( %this ) +{ + if( !isObject( %this.activeMat ) ) + return; + + // Cannot delete this material if it is the only one left on the Terrain + if ( ( ETerrainEditor.getMaterialCount() == 1 ) && + ( ETerrainEditor.getMaterialIndex( %this.activeMat.internalName ) != -1 ) ) + { + MessageBoxOK( "Error", "Cannot delete this Material, it is the only " @ + "Material still in use by the active Terrain." ); + return; + } + + TerrainMaterialSet.remove( %this.activeMat ); + TerrainMaterialDlgDeleteGroup.add( %this.activeMat ); + + %matLibTree = %this-->matLibTree; + %matLibTree.open( TerrainMaterialSet, false ); + %matLibTree.selectItem( 1 ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::activateMaterialCtrls( %this, %active ) +{ + %parent = %this-->matSettingsParent; + %count = %parent.getCount(); + for ( %i = 0; %i < %count; %i++ ) + %parent.getObject( %i ).setActive( %active ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialTreeCtrl::onSelect( %this, %item ) +{ + TerrainMaterialDlg.setActiveMaterial( %item ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialTreeCtrl::onUnSelect( %this, %item ) +{ + TerrainMaterialDlg.saveDirtyMaterial( %item ); + TerrainMaterialDlg.setActiveMaterial( 0 ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::setActiveMaterial( %this, %mat ) +{ + if ( isObject( %mat ) && + %mat.isMemberOfClass( TerrainMaterial ) ) + { + %this.activeMat = %mat; + + %this-->matNameCtrl.setText( %mat.internalName ); + if (%mat.diffuseMap $= ""){ + %this-->baseTexCtrl.setBitmap( "tools/materialEditor/gui/unknownImage" ); + }else{ + %this-->baseTexCtrl.setBitmap( %mat.diffuseMap ); + } + if (%mat.detailMap $= ""){ + %this-->detailTexCtrl.setBitmap( "tools/materialEditor/gui/unknownImage" ); + }else{ + %this-->detailTexCtrl.setBitmap( %mat.detailMap ); + } + if (%mat.macroMap $= ""){ + %this-->macroTexCtrl.setBitmap( "tools/materialEditor/gui/unknownImage" ); + }else{ + %this-->macroTexCtrl.setBitmap( %mat.macroMap ); + } + if (%mat.normalMap $= ""){ + %this-->normTexCtrl.setBitmap( "tools/materialEditor/gui/unknownImage" ); + }else{ + %this-->normTexCtrl.setBitmap( %mat.normalMap ); + } + %this-->detSizeCtrl.setText( %mat.detailSize ); + %this-->baseSizeCtrl.setText( %mat.diffuseSize ); + %this-->detStrengthCtrl.setText( %mat.detailStrength ); + %this-->detDistanceCtrl.setText( %mat.detailDistance ); + %this-->sideProjectionCtrl.setValue( %mat.useSideProjection ); + %this-->parallaxScaleCtrl.setText( %mat.parallaxScale ); + + %this-->macroSizeCtrl.setText( %mat.macroSize ); + %this-->macroStrengthCtrl.setText( %mat.macroStrength ); + %this-->macroDistanceCtrl.setText( %mat.macroDistance ); + + %this.activateMaterialCtrls( true ); + } + else + { + %this.activeMat = 0; + %this.activateMaterialCtrls( false ); + } +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) +{ + // Skip over obviously bad cases. + if ( !isObject( %mat ) || + !%mat.isMemberOfClass( TerrainMaterial ) ) + return; + + // Read out properties from the dialog. + + %newName = %this-->matNameCtrl.getText(); + + if (%this-->baseTexCtrl.bitmap $= "tools/materialEditor/gui/unknownImage"){ + %newDiffuse = ""; + }else{ + %newDiffuse = %this-->baseTexCtrl.bitmap; + } + if (%this-->normTexCtrl.bitmap $= "tools/materialEditor/gui/unknownImage"){ + %newNormal = ""; + }else{ + %newNormal = %this-->normTexCtrl.bitmap; + } + if (%this-->detailTexCtrl.bitmap $= "tools/materialEditor/gui/unknownImage"){ + %newDetail = ""; + }else{ + %newDetail = %this-->detailTexCtrl.bitmap; + } + if (%this-->macroTexCtrl.bitmap $= "tools/materialEditor/gui/unknownImage"){ + %newMacro = ""; + }else{ + %newMacro = %this-->macroTexCtrl.bitmap; + } + %detailSize = %this-->detSizeCtrl.getText(); + %diffuseSize = %this-->baseSizeCtrl.getText(); + %detailStrength = %this-->detStrengthCtrl.getText(); + %detailDistance = %this-->detDistanceCtrl.getText(); + %useSideProjection = %this-->sideProjectionCtrl.getValue(); + %parallaxScale = %this-->parallaxScaleCtrl.getText(); + + %macroSize = %this-->macroSizeCtrl.getText(); + %macroStrength = %this-->macroStrengthCtrl.getText(); + %macroDistance = %this-->macroDistanceCtrl.getText(); + + // If no properties of this materials have changed, + // return. + + if ( %mat.internalName $= %newName && + %mat.diffuseMap $= %newDiffuse && + %mat.normalMap $= %newNormal && + %mat.detailMap $= %newDetail && + %mat.macroMap $= %newMacro && + %mat.detailSize == %detailSize && + %mat.diffuseSize == %diffuseSize && + %mat.detailStrength == %detailStrength && + %mat.detailDistance == %detailDistance && + %mat.useSideProjection == %useSideProjection && + %mat.macroSize == %macroSize && + %mat.macroStrength == %macroStrength && + %mat.macroDistance == %macroDistance && + %mat.parallaxScale == %parallaxScale ) + return; + + // Make sure the material name is unique. + + if( %mat.internalName !$= %newName ) + { + %existingMat = TerrainMaterialSet.findObjectByInternalName( %newName ); + if( isObject( %existingMat ) ) + { + MessageBoxOK( "Error", + "There already is a terrain material called '" @ %newName @ "'.", "", "" ); + + // Reset the name edit control to the old name. + + %this-->matNameCtrl.setText( %mat.internalName ); + } + else + %mat.setInternalName( %newName ); + } + + %mat.diffuseMap = %newDiffuse; + %mat.normalMap = %newNormal; + %mat.detailMap = %newDetail; + %mat.macroMap = %newMacro; + %mat.detailSize = %detailSize; + %mat.diffuseSize = %diffuseSize; + %mat.detailStrength = %detailStrength; + %mat.detailDistance = %detailDistance; + %mat.macroSize = %macroSize; + %mat.macroStrength = %macroStrength; + %mat.macroDistance = %macroDistance; + %mat.useSideProjection = %useSideProjection; + %mat.parallaxScale = %parallaxScale; + + // Mark the material as dirty and needing saving. + + %fileName = %mat.getFileName(); + if( %fileName $= "" ) + %fileName = "art/terrains/materials.cs"; + + ETerrainMaterialPersistMan.setDirty( %mat, %fileName ); +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::snapshotMaterials( %this ) +{ + if( !isObject( TerrainMaterialDlgSnapshot ) ) + new SimGroup( TerrainMaterialDlgSnapshot ); + + %group = TerrainMaterialDlgSnapshot; + %group.clear(); + + %matCount = TerrainMaterialSet.getCount(); + for( %i = 0; %i < %matCount; %i ++ ) + { + %mat = TerrainMaterialSet.getObject( %i ); + if( !isMemberOfClass( %mat.getClassName(), "TerrainMaterial" ) ) + continue; + + %snapshot = new ScriptObject() + { + parentGroup = %group; + material = %mat; + internalName = %mat.internalName; + diffuseMap = %mat.diffuseMap; + normalMap = %mat.normalMap; + detailMap = %mat.detailMap; + macroMap = %mat.macroMap; + detailSize = %mat.detailSize; + diffuseSize = %mat.diffuseSize; + detailStrength = %mat.detailStrength; + detailDistance = %mat.detailDistance; + macroSize = %mat.macroSize; + macroStrength = %mat.macroStrength; + macroDistance = %mat.macroDistance; + useSideProjection = %mat.useSideProjection; + parallaxScale = %mat.parallaxScale; + }; + } +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::restoreMaterials( %this ) +{ + if( !isObject( TerrainMaterialDlgSnapshot ) ) + { + error( "TerrainMaterial::restoreMaterials - no snapshot present" ); + return; + } + + %count = TerrainMaterialDlgSnapshot.getCount(); + for( %i = 0; %i < %count; %i ++ ) + { + %obj = TerrainMaterialDlgSnapshot.getObject( %i ); + %mat = %obj.material; + + %mat.setInternalName( %obj.internalName ); + %mat.diffuseMap = %obj.diffuseMap; + %mat.normalMap = %obj.normalMap; + %mat.detailMap = %obj.detailMap; + %mat.macroMap = %obj.macroMap; + %mat.detailSize = %obj.detailSize; + %mat.diffuseSize = %obj.diffuseSize; + %mat.detailStrength = %obj.detailStrength; + %mat.detailDistance = %obj.detailDistance; + %mat.macroSize = %obj.macroSize; + %mat.macroStrength = %obj.macroStrength; + %mat.macroDistance = %obj.macroDistance; + %mat.useSideProjection = %obj.useSideProjection; + %mat.parallaxScale = %obj.parallaxScale; + } +} + +//----------------------------------------------------------------------------- + +function TerrainMaterialDlg::_selectTextureFileDialog( %this, %defaultFileName ) +{ + if( $Pref::TerrainEditor::LastPath $= "" ) + $Pref::TerrainEditor::LastPath = "art/terrains"; + + %dlg = new OpenFileDialog() + { + Filters = $TerrainEditor::TextureFileSpec; + DefaultPath = $Pref::TerrainEditor::LastPath; + DefaultFile = %defaultFileName; + ChangePath = false; + MustExist = true; + }; + + %ret = %dlg.Execute(); + if ( %ret ) + { + $Pref::TerrainEditor::LastPath = filePath( %dlg.FileName ); + %file = %dlg.FileName; + } + + %dlg.delete(); + + if ( !%ret ) + return; + + %file = filePath(%file) @ "/" @ fileBase(%file); + + return %file; +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/lighting.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/lighting.ed.cs new file mode 100644 index 000000000..8886b8eb9 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/lighting.ed.cs @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function EditorLightingMenu::onAdd( %this ) +{ + Parent::onAdd( %this ); + + // Get the light manager names. + %lightManagers = getLightManagerNames(); + + // Where we gonna insert them? + %this.lmFirstIndex = %this.getItemCount(); + + // Add the light mangers to the lighting menu. + %count = getFieldCount( %lightManagers ); + for ( %i = 0; %i < %count; %i++ ) + { + %lm = getField( %lightManagers, %i ); + + // Store a reverse lookup of the light manager + // name to the menu index... used in onMenuSelect. + %index = %this.lmFirstIndex + %i; + %this.lmToIndex[ %lm ] = %index; + + // The command just sets the light manager. + %cmd = "setLightManager(\"" @ %lm @ "\"); $pref::lightManager = \"" @ %lm @ "\";"; + + // Add it. + %this.addItem( %index, %lm TAB "" TAB %cmd ); + } + + // Store for later in EditorLightingMenu. + %this.lmLastIndex = %index; +} + +function EditorLightingMenu::onMenuSelect( %this ) +{ + %lm = getActiveLightManager(); + %index = %this.lmToIndex[ %lm ]; + %this.checkRadioItem( %this.lmFirstIndex, %this.lmLastIndex, %index ); + + //%selSize = EWorldEditor.getSelectionSize(); + %this.enableItem( 1, true /*%selSize == 1*/ ); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.cs new file mode 100644 index 000000000..f476ccaeb --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.cs @@ -0,0 +1,906 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +$Pref::WorldEditor::FileSpec = "Torque Mission Files (*.mis)|*.mis|All Files (*.*)|*.*|"; + +////////////////////////////////////////////////////////////////////////// +// File Menu Handlers +////////////////////////////////////////////////////////////////////////// + +function EditorFileMenu::onMenuSelect(%this) +{ + %this.enableItem(2, EditorIsDirty()); +} + +////////////////////////////////////////////////////////////////////////// + +// Package that gets temporarily activated to toggle editor after mission loading. +// Deactivates itself. +package BootEditor { + +function GameConnection::initialControlSet( %this ) +{ + Parent::initialControlSet( %this ); + + toggleEditor( true ); + deactivatePackage( "BootEditor" ); +} + +}; + +////////////////////////////////////////////////////////////////////////// + +/// Checks the various dirty flags and returns true if the +/// mission or other related resources need to be saved. +function EditorIsDirty() +{ + // We kept a hard coded test here, but we could break these + // into the registered tools if we wanted to. + %isDirty = ( isObject( "ETerrainEditor" ) && ( ETerrainEditor.isMissionDirty || ETerrainEditor.isDirty ) ) + || ( isObject( "EWorldEditor" ) && EWorldEditor.isDirty ) + || ( isObject( "ETerrainPersistMan" ) && ETerrainPersistMan.hasDirty() ); + + // Give the editor plugins a chance to set the dirty flag. + for ( %i = 0; %i < EditorPluginSet.getCount(); %i++ ) + { + %obj = EditorPluginSet.getObject(%i); + %isDirty |= %obj.isDirty(); + } + + return %isDirty; +} + +/// Clears all the dirty state without saving. +function EditorClearDirty() +{ + EWorldEditor.isDirty = false; + ETerrainEditor.isDirty = false; + ETerrainEditor.isMissionDirty = false; + ETerrainPersistMan.clearAll(); + + for ( %i = 0; %i < EditorPluginSet.getCount(); %i++ ) + { + %obj = EditorPluginSet.getObject(%i); + %obj.clearDirty(); + } +} + +function EditorQuitGame() +{ + if( EditorIsDirty()) + { + MessageBoxYesNoCancel("Level Modified", "Would you like to save your changes before quitting?", "EditorSaveMissionMenu(); quit();", "quit();", "" ); + } + else + quit(); +} + +function EditorExitMission() +{ + if( EditorIsDirty()) + { + MessageBoxYesNoCancel("Level Modified", "Would you like to save your changes before exiting?", "EditorDoExitMission(true);", "EditorDoExitMission(false);", ""); + } + else + EditorDoExitMission(false); +} + +function EditorDoExitMission(%saveFirst) +{ + if(%saveFirst) + { + EditorSaveMissionMenu(); + } + else + { + EditorClearDirty(); + } + + if (isObject( MainMenuGui )) + Editor.close("MainMenuGui"); + + disconnect(); +} + +function EditorOpenTorsionProject( %projectFile ) +{ + // Make sure we have a valid path to the Torsion installation. + + %torsionPath = EditorSettings.value( "WorldEditor/torsionPath" ); + if( !isFile( %torsionPath ) ) + { + MessageBoxOK( + "Torsion Not Found", + "Torsion not found at '" @ %torsionPath @ "'. Please set the correct path in the preferences." + ); + return; + } + + // Determine the path to the .torsion file. + + if( %projectFile $= "" ) + { + %projectName = fileBase( getExecutableName() ); + %projectFile = makeFullPath( %projectName @ ".torsion" ); + if( !isFile( %projectFile ) ) + { + %projectFile = findFirstFile( "*.torsion", false ); + if( !isFile( %projectFile ) ) + { + MessageBoxOK( + "Project File Not Found", + "Cannot find .torsion project file in '" @ getMainDotCsDir() @ "'." + ); + return; + } + } + } + + // Open the project in Torsion. + + shellExecute( %torsionPath, "\"" @ %projectFile @ "\"" ); +} + +function EditorOpenFileInTorsion( %file, %line ) +{ + // Make sure we have a valid path to the Torsion installation. + + %torsionPath = EditorSettings.value( "WorldEditor/torsionPath" ); + if( !isFile( %torsionPath ) ) + { + MessageBoxOK( + "Torsion Not Found", + "Torsion not found at '" @ %torsionPath @ "'. Please set the correct path in the preferences." + ); + return; + } + + // If no file was specified, take the current mission file. + + if( %file $= "" ) + %file = makeFullPath( $Server::MissionFile ); + + // Open the file in Torsion. + + %args = "\"" @ %file; + if( %line !$= "" ) + %args = %args @ ":" @ %line; + %args = %args @ "\""; + + shellExecute( %torsionPath, %args ); +} + +function EditorOpenDeclarationInTorsion( %object ) +{ + %fileName = %object.getFileName(); + if( %fileName $= "" ) + return; + + EditorOpenFileInTorsion( makeFullPath( %fileName ), %object.getDeclarationLine() ); +} + +function EditorNewLevel( %file ) +{ + %saveFirst = false; + if ( EditorIsDirty() ) + { + error(knob); + %saveFirst = MessageBox("Mission Modified", "Would you like to save changes to the current mission \"" @ + $Server::MissionFile @ "\" before creating a new mission?", "SaveDontSave", "Question") == $MROk; + } + + if(%saveFirst) + EditorSaveMission(); + + // Clear dirty flags first to avoid duplicate dialog box from EditorOpenMission() + if( isObject( Editor ) ) + { + EditorClearDirty(); + Editor.getUndoManager().clearAll(); + } + + if( %file $= "" ) + %file = EditorSettings.value( "WorldEditor/newLevelFile" ); + + if( !$missionRunning ) + { + activatePackage( "BootEditor" ); + StartLevel( %file ); + } + else + EditorOpenMission(%file); + + //EWorldEditor.isDirty = true; + //ETerrainEditor.isDirty = true; + EditorGui.saveAs = true; +} + +function EditorSaveMissionMenu() +{ + if(EditorGui.saveAs) + EditorSaveMissionAs(); + else + EditorSaveMission(); +} + +function EditorSaveMission() +{ + // just save the mission without renaming it + + // first check for dirty and read-only files: + if((EWorldEditor.isDirty || ETerrainEditor.isMissionDirty) && !isWriteableFileName($Server::MissionFile)) + { + MessageBox("Error", "Mission file \""@ $Server::MissionFile @ "\" is read-only. Continue?", "Ok", "Stop"); + return false; + } + if(ETerrainEditor.isDirty) + { + // Find all of the terrain files + initContainerTypeSearch($TypeMasks::TerrainObjectType); + + while ((%terrainObject = containerSearchNext()) != 0) + { + if (!isWriteableFileName(%terrainObject.terrainFile)) + { + if (MessageBox("Error", "Terrain file \""@ %terrainObject.terrainFile @ "\" is read-only. Continue?", "Ok", "Stop") == $MROk) + continue; + else + return false; + } + } + } + + // now write the terrain and mission files out: + + if(EWorldEditor.isDirty || ETerrainEditor.isMissionDirty) + MissionGroup.save($Server::MissionFile); + if(ETerrainEditor.isDirty) + { + // Find all of the terrain files + initContainerTypeSearch($TypeMasks::TerrainObjectType); + + while ((%terrainObject = containerSearchNext()) != 0) + %terrainObject.save(%terrainObject.terrainFile); + } + + ETerrainPersistMan.saveDirty(); + + // Give EditorPlugins a chance to save. + for ( %i = 0; %i < EditorPluginSet.getCount(); %i++ ) + { + %obj = EditorPluginSet.getObject(%i); + if ( %obj.isDirty() ) + %obj.onSaveMission( $Server::MissionFile ); + } + + EditorClearDirty(); + + EditorGui.saveAs = false; + + return true; +} + +function EditorSaveMissionAs( %missionName ) +{ + // If we didn't get passed a new mission name then + // prompt the user for one. + if ( %missionName $= "" ) + { + %dlg = new SaveFileDialog() + { + Filters = $Pref::WorldEditor::FileSpec; + DefaultPath = EditorSettings.value("LevelInformation/levelsDirectory"); + ChangePath = false; + OverwritePrompt = true; + }; + + %ret = %dlg.Execute(); + if(%ret) + { + // Immediately override/set the levelsDirectory + EditorSettings.setValue( "LevelInformation/levelsDirectory", collapseFilename(filePath( %dlg.FileName )) ); + + %missionName = %dlg.FileName; + } + + %dlg.delete(); + + if(! %ret) + return; + } + + if( fileExt( %missionName ) !$= ".mis" ) + %missionName = %missionName @ ".mis"; + + EWorldEditor.isDirty = true; + %saveMissionFile = $Server::MissionFile; + + $Server::MissionFile = %missionName; + + %copyTerrainsFailed = false; + + // Rename all the terrain files. Save all previous names so we can + // reset them if saving fails. + %newMissionName = fileBase(%missionName); + %oldMissionName = fileBase(%saveMissionFile); + + initContainerTypeSearch( $TypeMasks::TerrainObjectType ); + %savedTerrNames = new ScriptObject(); + for( %i = 0;; %i ++ ) + { + %terrainObject = containerSearchNext(); + if( !%terrainObject ) + break; + + %savedTerrNames.array[ %i ] = %terrainObject.terrainFile; + + %terrainFilePath = makeRelativePath( filePath( %terrainObject.terrainFile ), getMainDotCsDir() ); + %terrainFileName = fileName( %terrainObject.terrainFile ); + + // Workaround to have terrains created in an unsaved "New Level..." mission + // moved to the correct place. + + if( EditorGui.saveAs && %terrainFilePath $= "tools/art/terrains" ) + %terrainFilePath = "art/terrains"; + + // Try and follow the existing naming convention. + // If we can't, use systematic terrain file names. + if( strstr( %terrainFileName, %oldMissionName ) >= 0 ) + %terrainFileName = strreplace( %terrainFileName, %oldMissionName, %newMissionName ); + else + %terrainFileName = %newMissionName @ "_" @ %i @ ".ter"; + + %newTerrainFile = %terrainFilePath @ "/" @ %terrainFileName; + + if (!isWriteableFileName(%newTerrainFile)) + { + if (MessageBox("Error", "Terrain file \""@ %newTerrainFile @ "\" is read-only. Continue?", "Ok", "Stop") == $MROk) + continue; + else + { + %copyTerrainsFailed = true; + break; + } + } + + if( !%terrainObject.save( %newTerrainFile ) ) + { + error( "Failed to save '" @ %newTerrainFile @ "'" ); + %copyTerrainsFailed = true; + break; + } + + %terrainObject.terrainFile = %newTerrainFile; + } + + ETerrainEditor.isDirty = false; + + // Save the mission. + if(%copyTerrainsFailed || !EditorSaveMission()) + { + // It failed, so restore the mission and terrain filenames. + + $Server::MissionFile = %saveMissionFile; + + initContainerTypeSearch( $TypeMasks::TerrainObjectType ); + for( %i = 0;; %i ++ ) + { + %terrainObject = containerSearchNext(); + if( !%terrainObject ) + break; + + %terrainObject.terrainFile = %savedTerrNames.array[ %i ]; + } + } + + %savedTerrNames.delete(); +} + +function EditorOpenMission(%filename) +{ + if( EditorIsDirty()) + { + // "EditorSaveBeforeLoad();", "getLoadFilename(\"*.mis\", \"EditorDoLoadMission\");" + if(MessageBox("Mission Modified", "Would you like to save changes to the current mission \"" @ + $Server::MissionFile @ "\" before opening a new mission?", SaveDontSave, Question) == $MROk) + { + if(! EditorSaveMission()) + return; + } + } + + if(%filename $= "") + { + %dlg = new OpenFileDialog() + { + Filters = $Pref::WorldEditor::FileSpec; + DefaultPath = EditorSettings.value("LevelInformation/levelsDirectory"); + ChangePath = false; + MustExist = true; + }; + + %ret = %dlg.Execute(); + if(%ret) + { + // Immediately override/set the levelsDirectory + EditorSettings.setValue( "LevelInformation/levelsDirectory", collapseFilename(filePath( %dlg.FileName )) ); + %filename = %dlg.FileName; + } + + %dlg.delete(); + + if(! %ret) + return; + } + + // close the current editor, it will get cleaned up by MissionCleanup + if( isObject( "Editor" ) ) + Editor.close( LoadingGui ); + + EditorClearDirty(); + + // If we haven't yet connnected, create a server now. + // Otherwise just load the mission. + + if( !$missionRunning ) + { + activatePackage( "BootEditor" ); + StartLevel( %filename ); + } + else + { + loadMission( %filename, true ) ; + + pushInstantGroup(); + + // recreate and open the editor + Editor::create(); + MissionCleanup.add( Editor ); + MissionCleanup.add( Editor.getUndoManager() ); + EditorGui.loadingMission = true; + Editor.open(); + + popInstantGroup(); + } +} + +function EditorExportToCollada() +{ + + %dlg = new SaveFileDialog() + { + Filters = "COLLADA Files (*.dae)|*.dae|"; + DefaultPath = $Pref::WorldEditor::LastPath; + DefaultFile = ""; + ChangePath = false; + OverwritePrompt = true; + }; + + %ret = %dlg.Execute(); + if ( %ret ) + { + $Pref::WorldEditor::LastPath = filePath( %dlg.FileName ); + %exportFile = %dlg.FileName; + } + + if( fileExt( %exportFile ) !$= ".dae" ) + %exportFile = %exportFile @ ".dae"; + + %dlg.delete(); + + if ( !%ret ) + return; + + if ( EditorGui.currentEditor.getId() == ShapeEditorPlugin.getId() ) + ShapeEdShapeView.exportToCollada( %exportFile ); + else + EWorldEditor.colladaExportSelection( %exportFile ); +} + +function EditorMakePrefab() +{ + + %dlg = new SaveFileDialog() + { + Filters = "Prefab Files (*.prefab)|*.prefab|"; + DefaultPath = $Pref::WorldEditor::LastPath; + DefaultFile = ""; + ChangePath = false; + OverwritePrompt = true; + }; + + %ret = %dlg.Execute(); + if ( %ret ) + { + $Pref::WorldEditor::LastPath = filePath( %dlg.FileName ); + %saveFile = %dlg.FileName; + } + + if( fileExt( %saveFile ) !$= ".prefab" ) + %saveFile = %saveFile @ ".prefab"; + + %dlg.delete(); + + if ( !%ret ) + return; + + EWorldEditor.makeSelectionPrefab( %saveFile ); + + EditorTree.buildVisibleTree( true ); +} + +function EditorExplodePrefab() +{ + //echo( "EditorExplodePrefab()" ); + EWorldEditor.explodeSelectedPrefab(); + EditorTree.buildVisibleTree( true ); +} + +function makeSelectedAMesh() +{ + + %dlg = new SaveFileDialog() + { + Filters = "Collada file (*.dae)|*.dae|"; + DefaultPath = $Pref::WorldEditor::LastPath; + DefaultFile = ""; + ChangePath = false; + OverwritePrompt = true; + }; + + %ret = %dlg.Execute(); + if ( %ret ) + { + $Pref::WorldEditor::LastPath = filePath( %dlg.FileName ); + %saveFile = %dlg.FileName; + } + + if( fileExt( %saveFile ) !$= ".dae" ) + %saveFile = %saveFile @ ".dae"; + + %dlg.delete(); + + if ( !%ret ) + return; + + EWorldEditor.makeSelectionAMesh( %saveFile ); + + EditorTree.buildVisibleTree( true ); +} + +function EditorMount() +{ + echo( "EditorMount" ); + + %size = EWorldEditor.getSelectionSize(); + if ( %size != 2 ) + return; + + %a = EWorldEditor.getSelectedObject(0); + %b = EWorldEditor.getSelectedObject(1); + + //%a.mountObject( %b, 0 ); + EWorldEditor.mountRelative( %a, %b ); +} + +function EditorUnmount() +{ + echo( "EditorUnmount" ); + + %obj = EWorldEditor.getSelectedObject(0); + %obj.unmount(); +} + +////////////////////////////////////////////////////////////////////////// +// View Menu Handlers +////////////////////////////////////////////////////////////////////////// + +function EditorViewMenu::onMenuSelect( %this ) +{ + %this.checkItem( 1, EWorldEditor.renderOrthoGrid ); +} + +////////////////////////////////////////////////////////////////////////// +// Edit Menu Handlers +////////////////////////////////////////////////////////////////////////// + +function EditorEditMenu::onMenuSelect( %this ) +{ + // UndoManager is in charge of enabling or disabling the undo/redo items. + Editor.getUndoManager().updateUndoMenu( %this ); + + // SICKHEAD: It a perfect world we would abstract + // cut/copy/paste with a generic selection object + // which would know how to process itself. + + // Give the active editor a chance at fixing up + // the state of the edit menu. + // Do we really need this check here? + if ( isObject( EditorGui.currentEditor ) ) + EditorGui.currentEditor.onEditMenuSelect( %this ); +} + +////////////////////////////////////////////////////////////////////////// + +function EditorMenuEditDelete() +{ + if ( isObject( EditorGui.currentEditor ) ) + EditorGui.currentEditor.handleDelete(); +} + +function EditorMenuEditDeselect() +{ + if ( isObject( EditorGui.currentEditor ) ) + EditorGui.currentEditor.handleDeselect(); +} + +function EditorMenuEditCut() +{ + if ( isObject( EditorGui.currentEditor ) ) + EditorGui.currentEditor.handleCut(); +} + +function EditorMenuEditCopy() +{ + if ( isObject( EditorGui.currentEditor ) ) + EditorGui.currentEditor.handleCopy(); +} + +function EditorMenuEditPaste() +{ + if ( isObject( EditorGui.currentEditor ) ) + EditorGui.currentEditor.handlePaste(); +} + + + +////////////////////////////////////////////////////////////////////////// +// Window Menu Handler +////////////////////////////////////////////////////////////////////////// + +function EditorToolsMenu::onSelectItem(%this, %id) +{ + %toolName = getField( %this.item[%id], 2 ); + + EditorGui.setEditor(%toolName, %paletteName ); + + %this.checkRadioItem(0, %this.getItemCount(), %id); + return true; +} + +function EditorToolsMenu::setupDefaultState(%this) +{ + Parent::setupDefaultState(%this); +} + +////////////////////////////////////////////////////////////////////////// +// Camera Menu Handler +////////////////////////////////////////////////////////////////////////// + +function EditorCameraMenu::onSelectItem(%this, %id, %text) +{ + if(%id == 0 || %id == 1) + { + // Handle the Free Camera/Orbit Camera toggle + %this.checkRadioItem(0, 1, %id); + } + + return Parent::onSelectItem(%this, %id, %text); +} + +function EditorCameraMenu::setupDefaultState(%this) +{ + // Set the Free Camera/Orbit Camera check marks + %this.checkRadioItem(0, 1, 0); + Parent::setupDefaultState(%this); +} + +function EditorFreeCameraTypeMenu::onSelectItem(%this, %id, %text) +{ + // Handle the camera type radio + %this.checkRadioItem(0, 2, %id); + + return Parent::onSelectItem(%this, %id, %text); +} + +function EditorFreeCameraTypeMenu::setupDefaultState(%this) +{ + // Set the camera type check marks + %this.checkRadioItem(0, 2, 0); + Parent::setupDefaultState(%this); +} + +function EditorCameraSpeedMenu::onSelectItem(%this, %id, %text) +{ + // Grab and set speed + %speed = getField( %this.item[%id], 2 ); + $Camera::movementSpeed = %speed; + + // Update Editor + %this.checkRadioItem(0, 6, %id); + + // Update Toolbar TextEdit + EWorldEditorCameraSpeed.setText( $Camera::movementSpeed ); + + // Update Toolbar Slider + CameraSpeedDropdownCtrlContainer-->Slider.setValue( $Camera::movementSpeed ); + + return true; +} +function EditorCameraSpeedMenu::setupDefaultState(%this) +{ + // Setup camera speed gui's. Both menu and editorgui + %this.setupGuiControls(); + + //Grab and set speed + %defaultSpeed = EditorSettings.value("LevelInformation/levels/" @ EditorGui.levelName @ "/cameraSpeed"); + if( %defaultSpeed $= "" ) + { + // Update Editor with default speed + %defaultSpeed = 25; + } + $Camera::movementSpeed = %defaultSpeed; + + // Update Toolbar TextEdit + EWorldEditorCameraSpeed.setText( %defaultSpeed ); + + // Update Toolbar Slider + CameraSpeedDropdownCtrlContainer-->Slider.setValue( %defaultSpeed ); + + Parent::setupDefaultState(%this); +} + +function EditorCameraSpeedMenu::setupGuiControls(%this) +{ + // Default levelInfo params + %minSpeed = 5; + %maxSpeed = 200; + + %speedA = EditorSettings.value("LevelInformation/levels/" @ EditorGui.levelName @ "/cameraSpeedMin"); + %speedB = EditorSettings.value("LevelInformation/levels/" @ EditorGui.levelName @ "/cameraSpeedMax"); + if( %speedA < %speedB ) + { + if( %speedA == 0 ) + { + if( %speedB > 1 ) + %minSpeed = 1; + else + %minSpeed = 0.1; + } + else + { + %minSpeed = %speedA; + } + + %maxSpeed = %speedB; + } + + // Set up the camera speed items + %inc = ( (%maxSpeed - %minSpeed) / (%this.getItemCount() - 1) ); + for( %i = 0; %i < %this.getItemCount(); %i++) + %this.item[%i] = setField( %this.item[%i], 2, (%minSpeed + (%inc * %i))); + + // Set up min/max camera slider range + eval("CameraSpeedDropdownCtrlContainer-->Slider.range = \"" @ %minSpeed @ " " @ %maxSpeed @ "\";"); +} + +////////////////////////////////////////////////////////////////////////// +// Tools Menu Handler +////////////////////////////////////////////////////////////////////////// +function EditorUtilitiesMenu::onSelectItem(%this, %id, %text) +{ + return Parent::onSelectItem(%this, %id, %text); +} + +////////////////////////////////////////////////////////////////////////// +// World Menu Handler Object Menu +////////////////////////////////////////////////////////////////////////// + +function EditorWorldMenu::onMenuSelect(%this) +{ + %selSize = EWorldEditor.getSelectionSize(); + %lockCount = EWorldEditor.getSelectionLockCount(); + %hideCount = EWorldEditor.getSelectionHiddenCount(); + + %this.enableItem(0, %lockCount < %selSize); // Lock Selection + %this.enableItem(1, %lockCount > 0); // Unlock Selection + %this.enableItem(3, %hideCount < %selSize); // Hide Selection + %this.enableItem(4, %hideCount > 0); // Show Selection + %this.enableItem(6, %selSize > 1 && %lockCount == 0); // Align bounds + %this.enableItem(7, %selSize > 1 && %lockCount == 0); // Align center + %this.enableItem(9, %selSize > 0 && %lockCount == 0); // Reset Transforms + %this.enableItem(10, %selSize > 0 && %lockCount == 0); // Reset Selected Rotation + %this.enableItem(11, %selSize > 0 && %lockCount == 0); // Reset Selected Scale + %this.enableItem(12, %selSize > 0 && %lockCount == 0); // Transform Selection + %this.enableItem(14, %selSize > 0 && %lockCount == 0); // Drop Selection + + %this.enableItem(17, %selSize > 0); // Make Prefab + %this.enableItem(18, %selSize > 0); // Explode Prefab + + %this.enableItem(20, %selSize > 1); // Mount + %this.enableItem(21, %selSize > 0); // Unmount +} + +////////////////////////////////////////////////////////////////////////// + +function EditorDropTypeMenu::onSelectItem(%this, %id, %text) +{ + // This sets up which drop script function to use when + // a drop type is selected in the menu. + EWorldEditor.dropType = getField(%this.item[%id], 2); + + %this.checkRadioItem(0, (%this.getItemCount() - 1), %id); + + return true; +} + +function EditorDropTypeMenu::setupDefaultState(%this) +{ + // Check the radio item for the currently set drop type. + + %numItems = %this.getItemCount(); + + %dropTypeIndex = 0; + for( ; %dropTypeIndex < %numItems; %dropTypeIndex ++ ) + if( getField( %this.item[ %dropTypeIndex ], 2 ) $= EWorldEditor.dropType ) + break; + + // Default to screenCenter if we didn't match anything. + if( %dropTypeIndex > (%numItems - 1) ) + %dropTypeIndex = 4; + + %this.checkRadioItem( 0, (%numItems - 1), %dropTypeIndex ); + + Parent::setupDefaultState(%this); +} + +////////////////////////////////////////////////////////////////////////// + +function EditorAlignBoundsMenu::onSelectItem(%this, %id, %text) +{ + // Have the editor align all selected objects by the selected bounds. + EWorldEditor.alignByBounds(getField(%this.item[%id], 2)); + + return true; +} + +function EditorAlignBoundsMenu::setupDefaultState(%this) +{ + // Allow the parent to set the menu's default state + Parent::setupDefaultState(%this); +} + +////////////////////////////////////////////////////////////////////////// + +function EditorAlignCenterMenu::onSelectItem(%this, %id, %text) +{ + // Have the editor align all selected objects by the selected axis. + EWorldEditor.alignByAxis(getField(%this.item[%id], 2)); + + return true; +} + +function EditorAlignCenterMenu::setupDefaultState(%this) +{ + // Allow the parent to set the menu's default state + Parent::setupDefaultState(%this); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs new file mode 100644 index 000000000..be068b9ed --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs @@ -0,0 +1,425 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function EditorGui::buildMenus(%this) +{ + if(isObject(%this.menuBar)) + return; + + //set up %cmdctrl variable so that it matches OS standards + if( $platform $= "macos" ) + { + %cmdCtrl = "Cmd"; + %menuCmdCtrl = "Cmd"; + %quitShortcut = "Cmd Q"; + %redoShortcut = "Cmd-Shift Z"; + } + else + { + %cmdCtrl = "Ctrl"; + %menuCmdCtrl = "Alt"; + %quitShortcut = "Alt F4"; + %redoShortcut = "Ctrl Y"; + } + + // Sub menus (temporary, until MenuBuilder gets updated) + // The speed increments located here are overwritten in EditorCameraSpeedMenu::setupDefaultState. + // The new min/max for the editor camera speed range can be set in each level's levelInfo object. + if(!isObject(EditorCameraSpeedOptions)) + { + %this.cameraSpeedMenu = new PopupMenu(EditorCameraSpeedOptions) + { + superClass = "MenuBuilder"; + class = "EditorCameraSpeedMenu"; + + item[0] = "Slowest" TAB %cmdCtrl @ "-Shift 1" TAB "5"; + item[1] = "Slow" TAB %cmdCtrl @ "-Shift 2" TAB "35"; + item[2] = "Slower" TAB %cmdCtrl @ "-Shift 3" TAB "70"; + item[3] = "Normal" TAB %cmdCtrl @ "-Shift 4" TAB "100"; + item[4] = "Faster" TAB %cmdCtrl @ "-Shift 5" TAB "130"; + item[5] = "Fast" TAB %cmdCtrl @ "-Shift 6" TAB "165"; + item[6] = "Fastest" TAB %cmdCtrl @ "-Shift 7" TAB "200"; + }; + } + if(!isObject(EditorFreeCameraTypeOptions)) + { + %this.freeCameraTypeMenu = new PopupMenu(EditorFreeCameraTypeOptions) + { + superClass = "MenuBuilder"; + class = "EditorFreeCameraTypeMenu"; + + item[0] = "Standard" TAB "Ctrl 1" TAB "EditorGuiStatusBar.setCamera(\"Standard Camera\");"; + item[1] = "Orbit Camera" TAB "Ctrl 2" TAB "EditorGuiStatusBar.setCamera(\"Orbit Camera\");"; + Item[2] = "-"; + item[3] = "Smoothed" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Camera\");"; + item[4] = "Smoothed Rotate" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Rot Camera\");"; + }; + } + if(!isObject(EditorPlayerCameraTypeOptions)) + { + %this.playerCameraTypeMenu = new PopupMenu(EditorPlayerCameraTypeOptions) + { + superClass = "MenuBuilder"; + class = "EditorPlayerCameraTypeMenu"; + + Item[0] = "First Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"1st Person Camera\");"; + Item[1] = "Third Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"3rd Person Camera\");"; + }; + } + if(!isObject(EditorCameraBookmarks)) + { + %this.cameraBookmarksMenu = new PopupMenu(EditorCameraBookmarks) + { + superClass = "MenuBuilder"; + class = "EditorCameraBookmarksMenu"; + + //item[0] = "None"; + }; + } + %this.viewTypeMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + + item[ 0 ] = "Top" TAB "Alt 2" TAB "EditorGuiStatusBar.setCamera(\"Top View\");"; + item[ 1 ] = "Bottom" TAB "Alt 5" TAB "EditorGuiStatusBar.setCamera(\"Bottom View\");"; + item[ 2 ] = "Front" TAB "Alt 3" TAB "EditorGuiStatusBar.setCamera(\"Front View\");"; + item[ 3 ] = "Back" TAB "Alt 6" TAB "EditorGuiStatusBar.setCamera(\"Back View\");"; + item[ 4 ] = "Left" TAB "Alt 4" TAB "EditorGuiStatusBar.setCamera(\"Left View\");"; + item[ 5 ] = "Right" TAB "Alt 7" TAB "EditorGuiStatusBar.setCamera(\"Right View\");"; + item[ 6 ] = "Perspective" TAB "Alt 1" TAB "EditorGuiStatusBar.setCamera(\"Standard Camera\");"; + item[ 7 ] = "Isometric" TAB "Alt 8" TAB "EditorGuiStatusBar.setCamera(\"Isometric View\");"; + }; + + // Menu bar + %this.menuBar = new MenuBar(WorldEditorMenubar) + { + dynamicItemInsertPos = 3; + }; + + // File Menu + %fileMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorFileMenu"; + + barTitle = "File"; + }; + + + %fileMenu.appendItem("New Level" TAB "" TAB "schedule( 1, 0, \"EditorNewLevel\" );"); + %fileMenu.appendItem("Open Level..." TAB %cmdCtrl SPC "O" TAB "schedule( 1, 0, \"EditorOpenMission\" );"); + %fileMenu.appendItem("Save Level" TAB %cmdCtrl SPC "S" TAB "EditorSaveMissionMenu();"); + %fileMenu.appendItem("Save Level As..." TAB "" TAB "EditorSaveMissionAs();"); + %fileMenu.appendItem("-"); + + if( $platform $= "windows" ) + { + %fileMenu.appendItem( "Open Project in Torsion" TAB "" TAB "EditorOpenTorsionProject();" ); + %fileMenu.appendItem( "Open Level File in Torsion" TAB "" TAB "EditorOpenFileInTorsion();" ); + %fileMenu.appendItem( "-" ); + } + + %fileMenu.appendItem("Create Blank Terrain" TAB "" TAB "Canvas.pushDialog( CreateNewTerrainGui );"); + %fileMenu.appendItem("Import Terrain Heightmap" TAB "" TAB "Canvas.pushDialog( TerrainImportGui );"); + + %fileMenu.appendItem("Export Terrain Heightmap" TAB "" TAB "Canvas.pushDialog( TerrainExportGui );"); + %fileMenu.appendItem("-"); + %fileMenu.appendItem("Export To COLLADA..." TAB "" TAB "EditorExportToCollada();"); + //item[5] = "Import Terraform Data..." TAB "" TAB "Heightfield::import();"; + //item[6] = "Import Texture Data..." TAB "" TAB "Texture::import();"; + //item[7] = "-"; + //item[8] = "Export Terraform Data..." TAB "" TAB "Heightfield::saveBitmap(\"\");"; + + %fileMenu.appendItem( "-" ); + %fileMenu.appendItem( "Add FMOD Designer Audio..." TAB "" TAB "AddFMODProjectDlg.show();" ); + + %fileMenu.appendItem("-"); + %fileMenu.appendItem("Play Level" TAB "F11" TAB "Editor.close(\"PlayGui\");"); + + %fileMenu.appendItem("Exit Level" TAB "" TAB "EditorExitMission();"); + %fileMenu.appendItem("Quit" TAB %quitShortcut TAB "EditorQuitGame();"); + + %this.menuBar.insert(%fileMenu, %this.menuBar.getCount()); + + // Edit Menu + %editMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorEditMenu"; + internalName = "EditMenu"; + + barTitle = "Edit"; + + item[0] = "Undo" TAB %cmdCtrl SPC "Z" TAB "Editor.getUndoManager().undo();"; + item[1] = "Redo" TAB %redoShortcut TAB "Editor.getUndoManager().redo();"; + item[2] = "-"; + item[3] = "Cut" TAB %cmdCtrl SPC "X" TAB "EditorMenuEditCut();"; + item[4] = "Copy" TAB %cmdCtrl SPC "C" TAB "EditorMenuEditCopy();"; + item[5] = "Paste" TAB %cmdCtrl SPC "V" TAB "EditorMenuEditPaste();"; + item[6] = "Delete" TAB "Delete" TAB "EditorMenuEditDelete();"; + item[7] = "-"; + item[8] = "Deselect" TAB "X" TAB "EditorMenuEditDeselect();"; + Item[9] = "Select..." TAB "" TAB "EditorGui.toggleObjectSelectionsWindow();"; + item[10] = "-"; + item[11] = "Audio Parameters..." TAB "" TAB "EditorGui.toggleSFXParametersWindow();"; + item[12] = "Editor Settings..." TAB "" TAB "ESettingsWindow.ToggleVisibility();"; + item[13] = "Snap Options..." TAB "" TAB "ESnapOptions.ToggleVisibility();"; + item[14] = "-"; + item[15] = "Game Options..." TAB "" TAB "Canvas.pushDialog(optionsDlg);"; + item[16] = "PostEffect Manager" TAB "" TAB "Canvas.pushDialog(PostFXManager);"; + }; + %this.menuBar.insert(%editMenu, %this.menuBar.getCount()); + + // View Menu + %viewMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorViewMenu"; + internalName = "viewMenu"; + + barTitle = "View"; + + item[ 0 ] = "Visibility Layers" TAB "Alt V" TAB "VisibilityDropdownToggle();"; + item[ 1 ] = "Show Grid in Ortho Views" TAB %cmdCtrl @ "-Shift-Alt G" TAB "EditorGui.toggleOrthoGrid();"; + }; + %this.menuBar.insert(%viewMenu, %this.menuBar.getCount()); + + // Camera Menu + %cameraMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorCameraMenu"; + + barTitle = "Camera"; + + item[0] = "World Camera" TAB %this.freeCameraTypeMenu; + item[1] = "Player Camera" TAB %this.playerCameraTypeMenu; + item[2] = "-"; + Item[3] = "Toggle Camera" TAB %menuCmdCtrl SPC "C" TAB "commandToServer('ToggleCamera');"; + item[4] = "Place Camera at Selection" TAB "Ctrl Q" TAB "EWorldEditor.dropCameraToSelection();"; + item[5] = "Place Camera at Player" TAB "Alt Q" TAB "commandToServer('dropCameraAtPlayer');"; + item[6] = "Place Player at Camera" TAB "Alt W" TAB "commandToServer('DropPlayerAtCamera');"; + item[7] = "-"; + item[8] = "Fit View to Selection" TAB "F" TAB "commandToServer('EditorCameraAutoFit', EWorldEditor.getSelectionRadius()+1);"; + item[9] = "Fit View To Selection and Orbit" TAB "Alt F" TAB "EditorGuiStatusBar.setCamera(\"Orbit Camera\"); commandToServer('EditorCameraAutoFit', EWorldEditor.getSelectionRadius()+1);"; + item[10] = "-"; + item[11] = "Speed" TAB %this.cameraSpeedMenu; + item[12] = "View" TAB %this.viewTypeMenu; + item[13] = "-"; + Item[14] = "Add Bookmark..." TAB "Ctrl B" TAB "EditorGui.addCameraBookmarkByGui();"; + Item[15] = "Manage Bookmarks..." TAB "Ctrl-Shift B" TAB "EditorGui.toggleCameraBookmarkWindow();"; + item[16] = "Jump to Bookmark" TAB %this.cameraBookmarksMenu; + }; + %this.menuBar.insert(%cameraMenu, %this.menuBar.getCount()); + + // Editors Menu + %editorsMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorToolsMenu"; + + barTitle = "Editors"; + + //item[0] = "Object Editor" TAB "F1" TAB WorldEditorInspectorPlugin; + //item[1] = "Material Editor" TAB "F2" TAB MaterialEditorPlugin; + //item[2] = "-"; + //item[3] = "Terrain Editor" TAB "F3" TAB TerrainEditorPlugin; + //item[4] = "Terrain Painter" TAB "F4" TAB TerrainPainterPlugin; + //item[5] = "-"; + }; + %this.menuBar.insert(%editorsMenu, %this.menuBar.getCount()); + + // Lighting Menu + %lightingMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorLightingMenu"; + + barTitle = "Lighting"; + + item[0] = "Full Relight" TAB "Alt L" TAB "Editor.lightScene(\"\", forceAlways);"; + item[1] = "Toggle ShadowViz" TAB "" TAB "toggleShadowViz();"; + item[2] = "-"; + + // NOTE: The light managers will be inserted as the + // last menu items in EditorLightingMenu::onAdd(). + }; + %this.menuBar.insert(%lightingMenu, %this.menuBar.getCount()); + + // Tools Menu + %toolsMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorUtilitiesMenu"; + + barTitle = "Tools"; + + item[0] = "Network Graph" TAB "n" TAB "toggleNetGraph();"; + item[1] = "Profiler" TAB "ctrl F2" TAB "showMetrics(true);"; + item[2] = "Torque SimView" TAB "" TAB "tree();"; + item[3] = "Make Selected a Mesh" TAB "" TAB "makeSelectedAMesh();"; + }; + %this.menuBar.insert(%toolsMenu, %this.menuBar.getCount()); + + // Help Menu + %helpMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorHelpMenu"; + + barTitle = "Help"; + + item[0] = "Online Documentation..." TAB "Alt F1" TAB "gotoWebPage(EWorldEditor.documentationURL);"; + item[1] = "Offline User Guide..." TAB "" TAB "gotoWebPage(EWorldEditor.documentationLocal);"; + item[2] = "Offline Reference Guide..." TAB "" TAB "shellexecute(EWorldEditor.documentationReference);"; + item[3] = "Torque 3D Forums..." TAB "" TAB "gotoWebPage(EWorldEditor.forumURL);"; + }; + %this.menuBar.insert(%helpMenu, %this.menuBar.getCount()); + + // Menus that are added/removed dynamically (temporary) + + // World Menu + if(! isObject(%this.worldMenu)) + { + %this.dropTypeMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorDropTypeMenu"; + + // The onSelectItem() callback for this menu re-purposes the command field + // as the MenuBuilder version is not used. + item[0] = "at Origin" TAB "" TAB "atOrigin"; + item[1] = "at Camera" TAB "" TAB "atCamera"; + item[2] = "at Camera w/Rotation" TAB "" TAB "atCameraRot"; + item[3] = "Below Camera" TAB "" TAB "belowCamera"; + item[4] = "Screen Center" TAB "" TAB "screenCenter"; + item[5] = "at Centroid" TAB "" TAB "atCentroid"; + item[6] = "to Terrain" TAB "" TAB "toTerrain"; + item[7] = "Below Selection" TAB "" TAB "belowSelection"; + }; + + %this.alignBoundsMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorAlignBoundsMenu"; + + // The onSelectItem() callback for this menu re-purposes the command field + // as the MenuBuilder version is not used. + item[0] = "+X Axis" TAB "" TAB "0"; + item[1] = "+Y Axis" TAB "" TAB "1"; + item[2] = "+Z Axis" TAB "" TAB "2"; + item[3] = "-X Axis" TAB "" TAB "3"; + item[4] = "-Y Axis" TAB "" TAB "4"; + item[5] = "-Z Axis" TAB "" TAB "5"; + }; + + %this.alignCenterMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorAlignCenterMenu"; + + // The onSelectItem() callback for this menu re-purposes the command field + // as the MenuBuilder version is not used. + item[0] = "X Axis" TAB "" TAB "0"; + item[1] = "Y Axis" TAB "" TAB "1"; + item[2] = "Z Axis" TAB "" TAB "2"; + }; + + %this.worldMenu = new PopupMenu() + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + + barTitle = "Object"; + + item[0] = "Lock Selection" TAB %cmdCtrl @ " L" TAB "EWorldEditor.lockSelection(true); EWorldEditor.syncGui();"; + item[1] = "Unlock Selection" TAB %cmdCtrl @ "-Shift L" TAB "EWorldEditor.lockSelection(false); EWorldEditor.syncGui();"; + item[2] = "-"; + item[3] = "Hide Selection" TAB %cmdCtrl @ " H" TAB "EWorldEditor.hideSelection(true); EWorldEditor.syncGui();"; + item[4] = "Show Selection" TAB %cmdCtrl @ "-Shift H" TAB "EWorldEditor.hideSelection(false); EWorldEditor.syncGui();"; + item[5] = "-"; + item[6] = "Align Bounds" TAB %this.alignBoundsMenu; + item[7] = "Align Center" TAB %this.alignCenterMenu; + item[8] = "-"; + item[9] = "Reset Transforms" TAB "Ctrl R" TAB "EWorldEditor.resetTransforms();"; + item[10] = "Reset Selected Rotation" TAB "" TAB "EWorldEditor.resetSelectedRotation();"; + item[11] = "Reset Selected Scale" TAB "" TAB "EWorldEditor.resetSelectedScale();"; + item[12] = "Transform Selection..." TAB "Ctrl T" TAB "ETransformSelection.ToggleVisibility();"; + item[13] = "-"; + //item[13] = "Drop Camera to Selection" TAB "Ctrl Q" TAB "EWorldEditor.dropCameraToSelection();"; + //item[14] = "Add Selection to Instant Group" TAB "" TAB "EWorldEditor.addSelectionToAddGroup();"; + item[14] = "Drop Selection" TAB "Ctrl D" TAB "EWorldEditor.dropSelection();"; + //item[15] = "-"; + item[15] = "Drop Location" TAB %this.dropTypeMenu; + Item[16] = "-"; + Item[17] = "Make Selection Prefab" TAB "" TAB "EditorMakePrefab();"; + Item[18] = "Explode Selected Prefab" TAB "" TAB "EditorExplodePrefab();"; + Item[19] = "-"; + Item[20] = "Mount Selection A to B" TAB "" TAB "EditorMount();"; + Item[21] = "Unmount Selected Object" TAB "" TAB "EditorUnmount();"; + }; + } +} + +////////////////////////////////////////////////////////////////////////// + +function EditorGui::attachMenus(%this) +{ + %this.menuBar.attachToCanvas(Canvas, 0); +} + +function EditorGui::detachMenus(%this) +{ + %this.menuBar.removeFromCanvas(); +} + +function EditorGui::setMenuDefaultState(%this) +{ + if(! isObject(%this.menuBar)) + return 0; + + for(%i = 0;%i < %this.menuBar.getCount();%i++) + { + %menu = %this.menuBar.getObject(%i); + %menu.setupDefaultState(); + } + + %this.worldMenu.setupDefaultState(); +} + +////////////////////////////////////////////////////////////////////////// + +function EditorGui::findMenu(%this, %name) +{ + if(! isObject(%this.menuBar)) + return 0; + + for(%i = 0;%i < %this.menuBar.getCount();%i++) + { + %menu = %this.menuBar.getObject(%i); + + if(%name $= %menu.barTitle) + return %menu; + } + + return 0; +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/objectSnapOptions.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/objectSnapOptions.ed.cs new file mode 100644 index 000000000..33c231e53 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/objectSnapOptions.ed.cs @@ -0,0 +1,95 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + + +function ESnapOptions::onWake( %this ) +{ + ESnapOptionsTabTerrain-->NoAlignment.setStateOn(1); + + ESnapOptionsTabSoft-->NoAlignment.setStateOn(1); + ESnapOptionsTabSoft-->RenderSnapBounds.setStateOn(1); + ESnapOptionsTabSoft-->SnapBackfaceTolerance.setText(EWorldEditor.getSoftSnapBackfaceTolerance()); +} + +function ESnapOptions::hideDialog( %this ) +{ + %this.setVisible(false); + SnapToBar-->snappingSettingsBtn.setStateOn(false); +} + +function ESnapOptions::ToggleVisibility() +{ + if ( ESnapOptions.visible ) + { + ESnapOptions.setVisible(false); + SnapToBar-->snappingSettingsBtn.setStateOn(false); + } + else + { + ESnapOptions.setVisible(true); + ESnapOptions.selectWindow(); + ESnapOptions.setCollapseGroup(false); + SnapToBar-->snappingSettingsBtn.setStateOn(true); + } +} + +function ESnapOptions::setTerrainSnapAlignment( %this, %val ) +{ + EWorldEditor.setTerrainSnapAlignment(%val); +} + +function ESnapOptions::setSoftSnapAlignment( %this, %val ) +{ + EWorldEditor.setSoftSnapAlignment(%val); +} + +function ESnapOptions::setSoftSnapSize( %this ) +{ + %val = ESnapOptions-->SnapSize.getText(); + + EWorldEditor.setSoftSnapSize(%val); + EWorldEditor.syncGui(); +} + +function ESnapOptions::setGridSnapSize( %this ) +{ + %val = ESnapOptions-->GridSize.getText(); + + EWorldEditor.setGridSize( %val ); +} + +function ESnapOptions::toggleRenderSnapBounds( %this ) +{ + EWorldEditor.softSnapRender( ESnapOptionsTabSoft-->RenderSnapBounds.getValue() ); +} + +function ESnapOptions::toggleRenderSnappedTriangle( %this ) +{ + EWorldEditor.softSnapRenderTriangle( ESnapOptionsTabSoft-->RenderSnappedTriangle.getValue() ); +} + +function ESnapOptions::getSoftSnapBackfaceTolerance( %this ) +{ + %val = ESnapOptions-->SnapBackfaceTolerance.getText(); + + EWorldEditor.setSoftSnapBackfaceTolerance(%val); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/transformSelection.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/transformSelection.ed.cs new file mode 100644 index 000000000..7777e4acb --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/transformSelection.ed.cs @@ -0,0 +1,448 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function ETransformSelection::onWake( %this ) +{ + // Make everything relative + ETransformSelection-->PosRelative.setStateOn( true ); + ETransformSelection-->RotRelative.setStateOn( true ); + ETransformSelection-->ScaleRelative.setStateOn( true ); + ETransformSelection-->SizeRelative.setStateOn( false ); + + ETransformSelection-->GetPosButton.setActive( false ); + ETransformSelection-->GetRotButton.setActive( false ); + ETransformSelection-->GetScaleButton.setActive( false ); + ETransformSelection-->GetSizeButton.setActive( false ); + + // Size is always local + ETransformSelection-->SizeLocal.setStateOn( true ); + ETransformSelection-->SizeLocal.setActive( false ); + + ETransformSelection-->ScaleTabBook.selectPage( 0 ); // Scale page + + ETransformSelection-->ApplyButton.setActive( false ); + + EWorldEditor.ETransformSelectionDisplayed = false; +} + +function ETransformSelection::onVisible( %this, %state ) +{ + // If we are made visible, sync to the world editor + // selection. + + if( %state ) + %this.onSelectionChanged(); +} + +function ETransformSelection::hideDialog( %this ) +{ + %this.setVisible(false); + EWorldEditor.ETransformSelectionDisplayed = false; +} + +function ETransformSelection::ToggleVisibility( %this ) +{ + if ( ETransformSelection.visible ) + { + ETransformSelection.setVisible(false); + EWorldEditor.ETransformSelectionDisplayed = false; + } + else + { + ETransformSelection.setVisible(true); + ETransformSelection.selectWindow(); + ETransformSelection.setCollapseGroup(false); + EWorldEditor.ETransformSelectionDisplayed = true; + } +} + +function ETransformSelection::disableAllButtons( %this ) +{ + ETransformSelection-->GetPosButton.setActive( false ); + ETransformSelection-->GetRotButton.setActive( false ); + ETransformSelection-->GetScaleButton.setActive( false ); + ETransformSelection-->GetSizeButton.setActive( false ); + + ETransformSelection-->ApplyButton.setActive( false ); +} + +function ETransformSelection::onSelectionChanged( %this ) +{ + // Count the number of selected SceneObjects. There are + // other object classes that could be selected, such + // as SimGroups. + %count = EWorldEditor.getSelectionSize(); + %sceneObjects = 0; + %globalBoundsObjects = 0; + for( %i=0; %i<%count; %i++) + { + %obj = EWorldEditor.getSelectedObject( %i ); + if( %obj.isMemberOfClass("SceneObject") ) + { + %sceneObjects++; + + if( %obj.isGlobalBounds() ) + { + %globalBoundsObjects++; + } + } + } + + if( %sceneObjects == 0 ) + { + // With nothing selected, disable all Get buttons + ETransformSelection.disableAllButtons(); + } + else if( %sceneObjects == 1 ) + { + // With one selected, all Get buttons are active + ETransformSelection-->GetPosButton.setActive( true ); + ETransformSelection-->GetRotButton.setActive( true ); + + // Special case for Scale and Size for global bounds objects + if( %globalBoundsObjects == 1 ) + { + ETransformSelection-->GetSizeButton.setActive( false ); + ETransformSelection-->GetScaleButton.setActive( false ); + } + else + { + ETransformSelection-->GetSizeButton.setActive( true ); + ETransformSelection-->GetScaleButton.setActive( true ); + } + + ETransformSelection-->ApplyButton.setActive( true ); + } + else + { + // With more than one selected, only the position button + // is active + ETransformSelection-->GetPosButton.setActive( true ); + ETransformSelection-->GetRotButton.setActive( false ); + ETransformSelection-->GetScaleButton.setActive( false ); + ETransformSelection-->GetSizeButton.setActive( false ); + + ETransformSelection-->ApplyButton.setActive( true ); + + // If both RotRelative and RotLocal are unchecked, then go with RotLocal + if( ETransformSelection-->RotRelative.getValue() == 0 && ETransformSelection-->RotLocal.getValue() == 0 ) + { + ETransformSelection-->RotLocal.setStateOn( true ); + } + } +} + +function ETransformSelection::apply( %this ) +{ + %position = ETransformSelection-->DoPosition.getValue(); + %p = ETransformSelection-->PosX.getValue() SPC ETransformSelection-->PosY.getValue() SPC ETransformSelection-->PosZ.getValue(); + %relativePos = ETransformSelection-->PosRelative.getValue(); + + %rotate = ETransformSelection-->DoRotation.getValue(); + %r = mDegToRad(ETransformSelection-->Pitch.getValue()) SPC mDegToRad(ETransformSelection-->Bank.getValue()) SPC mDegToRad(ETransformSelection-->Heading.getValue()); + %relativeRot = ETransformSelection-->RotRelative.getValue(); + %rotLocal = ETransformSelection-->RotLocal.getValue(); + + // We need to check which Tab page is active + if( ETransformSelection-->ScaleTabBook.getSelectedPage() == 0 ) + { + // Scale Page + %scale = ETransformSelection-->DoScale.getValue(); + %s = ETransformSelection-->ScaleX.getValue() SPC ETransformSelection-->ScaleY.getValue() SPC ETransformSelection-->ScaleZ.getValue(); + %sRelative = ETransformSelection-->ScaleRelative.getValue(); + %sLocal = ETransformSelection-->ScaleLocal.getValue(); + + %size = false; + } + else + { + // Size Page + %size = ETransformSelection-->DoSize.getValue(); + %s = ETransformSelection-->SizeX.getValue() SPC ETransformSelection-->SizeY.getValue() SPC ETransformSelection-->SizeZ.getValue(); + %sRelative = ETransformSelection-->SizeRelative.getValue(); + %sLocal = ETransformSelection-->SizeLocal.getValue(); + + %scale = false; + } + + EWorldEditor.transformSelection(%position, %p, %relativePos, %rotate, %r, %relativeRot, %rotLocal, %scale ? 1 : (%size ? 2 : 0), %s, %sRelative, %sLocal); +} + +function ETransformSelection::getAbsPosition( %this ) +{ + %pos = EWorldEditor.getSelectionCentroid(); + ETransformSelection-->PosX.setText(getWord(%pos, 0)); + ETransformSelection-->PosY.setText(getWord(%pos, 1)); + ETransformSelection-->PosZ.setText(getWord(%pos, 2)); + + // Turn off relative as we're populating absolute values + ETransformSelection-->PosRelative.setValue(0); + + // Finally, set the Position check box as active. The user + // likely wants this if they're getting the position. + ETransformSelection-->DoPosition.setValue(1); +} + +function ETransformSelection::getAbsRotation( %this ) +{ + %count = EWorldEditor.getSelectionSize(); + + // If we have more than one SceneObject selected, + // we must exit. + %obj = -1; + for( %i=0; %i<%count; %i++) + { + %test = EWorldEditor.getSelectedObject( %i ); + if( %test.isMemberOfClass("SceneObject") ) + { + if( %obj != -1 ) + return; + + %obj = %test; + } + } + + if( %obj == -1 ) + { + // No SceneObjects selected + return; + } + + %rot = %obj.getEulerRotation(); + ETransformSelection-->Pitch.setText(getWord(%rot, 0)); + ETransformSelection-->Bank.setText(getWord(%rot, 1)); + ETransformSelection-->Heading.setText(getWord(%rot, 2)); + + // Turn off relative as we're populating absolute values. + // Of course this means that we need to set local on. + ETransformSelection-->RotRelative.setValue(0); + ETransformSelection-->RotLocal.setValue(1); + + // Finally, set the Rotation check box as active. The user + // likely wants this if they're getting the position. + ETransformSelection-->DoRotation.setValue(1); +} + +function ETransformSelection::getAbsScale( %this ) +{ + %count = EWorldEditor.getSelectionSize(); + + // If we have more than one SceneObject selected, + // we must exit. + %obj = -1; + for( %i=0; %i<%count; %i++) + { + %test = EWorldEditor.getSelectedObject( %i ); + if( %test.isMemberOfClass("SceneObject") ) + { + if( %obj != -1 ) + return; + + %obj = %test; + } + } + + if( %obj == -1 ) + { + // No SceneObjects selected + return; + } + + %scale = %obj.scale; + %scalex = getWord(%scale, 0); + ETransformSelection-->ScaleX.setText(%scalex); + if( ETransformSelectionScaleProportional.getValue() == false ) + { + ETransformSelection-->ScaleY.setText(getWord(%scale, 1)); + ETransformSelection-->ScaleZ.setText(getWord(%scale, 2)); + } + else + { + ETransformSelection-->ScaleY.setText(%scalex); + ETransformSelection-->ScaleZ.setText(%scalex); + } + + // Turn off relative as we're populating absolute values + ETransformSelection-->ScaleRelative.setValue(0); + + // Finally, set the Scale check box as active. The user + // likely wants this if they're getting the position. + ETransformSelection-->DoScale.setValue(1); +} + +function ETransformSelection::getAbsSize( %this ) +{ + %count = EWorldEditor.getSelectionSize(); + + // If we have more than one SceneObject selected, + // we must exit. + %obj = -1; + for( %i=0; %i<%count; %i++) + { + %test = EWorldEditor.getSelectedObject( %i ); + if( %test.isMemberOfClass("SceneObject") ) + { + if( %obj != -1 ) + return; + + %obj = %test; + } + } + + if( %obj == -1 ) + { + // No SceneObjects selected + return; + } + + %size = %obj.getObjectBox(); + %scale = %obj.getScale(); + + %sizex = (getWord(%size, 3) - getWord(%size, 0)) * getWord(%scale, 0); + ETransformSelection-->SizeX.setText( %sizex ); + if( ETransformSelectionSizeProportional.getValue() == false ) + { + ETransformSelection-->SizeY.setText( (getWord(%size, 4) - getWord(%size, 1)) * getWord(%scale, 1) ); + ETransformSelection-->SizeZ.setText( (getWord(%size, 5) - getWord(%size, 2)) * getWord(%scale, 2) ); + } + else + { + ETransformSelection-->SizeY.setText( %sizex ); + ETransformSelection-->SizeZ.setText( %sizex ); + } + + // Turn off relative as we're populating absolute values + ETransformSelection-->SizeRelative.setValue(0); + + // Finally, set the Size check box as active. The user + // likely wants this if they're getting the position. + ETransformSelection-->DoSize.setValue(1); +} + +function ETransformSelection::RotRelativeChanged( %this ) +{ + if( ETransformSelection-->RotRelative.getValue() == 0 ) + { + // With absolute rotation, it must happen locally + ETransformSelection-->RotLocal.setStateOn( true ); + } +} + +function ETransformSelection::RotLocalChanged( %this ) +{ + if( ETransformSelection-->RotLocal.getValue() == 0 ) + { + // Non-local rotation can only happen relatively + ETransformSelection-->RotRelative.setStateOn( true ); + } +} + +//----------------------------------------------------------------------------- + +function ETransformSelectionScaleProportional::onClick( %this ) +{ + if( %this.getValue() == 1 ) + { + %scalex = ETransformSelection-->ScaleX.getValue(); + ETransformSelection-->ScaleY.setValue( %scalex ); + ETransformSelection-->ScaleZ.setValue( %scalex ); + + ETransformSelection-->ScaleY.setActive( false ); + ETransformSelection-->ScaleZ.setActive( false ); + } + else + { + ETransformSelection-->ScaleY.setActive( true ); + ETransformSelection-->ScaleZ.setActive( true ); + } + + Parent::onClick(%this); +} + +function ETransformSelectionSizeProportional::onClick( %this ) +{ + if( %this.getValue() == 1 ) + { + %scalex = ETransformSelection-->SizeX.getValue(); + ETransformSelection-->SizeY.setValue( %scalex ); + ETransformSelection-->SizeZ.setValue( %scalex ); + + ETransformSelection-->SizeY.setActive( false ); + ETransformSelection-->SizeZ.setActive( false ); + } + else + { + ETransformSelection-->SizeY.setActive( true ); + ETransformSelection-->SizeZ.setActive( true ); + } + + Parent::onClick(%this); +} + +//----------------------------------------------------------------------------- + +function ETransformSelectionButtonClass::onClick( %this ) +{ + %id = %this.getRoot().getFirstResponder(); + if( %id > -1 && ETransformSelection.controlIsChild(%id) ) + { + (%id).clearFirstResponder(true); + } +} + +function ETransformSelectionCheckBoxClass::onClick( %this ) +{ + %id = %this.getRoot().getFirstResponder(); + if( %id > -1 && ETransformSelection.controlIsChild(%id) ) + { + (%id).clearFirstResponder(true); + } +} + +//----------------------------------------------------------------------------- + +function ETransformSelectionTextEdit::onGainFirstResponder( %this ) +{ + if( %this.isActive() ) + { + %this.selectAllText(); + } +} + +function ETransformSelectionTextEdit::onValidate( %this ) +{ + if( %this.getInternalName() $= "ScaleX" && ETransformSelectionScaleProportional.getValue() == true ) + { + // Set the Y and Z values to match + %scalex = ETransformSelection-->ScaleX.getValue(); + ETransformSelection-->ScaleY.setValue( %scalex ); + ETransformSelection-->ScaleZ.setValue( %scalex ); + } + + if( %this.getInternalName() $= "SizeX" && ETransformSelectionSizeProportional.getValue() == true ) + { + // Set the Y and Z values to match + %sizex = ETransformSelection-->SizeX.getValue(); + ETransformSelection-->SizeY.setValue( %sizex ); + ETransformSelection-->SizeZ.setValue( %sizex ); + } +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/undoManager.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/undoManager.ed.cs new file mode 100644 index 000000000..7f05ffd19 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/undoManager.ed.cs @@ -0,0 +1,147 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function EUndoManager::onUndo( %this ) +{ +} + +function EUndoManager::onRedo( %this ) +{ +} + +function EUndoManager::onAddUndo( %this ) +{ +} + +function EUndoManager::onRemoveUndo( %this ) +{ +} + +function EUndoManager::onClear( %this ) +{ +} + +function EUndoManager::updateUndoMenu( %this, %editMenu ) +{ + // TODO: If we ever fix the TerrainEditor and WorldEditor + // to have descriptive UndoAction names then we can change + // the text as part of the menu update. + + %undoName = %this.getNextUndoName(); + %redoName = %this.getNextRedoName(); + + %editMenu.setItemName( 0, "Undo " @ %undoName ); + %editMenu.setItemName( 1, "Redo " @ %redoName ); + + %editMenu.enableItem( 0, %undoName !$= "" ); + %editMenu.enableItem( 1, %redoName !$= "" ); +} + + +/// A helper for submitting a creation undo action. +function MECreateUndoAction::submit( %undoObject ) +{ + // The instant group will try to add our + // UndoAction if we don't disable it. + pushInstantGroup(); + + // Create the undo action. + %action = new MECreateUndoAction() + { + actionName = "Create " @ %undoObject.getClassName(); + }; + + // Restore the instant group. + popInstantGroup(); + + // Set the object to undo. + %action.addObject( %undoObject ); + + // Submit it. + %action.addToManager( Editor.getUndoManager() ); +} + +function MECreateUndoAction::onUndone( %this ) +{ + EWorldEditor.syncGui(); +} + +function MECreateUndoAction::onRedone( %this ) +{ + EWorldEditor.syncGui(); +} + + +/// A helper for submitting a delete undo action. +/// If %wordSeperated is not specified or is false it is assumed %deleteObjects +/// is tab sperated. +function MEDeleteUndoAction::submit( %deleteObjects, %wordSeperated ) +{ + // The instant group will try to add our + // UndoAction if we don't disable it. + pushInstantGroup(); + + // Create the undo action. + %action = new MEDeleteUndoAction() + { + actionName = "Delete"; + }; + + // Restore the instant group. + popInstantGroup(); + + // Add the deletion objects to the action which + // will take care of properly deleting them. + %deleteObjects = trim( %deleteObjects ); + + if ( %wordSeperated ) + { + %count = getWordCount( %deleteObjects ); + for ( %i = 0; %i < %count; %i++ ) + { + %object = getWord( %deleteObjects, %i ); + %action.deleteObject( %object ); + } + } + else + { + %count = getFieldCount( %deleteObjects ); + for ( %i = 0; %i < %count; %i++ ) + { + %object = getField( %deleteObjects, %i ); + %action.deleteObject( %object ); + } + } + + // Submit it. + %action.addToManager( Editor.getUndoManager() ); +} + +function MEDeleteUndoAction::onUndone( %this ) +{ + EWorldEditor.syncGui(); +} + +function MEDeleteUndoAction::onRedone( %this ) +{ + EWorldEditor.syncGui(); +} diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/visibilityLayer.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/visibilityLayer.ed.cs new file mode 100644 index 000000000..268e4b0b3 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/visibilityLayer.ed.cs @@ -0,0 +1,201 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +function EVisibility::onWake( %this ) +{ + // Create the array if it + // doesn't already exist. + if ( !isObject( %this.array ) ) + %this.array = new ArrayObject(); + + // Create the array if it + // doesn't already exist. + if ( !isObject( %this.classArray ) ) + { + %this.classArray = new ArrayObject(); + %this.addClassOptions(); + } + + %this.updateOptions(); + +} + +function EVisibility::updateOptions( %this ) +{ + // First clear the stack control. + %this-->theVisOptionsList.clear(); + + // Go through all the + // parameters in our array and + // create a check box for each. + for ( %i = 0; %i < %this.array.count(); %i++ ) + { + %text = " " @ %this.array.getValue( %i ); + %val = %this.array.getKey( %i ); + %var = getWord( %val, 0 ); + %toggleFunction = getWord( %val, 1 ); + + %textLength = strlen( %text ); + + %cmd = ""; + if ( %toggleFunction !$= "" ) + %cmd = %toggleFunction @ "( $thisControl.getValue() );"; + + %checkBox = new GuiCheckBoxCtrl() + { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxListProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = (%textLength * 4) @ " 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = %var; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + text = %text; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + Command = %cmd; + }; + + %this-->theVisOptionsList.addGuiControl( %checkBox ); + } +} + +function EVisibility::addOption( %this, %text, %varName, %toggleFunction ) +{ + // Create the array if it + // doesn't already exist. + if ( !isObject( %this.array ) ) + %this.array = new ArrayObject(); + + %this.array.push_back( %varName @ " " @ %toggleFunction, %text ); + %this.array.uniqueKey(); + %this.array.sortd(); + %this.updateOptions(); +} + +function EVisibility::addClassOptions( %this ) +{ + %visList = %this-->theClassVisList; + %selList = %this-->theClassSelList; + + // First clear the stack control. + + %visList.clear(); + %selList.clear(); + + %classList = enumerateConsoleClasses( "SceneObject" ); + %classCount = getFieldCount( %classList ); + + for ( %i = 0; %i < %classCount; %i++ ) + { + %className = getField( %classList, %i ); + %this.classArray.push_back( %className ); + } + + // Remove duplicates and sort by key. + %this.classArray.uniqueKey(); + %this.classArray.sortkd(); + + // Go through all the + // parameters in our array and + // create a check box for each. + for ( %i = 0; %i < %this.classArray.count(); %i++ ) + { + %class = %this.classArray.getKey( %i ); + + %visVar = "$" @ %class @ "::isRenderable"; + %selVar = "$" @ %class @ "::isSelectable"; + + %textLength = strlen( %class ); + %text = " " @ %class; + + // Add visibility toggle. + + %visCheckBox = new GuiCheckBoxCtrl() + { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxListFlipedProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = (%textLength * 4) @ " 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = %visVar; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Show/hide all " @ %class @ " objects."; + text = %text; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + + %visList.addGuiControl( %visCheckBox ); + + // Add selectability toggle. + + %selCheckBox = new GuiCheckBoxCtrl() + { + canSaveDynamicFields = "0"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxListFlipedProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = (%textLength * 4) @ " 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Variable = %selVar; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + tooltip = "Enable/disable selection of all " @ %class @ " objects."; + text = %text; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + + %selList.addGuiControl( %selCheckBox ); + } +} + +function togglePhysicsDebugViz( %enable ) +{ + if(physicsPluginPresent()) + { + physicsDebugDraw(%enable); + } +} diff --git a/Templates/BaseGame/source/readme.txt b/Templates/BaseGame/source/readme.txt new file mode 100644 index 000000000..e79addd05 --- /dev/null +++ b/Templates/BaseGame/source/readme.txt @@ -0,0 +1,7 @@ +Your project specific source files and subfolders go into this directory. + +Simply add them to this folder and then regenerate your project +Visual Studio Solution/XCode workspace with the Torque Toolbox. + + + diff --git a/Templates/BaseGame/source/torqueConfig.h b/Templates/BaseGame/source/torqueConfig.h new file mode 100644 index 000000000..365476b19 --- /dev/null +++ b/Templates/BaseGame/source/torqueConfig.h @@ -0,0 +1,246 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef _TORQUECONFIG_H_ +#define _TORQUECONFIG_H_ + +//----------------------------------------------------------------------------- +//Hi, and welcome to the Torque Config file. +// +//This file is a central reference for the various configuration flags that +//you'll be using when controlling what sort of a Torque build you have. In +//general, the information here is global for your entire codebase, applying +//not only to your game proper, but also to all of your tools. + +/// What's the name of your application? Used in a variety of places. +#define TORQUE_APP_NAME "Full" + +#define TORQUE_NET_DEFAULT_MULTICAST_ADDRESS "ff04::7467:656E:6574:776B" + +/// What version of the application specific source code is this? +/// +/// Version number is major * 1000 + minor * 100 + revision * 10. +#define TORQUE_APP_VERSION 1000 + +/// Human readable application version string. +#define TORQUE_APP_VERSION_STRING "1.0" + +/// Define me if you want to enable multithreading support. +#ifndef TORQUE_MULTITHREAD +#define TORQUE_MULTITHREAD +#endif + +/// Define me if you want to disable Torque memory manager. +#ifndef TORQUE_DISABLE_MEMORY_MANAGER +#define TORQUE_DISABLE_MEMORY_MANAGER +#endif + +/// The improved SimDictionary uses C++11 and is designed for games where +/// there are over 10000 simobjects active normally. To enable the new +/// SimDictionary just uncomment the line below. +//#define USE_NEW_SIMDICTIONARY + +/// Define me if you want to disable the virtual mount system. +//#define TORQUE_DISABLE_VIRTUAL_MOUNT_SYSTEM + +/// Define me if you want to disable looking for the root of a given path +/// within a zip file. This means that the zip file name itself must be +/// the root of the path. Requires the virtual mount system to be active. +//#define TORQUE_DISABLE_FIND_ROOT_WITHIN_ZIP + +//Uncomment this define if you want to use the alternative zip support where you can +//define your directories and files inside the zip just like you would on disk +//instead of the default zip support that treats the zip as an extra directory. +//#define TORQUE_ZIP_DISK_LAYOUT + +/// Define me if you don't want Torque to compile dso's +#define TORQUE_NO_DSO_GENERATION + +// Define me if this build is a tools build + +#ifndef TORQUE_PLAYER +# define TORQUE_TOOLS +#else +# undef TORQUE_TOOLS +#endif + +/// Define me if you want to enable the profiler. +/// See also the TORQUE_SHIPPING block below +//#define TORQUE_ENABLE_PROFILER + +/// Define me to enable debug mode; enables a great number of additional +/// sanity checks, as well as making AssertFatal and AssertWarn do something. +/// This is usually defined by the build target. +//#define TORQUE_DEBUG + +/// Define me if this is a shipping build; if defined I will instruct Torque +/// to batten down some hatches and generally be more "final game" oriented. +/// Notably this disables a liberal resource manager file searching, and +/// console help strings. +//#define TORQUE_SHIPPING + +/// Define me to enable a variety of network debugging aids. +/// +/// - NetConnection packet logging. +/// - DebugChecksum guards to detect mismatched pack/unpacks. +/// - Detection of invalid destination ghosts. +/// +//#define TORQUE_DEBUG_NET + +/// Define me to enable detailed console logging of net moves. +//#define TORQUE_DEBUG_NET_MOVES + +/// Enable this define to change the default Net::MaxPacketDataSize +/// Do this at your own risk since it has the potential to cause packets +/// to be split up by old routers and Torque does not have a mechanism to +/// stitch split packets back together. Using this define can be very useful +/// in controlled network hardware environments (like a LAN) or for singleplayer +/// games (like BArricade and its large paths) +//#define MAXPACKETSIZE 1500 + +/// Modify me to enable metric gathering code in the renderers. +/// +/// 0 does nothing; higher numbers enable higher levels of metric gathering. +//#define TORQUE_GATHER_METRICS 0 + +/// Define me if you want to enable debug guards in the memory manager. +/// +/// Debug guards are known values placed before and after every block of +/// allocated memory. They are checked periodically by Memory::validate(), +/// and if they are modified (indicating an access to memory the app doesn't +/// "own"), an error is flagged (ie, you'll see a crash in the memory +/// manager's validate code). Using this and a debugger, you can track down +/// memory corruption issues quickly. +//#define TORQUE_DEBUG_GUARD + +/// Define me if you want to enable instanced-static behavior +//#define TORQUE_ENABLE_THREAD_STATICS + +/// Define me if you want to gather static-usage metrics +//#define TORQUE_ENABLE_THREAD_STATIC_METRICS + +/// Define me if you want to enable debug guards on the FrameAllocator. +/// +/// This is similar to the above memory manager guards, but applies only to the +/// fast FrameAllocator temporary pool memory allocations. The guards are only +/// checked when the FrameAllocator frees memory (when it's water mark changes). +/// This is most useful for detecting buffer overruns when using FrameTemp<> . +/// A buffer overrun in the FrameAllocator is unlikely to cause a crash, but may +/// still result in unexpected behavior, if other FrameTemp's are stomped. +//#define FRAMEALLOCATOR_DEBUG_GUARD + +/// This #define is used by the FrameAllocator to align starting addresses to +/// be byte aligned to this value. This is important on the 360 and possibly +/// on other platforms as well. Use this #define anywhere alignment is needed. +/// +/// NOTE: Do not change this value per-platform unless you have a very good +/// reason for doing so. It has the potential to cause inconsistencies in +/// memory which is allocated and expected to be contiguous. +/// +///@ TODO: Make sure that everywhere this should be used, it is being used. +#define TORQUE_BYTE_ALIGNMENT 4 + +/// This #define should be set if the engine should use a 32-bit format for +/// 24-bit textures. The most notable case is converting RGB->RGBX for various +/// reasons. + +// CodeReview: It may be worth determining this at run-time. Right now I just +// want to wrap code which forces the conversion from 24->32 in a common +// #define so it is easily turned on/off for the problems we are encountering in +// the lighting. [5/11/2007 Pat] +//#define TORQUE_FORCE_24_BIT_TO_32_BIT_TEXTURES + +/// This #define is used by the FrameAllocator to set the size of the frame. +/// +/// It was previously set to 3MB but I've increased it to 32MB due to the +/// FrameAllocator being used as temporary storage for bitmaps in the D3D9 +/// texture manager. +#define TORQUE_FRAME_SIZE 32 << 20 + +// Finally, we define some dependent #defines. This enables some subsidiary +// functionality to get automatically turned on in certain configurations. + +#ifdef TORQUE_DEBUG + + #define TORQUE_GATHER_METRICS 0 + #define TORQUE_ENABLE_PROFILE_PATH + #ifndef TORQUE_DEBUG_GUARD + #define TORQUE_DEBUG_GUARD + #endif + #ifndef TORQUE_NET_STATS + #define TORQUE_NET_STATS + #endif + + // Enables the C++ assert macros AssertFatal, AssertWarn, etc. + #define TORQUE_ENABLE_ASSERTS + +#endif + +#ifdef TORQUE_RELEASE + // If it's not DEBUG, it's a RELEASE build, put appropriate things here. +#endif + +#ifdef TORQUE_SHIPPING + + // TORQUE_SHIPPING flags here. + +#else + + // Enable the profiler by default, if we're not doing a shipping build. + #define TORQUE_ENABLE_PROFILER + + // Enable the TorqueScript assert() instruction if not shipping. + #define TORQUE_ENABLE_SCRIPTASSERTS + + // We also enable GFX debug events for use in Pix and other graphics + // debugging tools. + #define TORQUE_ENABLE_GFXDEBUGEVENTS + +#endif + +#ifdef TORQUE_TOOLS +# define TORQUE_INSTANCE_EXCLUSION "TorqueToolsTest" +#else +# define TORQUE_INSTANCE_EXCLUSION "TorqueTest" +#endif + +// This is the lighting system thats enabled by default when the scene graphs are created. +//#define DEFAULT_LIGHTING_SYSTEM "SynapseGaming Lighting Kit" +#define DEFAULT_LIGHTING_SYSTEM "Basic Lighting" + +// Someday, it might make sense to do some pragma magic here so we error +// on inconsistent flags. + +// The Xbox360 has it's own profiling tools, the Torque Profiler should not be used +#ifdef TORQUE_OS_XENON +# ifdef TORQUE_ENABLE_PROFILER +# undef TORQUE_ENABLE_PROFILER +# endif +# +# ifdef TORQUE_ENABLE_PROFILE_PATH +# undef TORQUE_ENABLE_PROFILE_PATH +#endif +#endif + + +#endif // _TORQUECONFIG_H_ + diff --git a/Templates/BaseGame/thumb.png b/Templates/BaseGame/thumb.png new file mode 100644 index 000000000..abb73e9fc Binary files /dev/null and b/Templates/BaseGame/thumb.png differ diff --git a/Templates/Empty/game/core/main.cs b/Templates/Empty/game/core/main.cs index f666c948c..9888fa4de 100644 --- a/Templates/Empty/game/core/main.cs +++ b/Templates/Empty/game/core/main.cs @@ -28,6 +28,12 @@ $WORD::BITDEPTH = 3; $WORD::REFRESH = 4; $WORD::AA = 5; +//We need to hook the missing/warn material stuff early, so do it here +$Core::MissingTexturePath = "core/art/missingTexture"; +$Core::UnAvailableTexturePath = "core/art/unavailable"; +$Core::WarningTexturePath = "core/art/warnMat"; +$Core::CommonShaderPath = "shaders/common"; + //--------------------------------------------------------------------------------------------- // CorePackage // Adds functionality for this mod to some standard functions. diff --git a/Templates/Empty/game/core/scripts/client/postFx/GammaPostFX.cs b/Templates/Empty/game/core/scripts/client/postFx/GammaPostFX.cs index b88f31305..a61a3af9d 100644 --- a/Templates/Empty/game/core/scripts/client/postFx/GammaPostFX.cs +++ b/Templates/Empty/game/core/scripts/client/postFx/GammaPostFX.cs @@ -55,6 +55,7 @@ singleton PostEffect( GammaPostFX ) texture[0] = "$backBuffer"; texture[1] = $HDRPostFX::colorCorrectionRamp; + targetFormat = getBestHDRFormat(); }; function GammaPostFX::preProcess( %this ) diff --git a/Templates/Empty/game/core/scripts/client/postFx/MLAA.cs b/Templates/Empty/game/core/scripts/client/postFx/MLAA.cs index bef075ec4..e09f45a3c 100644 --- a/Templates/Empty/game/core/scripts/client/postFx/MLAA.cs +++ b/Templates/Empty/game/core/scripts/client/postFx/MLAA.cs @@ -46,7 +46,7 @@ singleton ShaderData( MLAA_EdgeDetectionShader ) { DXVertexShaderFile = "shaders/common/postFx/mlaa/offsetV.hlsl"; DXPixelShaderFile = "shaders/common/postFx/mlaa/edgeDetectionP.hlsl"; - + OGLVertexShaderFile = "shaders/common/postFx/mlaa/gl/offsetV.glsl"; OGLPixelShaderFile = "shaders/common/postFx/mlaa/gl/edgeDetectionP.glsl"; @@ -75,7 +75,7 @@ singleton ShaderData( MLAA_BlendWeightCalculationShader ) { DXVertexShaderFile = "shaders/common/postFx/mlaa/passthruV.hlsl"; DXPixelShaderFile = "shaders/common/postFx/mlaa/blendWeightCalculationP.hlsl"; - + OGLVertexShaderFile = "shaders/common/postFx/mlaa/gl/passthruV.glsl"; OGLPixelShaderFile = "shaders/common/postFx/mlaa/gl/blendWeightCalculationP.glsl"; @@ -162,7 +162,7 @@ singleton PostEffect( MLAAFx ) texture[0] = "$inTex"; // Edges mask texture[1] = "$inTex"; // Edges mask - texture[2] = "AreaMap33.dds"; + texture[2] = "./AreaMap33.dds"; }; new PostEffect() diff --git a/Templates/Empty/game/core/scripts/client/postFx/caustics.cs b/Templates/Empty/game/core/scripts/client/postFx/caustics.cs index a712ef82a..7d598347e 100644 --- a/Templates/Empty/game/core/scripts/client/postFx/caustics.cs +++ b/Templates/Empty/game/core/scripts/client/postFx/caustics.cs @@ -58,7 +58,7 @@ singleton PostEffect( CausticsPFX ) shader = PFX_CausticsShader; stateBlock = PFX_CausticsStateBlock; texture[0] = "#prepass"; - texture[1] = "textures/caustics_1"; - texture[2] = "textures/caustics_2"; + texture[1] = "./textures/caustics_1"; + texture[2] = "./textures/caustics_2"; target = "$backBuffer"; }; diff --git a/Templates/Empty/game/core/scripts/client/postFx/dof.cs b/Templates/Empty/game/core/scripts/client/postFx/dof.cs index 1ba1a476b..dce41daea 100644 --- a/Templates/Empty/game/core/scripts/client/postFx/dof.cs +++ b/Templates/Empty/game/core/scripts/client/postFx/dof.cs @@ -318,8 +318,8 @@ singleton GFXStateBlockData( PFX_DOFFinalStateBlock ) singleton ShaderData( PFX_DOFDownSampleShader ) { - DXVertexShaderFile = "shaders/common/postFx/dof/DOF_DownSample_V.hlsl"; - DXPixelShaderFile = "shaders/common/postFx/dof/DOF_DownSample_P.hlsl"; + DXVertexShaderFile = "shaders/common/postFx/dof/DOF_DownSample_V.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/dof/DOF_DownSample_P.hlsl"; OGLVertexShaderFile = "shaders/common/postFx/dof/gl/DOF_DownSample_V.glsl"; OGLPixelShaderFile = "shaders/common/postFx/dof/gl/DOF_DownSample_P.glsl"; @@ -352,7 +352,7 @@ singleton ShaderData( PFX_DOFBlurXShader : PFX_DOFBlurYShader ) singleton ShaderData( PFX_DOFCalcCoCShader ) { DXVertexShaderFile = "shaders/common/postFx/dof/DOF_CalcCoC_V.hlsl"; - DXPixelShaderFile = "shaders/common/postFx/dof/DOF_CalcCoC_P.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/dof/DOF_CalcCoC_P.hlsl"; OGLVertexShaderFile = "shaders/common/postFx/dof/gl/DOF_CalcCoC_V.glsl"; OGLPixelShaderFile = "shaders/common/postFx/dof/gl/DOF_CalcCoC_P.glsl"; @@ -366,7 +366,7 @@ singleton ShaderData( PFX_DOFCalcCoCShader ) singleton ShaderData( PFX_DOFSmallBlurShader ) { DXVertexShaderFile = "shaders/common/postFx/dof/DOF_SmallBlur_V.hlsl"; - DXPixelShaderFile = "shaders/common/postFx/dof/DOF_SmallBlur_P.hlsl"; + DXPixelShaderFile = "shaders/common/postFx/dof/DOF_SmallBlur_P.hlsl"; OGLVertexShaderFile = "shaders/common/postFx/dof/gl/DOF_SmallBlur_V.glsl"; OGLPixelShaderFile = "shaders/common/postFx/dof/gl/DOF_SmallBlur_P.glsl"; diff --git a/Templates/Empty/game/core/scripts/client/postFx/ssao.cs b/Templates/Empty/game/core/scripts/client/postFx/ssao.cs index 063cee087..09dfa6bb4 100644 --- a/Templates/Empty/game/core/scripts/client/postFx/ssao.cs +++ b/Templates/Empty/game/core/scripts/client/postFx/ssao.cs @@ -200,7 +200,7 @@ singleton PostEffect( SSAOPostFx ) stateBlock = SSAOStateBlock; texture[0] = "#prepass"; - texture[1] = "noise.png"; + texture[1] = "./noise.png"; texture[2] = "#ssao_pow_table"; target = "$outTex"; diff --git a/Templates/Full/game/Full.torsion.opt b/Templates/Full/game/Full.torsion.opt new file mode 100644 index 000000000..52398bf4d --- /dev/null +++ b/Templates/Full/game/Full.torsion.opt @@ -0,0 +1,14 @@ +<TorsionProjectOptions> +<Address>127.0.0.1</Address> +<Password>password</Password> +<Port>6060</Port> +<LastConfig>Debug</LastConfig> +<Breakpoints/> +<Bookmarks/> +<OpenFiles> +<File ScrollX="0" ScrollY="0">art\main.cs</File> +<File ScrollX="0" ScrollY="9">core\main.cs</File> +<File ScrollX="0" ScrollY="9" Active="true">..\..\Empty\game\core\main.cs</File> +<File ScrollX="0" ScrollY="15">..\..\BaseGame\game\core\main.cs</File> +</OpenFiles> +</TorsionProjectOptions> diff --git a/Templates/Full/game/core/main.cs b/Templates/Full/game/core/main.cs index f666c948c..9888fa4de 100644 --- a/Templates/Full/game/core/main.cs +++ b/Templates/Full/game/core/main.cs @@ -28,6 +28,12 @@ $WORD::BITDEPTH = 3; $WORD::REFRESH = 4; $WORD::AA = 5; +//We need to hook the missing/warn material stuff early, so do it here +$Core::MissingTexturePath = "core/art/missingTexture"; +$Core::UnAvailableTexturePath = "core/art/unavailable"; +$Core::WarningTexturePath = "core/art/warnMat"; +$Core::CommonShaderPath = "shaders/common"; + //--------------------------------------------------------------------------------------------- // CorePackage // Adds functionality for this mod to some standard functions. diff --git a/Templates/Full/game/core/scripts/client/postFx/MLAA.cs b/Templates/Full/game/core/scripts/client/postFx/MLAA.cs index f1656fb51..e09f45a3c 100644 --- a/Templates/Full/game/core/scripts/client/postFx/MLAA.cs +++ b/Templates/Full/game/core/scripts/client/postFx/MLAA.cs @@ -162,7 +162,7 @@ singleton PostEffect( MLAAFx ) texture[0] = "$inTex"; // Edges mask texture[1] = "$inTex"; // Edges mask - texture[2] = "AreaMap33.dds"; + texture[2] = "./AreaMap33.dds"; }; new PostEffect() diff --git a/Templates/Full/game/core/scripts/client/postFx/caustics.cs b/Templates/Full/game/core/scripts/client/postFx/caustics.cs index a712ef82a..7d598347e 100644 --- a/Templates/Full/game/core/scripts/client/postFx/caustics.cs +++ b/Templates/Full/game/core/scripts/client/postFx/caustics.cs @@ -58,7 +58,7 @@ singleton PostEffect( CausticsPFX ) shader = PFX_CausticsShader; stateBlock = PFX_CausticsStateBlock; texture[0] = "#prepass"; - texture[1] = "textures/caustics_1"; - texture[2] = "textures/caustics_2"; + texture[1] = "./textures/caustics_1"; + texture[2] = "./textures/caustics_2"; target = "$backBuffer"; }; diff --git a/Templates/Full/game/core/scripts/client/postFx/ssao.cs b/Templates/Full/game/core/scripts/client/postFx/ssao.cs index 063cee087..09dfa6bb4 100644 --- a/Templates/Full/game/core/scripts/client/postFx/ssao.cs +++ b/Templates/Full/game/core/scripts/client/postFx/ssao.cs @@ -200,7 +200,7 @@ singleton PostEffect( SSAOPostFx ) stateBlock = SSAOStateBlock; texture[0] = "#prepass"; - texture[1] = "noise.png"; + texture[1] = "./noise.png"; texture[2] = "#ssao_pow_table"; target = "$outTex"; diff --git a/Tools/CMake/template.torsion.in b/Tools/CMake/template.torsion.in index f832ad13b..a1eeab78e 100644 --- a/Tools/CMake/template.torsion.in +++ b/Tools/CMake/template.torsion.in @@ -9,9 +9,10 @@ <Folder>art</Folder> <Folder>levels</Folder> <Folder>shaders</Folder> +<Folder>data</Folder> <Folder>tools</Folder> </Mods> -<ScannerExts>cs; gui</ScannerExts> +<ScannerExts>cs; gui; taml; module;</ScannerExts> <Configs> <Config> <Name>Release</Name> @@ -24,7 +25,7 @@ </Config> <Config> <Name>Debug</Name> -<Executable>@TORQUE_APP_NAME@.exe</Executable> +<Executable>@TORQUE_APP_NAME@_Debug.exe</Executable> <Arguments/> <HasExports>true</HasExports> <Precompile>true</Precompile>