lightBase.cpp

Engine/source/T3D/lightBase.cpp

More...

Public Variables

_lbplayAnimation1 ("@brief Plays the light animation assigned to this light with the existing LightAnimData datablock.\n\n" "@tsexample\n" "// Play the animation assigned to this light\n" "CrystalLight.playAnimation();\n" "@endtsexample\n\n", "LightBase", "void playAnimation();")
_lbplayAnimation2 ("@brief Plays the light animation on this light using a new LightAnimData. If no LightAnimData " "is passed the existing one is played.\n\n" "@param anim Name of the LightAnimData datablock to be played\n\n" "@tsexample\n" "// Play the animation using a new LightAnimData datablock\n" "CrystalLight.playAnimation(SubtlePulseLightAnim);\n" "@endtsexample\n\n", "LightBase", "void playAnimation(LightAnimData anim);")
bool

For frame signal.

Public Functions

ConsoleDocClass(LightBase , "@brief This is the base class <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> light <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">objects.\n\n</a>" "It is *NOT* intended <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be used directly in script, but exists <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> provide the base member variables " "and generic functionality. You should be using the derived classes <a href="/coding/class/classpointlight/">PointLight</a> and SpotLight, which " "can be declared in TorqueScript or added from the <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a81f4537631c9ab219ec74de554483adc">World</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Editor.\n\n</a>" "For this class, we only add basic lighting options that all lighting systems would use. " "The specific lighting system options are injected at runtime by the lighting system <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">itself.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">PointLight\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SpotLight\n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Lighting\n</a>" )
DefineEngineMethod(LightBase , pauseAnimation , void , () , "Stops the light animation." )
DefineEngineMethod(LightBase , playAnimation , void , (const char *anim) , ("") , "( [LightAnimData anim] )\<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1aded116371789db1fd63c90ef00c95a3d">t</a>" "Plays <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> light animation on the light. If no <a href="/coding/class/classlightanimdata/">LightAnimData</a> is passed the " "existing one is played." "@hide" )
DefineEngineMethod(LightBase , setLightEnabled , void , (bool state) , "@brief Toggles the light on and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">off\n\n</a>" "@param state Turns the light on (true) or off (false)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Disable the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">light\n</a>" "CrystalLight.setLightEnabled(false);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Renable the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">light\n</a>" "CrystalLight.setLightEnabled(true);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" )

Detailed Description

Public Variables

ConsoleDocFragment _lbplayAnimation1 ("@brief Plays the light animation assigned to this light with the existing LightAnimData datablock.\n\n" "@tsexample\n" "// Play the animation assigned to this light\n" "CrystalLight.playAnimation();\n" "@endtsexample\n\n", "LightBase", "void playAnimation();")
ConsoleDocFragment _lbplayAnimation2 ("@brief Plays the light animation on this light using a new LightAnimData. If no LightAnimData " "is passed the existing one is played.\n\n" "@param anim Name of the LightAnimData datablock to be played\n\n" "@tsexample\n" "// Play the animation using a new LightAnimData datablock\n" "CrystalLight.playAnimation(SubtlePulseLightAnim);\n" "@endtsexample\n\n", "LightBase", "void playAnimation(LightAnimData anim);")
bool gEditingMission 

For frame signal.

Public Functions

ConsoleDocClass(LightBase , "@brief This is the base class <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> light <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">objects.\n\n</a>" "It is *NOT* intended <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be used directly in script, but exists <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> provide the base member variables " "and generic functionality. You should be using the derived classes <a href="/coding/class/classpointlight/">PointLight</a> and SpotLight, which " "can be declared in TorqueScript or added from the <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a81f4537631c9ab219ec74de554483adc">World</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Editor.\n\n</a>" "For this class, we only add basic lighting options that all lighting systems would use. " "The specific lighting system options are injected at runtime by the lighting system <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">itself.\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">PointLight\n\n</a>" " @see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SpotLight\n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Lighting\n</a>" )

DefineEngineMethod(LightBase , pauseAnimation , void , () , "Stops the light animation." )

DefineEngineMethod(LightBase , playAnimation , void , (const char *anim) , ("") , "( [LightAnimData anim] )\<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1aded116371789db1fd63c90ef00c95a3d">t</a>" "Plays <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> light animation on the light. If no <a href="/coding/class/classlightanimdata/">LightAnimData</a> is passed the " "existing one is played." "@hide" )

DefineEngineMethod(LightBase , setLightEnabled , void , (bool state) , "@brief Toggles the light on and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">off\n\n</a>" "@param state Turns the light on (true) or off (false)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Disable the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">light\n</a>" "CrystalLight.setLightEnabled(false);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Renable the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">light\n</a>" "CrystalLight.setLightEnabled(true);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" )

IMPLEMENT_CONOBJECT(LightBase )

  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//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 25// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
 26// Copyright (C) 2015 Faust Logic, Inc.
 27//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 28
 29#include "platform/platform.h"
 30#include "T3D/lightBase.h"
 31
 32#include "console/consoleTypes.h"
 33#include "console/typeValidators.h"
 34#include "core/stream/bitStream.h"
 35#include "sim/netConnection.h"
 36#include "lighting/lightManager.h"
 37#include "lighting/shadowMap/lightShadowMap.h"
 38#include "scene/sceneRenderState.h"
 39#include "renderInstance/renderPassManager.h"
 40#include "console/engineAPI.h"
 41#include "gfx/gfxDrawUtil.h"
 42
 43extern bool gEditingMission;
 44
 45bool LightBase::smRenderViz = false;
 46
 47IMPLEMENT_CONOBJECT( LightBase );
 48
 49ConsoleDocClass( LightBase,
 50   "@brief This is the base class for light objects.\n\n"
 51
 52   "It is *NOT* intended to be used directly in script, but exists to provide the base member variables "
 53   "and generic functionality. You should be using the derived classes PointLight and SpotLight, which "
 54   "can be declared in TorqueScript or added from the World Editor.\n\n"
 55
 56   "For this class, we only add basic lighting options that all lighting systems would use. "
 57   "The specific lighting system options are injected at runtime by the lighting system itself.\n\n"
 58
 59   "@see PointLight\n\n"
 60   "@see SpotLight\n\n"
 61   "@ingroup Lighting\n"
 62);
 63
 64LightBase::LightBase()
 65   :  mIsEnabled( true ),
 66      mColor( LinearColorF::WHITE ),
 67      mBrightness( 1.0f ),
 68      mCastShadows( false ),
 69      mStaticRefreshFreq( 250 ),
 70      mDynamicRefreshFreq( 8 ),
 71      mPriority( 1.0f ),
 72      mAnimationData( NULL ),      
 73      mFlareData( NULL ),
 74      mFlareScale( 1.0f )
 75{
 76   mNetFlags.set( Ghostable | ScopeAlways );
 77   mTypeMask = LightObjectType;
 78
 79   mLight = LightManager::createLightInfo();
 80
 81   mFlareState.clear();
 82   mLocalRenderViz = false;
 83}
 84
 85LightBase::~LightBase()
 86{
 87   SAFE_DELETE( mLight );
 88}
 89
 90void LightBase::initPersistFields()
 91{
 92   // We only add the basic lighting options that all lighting
 93   // systems would use... the specific lighting system options
 94   // are injected at runtime by the lighting system itself.
 95
 96   addGroup( "Light" );
 97      
 98      addField( "isEnabled", TypeBool, Offset( mIsEnabled, LightBase ), "Enables/Disables the object rendering and functionality in the scene." );
 99      addField( "color", TypeColorF, Offset( mColor, LightBase ), "Changes the base color hue of the light." );
100      addField( "brightness", TypeF32, Offset( mBrightness, LightBase ), "Adjusts the lights power, 0 being off completely." );      
101      addField( "castShadows", TypeBool, Offset( mCastShadows, LightBase ), "Enables/disabled shadow casts by this light." );
102      //addField( "staticRefreshFreq", TypeS32, Offset( mStaticRefreshFreq, LightBase ), "static shadow refresh rate (milliseconds)" );
103      //addField( "dynamicRefreshFreq", TypeS32, Offset( mDynamicRefreshFreq, LightBase ), "dynamic shadow refresh rate (milliseconds)");
104      addField( "priority", TypeF32, Offset( mPriority, LightBase ), "Used for sorting of lights by the light manager. "
105        "Priority determines if a light has a stronger effect than, those with a lower value" );
106
107   endGroup( "Light" );
108
109   addGroup( "Light Animation" );
110
111      addField( "animate", TypeBool, Offset( mAnimState.active, LightBase ), "Toggles animation for the light on and off" );
112      addField( "animationType", TYPEID< LightAnimData >(), Offset( mAnimationData, LightBase ), "Datablock containing light animation information (LightAnimData)" );
113      addFieldV( "animationPeriod", TypeF32, Offset( mAnimState.animationPeriod, LightBase ), &CommonValidators::PositiveNonZeroFloat, "The length of time in seconds for a single playback of the light animation (must be > 0)" );
114      addField( "animationPhase", TypeF32, Offset( mAnimState.animationPhase, LightBase ), "The phase used to offset the animation start time to vary the animation of nearby lights." );      
115
116   endGroup( "Light Animation" );
117
118   addGroup( "Misc" );
119
120      addField( "flareType", TYPEID< LightFlareData >(), Offset( mFlareData, LightBase ), "Datablock containing light flare information (LightFlareData)" );
121      addField( "flareScale", TypeF32, Offset( mFlareScale, LightBase ), "Globally scales all features of the light flare" );
122
123   endGroup( "Misc" );
124
125   // Now inject any light manager specific fields.
126   LightManager::initLightFields();
127
128   // We do the parent fields at the end so that
129   // they show up that way in the inspector.
130   Parent::initPersistFields();
131
132   Con::addVariable( "$Light::renderViz", TypeBool, &smRenderViz,
133      "Toggles visualization of light object's radius or cone.\n"
134      "@ingroup Lighting");
135
136   Con::addVariable( "$Light::renderLightFrustums", TypeBool, &LightShadowMap::smDebugRenderFrustums,
137      "Toggles rendering of light frustums when the light is selected in the editor.\n\n"
138      "@note Only works for shadow mapped lights.\n\n"
139      "@ingroup Lighting" );
140}
141
142bool LightBase::onAdd()
143{
144   if ( !Parent::onAdd() )
145      return false;
146
147   // Update the light parameters.
148   _conformLights();
149   addToScene();
150
151   return true;
152}
153
154void LightBase::onRemove()
155{
156   removeFromScene();
157   Parent::onRemove();
158}
159
160void LightBase::submitLights( LightManager *lm, bool staticLighting )
161{
162   if ( !mIsEnabled || staticLighting )
163      return;
164
165   if (  mAnimState.active && 
166         mAnimState.animationPeriod > 0.0f &&
167         mAnimationData )
168   {
169      mAnimState.brightness = mBrightness;
170      mAnimState.transform = getRenderTransform();
171      mAnimState.color = mColor;
172
173      mAnimationData->animate( mLight, &mAnimState );
174   }
175
176   lm->registerGlobalLight( mLight, this );
177}
178
179void LightBase::inspectPostApply()
180{
181   // We do not call the parent here as it 
182   // will call setScale() and screw up the 
183   // real sizing fields on the light.
184
185   // Ok fine... then we must set MountedMask ourself.
186
187   _conformLights();
188   setMaskBits( EnabledMask | UpdateMask | TransformMask | DatablockMask | MountedMask );
189}
190
191void LightBase::setTransform( const MatrixF &mat )
192{
193   setMaskBits( TransformMask );
194   Parent::setTransform( mat );
195}
196
197void LightBase::prepRenderImage( SceneRenderState *state )
198{
199   if ( mIsEnabled && mFlareData )
200   {
201      mFlareState.fullBrightness = mBrightness;
202      mFlareState.scale = mFlareScale;
203      mFlareState.lightInfo = mLight;
204      mFlareState.lightMat = getRenderTransform();
205
206      mFlareData->prepRender( state, &mFlareState );
207   }
208
209   if ( !state->isDiffusePass() )
210      return;
211
212   const bool isSelectedInEditor = ( gEditingMission && isSelected() );
213
214   // If the light is selected or light visualization
215   // is enabled then register the callback.
216   if ( mLocalRenderViz || smRenderViz || isSelectedInEditor )
217   {
218      ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
219      ri->renderDelegate.bind( this, &LightBase::_onRenderViz );
220      ri->type = RenderPassManager::RIT_Editor;
221      state->getRenderPass()->addInst( ri );
222   }
223}
224
225void LightBase::_onRenderViz( ObjectRenderInst *ri, 
226                              SceneRenderState *state, 
227                              BaseMatInstance *overrideMat )
228{
229   if ( overrideMat )
230      return;
231   
232   _renderViz( state );
233}
234
235void LightBase::_onSelected()
236{
237   #ifdef TORQUE_DEBUG
238   // Enable debug rendering on the light.
239   if( isClientObject() )
240      mLight->enableDebugRendering( true );
241   #endif
242
243   Parent::_onSelected();
244}
245
246void LightBase::_onUnselected()
247{
248   #ifdef TORQUE_DEBUG
249   // Disable debug rendering on the light.
250   if( isClientObject() )
251      mLight->enableDebugRendering( false );
252   #endif
253
254   Parent::_onUnselected();
255}
256
257void LightBase::interpolateTick( F32 delta )
258{
259}
260
261void LightBase::processTick()
262{
263}
264
265void LightBase::advanceTime( F32 timeDelta )
266{
267   if ( isMounted() )
268   {
269      MatrixF mat( true );
270      mMount.object->getRenderMountTransform( 0.f, mMount.node, mMount.xfm, &mat );
271      mLight->setTransform( mat );
272      Parent::setTransform( mat );
273   }
274}
275
276U32 LightBase::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
277{
278   U32 retMask = Parent::packUpdate( conn, mask, stream );
279
280   stream->writeFlag( mIsEnabled );
281
282   if ( stream->writeFlag( mask & TransformMask ) )
283      stream->writeAffineTransform( mObjToWorld );
284
285   if ( stream->writeFlag( mask & UpdateMask ) )
286   {
287      stream->write( mColor );
288      stream->write( mBrightness );
289
290      stream->writeFlag( mCastShadows );
291      stream->write(mStaticRefreshFreq);
292      stream->write(mDynamicRefreshFreq);
293
294      stream->write( mPriority );      
295
296      mLight->packExtended( stream ); 
297
298      stream->writeFlag( mAnimState.active );
299      stream->write( mAnimState.animationPeriod );
300      stream->write( mAnimState.animationPhase );
301      stream->write( mFlareScale );
302   }
303
304   if ( stream->writeFlag( mask & DatablockMask ) )
305   {
306      if ( stream->writeFlag( mAnimationData ) )
307      {
308         stream->writeRangedU32( mAnimationData->getId(),
309                                 DataBlockObjectIdFirst, 
310                                 DataBlockObjectIdLast );
311      }
312
313      if ( stream->writeFlag( mFlareData ) )
314      {
315         stream->writeRangedU32( mFlareData->getId(),
316                                 DataBlockObjectIdFirst, 
317                                 DataBlockObjectIdLast );
318      }
319   }
320
321   return retMask;
322}
323
324void LightBase::unpackUpdate( NetConnection *conn, BitStream *stream )
325{
326   Parent::unpackUpdate( conn, stream );
327
328   mIsEnabled = stream->readFlag();
329
330   if ( stream->readFlag() ) // TransformMask
331      stream->readAffineTransform( &mObjToWorld );
332
333   if ( stream->readFlag() ) // UpdateMask
334   {   
335      stream->read( &mColor );
336      stream->read( &mBrightness );      
337      mCastShadows = stream->readFlag();
338      stream->read(&mStaticRefreshFreq);
339      stream->read(&mDynamicRefreshFreq);
340
341      stream->read( &mPriority );      
342      
343      mLight->unpackExtended( stream );
344
345      mAnimState.active = stream->readFlag();
346      stream->read( &mAnimState.animationPeriod );
347      stream->read( &mAnimState.animationPhase );
348      stream->read( &mFlareScale );
349   }
350
351   if ( stream->readFlag() ) // DatablockMask
352   {
353      if ( stream->readFlag() )
354      {
355         SimObjectId id = stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast );  
356         LightAnimData *datablock = NULL;
357         
358         if ( Sim::findObject( id, datablock ) )
359            mAnimationData = datablock;
360         else
361         {
362            conn->setLastError( "Light::unpackUpdate() - invalid LightAnimData!" );
363            mAnimationData = NULL;
364         }
365      }
366      else
367         mAnimationData = NULL;
368
369      if ( stream->readFlag() )
370      {
371         SimObjectId id = stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast );  
372         LightFlareData *datablock = NULL;
373
374         if ( Sim::findObject( id, datablock ) )
375            mFlareData = datablock;
376         else
377         {
378            conn->setLastError( "Light::unpackUpdate() - invalid LightCoronaData!" );
379            mFlareData = NULL;
380         }
381      }
382      else
383         mFlareData = NULL;
384   }
385   
386   if ( isProperlyAdded() )
387      _conformLights();
388}
389
390void LightBase::setLightEnabled( bool enabled )
391{
392   if ( mIsEnabled != enabled )
393   {
394      mIsEnabled = enabled;
395      setMaskBits( EnabledMask );
396   }
397}
398
399DefineEngineMethod( LightBase, setLightEnabled, void, ( bool state ),,
400   "@brief Toggles the light on and off\n\n"
401   
402   "@param state Turns the light on (true) or off (false)\n"
403
404   "@tsexample\n"
405   "// Disable the light\n"
406   "CrystalLight.setLightEnabled(false);\n\n"
407   "// Renable the light\n"
408   "CrystalLight.setLightEnabled(true);\n"
409   
410   "@endtsexample\n\n"
411)
412{
413  object->setLightEnabled( state );
414}
415
416//ConsoleMethod( LightBase, setLightEnabled, void, 3, 3, "( bool enabled )\t"
417//   "Toggles the light on and off." )
418//{
419//   object->setLightEnabled( dAtob( argv[2] ) );
420//}
421
422static ConsoleDocFragment _lbplayAnimation1(
423   "@brief Plays the light animation assigned to this light with the existing LightAnimData datablock.\n\n"
424   
425   "@tsexample\n"
426   "// Play the animation assigned to this light\n"
427   "CrystalLight.playAnimation();\n"
428   "@endtsexample\n\n",
429   "LightBase",
430   "void playAnimation();"
431);
432static ConsoleDocFragment _lbplayAnimation2(
433   "@brief Plays the light animation on this light using a new LightAnimData. If no LightAnimData "
434   "is passed the existing one is played.\n\n"
435   "@param anim Name of the LightAnimData datablock to be played\n\n"
436   "@tsexample\n"
437   "// Play the animation using a new LightAnimData datablock\n"
438   "CrystalLight.playAnimation(SubtlePulseLightAnim);\n"
439   "@endtsexample\n\n",
440   "LightBase",
441   "void playAnimation(LightAnimData anim);"
442);
443
444DefineEngineMethod( LightBase, playAnimation, void, (const char * anim), (""), "( [LightAnimData anim] )\t"
445   "Plays a light animation on the light.  If no LightAnimData is passed the "
446   "existing one is played."
447   "@hide")
448{
449   if ( String::isEmpty(anim) )
450    {
451        object->playAnimation();
452        return;
453    }
454
455    LightAnimData *animData;
456    if ( !Sim::findObject( anim, animData ) )
457    {
458        Con::errorf( "LightBase::playAnimation() - Invalid LightAnimData '%s'.", anim );
459        return;
460    }
461
462    // Play Animation.
463    object->playAnimation( animData );
464}
465
466void LightBase::playAnimation( void )
467{
468    if ( !mAnimState.active )
469    {
470        mAnimState.active = true;
471        setMaskBits( UpdateMask );
472    }
473}
474
475void LightBase::playAnimation( LightAnimData *animData )
476{
477    // Play Animation.
478    playAnimation();
479
480    // Update Datablock?
481    if ( mAnimationData != animData )
482    {
483        mAnimationData = animData;
484        setMaskBits( DatablockMask );
485    }
486}
487
488DefineEngineMethod( LightBase, pauseAnimation, void, (), , "Stops the light animation." )
489{
490    object->pauseAnimation();
491}
492
493void LightBase::pauseAnimation( void )
494{
495    if ( mAnimState.active )
496    {
497        mAnimState.active = false;
498        setMaskBits( UpdateMask );
499    }
500}
501