2012-09-19 15:15:01 +00:00
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION 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 "platform/platform.h"
# include "materials/materialDefinition.h"
# include "console/consoleTypes.h"
2014-11-04 03:42:51 +00:00
# include "console/engineAPI.h"
2012-09-19 15:15:01 +00:00
# include "math/mathTypes.h"
# include "materials/materialManager.h"
# include "sceneData.h"
# include "gfx/sim/cubemapData.h"
# include "gfx/gfxCubemap.h"
# include "math/mathIO.h"
# include "materials/matInstance.h"
# include "sfx/sfxTrack.h"
# include "sfx/sfxTypes.h"
# include "core/util/safeDelete.h"
2014-12-21 20:07:42 +00:00
# include "T3D/accumulationVolume.h"
2012-09-19 15:15:01 +00:00
IMPLEMENT_CONOBJECT ( Material ) ;
ConsoleDocClass ( Material ,
" @brief A material in Torque 3D is a data structure that describes a surface. \n \n "
" It contains many different types of information for rendering properties. "
" Torque 3D generates shaders from Material definitions. The shaders are compiled "
" at runtime and output into the example/shaders directory. Any errors or warnings "
" generated from compiling the procedurally generated shaders are output to the console "
" as well as the output window in the Visual C IDE. \n \n "
" @tsexample \n "
" singleton Material(DECAL_scorch) \n "
" { \n "
" baseTex[0] = \" ./scorch_decal.png \" ; \n "
" vertColor[ 0 ] = true; \n \n "
" translucent = true; \n "
" translucentBlendOp = None; \n "
" translucentZWrite = true; \n "
" alphaTest = true; \n "
" alphaRef = 84; \n "
" }; \n "
" @endtsexample \n \n "
" @see Rendering \n "
" @see ShaderData \n "
" @ingroup GFX \n " ) ;
ImplementBitfieldType ( MaterialAnimType ,
" The type of animation effect to apply to this material. \n "
" @ingroup GFX \n \n " )
{ Material : : Scroll , " Scroll " , " Scroll the material along the X/Y axis. \n " } ,
{ Material : : Rotate , " Rotate " , " Rotate the material around a point. \n " } ,
{ Material : : Wave , " Wave " , " Warps the material with an animation using Sin, Triangle or Square mathematics. \n " } ,
{ Material : : Scale , " Scale " , " Scales the material larger and smaller with a pulsing effect. \n " } ,
{ Material : : Sequence , " Sequence " , " Enables the material to have multiple frames of animation in its imagemap. \n " }
EndImplementBitfieldType ;
ImplementEnumType ( MaterialBlendOp ,
" The type of graphical blending operation to apply to this material \n "
" @ingroup GFX \n \n " )
{ Material : : None , " None " , " Disable blending for this material. " } ,
{ Material : : Mul , " Mul " , " Multiplicative blending. " } ,
{ Material : : Add , " Add " , " Adds the color of the material to the frame buffer with full alpha for each pixel. " } ,
{ Material : : AddAlpha , " AddAlpha " , " The color is modulated by the alpha channel before being added to the frame buffer. " } ,
{ Material : : Sub , " Sub " , " Subtractive Blending. Reverses the color model, causing dark colors to have a stronger visual effect. " } ,
{ Material : : LerpAlpha , " LerpAlpha " , " Linearly interpolates between Material color and frame buffer color based on alpha. " }
EndImplementEnumType ;
ImplementEnumType ( MaterialWaveType ,
" When using the Wave material animation, one of these Wave Types will be used to determine the type of wave to display. \n "
" @ingroup GFX \n " )
{ Material : : Sin , " Sin " , " Warps the material along a curved Sin Wave. " } ,
{ Material : : Triangle , " Triangle " , " Warps the material along a sharp Triangle Wave. " } ,
{ Material : : Square , " Square " , " Warps the material along a wave which transitions between two oppposite states. As a Square Wave, the transition is quick and sudden. " } ,
EndImplementEnumType ;
bool Material : : sAllowTextureTargetAssignment = false ;
GFXCubemap * Material : : GetNormalizeCube ( )
{
if ( smNormalizeCube )
return smNormalizeCube ;
smNormalizeCube = GFX - > createCubemap ( ) ;
smNormalizeCube - > initNormalize ( 64 ) ;
return smNormalizeCube ;
}
GFXCubemapHandle Material : : smNormalizeCube ;
Material : : Material ( )
{
for ( U32 i = 0 ; i < MAX_STAGES ; i + + )
{
mDiffuse [ i ] . set ( 1.0f , 1.0f , 1.0f , 1.0f ) ;
mSpecular [ i ] . set ( 1.0f , 1.0f , 1.0f , 1.0f ) ;
mSpecularPower [ i ] = 8.0f ;
2013-10-29 19:10:23 +00:00
mSpecularStrength [ i ] = 1.0f ;
2012-09-19 15:15:01 +00:00
mPixelSpecular [ i ] = false ;
2014-12-21 20:07:42 +00:00
mAccuEnabled [ i ] = false ;
mAccuScale [ i ] = 1.0f ;
mAccuDirection [ i ] = 1.0f ;
mAccuStrength [ i ] = 0.6f ;
mAccuCoverage [ i ] = 0.9f ;
mAccuSpecular [ i ] = 16.0f ;
2012-09-19 15:15:01 +00:00
mParallaxScale [ i ] = 0.0f ;
mVertLit [ i ] = false ;
mVertColor [ i ] = false ;
mGlow [ i ] = false ;
mEmissive [ i ] = false ;
mDetailScale [ i ] . set ( 2.0f , 2.0f ) ;
mDetailNormalMapStrength [ i ] = 1.0f ;
mMinnaertConstant [ i ] = - 1.0f ;
mSubSurface [ i ] = false ;
mSubSurfaceColor [ i ] . set ( 1.0f , 0.2f , 0.2f , 1.0f ) ;
mSubSurfaceRolloff [ i ] = 0.2f ;
mAnimFlags [ i ] = 0 ;
mScrollDir [ i ] . set ( 0.0f , 0.0f ) ;
mScrollSpeed [ i ] = 0.0f ;
mScrollOffset [ i ] . set ( 0.0f , 0.0f ) ;
mRotSpeed [ i ] = 0.0f ;
mRotPivotOffset [ i ] . set ( 0.0f , 0.0f ) ;
mRotPos [ i ] = 0.0f ;
mWavePos [ i ] = 0.0f ;
mWaveFreq [ i ] = 0.0f ;
mWaveAmp [ i ] = 0.0f ;
mWaveType [ i ] = 0 ;
mSeqFramePerSec [ i ] = 0.0f ;
mSeqSegSize [ i ] = 0.0f ;
The final step (barring any overlooked missing bits, requested refactors, and of course, rolling in dependencies already submitted as PRs) consists of:
renderPrePassMgr.cpp related:
A) shifting .addFeature( MFT_XYZ); calls from ProcessedShaderMaterial::_determineFeatures to ProcessedPrePassMaterial::_determineFeatures
B) mimicking the "// set the XXX if different" entries from RenderMeshMgr::render in RenderPrePassMgr::render
C) fleshing out ProcessedPrePassMaterial::getNumStages() so that it shares a 1:1 correlation with ProcessedShaderMaterial::getNumStages()
D) causing inline void Swizzle<T, mapLength>::ToBuffer( void *destination, const void *source, const dsize_t size ) to silently fail rather than fatally assert if a source or destination buffer is not yet ready to be filled. (support for #customTarget scripted render targets)
Reflections:
A) removing reflectRenderState.disableAdvancedLightingBins(true); entries. this would otherwise early out from prepass and provide no color data whatsoever.
B) removing the fd.features.addFeature( MFT_ForwardShading ); entry forcing all materials to be forward lit when reflected.
C) 2 things best described bluntly as working hacks:
C1) when reflected, a scattersky is rotated PI along it's z then x axis in order to draw properly.
C2) along similar lines, in terraincellmaterial, we shut off culling if it's a prepass material.
Skies: scattersky is given a pair of rotations for reflection purposes, all sky objects are given a z value for depth testing.
2016-02-16 08:50:49 +00:00
// Deferred Shading
mMatInfoFlags [ i ] = 0.0f ;
2012-09-19 15:15:01 +00:00
}
dMemset ( mCellIndex , 0 , sizeof ( mCellIndex ) ) ;
dMemset ( mCellLayout , 0 , sizeof ( mCellLayout ) ) ;
dMemset ( mCellSize , 0 , sizeof ( mCellSize ) ) ;
dMemset ( mNormalMapAtlas , 0 , sizeof ( mNormalMapAtlas ) ) ;
dMemset ( mUseAnisotropic , 0 , sizeof ( mUseAnisotropic ) ) ;
The final step (barring any overlooked missing bits, requested refactors, and of course, rolling in dependencies already submitted as PRs) consists of:
renderPrePassMgr.cpp related:
A) shifting .addFeature( MFT_XYZ); calls from ProcessedShaderMaterial::_determineFeatures to ProcessedPrePassMaterial::_determineFeatures
B) mimicking the "// set the XXX if different" entries from RenderMeshMgr::render in RenderPrePassMgr::render
C) fleshing out ProcessedPrePassMaterial::getNumStages() so that it shares a 1:1 correlation with ProcessedShaderMaterial::getNumStages()
D) causing inline void Swizzle<T, mapLength>::ToBuffer( void *destination, const void *source, const dsize_t size ) to silently fail rather than fatally assert if a source or destination buffer is not yet ready to be filled. (support for #customTarget scripted render targets)
Reflections:
A) removing reflectRenderState.disableAdvancedLightingBins(true); entries. this would otherwise early out from prepass and provide no color data whatsoever.
B) removing the fd.features.addFeature( MFT_ForwardShading ); entry forcing all materials to be forward lit when reflected.
C) 2 things best described bluntly as working hacks:
C1) when reflected, a scattersky is rotated PI along it's z then x axis in order to draw properly.
C2) along similar lines, in terraincellmaterial, we shut off culling if it's a prepass material.
Skies: scattersky is given a pair of rotations for reflection purposes, all sky objects are given a z value for depth testing.
2016-02-16 08:50:49 +00:00
// Deferred Shading : Metalness
dMemset ( mUseMetalness , 0 , sizeof ( mUseMetalness ) ) ;
2012-09-19 15:15:01 +00:00
mImposterLimits = Point4F : : Zero ;
mDoubleSided = false ;
mTranslucent = false ;
mTranslucentBlendOp = LerpAlpha ;
mTranslucentZWrite = false ;
mAlphaTest = false ;
mAlphaRef = 1 ;
mCastShadows = true ;
2015-11-03 05:06:51 +00:00
mCastDynamicShadows = false ;
2012-09-19 15:15:01 +00:00
mPlanarReflection = false ;
mCubemapData = NULL ;
mDynamicCubemap = NULL ;
mLastUpdateTime = 0 ;
mAutoGenerated = false ;
mShowDust = false ;
mShowFootprints = true ;
dMemset ( mEffectColor , 0 , sizeof ( mEffectColor ) ) ;
mFootstepSoundId = - 1 ; mImpactSoundId = - 1 ;
mFootstepSoundCustom = 0 ; mImpactSoundCustom = 0 ;
mFriction = 0.0 ;
mDirectSoundOcclusion = 1.f ;
mReverbSoundOcclusion = 1.0 ;
}
void Material : : initPersistFields ( )
{
addField ( " mapTo " , TypeRealString , Offset ( mMapTo , Material ) ,
" Used to map this material to the material name used by TSShape. " ) ;
addArray ( " Stages " , MAX_STAGES ) ;
addField ( " diffuseColor " , TypeColorF , Offset ( mDiffuse , Material ) , MAX_STAGES ,
" This color is multiplied against the diffuse texture color. If no diffuse texture "
" is present this is the material color. " ) ;
addField ( " diffuseMap " , TypeImageFilename , Offset ( mDiffuseMapFilename , Material ) , MAX_STAGES ,
" The diffuse color texture map. " ) ;
addField ( " overlayMap " , TypeImageFilename , Offset ( mOverlayMapFilename , Material ) , MAX_STAGES ,
" A secondary diffuse color texture map which will use the second texcoord of a mesh. " ) ;
addField ( " lightMap " , TypeImageFilename , Offset ( mLightMapFilename , Material ) , MAX_STAGES ,
" The lightmap texture used with pureLight. " ) ;
addField ( " toneMap " , TypeImageFilename , Offset ( mToneMapFilename , Material ) , MAX_STAGES ,
" The tonemap texture used with pureLight. " ) ;
addField ( " detailMap " , TypeImageFilename , Offset ( mDetailMapFilename , Material ) , MAX_STAGES ,
" A typically greyscale detail texture additively blended into the material. " ) ;
addField ( " detailScale " , TypePoint2F , Offset ( mDetailScale , Material ) , MAX_STAGES ,
" The scale factor for the detail map. " ) ;
addField ( " normalMap " , TypeImageFilename , Offset ( mNormalMapFilename , Material ) , MAX_STAGES ,
" The normal map texture. You can use the DXTnm format only when per-pixel "
" specular highlights are disabled, or a specular map is in use. " ) ;
addField ( " detailNormalMap " , TypeImageFilename , Offset ( mDetailNormalMapFilename , Material ) , MAX_STAGES ,
" A second normal map texture applied at the detail scale. You can use the DXTnm "
" format only when per-pixel specular highlights are disabled. " ) ;
addField ( " detailNormalMapStrength " , TypeF32 , Offset ( mDetailNormalMapStrength , Material ) , MAX_STAGES ,
" Used to scale the strength of the detail normal map when blended with the base normal map. " ) ;
addField ( " specular " , TypeColorF , Offset ( mSpecular , Material ) , MAX_STAGES ,
" The color of the specular highlight when not using a specularMap. " ) ;
addField ( " specularPower " , TypeF32 , Offset ( mSpecularPower , Material ) , MAX_STAGES ,
2013-10-29 19:10:23 +00:00
" The hardness of the specular highlight when not using a specularMap. " ) ;
addField ( " specularStrength " , TypeF32 , Offset ( mSpecularStrength , Material ) , MAX_STAGES ,
" The strength of the specular highlight when not using a specularMap. " ) ;
2012-09-19 15:15:01 +00:00
addField ( " pixelSpecular " , TypeBool , Offset ( mPixelSpecular , Material ) , MAX_STAGES ,
" This enables per-pixel specular highlights controlled by the alpha channel of the "
" normal map texture. Note that if pixel specular is enabled the DXTnm format will not "
" work with your normal map, unless you are also using a specular map. " ) ;
2014-12-21 20:07:42 +00:00
addProtectedField ( " accuEnabled " , TYPEID < bool > ( ) , Offset ( mAccuEnabled , Material ) ,
& _setAccuEnabled , & defaultProtectedGetFn , MAX_STAGES , " Accumulation texture. " ) ;
addField ( " accuScale " , TypeF32 , Offset ( mAccuScale , Material ) , MAX_STAGES ,
" The scale that is applied to the accu map texture. You can use this to fit the texture to smaller or larger objects. " ) ;
addField ( " accuDirection " , TypeF32 , Offset ( mAccuDirection , Material ) , MAX_STAGES ,
" The direction of the accumulation. Chose whether you want the accu map to go from top to bottom (ie. snow) or upwards (ie. mold). " ) ;
addField ( " accuStrength " , TypeF32 , Offset ( mAccuStrength , Material ) , MAX_STAGES ,
" The strength of the accu map. This changes the transparency of the accu map texture. Make it subtle or add more contrast. " ) ;
addField ( " accuCoverage " , TypeF32 , Offset ( mAccuCoverage , Material ) , MAX_STAGES ,
" The coverage ratio of the accu map texture. Use this to make the entire shape pick up some of the accu map texture or none at all. " ) ;
addField ( " accuSpecular " , TypeF32 , Offset ( mAccuSpecular , Material ) , MAX_STAGES ,
" Changes specularity to this value where the accumulated material is present. " ) ;
2012-09-19 15:15:01 +00:00
addField ( " specularMap " , TypeImageFilename , Offset ( mSpecularMapFilename , Material ) , MAX_STAGES ,
" The specular map texture. The RGB channels of this texture provide a per-pixel replacement for the 'specular' parameter on the material. "
" If this texture contains alpha information, the alpha channel of the texture will be used as the gloss map. "
" This provides a per-pixel replacement for the 'specularPower' on the material " ) ;
addField ( " parallaxScale " , TypeF32 , Offset ( mParallaxScale , Material ) , MAX_STAGES ,
" Enables parallax mapping and defines the scale factor for the parallax effect. Typically "
" this value is less than 0.4 else the effect breaks down. " ) ;
addField ( " useAnisotropic " , TypeBool , Offset ( mUseAnisotropic , Material ) , MAX_STAGES ,
" Use anisotropic filtering for the textures of this stage. " ) ;
The final step (barring any overlooked missing bits, requested refactors, and of course, rolling in dependencies already submitted as PRs) consists of:
renderPrePassMgr.cpp related:
A) shifting .addFeature( MFT_XYZ); calls from ProcessedShaderMaterial::_determineFeatures to ProcessedPrePassMaterial::_determineFeatures
B) mimicking the "// set the XXX if different" entries from RenderMeshMgr::render in RenderPrePassMgr::render
C) fleshing out ProcessedPrePassMaterial::getNumStages() so that it shares a 1:1 correlation with ProcessedShaderMaterial::getNumStages()
D) causing inline void Swizzle<T, mapLength>::ToBuffer( void *destination, const void *source, const dsize_t size ) to silently fail rather than fatally assert if a source or destination buffer is not yet ready to be filled. (support for #customTarget scripted render targets)
Reflections:
A) removing reflectRenderState.disableAdvancedLightingBins(true); entries. this would otherwise early out from prepass and provide no color data whatsoever.
B) removing the fd.features.addFeature( MFT_ForwardShading ); entry forcing all materials to be forward lit when reflected.
C) 2 things best described bluntly as working hacks:
C1) when reflected, a scattersky is rotated PI along it's z then x axis in order to draw properly.
C2) along similar lines, in terraincellmaterial, we shut off culling if it's a prepass material.
Skies: scattersky is given a pair of rotations for reflection purposes, all sky objects are given a z value for depth testing.
2016-02-16 08:50:49 +00:00
2012-09-19 15:15:01 +00:00
addField ( " vertLit " , TypeBool , Offset ( mVertLit , Material ) , MAX_STAGES ,
" If true the vertex color is used for lighting. " ) ;
addField ( " vertColor " , TypeBool , Offset ( mVertColor , Material ) , MAX_STAGES ,
" If enabled, vertex colors are premultiplied with diffuse colors. " ) ;
addField ( " minnaertConstant " , TypeF32 , Offset ( mMinnaertConstant , Material ) , MAX_STAGES ,
" The Minnaert shading constant value. Must be greater than 0 to enable the effect. " ) ;
addField ( " subSurface " , TypeBool , Offset ( mSubSurface , Material ) , MAX_STAGES ,
" Enables the subsurface scattering approximation. " ) ;
addField ( " subSurfaceColor " , TypeColorF , Offset ( mSubSurfaceColor , Material ) , MAX_STAGES ,
" The color used for the subsurface scattering approximation. " ) ;
addField ( " subSurfaceRolloff " , TypeF32 , Offset ( mSubSurfaceRolloff , Material ) , MAX_STAGES ,
" The 0 to 1 rolloff factor used in the subsurface scattering approximation. " ) ;
addField ( " glow " , TypeBool , Offset ( mGlow , Material ) , MAX_STAGES ,
" Enables rendering this material to the glow buffer. " ) ;
addField ( " emissive " , TypeBool , Offset ( mEmissive , Material ) , MAX_STAGES ,
" Enables emissive lighting for the material. " ) ;
addField ( " doubleSided " , TypeBool , Offset ( mDoubleSided , Material ) ,
" Disables backface culling casing surfaces to be double sided. "
" Note that the lighting on the backside will be a mirror of the front "
" side of the surface. " ) ;
addField ( " animFlags " , TYPEID < AnimType > ( ) , Offset ( mAnimFlags , Material ) , MAX_STAGES ,
" The types of animation to play on this material. " ) ;
addField ( " scrollDir " , TypePoint2F , Offset ( mScrollDir , Material ) , MAX_STAGES ,
" The scroll direction in UV space when scroll animation is enabled. " ) ;
addField ( " scrollSpeed " , TypeF32 , Offset ( mScrollSpeed , Material ) , MAX_STAGES ,
" The speed to scroll the texture in UVs per second when scroll animation is enabled. " ) ;
addField ( " rotSpeed " , TypeF32 , Offset ( mRotSpeed , Material ) , MAX_STAGES ,
" The speed to rotate the texture in degrees per second when rotation animation is enabled. " ) ;
addField ( " rotPivotOffset " , TypePoint2F , Offset ( mRotPivotOffset , Material ) , MAX_STAGES ,
" The piviot position in UV coordinates to center the rotation animation. " ) ;
addField ( " waveType " , TYPEID < WaveType > ( ) , Offset ( mWaveType , Material ) , MAX_STAGES ,
" The type of wave animation to perform when wave animation is enabled. " ) ;
addField ( " waveFreq " , TypeF32 , Offset ( mWaveFreq , Material ) , MAX_STAGES ,
" The wave frequency when wave animation is enabled. " ) ;
addField ( " waveAmp " , TypeF32 , Offset ( mWaveAmp , Material ) , MAX_STAGES ,
" The wave amplitude when wave animation is enabled. " ) ;
addField ( " sequenceFramePerSec " , TypeF32 , Offset ( mSeqFramePerSec , Material ) , MAX_STAGES ,
" The number of frames per second for frame based sequence animations if greater than zero. " ) ;
addField ( " sequenceSegmentSize " , TypeF32 , Offset ( mSeqSegSize , Material ) , MAX_STAGES ,
" The size of each frame in UV units for sequence animations. " ) ;
// Texture atlasing
addField ( " cellIndex " , TypePoint2I , Offset ( mCellIndex , Material ) , MAX_STAGES ,
" @internal " ) ;
addField ( " cellLayout " , TypePoint2I , Offset ( mCellLayout , Material ) , MAX_STAGES ,
" @internal " ) ;
addField ( " cellSize " , TypeS32 , Offset ( mCellSize , Material ) , MAX_STAGES ,
" @internal " ) ;
addField ( " bumpAtlas " , TypeBool , Offset ( mNormalMapAtlas , Material ) , MAX_STAGES ,
" @internal " ) ;
// For backwards compatibility.
//
// They point at the new 'map' fields, but reads always return
// an empty string and writes only apply if the value is not empty.
//
addProtectedField ( " baseTex " , TypeImageFilename , Offset ( mDiffuseMapFilename , Material ) ,
defaultProtectedSetNotEmptyFn , emptyStringProtectedGetFn , MAX_STAGES ,
" For backwards compatibility. \n @see diffuseMap \n " ) ;
addProtectedField ( " detailTex " , TypeImageFilename , Offset ( mDetailMapFilename , Material ) ,
defaultProtectedSetNotEmptyFn , emptyStringProtectedGetFn , MAX_STAGES ,
" For backwards compatibility. \n @see detailMap \n " ) ;
addProtectedField ( " overlayTex " , TypeImageFilename , Offset ( mOverlayMapFilename , Material ) ,
defaultProtectedSetNotEmptyFn , emptyStringProtectedGetFn , MAX_STAGES ,
" For backwards compatibility. \n @see overlayMap \n " ) ;
addProtectedField ( " bumpTex " , TypeImageFilename , Offset ( mNormalMapFilename , Material ) ,
defaultProtectedSetNotEmptyFn , emptyStringProtectedGetFn , MAX_STAGES ,
" For backwards compatibility. \n @see normalMap \n " ) ;
addProtectedField ( " colorMultiply " , TypeColorF , Offset ( mDiffuse , Material ) ,
defaultProtectedSetNotEmptyFn , emptyStringProtectedGetFn , MAX_STAGES ,
" For backwards compatibility. \n @see diffuseColor \n " ) ;
endArray ( " Stages " ) ;
addField ( " castShadows " , TypeBool , Offset ( mCastShadows , Material ) ,
" If set to false the lighting system will not cast shadows from this material. " ) ;
2015-10-13 23:12:19 +00:00
addField ( " castDynamicShadows " , TypeBool , Offset ( mCastDynamicShadows , Material ) ,
" If set to false the lighting system will not cast dynamic shadows from this material. " ) ;
2012-09-19 15:15:01 +00:00
addField ( " planarReflection " , TypeBool , Offset ( mPlanarReflection , Material ) , " @internal " ) ;
addField ( " translucent " , TypeBool , Offset ( mTranslucent , Material ) ,
" If true this material is translucent blended. " ) ;
addField ( " translucentBlendOp " , TYPEID < BlendOp > ( ) , Offset ( mTranslucentBlendOp , Material ) ,
" The type of blend operation to use when the material is translucent. " ) ;
addField ( " translucentZWrite " , TypeBool , Offset ( mTranslucentZWrite , Material ) ,
" If enabled and the material is translucent it will write into the depth buffer. " ) ;
addField ( " alphaTest " , TypeBool , Offset ( mAlphaTest , Material ) ,
" Enables alpha test when rendering the material. \n @see alphaRef \n " ) ;
addField ( " alphaRef " , TypeS32 , Offset ( mAlphaRef , Material ) ,
" The alpha reference value for alpha testing. Must be between 0 to 255. \n @see alphaTest \n " ) ;
addField ( " cubemap " , TypeRealString , Offset ( mCubemapName , Material ) ,
" The name of a CubemapData for environment mapping. " ) ;
addField ( " dynamicCubemap " , TypeBool , Offset ( mDynamicCubemap , Material ) ,
" Enables the material to use the dynamic cubemap from the ShapeBase object its applied to. " ) ;
addGroup ( " Behavioral " ) ;
addField ( " showFootprints " , TypeBool , Offset ( mShowFootprints , Material ) ,
" Whether to show player footprint decals on this material. \n \n "
" @see PlayerData::decalData " ) ;
addField ( " showDust " , TypeBool , Offset ( mShowDust , Material ) ,
" Whether to emit dust particles from a shape moving over the material. This is, for example, used by "
" vehicles or players to decide whether to show dust trails. " ) ;
addField ( " effectColor " , TypeColorF , Offset ( mEffectColor , Material ) , NUM_EFFECT_COLOR_STAGES ,
" If #showDust is true, this is the set of colors to use for the ParticleData of the dust "
" emitter. \n \n "
" @see ParticleData::colors " ) ;
addField ( " footstepSoundId " , TypeS32 , Offset ( mFootstepSoundId , Material ) ,
" What sound to play from the PlayerData sound list when the player walks over the material. -1 (default) to not play any sound. \n "
" \n "
" The IDs are: \n \n "
" - 0: PlayerData::FootSoftSound \n "
" - 1: PlayerData::FootHardSound \n "
" - 2: PlayerData::FootMetalSound \n "
" - 3: PlayerData::FootSnowSound \n "
" - 4: PlayerData::FootShallowSound \n "
" - 5: PlayerData::FootWadingSound \n "
" - 6: PlayerData::FootUnderwaterSound \n "
" - 7: PlayerData::FootBubblesSound \n "
" - 8: PlayerData::movingBubblesSound \n "
" - 9: PlayerData::waterBreathSound \n "
" - 10: PlayerData::impactSoftSound \n "
" - 11: PlayerData::impactHardSound \n "
" - 12: PlayerData::impactMetalSound \n "
" - 13: PlayerData::impactSnowSound \n "
" - 14: PlayerData::impactWaterEasy \n "
" - 15: PlayerData::impactWaterMedium \n "
" - 16: PlayerData::impactWaterHard \n "
" - 17: PlayerData::exitingWater \n " ) ;
addField ( " customFootstepSound " , TypeSFXTrackName , Offset ( mFootstepSoundCustom , Material ) ,
" The sound to play when the player walks over the material. If this is set, it overrides #footstepSoundId. This field is "
" useful for directly assigning custom footstep sounds to materials without having to rely on the PlayerData sound assignment. \n \n "
" @warn Be aware that materials are client-side objects. This means that the SFXTracks assigned to materials must be client-side, too. " ) ;
addField ( " impactSoundId " , TypeS32 , Offset ( mImpactSoundId , Material ) ,
" What sound to play from the PlayerData sound list when the player impacts on the surface with a velocity equal or greater "
" than PlayerData::groundImpactMinSpeed. \n \n "
" For a list of IDs, see #footstepSoundId " ) ;
addField ( " customImpactSound " , TypeSFXTrackName , Offset ( mImpactSoundCustom , Material ) ,
" The sound to play when the player impacts on the surface with a velocity equal or greater than PlayerData::groundImpactMinSpeed. "
" If this is set, it overrides #impactSoundId. This field is useful for directly assigning custom impact sounds to materials "
" without having to rely on the PlayerData sound assignment. \n \n "
" @warn Be aware that materials are client-side objects. This means that the SFXTracks assigned to materials must be client-side, too. " ) ;
//Deactivate these for the moment as they are not used.
#if 0
addField ( " friction " , TypeF32 , Offset ( mFriction , Material ) ) ;
addField ( " directSoundOcclusion " , TypeF32 , Offset ( mDirectSoundOcclusion , Material ) ) ;
addField ( " reverbSoundOcclusion " , TypeF32 , Offset ( mReverbSoundOcclusion , Material ) ) ;
# endif
endGroup ( " Behavioral " ) ;
Parent : : initPersistFields ( ) ;
}
bool Material : : writeField ( StringTableEntry fieldname , const char * value )
{
// Never allow the old field names to be written.
if ( fieldname = = StringTable - > insert ( " baseTex " ) | |
fieldname = = StringTable - > insert ( " detailTex " ) | |
fieldname = = StringTable - > insert ( " overlayTex " ) | |
fieldname = = StringTable - > insert ( " bumpTex " ) | |
fieldname = = StringTable - > insert ( " envTex " ) | |
fieldname = = StringTable - > insert ( " colorMultiply " ) )
return false ;
return Parent : : writeField ( fieldname , value ) ;
}
bool Material : : onAdd ( )
{
if ( Parent : : onAdd ( ) = = false )
return false ;
mCubemapData = dynamic_cast < CubemapData * > ( Sim : : findObject ( mCubemapName ) ) ;
if ( mTranslucentBlendOp > = NumBlendTypes | | mTranslucentBlendOp < 0 )
{
Con : : errorf ( " Invalid blend op in material: %s " , getName ( ) ) ;
mTranslucentBlendOp = LerpAlpha ;
}
SimSet * matSet = MATMGR - > getMaterialSet ( ) ;
if ( matSet )
matSet - > addObject ( ( SimObject * ) this ) ;
// save the current script path for texture lookup later
const String scriptFile = Con : : getVariable ( " $Con::File " ) ; // current script file - local materials.cs
String : : SizeType slash = scriptFile . find ( ' / ' , scriptFile . length ( ) , String : : Right ) ;
if ( slash ! = String : : NPos )
mPath = scriptFile . substr ( 0 , slash + 1 ) ;
_mapMaterial ( ) ;
return true ;
}
void Material : : onRemove ( )
{
smNormalizeCube = NULL ;
Parent : : onRemove ( ) ;
}
void Material : : inspectPostApply ( )
{
Parent : : inspectPostApply ( ) ;
// Reload the material instances which
// use this material.
if ( isProperlyAdded ( ) )
reload ( ) ;
}
bool Material : : isLightmapped ( ) const
{
bool ret = false ;
for ( U32 i = 0 ; i < MAX_STAGES ; i + + )
ret | = mLightMapFilename [ i ] . isNotEmpty ( ) | | mToneMapFilename [ i ] . isNotEmpty ( ) | | mVertLit [ i ] ;
return ret ;
}
void Material : : updateTimeBasedParams ( )
{
U32 lastTime = MATMGR - > getLastUpdateTime ( ) ;
F32 dt = MATMGR - > getDeltaTime ( ) ;
if ( mLastUpdateTime ! = lastTime )
{
for ( U32 i = 0 ; i < MAX_STAGES ; i + + )
{
mScrollOffset [ i ] + = mScrollDir [ i ] * mScrollSpeed [ i ] * dt ;
mRotPos [ i ] + = mRotSpeed [ i ] * dt ;
mWavePos [ i ] + = mWaveFreq [ i ] * dt ;
}
mLastUpdateTime = lastTime ;
}
}
void Material : : _mapMaterial ( )
{
if ( String ( getName ( ) ) . isEmpty ( ) )
{
Con : : warnf ( " [Material::mapMaterial] - Cannot map unnamed Material " ) ;
return ;
}
// If mapTo not defined in script, try to use the base texture name instead
if ( mMapTo . isEmpty ( ) )
{
if ( mDiffuseMapFilename [ 0 ] . isEmpty ( ) )
return ;
else
{
// extract filename from base texture
if ( mDiffuseMapFilename [ 0 ] . isNotEmpty ( ) )
{
U32 slashPos = mDiffuseMapFilename [ 0 ] . find ( ' / ' , 0 , String : : Right ) ;
if ( slashPos = = String : : NPos )
// no '/' character, must be no path, just the filename
mMapTo = mDiffuseMapFilename [ 0 ] ;
else
// use everything after the last slash
mMapTo = mDiffuseMapFilename [ 0 ] . substr ( slashPos + 1 , mDiffuseMapFilename [ 0 ] . length ( ) - slashPos - 1 ) ;
}
}
}
// add mapping
MATMGR - > mapMaterial ( mMapTo , getName ( ) ) ;
}
BaseMatInstance * Material : : createMatInstance ( )
{
return new MatInstance ( * this ) ;
}
void Material : : flush ( )
{
MATMGR - > flushInstance ( this ) ;
}
void Material : : reload ( )
{
MATMGR - > reInitInstance ( this ) ;
}
void Material : : StageData : : getFeatureSet ( FeatureSet * outFeatures ) const
{
TextureTable : : ConstIterator iter = mTextures . begin ( ) ;
for ( ; iter ! = mTextures . end ( ) ; iter + + )
{
if ( iter - > value . isValid ( ) )
outFeatures - > addFeature ( * iter - > key ) ;
}
}
2014-11-04 03:42:51 +00:00
DefineConsoleMethod ( Material , flush , void , ( ) , ,
2012-09-19 15:15:01 +00:00
" Flushes all material instances that use this material. " )
{
object - > flush ( ) ;
}
2014-11-04 03:42:51 +00:00
DefineConsoleMethod ( Material , reload , void , ( ) , ,
2012-09-19 15:15:01 +00:00
" Reloads all material instances that use this material. " )
{
object - > reload ( ) ;
}
2014-11-04 03:42:51 +00:00
DefineConsoleMethod ( Material , dumpInstances , void , ( ) , ,
2012-09-19 15:15:01 +00:00
" Dumps a formatted list of the currently allocated material instances for this material to the console. " )
{
MATMGR - > dumpMaterialInstances ( object ) ;
}
2014-11-04 03:42:51 +00:00
DefineConsoleMethod ( Material , getAnimFlags , const char * , ( U32 id ) , , " " )
2012-09-19 15:15:01 +00:00
{
char * animFlags = Con : : getReturnBuffer ( 512 ) ;
2014-11-04 03:42:51 +00:00
if ( object - > mAnimFlags [ id ] & Material : : Scroll )
2012-09-19 15:15:01 +00:00
{
if ( dStrcmp ( animFlags , " " ) = = 0 )
dStrcpy ( animFlags , " $Scroll " ) ;
}
2014-11-04 03:42:51 +00:00
if ( object - > mAnimFlags [ id ] & Material : : Rotate )
2012-09-19 15:15:01 +00:00
{
if ( dStrcmp ( animFlags , " " ) = = 0 )
dStrcpy ( animFlags , " $Rotate " ) ;
else
dStrcat ( animFlags , " | $Rotate " ) ;
}
2014-11-04 03:42:51 +00:00
if ( object - > mAnimFlags [ id ] & Material : : Wave )
2012-09-19 15:15:01 +00:00
{
if ( dStrcmp ( animFlags , " " ) = = 0 )
dStrcpy ( animFlags , " $Wave " ) ;
else
dStrcat ( animFlags , " | $Wave " ) ;
}
2014-11-04 03:42:51 +00:00
if ( object - > mAnimFlags [ id ] & Material : : Scale )
2012-09-19 15:15:01 +00:00
{
if ( dStrcmp ( animFlags , " " ) = = 0 )
dStrcpy ( animFlags , " $Scale " ) ;
else
dStrcat ( animFlags , " | $Scale " ) ;
}
2014-11-04 03:42:51 +00:00
if ( object - > mAnimFlags [ id ] & Material : : Sequence )
2012-09-19 15:15:01 +00:00
{
if ( dStrcmp ( animFlags , " " ) = = 0 )
dStrcpy ( animFlags , " $Sequence " ) ;
else
dStrcat ( animFlags , " | $Sequence " ) ;
}
return animFlags ;
}
2014-11-04 03:42:51 +00:00
DefineConsoleMethod ( Material , getFilename , const char * , ( ) , , " Get filename of material " )
2012-09-19 15:15:01 +00:00
{
SimObject * material = static_cast < SimObject * > ( object ) ;
return material - > getFilename ( ) ;
}
2014-11-04 03:42:51 +00:00
DefineConsoleMethod ( Material , isAutoGenerated , bool , ( ) , ,
2012-09-19 15:15:01 +00:00
" Returns true if this Material was automatically generated by MaterialList::mapMaterials() " )
{
return object - > isAutoGenerated ( ) ;
}
2014-11-04 03:42:51 +00:00
DefineConsoleMethod ( Material , setAutoGenerated , void , ( bool isAutoGenerated ) , ,
2012-09-19 15:15:01 +00:00
" setAutoGenerated(bool isAutoGenerated): Set whether or not the Material is autogenerated. " )
{
2014-11-04 03:42:51 +00:00
object - > setAutoGenerated ( isAutoGenerated ) ;
2014-12-21 20:07:42 +00:00
}
// Accumulation
bool Material : : _setAccuEnabled ( void * object , const char * index , const char * data )
{
Material * mat = reinterpret_cast < Material * > ( object ) ;
if ( index )
{
U32 i = dAtoui ( index ) ;
mat - > mAccuEnabled [ i ] = dAtob ( data ) ;
AccumulationVolume : : refreshVolumes ( ) ;
}
return true ;
2012-09-19 15:15:01 +00:00
}