lightAnimData.cpp
Engine/source/T3D/lightAnimData.cpp
Public Functions
ConsoleDocClass(LightAnimData , "@brief A datablock which defines and performs light animation, such as rotation, brightness fade, and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">colorization.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "datablock <a href="/coding/class/classlightanimdata/">LightAnimData</a>(SubtlePulseLightAnim)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " brightnessA=0.5;\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " brightnessZ=1;\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " brightnessPeriod=1;\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " brightnessKeys=\"aza\";\n" " brightnessSmooth = true;\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">LightBase\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">LightDescription\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">FX\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Lighting\n</a>" )
Detailed Description
Public Functions
ConsoleDocClass(LightAnimData , "@brief A datablock which defines and performs light animation, such as rotation, brightness fade, and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">colorization.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "datablock <a href="/coding/class/classlightanimdata/">LightAnimData</a>(SubtlePulseLightAnim)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " brightnessA=0.5;\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " brightnessZ=1;\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " brightnessPeriod=1;\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " brightnessKeys=\"aza\";\n" " brightnessSmooth = true;\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">LightBase\n\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">LightDescription\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">FX\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Lighting\n</a>" )
IMPLEMENT_CO_DATABLOCK_V1(LightAnimData )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "lightAnimData.h" 26 27#include "console/consoleTypes.h" 28#include "T3D/lightBase.h" 29#include "math/mRandom.h" 30#include "math/mathIO.h" 31#include "T3D/gameBase/processList.h" 32#include "core/stream/bitStream.h" 33 34 35LightAnimData::LightAnimData() 36{ 37} 38 39LightAnimData::~LightAnimData() 40{ 41} 42 43IMPLEMENT_CO_DATABLOCK_V1( LightAnimData ); 44 45ConsoleDocClass( LightAnimData, 46 "@brief A datablock which defines and performs light animation, such as rotation, brightness fade, and colorization.\n\n" 47 48 "@tsexample\n" 49 "datablock LightAnimData( SubtlePulseLightAnim )\n" 50 "{\n" 51 " brightnessA = 0.5;\n" 52 " brightnessZ = 1;\n" 53 " brightnessPeriod = 1;\n" 54 " brightnessKeys = \"aza\";\n" 55 " brightnessSmooth = true;\n" 56 "};\n" 57 "@endtsexample\n\n" 58 "@see LightBase\n\n" 59 "@see LightDescription\n\n" 60 "@ingroup FX\n" 61 "@ingroup Lighting\n" 62); 63 64void LightAnimData::initPersistFields() 65{ 66 addGroup( "Offset", 67 "The XYZ translation animation state relative to the light position." ); 68 69 addField( "offsetA", TypeF32, Offset( mOffset.value1, LightAnimData ), 3, 70 "The value of the A key in the keyframe sequence." ); 71 72 addField( "offsetZ", TypeF32, Offset( mOffset.value2, LightAnimData ), 3, 73 "The value of the Z key in the keyframe sequence." ); 74 75 addField( "offsetPeriod", TypeF32, Offset( mOffset.period, LightAnimData ), 3, 76 "The animation time for keyframe sequence." ); 77 78 addField( "offsetKeys", TypeString, Offset( mOffset.keys, LightAnimData ), 3, 79 "The keyframe sequence encoded into a string where characters from A to Z define " 80 "a position between the two animation values." ); 81 82 addField( "offsetSmooth", TypeBool, Offset( mOffset.smooth, LightAnimData ), 3, 83 "If true the transition between keyframes will be smooth." ); 84 85 endGroup( "Offset" ); 86 87 addGroup( "Rotation", 88 "The XYZ rotation animation state relative to the light orientation." ); 89 90 addField( "rotA", TypeF32, Offset( mRot.value1, LightAnimData ), 3, 91 "The value of the A key in the keyframe sequence." ); 92 93 addField( "rotZ", TypeF32, Offset( mRot.value2, LightAnimData ), 3, 94 "The value of the Z key in the keyframe sequence." ); 95 96 addField( "rotPeriod", TypeF32, Offset( mRot.period, LightAnimData ), 3, 97 "The animation time for keyframe sequence." ); 98 99 addField( "rotKeys", TypeString, Offset( mRot.keys, LightAnimData ), 3, 100 "The keyframe sequence encoded into a string where characters from A to Z define " 101 "a position between the two animation values." ); 102 103 addField( "rotSmooth", TypeBool, Offset( mRot.smooth, LightAnimData ), 3, 104 "If true the transition between keyframes will be smooth." ); 105 106 endGroup( "Rotation" ); 107 108 addGroup( "Color", 109 "The RGB color animation state." ); 110 111 addField( "colorA", TypeF32, Offset( mColor.value1, LightAnimData ), 3, 112 "The value of the A key in the keyframe sequence." ); 113 114 addField( "colorZ", TypeF32, Offset( mColor.value2, LightAnimData ), 3, 115 "The value of the Z key in the keyframe sequence." ); 116 117 addField( "colorPeriod", TypeF32, Offset( mColor.period, LightAnimData ), 3, 118 "The animation time for keyframe sequence." ); 119 120 addField( "colorKeys", TypeString, Offset( mColor.keys, LightAnimData ), 3, 121 "The keyframe sequence encoded into a string where characters from A to Z define " 122 "a position between the two animation values." ); 123 124 addField( "colorSmooth", TypeBool, Offset( mColor.smooth, LightAnimData ), 3, 125 "If true the transition between keyframes will be smooth." ); 126 127 endGroup( "Color" ); 128 129 addGroup( "Brightness", 130 "The brightness animation state." ); 131 132 addField( "brightnessA", TypeF32, Offset( mBrightness.value1, LightAnimData ), 133 "The value of the A key in the keyframe sequence." ); 134 135 addField( "brightnessZ", TypeF32, Offset( mBrightness.value2, LightAnimData ), 136 "The value of the Z key in the keyframe sequence." ); 137 138 addField( "brightnessPeriod", TypeF32, Offset( mBrightness.period, LightAnimData ), 139 "The animation time for keyframe sequence." ); 140 141 addField( "brightnessKeys", TypeString, Offset( mBrightness.keys, LightAnimData ), 142 "The keyframe sequence encoded into a string where characters from A to Z define " 143 "a position between the two animation values." ); 144 145 addField( "brightnessSmooth", TypeBool, Offset( mBrightness.smooth, LightAnimData ), 146 "If true the transition between keyframes will be smooth." ); 147 148 endGroup( "Brightness" ); 149 150 Parent::initPersistFields(); 151} 152 153bool LightAnimData::preload( bool server, String &errorStr ) 154{ 155 if ( !Parent::preload( server, errorStr ) ) 156 return false; 157 158 _updateKeys(); 159 160 return true; 161} 162 163void LightAnimData::inspectPostApply() 164{ 165 Parent::inspectPostApply(); 166 _updateKeys(); 167} 168 169void LightAnimData::_updateKeys() 170{ 171 mOffset.updateKey(); 172 mRot.updateKey(); 173 mColor.updateKey(); 174 mBrightness.updateKey(); 175} 176 177template<U32 COUNT> 178void LightAnimData::AnimValue<COUNT>::updateKey() 179{ 180 for ( U32 i=0; i < COUNT; i++ ) 181 { 182 timeScale[i] = 0.0f; 183 keyLen[i] = 0.0f; 184 185 if ( keys[i] && keys[i][0] && period[i] > 0.0f ) 186 { 187 keyLen[i] = dStrlen( keys[i] ); 188 timeScale[i] = (F32)( keyLen[i] - 1 ) / period[i]; 189 } 190 } 191} 192 193template<U32 COUNT> 194bool LightAnimData::AnimValue<COUNT>::animate(F32 time, F32 *output, bool multiply) 195{ 196 F32 scaledTime, lerpFactor, valueRange, keyFrameLerp; 197 U32 posFrom, posTo; 198 S32 keyFrameFrom, keyFrameTo; 199 F32 initialValue = *output; 200 if (!multiply) 201 initialValue = 1; 202 203 bool wasAnimated = false; 204 205 for ( U32 i=0; i < COUNT; i++ ) 206 { 207 if ( mIsZero( timeScale[i] ) ) 208 continue; 209 210 wasAnimated = true; 211 212 scaledTime = mFmod( time, period[i] ) * timeScale[i]; 213 214 posFrom = mFloor( scaledTime ); 215 posTo = mCeil( scaledTime ); 216 217 keyFrameFrom = dToupper( keys[i][posFrom] ) - 65; 218 keyFrameTo = dToupper( keys[i][posTo] ) - 65; 219 valueRange = ( value2[i] - value1[i] ) / 25.0f; 220 221 if ( !smooth[i] ) 222 output[i] = (value1[i] + (keyFrameFrom * valueRange)) * initialValue; 223 else 224 { 225 lerpFactor = scaledTime - posFrom; 226 keyFrameLerp = ( keyFrameTo - keyFrameFrom ) * lerpFactor; 227 228 output[i] = (value1[i] + ((keyFrameFrom + keyFrameLerp) * valueRange)) * initialValue; 229 } 230 } 231 232 return wasAnimated; 233} 234 235template<U32 COUNT> 236void LightAnimData::AnimValue<COUNT>::write( BitStream *stream ) const 237{ 238 for ( U32 i=0; i < COUNT; i++ ) 239 { 240 stream->write( value1[i] ); 241 stream->write( value2[i] ); 242 stream->write( period[i] ); 243 stream->writeString( keys[i] ); 244 } 245} 246 247template<U32 COUNT> 248void LightAnimData::AnimValue<COUNT>::read( BitStream *stream ) 249{ 250 for ( U32 i=0; i < COUNT; i++ ) 251 { 252 stream->read( &value1[i] ); 253 stream->read( &value2[i] ); 254 stream->read( &period[i] ); 255 keys[i] = stream->readSTString(); 256 } 257} 258 259void LightAnimData::packData( BitStream *stream ) 260{ 261 Parent::packData( stream ); 262 263 mOffset.write( stream ); 264 mRot.write( stream ); 265 mColor.write( stream ); 266 mBrightness.write( stream ); 267} 268 269void LightAnimData::unpackData( BitStream *stream ) 270{ 271 Parent::unpackData( stream ); 272 273 mOffset.read( stream ); 274 mRot.read( stream ); 275 mColor.read( stream ); 276 mBrightness.read( stream ); 277} 278 279void LightAnimData::animate( LightInfo *lightInfo, LightAnimState *state ) 280{ 281 PROFILE_SCOPE( LightAnimData_animate ); 282 283 // Calculate the input time for animation. 284 F32 time = state->animationPhase + 285 ( (F32)Sim::getCurrentTime() * 0.001f ) / 286 state->animationPeriod; 287 288 MatrixF transform( state->transform ); 289 290 EulerF euler( Point3F::Zero ); 291 if ( mRot.animate( time, euler ) ) 292 { 293 euler.x = mDegToRad( euler.x ); 294 euler.y = mDegToRad( euler.y ); 295 euler.z = mDegToRad( euler.z ); 296 MatrixF rot( euler ); 297 transform.mul( rot ); 298 } 299 300 Point3F offset( Point3F::Zero ); 301 if ( mOffset.animate( time, offset ) ) 302 transform.displace( offset ); 303 304 lightInfo->setTransform( transform ); 305 306 LinearColorF color = state->color; 307 mColor.animate( time, color ); 308 lightInfo->setColor( color ); 309 310 F32 brightness = state->brightness; 311 mBrightness.animate( time, &brightness, true ); 312 lightInfo->setBrightness( brightness ); 313} 314