123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION 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 "T3D/lightDescription.h"
- #include "lighting/lightManager.h"
- #include "T3D/lightFlareData.h"
- #include "T3D/lightAnimData.h"
- #include "core/stream/bitStream.h"
- #include "lighting/lightInfo.h"
- #include "console/engineAPI.h"
- LightDescription::LightDescription()
- : color( LinearColorF::WHITE ),
- brightness( 1.0f ),
- range( 5.0f ),
- castShadows( false ),
- mStaticRefreshFreq( 250 ),
- mDynamicRefreshFreq( 8 ),
- animationData( NULL ),
- animationDataId( 0 ),
- animationPeriod( 1.0f ),
- animationPhase( 1.0f ),
- flareData( NULL ),
- flareDataId( 0 ),
- flareScale( 1.0f )
- {
- }
- LightDescription::~LightDescription()
- {
- }
- IMPLEMENT_CO_DATABLOCK_V1( LightDescription );
- ConsoleDocClass( LightDescription,
- "@brief A helper datablock used by classes (such as shapebase) "
- "that submit lights to the scene but do not use actual \"LightBase\" objects.\n\n"
- "This datablock stores the properties of that light as fields that can be initialized from script."
- "@tsexample\n"
- "// Declare a light description to be used on a rocket launcher projectile\n"
- "datablock LightDescription(RocketLauncherLightDesc)\n"
- "{\n"
- " range = 4.0;\n"
- " color = \"1 1 0\";\n"
- " brightness = 5.0;\n"
- " animationType = PulseLightAnim;\n"
- " animationPeriod = 0.25;\n"
- "};\n\n"
- "// Declare a ProjectileDatablock which uses the light description\n"
- "datablock ProjectileData(RocketLauncherProjectile)\n"
- "{\n"
- " lightDesc = RocketLauncherLightDesc;\n\n"
- " projectileShapeName = \"art/shapes/weapons/SwarmGun/rocket.dts\";\n\n"
- " directDamage = 30;\n"
- " radiusDamage = 30;\n"
- " damageRadius = 5;\n"
- " areaImpulse = 2500;\n\n"
- " // ... remaining ProjectileData fields not listed for this example\n"
- "};\n"
- "@endtsexample\n\n"
- "@see LightBase\n\n"
- "@ingroup Lighting\n"
- );
- void LightDescription::initPersistFields()
- {
- docsURL;
- addGroup( "Light" );
- addField( "color", TypeColorF, Offset( color, LightDescription ), "Changes the base color hue of the light." );
- addField( "brightness", TypeF32, Offset( brightness, LightDescription ), "Adjusts the lights power, 0 being off completely." );
- addField( "range", TypeF32, Offset( range, LightDescription ), "Controls the size (radius) of the light" );
- addField( "castShadows", TypeBool, Offset( castShadows, LightDescription ), "Enables/disabled shadow casts by this light." );
- addField( "staticRefreshFreq", TypeS32, Offset( mStaticRefreshFreq, LightDescription ), "static shadow refresh rate (milliseconds)" );
- addField( "dynamicRefreshFreq", TypeS32, Offset( mDynamicRefreshFreq, LightDescription ), "dynamic shadow refresh rate (milliseconds)");
- endGroup( "Light" );
- addGroup( "Light Animation" );
- addField( "animationType", TYPEID< LightAnimData >(), Offset( animationData, LightDescription ), "Datablock containing light animation information (LightAnimData)" );
- addField( "animationPeriod", TypeF32, Offset( animationPeriod, LightDescription ), "The length of time in seconds for a single playback of the light animation" );
- addField( "animationPhase", TypeF32, Offset( animationPhase, LightDescription ), "The phase used to offset the animation start time to vary the animation of nearby lights." );
- endGroup( "Light Animation" );
- addGroup( "Misc" );
- addField( "flareType", TYPEID< LightFlareData >(), Offset( flareData, LightDescription ), "Datablock containing light flare information (LightFlareData)" );
- addField( "flareScale", TypeF32, Offset( flareScale, LightDescription ), "Globally scales all features of the light flare" );
- endGroup( "Misc" );
- LightManager::initLightFields();
- Parent::initPersistFields();
- }
- void LightDescription::inspectPostApply()
- {
- Parent::inspectPostApply();
- // Hack to allow changing properties in game.
- // Do the same work as preload.
- animationData = NULL;
- flareData = NULL;
- String str;
- _preload( false, str );
- }
- bool LightDescription::onAdd()
- {
- if ( !Parent::onAdd() )
- return false;
- return true;
- }
- bool LightDescription::preload( bool server, String &errorStr )
- {
- if ( !Parent::preload( server, errorStr ) )
- return false;
- return _preload( server, errorStr );
- }
- void LightDescription::packData( BitStream *stream )
- {
- Parent::packData( stream );
- stream->write( color );
- stream->write( brightness );
- stream->write( range );
- stream->writeFlag( castShadows );
- stream->write(mStaticRefreshFreq);
- stream->write(mDynamicRefreshFreq);
- stream->write( animationPeriod );
- stream->write( animationPhase );
- stream->write( flareScale );
- if ( stream->writeFlag( animationData ) )
- {
- stream->writeRangedU32( animationData->getId(),
- DataBlockObjectIdFirst,
- DataBlockObjectIdLast );
- }
- if ( stream->writeFlag( flareData ) )
- {
- stream->writeRangedU32( flareData->getId(),
- DataBlockObjectIdFirst,
- DataBlockObjectIdLast );
- }
- }
- void LightDescription::unpackData( BitStream *stream )
- {
- Parent::unpackData( stream );
- stream->read( &color );
- stream->read( &brightness );
- stream->read( &range );
- castShadows = stream->readFlag();
- stream->read(&mStaticRefreshFreq);
- stream->read(&mDynamicRefreshFreq);
- stream->read( &animationPeriod );
- stream->read( &animationPhase );
- stream->read( &flareScale );
-
- if ( stream->readFlag() )
- animationDataId = stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast );
- if ( stream->readFlag() )
- flareDataId = stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast );
- }
- void LightDescription::submitLight( LightState *state, const MatrixF &xfm, LightManager *lm, SimObject *object )
- {
- LightInfo *li = state->lightInfo;
-
- li->setRange( range );
- li->setColor( color );
- li->setCastShadows( castShadows );
- li->setStaticRefreshFreq(mStaticRefreshFreq);
- li->setDynamicRefreshFreq(mDynamicRefreshFreq);
- li->setTransform( xfm );
- if ( animationData )
- {
- LightAnimState *animState = &state->animState;
- animState->brightness = brightness;
- animState->transform = xfm;
- animState->color = color;
- animState->animationPeriod = animationPeriod;
- animState->animationPhase = animationPhase;
- animationData->animate( li, animState );
- }
- lm->registerGlobalLight( li, object );
- }
- void LightDescription::prepRender( SceneRenderState *sceneState, LightState *lightState, const MatrixF &xfm )
- {
- if ( flareData )
- {
- LightFlareState *flareState = &lightState->flareState;
- flareState->fullBrightness = brightness;
- flareState->scale = flareScale;
- flareState->lightMat = xfm;
- flareState->lightInfo = lightState->lightInfo;
- flareData->prepRender( sceneState, flareState );
- }
- }
- bool LightDescription::_preload( bool server, String &errorStr )
- {
- if (!animationData && animationDataId != 0)
- if (Sim::findObject(animationDataId, animationData) == false)
- Con::errorf(ConsoleLogEntry::General, "LightDescription::onAdd: Invalid packet, bad datablockId(animationData): %d", animationDataId);
- if (!flareData && flareDataId != 0)
- if (Sim::findObject(flareDataId, flareData) == false)
- Con::errorf(ConsoleLogEntry::General, "LightDescription::onAdd: Invalid packet, bad datablockId(flareData): %d", flareDataId);
- return true;
- }
- DefineEngineMethod( LightDescription, apply, void, (),,
- "@brief Force an inspectPostApply call for the benefit of tweaking via the console\n\n"
-
- "Normally this functionality is only exposed to objects via the World Editor, once changes have been made. "
- "Exposing apply to script allows you to make changes to it on the fly without the World Editor.\n\n"
- "@note This is intended for debugging and tweaking, not for game play\n\n"
- "@tsexample\n"
- "// Change a property of the light description\n"
- "RocketLauncherLightDesc.brightness = 10;\n\n"
- "// Make it so\n"
- "RocketLauncherLightDesc.apply();\n"
-
- "@endtsexample\n\n"
- )
- {
- object->inspectPostApply();
- }
- //ConsoleMethod( LightDescription, apply, void, 2, 2, "force an inspectPostApply for the benefit of tweaking via the console" )
- //{
- // object->inspectPostApply();
- //}
|