afxEA_SpotLight_T3D.cpp
Engine/source/afx/ea/afxEA_SpotLight_T3D.cpp
Classes:
Detailed Description
1 2 3//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 4// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames 5// Copyright (C) 2015 Faust Logic, Inc. 6// 7// Permission is hereby granted, free of charge, to any person obtaining a copy 8// of this software and associated documentation files (the "Software"), to 9// deal in the Software without restriction, including without limitation the 10// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11// sell copies of the Software, and to permit persons to whom the Software is 12// furnished to do so, subject to the following conditions: 13// 14// The above copyright notice and this permission notice shall be included in 15// all copies or substantial portions of the Software. 16// 17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23// IN THE SOFTWARE. 24// 25//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 26 27#include <typeinfo> 28#include "afx/arcaneFX.h" 29 30#include "T3D/spotLight.h" 31 32#include "afx/ce/afxSpotLight_T3D.h" 33#include "afx/afxEffectDefs.h" 34#include "afx/afxEffectWrapper.h" 35#include "afx/afxChoreographer.h" 36 37//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 38// afxEA_T3DSpotLight 39 40class SpotLightProxy; 41 42class afxEA_T3DSpotLight : public afxEffectWrapper 43{ 44 typedef afxEffectWrapper Parent; 45 46 afxT3DSpotLightData* light_data; 47 SpotLightProxy* light; 48 49 void do_runtime_substitutions(); 50 51public: 52 /*C*/ afxEA_T3DSpotLight(); 53 /*D*/ ~afxEA_T3DSpotLight(); 54 55 virtual void ea_set_datablock(SimDataBlock*); 56 virtual bool ea_start(); 57 virtual bool ea_update(F32 dt); 58 virtual void ea_finish(bool was_stopped); 59 virtual void ea_set_scope_status(bool flag); 60 virtual void onDeleteNotify(SimObject*); 61 virtual void getBaseColor(LinearColorF& color); 62 63 virtual bool ea_is_enabled() { return true; } 64}; 65 66//~~~~~~~~~~~~~~~~~~~~// 67 68class SpotLightProxy : public SpotLight 69{ 70 F32 mFade_amt; 71 72public: 73 SpotLightProxy() { mFade_amt = 1.0f; } 74 75 void force_ghost() 76 { 77 mNetFlags.clear(Ghostable | ScopeAlways); 78 mNetFlags.set(IsGhost); 79 } 80 81 void setFadeAmount(F32 fade_amt) 82 { 83 mFade_amt = fade_amt; 84 mLight->setBrightness(mBrightness*fade_amt); 85 } 86 87 void updateTransform(const MatrixF& xfm) 88 { 89 mLight->setTransform(xfm); 90 LightBase::setTransform(xfm); 91 } 92 93 void initWithDataBlock(const afxT3DSpotLightData* db) 94 { 95 mRange = getMax(db->mRange, 0.05f); 96 mInnerConeAngle = db->mInnerConeAngle; 97 mOuterConeAngle = db->mOuterConeAngle; 98 99 mColor = db->mColor; 100 mBrightness = db->mBrightness; 101 mCastShadows = db->mCastShadows; 102 mPriority = db->mPriority; 103 mFlareData = db->mFlareData; 104 mAnimationData = db->mAnimationData; 105 mAnimState.active = (mAnimationData != 0); 106 107 mLocalRenderViz = db->mLocalRenderViz; 108 109 mLight->setType( LightInfo::Spot ); 110 mLight->setBrightness( db->mBrightness ); 111 mLight->setRange( db->mRange ); 112 mLight->setColor( db->mColor ); 113 mLight->setCastShadows( db->mCastShadows ); 114 mLight->setPriority( db->mPriority ); 115 mLight->setInnerConeAngle( db->mInnerConeAngle ); 116 mLight->setOuterConeAngle( db->mOuterConeAngle ); 117 118 // Update the bounds and scale to fit our light. 119 F32 radius = mRange * mSin( mDegToRad( mOuterConeAngle ) * 0.5f ); 120 mObjBox.minExtents.set( -1, -1, -1 ); 121 mObjBox.maxExtents.set( 1, 1, 1 ); 122 mObjScale.set( radius, mRange, radius ); 123 124 //_conformLights(); 125 } 126 127 void setLiveColor(const LinearColorF& live_color) 128 { 129 mLight->setColor(live_color); 130 } 131 132 void submitLights(LightManager* lm, bool staticLighting) 133 { 134 if (mAnimState.active && mAnimationData && mFade_amt < 1.0f) 135 { 136 F32 mBrightness_save = mBrightness; 137 mBrightness *= mFade_amt; 138 SpotLight::submitLights(lm, staticLighting); 139 mBrightness = mBrightness_save; 140 return; 141 } 142 143 SpotLight::submitLights(lm, staticLighting); 144 } 145}; 146 147//~~~~~~~~~~~~~~~~~~~~// 148 149afxEA_T3DSpotLight::afxEA_T3DSpotLight() 150{ 151 light_data = 0; 152 light = 0; 153} 154 155afxEA_T3DSpotLight::~afxEA_T3DSpotLight() 156{ 157 if (light) 158 light->deleteObject(); 159 if (light_data && light_data->isTempClone()) 160 delete light_data; 161 light_data = 0; 162} 163 164void afxEA_T3DSpotLight::ea_set_datablock(SimDataBlock* db) 165{ 166 light_data = dynamic_cast<afxT3DSpotLightData*>(db); 167} 168 169bool afxEA_T3DSpotLight::ea_start() 170{ 171 if (!light_data) 172 { 173 Con::errorf("afxEA_T3DSpotLight::ea_start() -- missing or incompatible datablock."); 174 return false; 175 } 176 177 do_runtime_substitutions(); 178 179 // create and register effect 180 light = new SpotLightProxy(); 181 light->force_ghost(); 182 if (!light->registerObject()) 183 { 184 delete light; 185 light = 0; 186 Con::errorf("afxEA_T3DSpotLight::ea_update() -- effect failed to register."); 187 return false; 188 } 189 deleteNotify(light); 190 191 light->initWithDataBlock(light_data); 192 193 return true; 194} 195 196bool afxEA_T3DSpotLight::ea_update(F32 dt) 197{ 198 if (light) 199 { 200#if 0 // AFX_T3D_DISABLED 201 // With sgLightObject lights, the following code block would hook 202 // the constraint object up to the light in case the light was 203 // configured to exclude it from flare occusions. The code remains 204 // here in case we need to implement the same feature for T3D light. 205 206 getPosConstraint(); 207 getSceneObject() : 0; 208 light->setConstraintObject(cons_obj); 209#endif 210 211 light->setLiveColor(mUpdated_color); 212 213 if (mDo_fades) 214 light->setFadeAmount(mFade_value); 215 216 light->updateTransform(mUpdated_xfm); 217 218 // scale should not be updated this way. It messes up the culling. 219 //light->setScale(updated_scale); 220 } 221 222 return true; 223} 224 225void afxEA_T3DSpotLight::ea_finish(bool was_stopped) 226{ 227 if (light) 228 { 229 light->deleteObject(); 230 light = 0; 231 } 232} 233 234void afxEA_T3DSpotLight::ea_set_scope_status(bool in_scope) 235{ 236 if (light) 237 light->setLightEnabled(in_scope); 238} 239 240void afxEA_T3DSpotLight::onDeleteNotify(SimObject* obj) 241{ 242 if (light == dynamic_cast<SpotLight*>(obj)) 243 light = 0; 244 245 Parent::onDeleteNotify(obj); 246} 247 248void afxEA_T3DSpotLight::getBaseColor(LinearColorF& color) 249{ 250 if (light_data) 251 color = light_data->mColor; 252} 253 254void afxEA_T3DSpotLight::do_runtime_substitutions() 255{ 256 // only clone the datablock if there are substitutions 257 if (light_data->getSubstitutionCount() > 0) 258 { 259 // clone the datablock and perform substitutions 260 afxT3DSpotLightData* orig_db = light_data; 261 light_data = new afxT3DSpotLightData(*orig_db, true); 262 orig_db->performSubstitutions(light_data, mChoreographer, mGroup_index); 263 } 264} 265 266//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 267 268class afxEA_T3DSpotLightDesc : public afxEffectAdapterDesc, public afxEffectDefs 269{ 270 static afxEA_T3DSpotLightDesc desc; 271 272public: 273 virtual bool testEffectType(const SimDataBlock*) const; 274 virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const; 275 virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; } 276 virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; } 277 278 virtual afxEffectWrapper* create() const { return new afxEA_T3DSpotLight; } 279}; 280 281afxEA_T3DSpotLightDesc afxEA_T3DSpotLightDesc::desc; 282 283bool afxEA_T3DSpotLightDesc::testEffectType(const SimDataBlock* db) const 284{ 285 return (typeid(afxT3DSpotLightData) == typeid(*db)); 286} 287 288bool afxEA_T3DSpotLightDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const 289{ 290 return (timing.lifetime < 0); 291} 292 293 294//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 295