materialDefinition.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "materials/materialDefinition.h"
  24. #include "console/consoleTypes.h"
  25. #include "math/mathTypes.h"
  26. #include "materials/materialManager.h"
  27. #include "sceneData.h"
  28. #include "gfx/sim/cubemapData.h"
  29. #include "gfx/gfxCubemap.h"
  30. #include "math/mathIO.h"
  31. #include "materials/matInstance.h"
  32. #include "sfx/sfxTrack.h"
  33. #include "sfx/sfxTypes.h"
  34. #include "core/util/safeDelete.h"
  35. IMPLEMENT_CONOBJECT( Material );
  36. ConsoleDocClass( Material,
  37. "@brief A material in Torque 3D is a data structure that describes a surface.\n\n"
  38. "It contains many different types of information for rendering properties. "
  39. "Torque 3D generates shaders from Material definitions. The shaders are compiled "
  40. "at runtime and output into the example/shaders directory. Any errors or warnings "
  41. "generated from compiling the procedurally generated shaders are output to the console "
  42. "as well as the output window in the Visual C IDE.\n\n"
  43. "@tsexample\n"
  44. "singleton Material(DECAL_scorch)\n"
  45. "{\n"
  46. " baseTex[0] = \"./scorch_decal.png\";\n"
  47. " vertColor[ 0 ] = true;\n\n"
  48. " translucent = true;\n"
  49. " translucentBlendOp = None;\n"
  50. " translucentZWrite = true;\n"
  51. " alphaTest = true;\n"
  52. " alphaRef = 84;\n"
  53. "};\n"
  54. "@endtsexample\n\n"
  55. "@see Rendering\n"
  56. "@see ShaderData\n"
  57. "@ingroup GFX\n");
  58. ImplementBitfieldType( MaterialAnimType,
  59. "The type of animation effect to apply to this material.\n"
  60. "@ingroup GFX\n\n")
  61. { Material::Scroll, "Scroll", "Scroll the material along the X/Y axis.\n" },
  62. { Material::Rotate, "Rotate" , "Rotate the material around a point.\n"},
  63. { Material::Wave, "Wave" , "Warps the material with an animation using Sin, Triangle or Square mathematics.\n"},
  64. { Material::Scale, "Scale", "Scales the material larger and smaller with a pulsing effect.\n" },
  65. { Material::Sequence, "Sequence", "Enables the material to have multiple frames of animation in its imagemap.\n" }
  66. EndImplementBitfieldType;
  67. ImplementEnumType( MaterialBlendOp,
  68. "The type of graphical blending operation to apply to this material\n"
  69. "@ingroup GFX\n\n")
  70. { Material::None, "None", "Disable blending for this material." },
  71. { Material::Mul, "Mul", "Multiplicative blending." },
  72. { Material::Add, "Add", "Adds the color of the material to the frame buffer with full alpha for each pixel." },
  73. { Material::AddAlpha, "AddAlpha", "The color is modulated by the alpha channel before being added to the frame buffer." },
  74. { Material::Sub, "Sub", "Subtractive Blending. Reverses the color model, causing dark colors to have a stronger visual effect." },
  75. { Material::LerpAlpha, "LerpAlpha", "Linearly interpolates between Material color and frame buffer color based on alpha." }
  76. EndImplementEnumType;
  77. ImplementEnumType( MaterialWaveType,
  78. "When using the Wave material animation, one of these Wave Types will be used to determine the type of wave to display.\n"
  79. "@ingroup GFX\n")
  80. { Material::Sin, "Sin", "Warps the material along a curved Sin Wave." },
  81. { Material::Triangle, "Triangle", "Warps the material along a sharp Triangle Wave." },
  82. { 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." },
  83. EndImplementEnumType;
  84. bool Material::sAllowTextureTargetAssignment = false;
  85. GFXCubemap * Material::GetNormalizeCube()
  86. {
  87. if(smNormalizeCube)
  88. return smNormalizeCube;
  89. smNormalizeCube = GFX->createCubemap();
  90. smNormalizeCube->initNormalize(64);
  91. return smNormalizeCube;
  92. }
  93. GFXCubemapHandle Material::smNormalizeCube;
  94. Material::Material()
  95. {
  96. for( U32 i=0; i<MAX_STAGES; i++ )
  97. {
  98. mDiffuse[i].set( 1.0f, 1.0f, 1.0f, 1.0f );
  99. mSpecular[i].set( 1.0f, 1.0f, 1.0f, 1.0f );
  100. mSpecularPower[i] = 8.0f;
  101. mSpecularStrength[i] = 1.0f;
  102. mPixelSpecular[i] = false;
  103. mParallaxScale[i] = 0.0f;
  104. mVertLit[i] = false;
  105. mVertColor[ i ] = false;
  106. mGlow[i] = false;
  107. mEmissive[i] = false;
  108. mDetailScale[i].set( 2.0f, 2.0f );
  109. mDetailNormalMapStrength[i] = 1.0f;
  110. mMinnaertConstant[i] = -1.0f;
  111. mSubSurface[i] = false;
  112. mSubSurfaceColor[i].set( 1.0f, 0.2f, 0.2f, 1.0f );
  113. mSubSurfaceRolloff[i] = 0.2f;
  114. mAnimFlags[i] = 0;
  115. mScrollDir[i].set( 0.0f, 0.0f );
  116. mScrollSpeed[i] = 0.0f;
  117. mScrollOffset[i].set( 0.0f, 0.0f );
  118. mRotSpeed[i] = 0.0f;
  119. mRotPivotOffset[i].set( 0.0f, 0.0f );
  120. mRotPos[i] = 0.0f;
  121. mWavePos[i] = 0.0f;
  122. mWaveFreq[i] = 0.0f;
  123. mWaveAmp[i] = 0.0f;
  124. mWaveType[i] = 0;
  125. mSeqFramePerSec[i] = 0.0f;
  126. mSeqSegSize[i] = 0.0f;
  127. }
  128. dMemset(mCellIndex, 0, sizeof(mCellIndex));
  129. dMemset(mCellLayout, 0, sizeof(mCellLayout));
  130. dMemset(mCellSize, 0, sizeof(mCellSize));
  131. dMemset(mNormalMapAtlas, 0, sizeof(mNormalMapAtlas));
  132. dMemset(mUseAnisotropic, 0, sizeof(mUseAnisotropic));
  133. mImposterLimits = Point4F::Zero;
  134. mDoubleSided = false;
  135. mTranslucent = false;
  136. mTranslucentBlendOp = LerpAlpha;
  137. mTranslucentZWrite = false;
  138. mAlphaTest = false;
  139. mAlphaRef = 1;
  140. mCastShadows = true;
  141. mPlanarReflection = false;
  142. mCubemapData = NULL;
  143. mDynamicCubemap = NULL;
  144. mLastUpdateTime = 0;
  145. mAutoGenerated = false;
  146. mShowDust = false;
  147. mShowFootprints = true;
  148. dMemset( mEffectColor, 0, sizeof( mEffectColor ) );
  149. mFootstepSoundId = -1; mImpactSoundId = -1;
  150. mFootstepSoundCustom = 0; mImpactSoundCustom = 0;
  151. mFriction = 0.0;
  152. mDirectSoundOcclusion = 1.f;
  153. mReverbSoundOcclusion = 1.0;
  154. }
  155. void Material::initPersistFields()
  156. {
  157. addField("mapTo", TypeRealString, Offset(mMapTo, Material),
  158. "Used to map this material to the material name used by TSShape." );
  159. addArray( "Stages", MAX_STAGES );
  160. addField("diffuseColor", TypeColorF, Offset(mDiffuse, Material), MAX_STAGES,
  161. "This color is multiplied against the diffuse texture color. If no diffuse texture "
  162. "is present this is the material color." );
  163. addField("diffuseMap", TypeImageFilename, Offset(mDiffuseMapFilename, Material), MAX_STAGES,
  164. "The diffuse color texture map." );
  165. addField("overlayMap", TypeImageFilename, Offset(mOverlayMapFilename, Material), MAX_STAGES,
  166. "A secondary diffuse color texture map which will use the second texcoord of a mesh." );
  167. addField("lightMap", TypeImageFilename, Offset(mLightMapFilename, Material), MAX_STAGES,
  168. "The lightmap texture used with pureLight." );
  169. addField("toneMap", TypeImageFilename, Offset(mToneMapFilename, Material), MAX_STAGES,
  170. "The tonemap texture used with pureLight.");
  171. addField("detailMap", TypeImageFilename, Offset(mDetailMapFilename, Material), MAX_STAGES,
  172. "A typically greyscale detail texture additively blended into the material." );
  173. addField("detailScale", TypePoint2F, Offset(mDetailScale, Material), MAX_STAGES,
  174. "The scale factor for the detail map." );
  175. addField( "normalMap", TypeImageFilename, Offset(mNormalMapFilename, Material), MAX_STAGES,
  176. "The normal map texture. You can use the DXTnm format only when per-pixel "
  177. "specular highlights are disabled, or a specular map is in use." );
  178. addField( "detailNormalMap", TypeImageFilename, Offset(mDetailNormalMapFilename, Material), MAX_STAGES,
  179. "A second normal map texture applied at the detail scale. You can use the DXTnm "
  180. "format only when per-pixel specular highlights are disabled." );
  181. addField( "detailNormalMapStrength", TypeF32, Offset(mDetailNormalMapStrength, Material), MAX_STAGES,
  182. "Used to scale the strength of the detail normal map when blended with the base normal map." );
  183. addField("specular", TypeColorF, Offset(mSpecular, Material), MAX_STAGES,
  184. "The color of the specular highlight when not using a specularMap." );
  185. addField("specularPower", TypeF32, Offset(mSpecularPower, Material), MAX_STAGES,
  186. "The hardness of the specular highlight when not using a specularMap." );
  187. addField("specularStrength", TypeF32, Offset(mSpecularStrength, Material), MAX_STAGES,
  188. "The strength of the specular highlight when not using a specularMap." );
  189. addField("pixelSpecular", TypeBool, Offset(mPixelSpecular, Material), MAX_STAGES,
  190. "This enables per-pixel specular highlights controlled by the alpha channel of the "
  191. "normal map texture. Note that if pixel specular is enabled the DXTnm format will not "
  192. "work with your normal map, unless you are also using a specular map." );
  193. addField( "specularMap", TypeImageFilename, Offset(mSpecularMapFilename, Material), MAX_STAGES,
  194. "The specular map texture. The RGB channels of this texture provide a per-pixel replacement for the 'specular' parameter on the material. "
  195. "If this texture contains alpha information, the alpha channel of the texture will be used as the gloss map. "
  196. "This provides a per-pixel replacement for the 'specularPower' on the material" );
  197. addField( "parallaxScale", TypeF32, Offset(mParallaxScale, Material), MAX_STAGES,
  198. "Enables parallax mapping and defines the scale factor for the parallax effect. Typically "
  199. "this value is less than 0.4 else the effect breaks down." );
  200. addField( "useAnisotropic", TypeBool, Offset(mUseAnisotropic, Material), MAX_STAGES,
  201. "Use anisotropic filtering for the textures of this stage." );
  202. addField("envMap", TypeImageFilename, Offset(mEnvMapFilename, Material), MAX_STAGES,
  203. "The name of an environment map cube map to apply to this material." );
  204. addField("vertLit", TypeBool, Offset(mVertLit, Material), MAX_STAGES,
  205. "If true the vertex color is used for lighting." );
  206. addField( "vertColor", TypeBool, Offset( mVertColor, Material ), MAX_STAGES,
  207. "If enabled, vertex colors are premultiplied with diffuse colors." );
  208. addField("minnaertConstant", TypeF32, Offset(mMinnaertConstant, Material), MAX_STAGES,
  209. "The Minnaert shading constant value. Must be greater than 0 to enable the effect." );
  210. addField("subSurface", TypeBool, Offset(mSubSurface, Material), MAX_STAGES,
  211. "Enables the subsurface scattering approximation." );
  212. addField("subSurfaceColor", TypeColorF, Offset(mSubSurfaceColor, Material), MAX_STAGES,
  213. "The color used for the subsurface scattering approximation." );
  214. addField("subSurfaceRolloff", TypeF32, Offset(mSubSurfaceRolloff, Material), MAX_STAGES,
  215. "The 0 to 1 rolloff factor used in the subsurface scattering approximation." );
  216. addField("glow", TypeBool, Offset(mGlow, Material), MAX_STAGES,
  217. "Enables rendering this material to the glow buffer." );
  218. addField("emissive", TypeBool, Offset(mEmissive, Material), MAX_STAGES,
  219. "Enables emissive lighting for the material." );
  220. addField("doubleSided", TypeBool, Offset(mDoubleSided, Material),
  221. "Disables backface culling casing surfaces to be double sided. "
  222. "Note that the lighting on the backside will be a mirror of the front "
  223. "side of the surface." );
  224. addField("animFlags", TYPEID< AnimType >(), Offset(mAnimFlags, Material), MAX_STAGES,
  225. "The types of animation to play on this material." );
  226. addField("scrollDir", TypePoint2F, Offset(mScrollDir, Material), MAX_STAGES,
  227. "The scroll direction in UV space when scroll animation is enabled." );
  228. addField("scrollSpeed", TypeF32, Offset(mScrollSpeed, Material), MAX_STAGES,
  229. "The speed to scroll the texture in UVs per second when scroll animation is enabled." );
  230. addField("rotSpeed", TypeF32, Offset(mRotSpeed, Material), MAX_STAGES,
  231. "The speed to rotate the texture in degrees per second when rotation animation is enabled." );
  232. addField("rotPivotOffset", TypePoint2F, Offset(mRotPivotOffset, Material), MAX_STAGES,
  233. "The piviot position in UV coordinates to center the rotation animation." );
  234. addField("waveType", TYPEID< WaveType >(), Offset(mWaveType, Material), MAX_STAGES,
  235. "The type of wave animation to perform when wave animation is enabled." );
  236. addField("waveFreq", TypeF32, Offset(mWaveFreq, Material), MAX_STAGES,
  237. "The wave frequency when wave animation is enabled." );
  238. addField("waveAmp", TypeF32, Offset(mWaveAmp, Material), MAX_STAGES,
  239. "The wave amplitude when wave animation is enabled." );
  240. addField("sequenceFramePerSec", TypeF32, Offset(mSeqFramePerSec, Material), MAX_STAGES,
  241. "The number of frames per second for frame based sequence animations if greater than zero." );
  242. addField("sequenceSegmentSize", TypeF32, Offset(mSeqSegSize, Material), MAX_STAGES,
  243. "The size of each frame in UV units for sequence animations." );
  244. // Texture atlasing
  245. addField("cellIndex", TypePoint2I, Offset(mCellIndex, Material), MAX_STAGES,
  246. "@internal" );
  247. addField("cellLayout", TypePoint2I, Offset(mCellLayout, Material), MAX_STAGES,
  248. "@internal");
  249. addField("cellSize", TypeS32, Offset(mCellSize, Material), MAX_STAGES,
  250. "@internal");
  251. addField("bumpAtlas", TypeBool, Offset(mNormalMapAtlas, Material), MAX_STAGES,
  252. "@internal");
  253. // For backwards compatibility.
  254. //
  255. // They point at the new 'map' fields, but reads always return
  256. // an empty string and writes only apply if the value is not empty.
  257. //
  258. addProtectedField("baseTex", TypeImageFilename, Offset(mDiffuseMapFilename, Material),
  259. defaultProtectedSetNotEmptyFn, emptyStringProtectedGetFn, MAX_STAGES,
  260. "For backwards compatibility.\n@see diffuseMap\n" );
  261. addProtectedField("detailTex", TypeImageFilename, Offset(mDetailMapFilename, Material),
  262. defaultProtectedSetNotEmptyFn, emptyStringProtectedGetFn, MAX_STAGES,
  263. "For backwards compatibility.\n@see detailMap\n");
  264. addProtectedField("overlayTex", TypeImageFilename, Offset(mOverlayMapFilename, Material),
  265. defaultProtectedSetNotEmptyFn, emptyStringProtectedGetFn, MAX_STAGES,
  266. "For backwards compatibility.\n@see overlayMap\n");
  267. addProtectedField("bumpTex", TypeImageFilename, Offset(mNormalMapFilename, Material),
  268. defaultProtectedSetNotEmptyFn, emptyStringProtectedGetFn, MAX_STAGES,
  269. "For backwards compatibility.\n@see normalMap\n");
  270. addProtectedField("envTex", TypeImageFilename, Offset(mEnvMapFilename, Material),
  271. defaultProtectedSetNotEmptyFn, emptyStringProtectedGetFn, MAX_STAGES,
  272. "For backwards compatibility.\n@see envMap\n");
  273. addProtectedField("colorMultiply", TypeColorF, Offset(mDiffuse, Material),
  274. defaultProtectedSetNotEmptyFn, emptyStringProtectedGetFn, MAX_STAGES,
  275. "For backwards compatibility.\n@see diffuseColor\n");
  276. endArray( "Stages" );
  277. addField( "castShadows", TypeBool, Offset(mCastShadows, Material),
  278. "If set to false the lighting system will not cast shadows from this material." );
  279. addField("planarReflection", TypeBool, Offset(mPlanarReflection, Material), "@internal" );
  280. addField("translucent", TypeBool, Offset(mTranslucent, Material),
  281. "If true this material is translucent blended." );
  282. addField("translucentBlendOp", TYPEID< BlendOp >(), Offset(mTranslucentBlendOp, Material),
  283. "The type of blend operation to use when the material is translucent." );
  284. addField("translucentZWrite", TypeBool, Offset(mTranslucentZWrite, Material),
  285. "If enabled and the material is translucent it will write into the depth buffer." );
  286. addField("alphaTest", TypeBool, Offset(mAlphaTest, Material),
  287. "Enables alpha test when rendering the material.\n@see alphaRef\n" );
  288. addField("alphaRef", TypeS32, Offset(mAlphaRef, Material),
  289. "The alpha reference value for alpha testing. Must be between 0 to 255.\n@see alphaTest\n" );
  290. addField("cubemap", TypeRealString, Offset(mCubemapName, Material),
  291. "The name of a CubemapData for environment mapping." );
  292. addField("dynamicCubemap", TypeBool, Offset(mDynamicCubemap, Material),
  293. "Enables the material to use the dynamic cubemap from the ShapeBase object its applied to." );
  294. addGroup( "Behavioral" );
  295. addField( "showFootprints", TypeBool, Offset( mShowFootprints, Material ),
  296. "Whether to show player footprint decals on this material.\n\n"
  297. "@see PlayerData::decalData" );
  298. addField( "showDust", TypeBool, Offset( mShowDust, Material ),
  299. "Whether to emit dust particles from a shape moving over the material. This is, for example, used by "
  300. "vehicles or players to decide whether to show dust trails." );
  301. addField( "effectColor", TypeColorF, Offset( mEffectColor, Material ), NUM_EFFECT_COLOR_STAGES,
  302. "If #showDust is true, this is the set of colors to use for the ParticleData of the dust "
  303. "emitter.\n\n"
  304. "@see ParticleData::colors" );
  305. addField( "footstepSoundId", TypeS32, Offset( mFootstepSoundId, Material ),
  306. "What sound to play from the PlayerData sound list when the player walks over the material. -1 (default) to not play any sound.\n"
  307. "\n"
  308. "The IDs are:\n\n"
  309. "- 0: PlayerData::FootSoftSound\n"
  310. "- 1: PlayerData::FootHardSound\n"
  311. "- 2: PlayerData::FootMetalSound\n"
  312. "- 3: PlayerData::FootSnowSound\n"
  313. "- 4: PlayerData::FootShallowSound\n"
  314. "- 5: PlayerData::FootWadingSound\n"
  315. "- 6: PlayerData::FootUnderwaterSound\n"
  316. "- 7: PlayerData::FootBubblesSound\n"
  317. "- 8: PlayerData::movingBubblesSound\n"
  318. "- 9: PlayerData::waterBreathSound\n"
  319. "- 10: PlayerData::impactSoftSound\n"
  320. "- 11: PlayerData::impactHardSound\n"
  321. "- 12: PlayerData::impactMetalSound\n"
  322. "- 13: PlayerData::impactSnowSound\n"
  323. "- 14: PlayerData::impactWaterEasy\n"
  324. "- 15: PlayerData::impactWaterMedium\n"
  325. "- 16: PlayerData::impactWaterHard\n"
  326. "- 17: PlayerData::exitingWater\n" );
  327. addField( "customFootstepSound", TypeSFXTrackName, Offset( mFootstepSoundCustom, Material ),
  328. "The sound to play when the player walks over the material. If this is set, it overrides #footstepSoundId. This field is "
  329. "useful for directly assigning custom footstep sounds to materials without having to rely on the PlayerData sound assignment.\n\n"
  330. "@warn Be aware that materials are client-side objects. This means that the SFXTracks assigned to materials must be client-side, too." );
  331. addField( "impactSoundId", TypeS32, Offset( mImpactSoundId, Material ),
  332. "What sound to play from the PlayerData sound list when the player impacts on the surface with a velocity equal or greater "
  333. "than PlayerData::groundImpactMinSpeed.\n\n"
  334. "For a list of IDs, see #footstepSoundId" );
  335. addField( "customImpactSound", TypeSFXTrackName, Offset( mImpactSoundCustom, Material ),
  336. "The sound to play when the player impacts on the surface with a velocity equal or greater than PlayerData::groundImpactMinSpeed. "
  337. "If this is set, it overrides #impactSoundId. This field is useful for directly assigning custom impact sounds to materials "
  338. "without having to rely on the PlayerData sound assignment.\n\n"
  339. "@warn Be aware that materials are client-side objects. This means that the SFXTracks assigned to materials must be client-side, too." );
  340. //Deactivate these for the moment as they are not used.
  341. #if 0
  342. addField( "friction", TypeF32, Offset( mFriction, Material ) );
  343. addField( "directSoundOcclusion", TypeF32, Offset( mDirectSoundOcclusion, Material ) );
  344. addField( "reverbSoundOcclusion", TypeF32, Offset( mReverbSoundOcclusion, Material ) );
  345. #endif
  346. endGroup( "Behavioral" );
  347. Parent::initPersistFields();
  348. }
  349. bool Material::writeField( StringTableEntry fieldname, const char *value )
  350. {
  351. // Never allow the old field names to be written.
  352. if ( fieldname == StringTable->insert("baseTex") ||
  353. fieldname == StringTable->insert("detailTex") ||
  354. fieldname == StringTable->insert("overlayTex") ||
  355. fieldname == StringTable->insert("bumpTex") ||
  356. fieldname == StringTable->insert("envTex") ||
  357. fieldname == StringTable->insert("colorMultiply") )
  358. return false;
  359. return Parent::writeField( fieldname, value );
  360. }
  361. bool Material::onAdd()
  362. {
  363. if (Parent::onAdd() == false)
  364. return false;
  365. mCubemapData = dynamic_cast<CubemapData*>(Sim::findObject( mCubemapName ) );
  366. if( mTranslucentBlendOp >= NumBlendTypes || mTranslucentBlendOp < 0 )
  367. {
  368. Con::errorf( "Invalid blend op in material: %s", getName() );
  369. mTranslucentBlendOp = LerpAlpha;
  370. }
  371. SimSet *matSet = MATMGR->getMaterialSet();
  372. if( matSet )
  373. matSet->addObject( (SimObject*)this );
  374. // save the current script path for texture lookup later
  375. const String scriptFile = Con::getVariable("$Con::File"); // current script file - local materials.cs
  376. String::SizeType slash = scriptFile.find( '/', scriptFile.length(), String::Right );
  377. if ( slash != String::NPos )
  378. mPath = scriptFile.substr( 0, slash + 1 );
  379. _mapMaterial();
  380. return true;
  381. }
  382. void Material::onRemove()
  383. {
  384. smNormalizeCube = NULL;
  385. Parent::onRemove();
  386. }
  387. void Material::inspectPostApply()
  388. {
  389. Parent::inspectPostApply();
  390. // Reload the material instances which
  391. // use this material.
  392. if ( isProperlyAdded() )
  393. reload();
  394. }
  395. bool Material::isLightmapped() const
  396. {
  397. bool ret = false;
  398. for( U32 i=0; i<MAX_STAGES; i++ )
  399. ret |= mLightMapFilename[i].isNotEmpty() || mToneMapFilename[i].isNotEmpty() || mVertLit[i];
  400. return ret;
  401. }
  402. void Material::updateTimeBasedParams()
  403. {
  404. U32 lastTime = MATMGR->getLastUpdateTime();
  405. F32 dt = MATMGR->getDeltaTime();
  406. if (mLastUpdateTime != lastTime)
  407. {
  408. for (U32 i = 0; i < MAX_STAGES; i++)
  409. {
  410. mScrollOffset[i] += mScrollDir[i] * mScrollSpeed[i] * dt;
  411. mRotPos[i] += mRotSpeed[i] * dt;
  412. mWavePos[i] += mWaveFreq[i] * dt;
  413. }
  414. mLastUpdateTime = lastTime;
  415. }
  416. }
  417. void Material::_mapMaterial()
  418. {
  419. if( String(getName()).isEmpty() )
  420. {
  421. Con::warnf( "[Material::mapMaterial] - Cannot map unnamed Material" );
  422. return;
  423. }
  424. // If mapTo not defined in script, try to use the base texture name instead
  425. if( mMapTo.isEmpty() )
  426. {
  427. if ( mDiffuseMapFilename[0].isEmpty() )
  428. return;
  429. else
  430. {
  431. // extract filename from base texture
  432. if ( mDiffuseMapFilename[0].isNotEmpty() )
  433. {
  434. U32 slashPos = mDiffuseMapFilename[0].find('/',0,String::Right);
  435. if (slashPos == String::NPos)
  436. // no '/' character, must be no path, just the filename
  437. mMapTo = mDiffuseMapFilename[0];
  438. else
  439. // use everything after the last slash
  440. mMapTo = mDiffuseMapFilename[0].substr(slashPos+1, mDiffuseMapFilename[0].length() - slashPos - 1);
  441. }
  442. }
  443. }
  444. // add mapping
  445. MATMGR->mapMaterial(mMapTo,getName());
  446. }
  447. BaseMatInstance* Material::createMatInstance()
  448. {
  449. return new MatInstance(*this);
  450. }
  451. void Material::flush()
  452. {
  453. MATMGR->flushInstance( this );
  454. }
  455. void Material::reload()
  456. {
  457. MATMGR->reInitInstance( this );
  458. }
  459. void Material::StageData::getFeatureSet( FeatureSet *outFeatures ) const
  460. {
  461. TextureTable::ConstIterator iter = mTextures.begin();
  462. for ( ; iter != mTextures.end(); iter++ )
  463. {
  464. if ( iter->value.isValid() )
  465. outFeatures->addFeature( *iter->key );
  466. }
  467. }
  468. ConsoleMethod( Material, flush, void, 2, 2,
  469. "Flushes all material instances that use this material." )
  470. {
  471. object->flush();
  472. }
  473. ConsoleMethod( Material, reload, void, 2, 2,
  474. "Reloads all material instances that use this material." )
  475. {
  476. object->reload();
  477. }
  478. ConsoleMethod( Material, dumpInstances, void, 2, 2,
  479. "Dumps a formatted list of the currently allocated material instances for this material to the console." )
  480. {
  481. MATMGR->dumpMaterialInstances( object );
  482. }
  483. ConsoleMethod( Material, getAnimFlags, const char*, 3, 3, "" )
  484. {
  485. char * animFlags = Con::getReturnBuffer(512);
  486. if(object->mAnimFlags[ dAtoi(argv[2]) ] & Material::Scroll)
  487. {
  488. if(dStrcmp( animFlags, "" ) == 0)
  489. dStrcpy( animFlags, "$Scroll" );
  490. }
  491. if(object->mAnimFlags[ dAtoi(argv[2]) ] & Material::Rotate)
  492. {
  493. if(dStrcmp( animFlags, "" ) == 0)
  494. dStrcpy( animFlags, "$Rotate" );
  495. else
  496. dStrcat( animFlags, " | $Rotate");
  497. }
  498. if(object->mAnimFlags[ dAtoi(argv[2]) ] & Material::Wave)
  499. {
  500. if(dStrcmp( animFlags, "" ) == 0)
  501. dStrcpy( animFlags, "$Wave" );
  502. else
  503. dStrcat( animFlags, " | $Wave");
  504. }
  505. if(object->mAnimFlags[ dAtoi(argv[2]) ] & Material::Scale)
  506. {
  507. if(dStrcmp( animFlags, "" ) == 0)
  508. dStrcpy( animFlags, "$Scale" );
  509. else
  510. dStrcat( animFlags, " | $Scale");
  511. }
  512. if(object->mAnimFlags[ dAtoi(argv[2]) ] & Material::Sequence)
  513. {
  514. if(dStrcmp( animFlags, "" ) == 0)
  515. dStrcpy( animFlags, "$Sequence" );
  516. else
  517. dStrcat( animFlags, " | $Sequence");
  518. }
  519. return animFlags;
  520. }
  521. ConsoleMethod(Material, getFilename, const char*, 2, 2, "Get filename of material")
  522. {
  523. SimObject *material = static_cast<SimObject *>(object);
  524. return material->getFilename();
  525. }
  526. ConsoleMethod( Material, isAutoGenerated, bool, 2, 2,
  527. "Returns true if this Material was automatically generated by MaterialList::mapMaterials()" )
  528. {
  529. return object->isAutoGenerated();
  530. }
  531. ConsoleMethod( Material, setAutoGenerated, void, 3, 3,
  532. "setAutoGenerated(bool isAutoGenerated): Set whether or not the Material is autogenerated." )
  533. {
  534. object->setAutoGenerated(dAtob(argv[2]));
  535. }