afxEA_PointLight_T3D.cpp
Engine/source/afx/ea/afxEA_PointLight_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/pointLight.h" 31 32#include "afx/ce/afxPointLight_T3D.h" 33#include "afx/afxEffectDefs.h" 34#include "afx/afxEffectWrapper.h" 35#include "afx/afxChoreographer.h" 36 37//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 38// afxEA_T3DPointLight 39 40class PointLightProxy; 41 42class afxEA_T3DPointLight : public afxEffectWrapper 43{ 44 typedef afxEffectWrapper Parent; 45 46 afxT3DPointLightData* light_data; 47 PointLightProxy* light; 48 49 void do_runtime_substitutions(); 50 51public: 52 /*C*/ afxEA_T3DPointLight(); 53 /*D*/ ~afxEA_T3DPointLight(); 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 PointLightProxy : public PointLight 69{ 70 F32 mFade_amt; 71 72public: 73 PointLightProxy() { 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 afxT3DPointLightData* db) 94 { 95 mRadius = db->mRadius; 96 97 mColor = db->mColor; 98 mBrightness = db->mBrightness; 99 mCastShadows = db->mCastShadows; 100 mPriority = db->mPriority; 101 mFlareData = db->mFlareData; 102 mAnimationData = db->mAnimationData; 103 mAnimState.active = (mAnimationData != 0); 104 105 mLocalRenderViz = db->mLocalRenderViz; 106 107 mLight->setType( LightInfo::Point ); 108 mLight->setBrightness( db->mBrightness ); 109 mLight->setRange( db->mRadius ); 110 mLight->setColor( db->mColor ); 111 mLight->setCastShadows( db->mCastShadows ); 112 mLight->setPriority( db->mPriority ); 113 114 // Update the bounds and scale to fit our light. 115 mObjBox.minExtents.set( -1, -1, -1 ); 116 mObjBox.maxExtents.set( 1, 1, 1 ); 117 mObjScale.set( db->mRadius, db->mRadius, db->mRadius ); 118 119 //_conformLights(); 120 } 121 122 void setLiveColor(const LinearColorF& live_color) 123 { 124 mLight->setColor(live_color); 125 } 126 127 void submitLights(LightManager* lm, bool staticLighting) 128 { 129 if (mAnimState.active && mAnimationData && mFade_amt < 1.0f) 130 { 131 F32 mBrightness_save = mBrightness; 132 mBrightness *= mFade_amt; 133 PointLight::submitLights(lm, staticLighting); 134 mBrightness = mBrightness_save; 135 return; 136 } 137 138 PointLight::submitLights(lm, staticLighting); 139 } 140 141}; 142 143//~~~~~~~~~~~~~~~~~~~~// 144 145afxEA_T3DPointLight::afxEA_T3DPointLight() 146{ 147 light_data = 0; 148 light = 0; 149} 150 151afxEA_T3DPointLight::~afxEA_T3DPointLight() 152{ 153 if (light) 154 light->deleteObject(); 155 if (light_data && light_data->isTempClone()) 156 delete light_data; 157 light_data = 0; 158} 159 160void afxEA_T3DPointLight::ea_set_datablock(SimDataBlock* db) 161{ 162 light_data = dynamic_cast<afxT3DPointLightData*>(db); 163} 164 165bool afxEA_T3DPointLight::ea_start() 166{ 167 if (!light_data) 168 { 169 Con::errorf("afxEA_T3DPointLight::ea_start() -- missing or incompatible datablock."); 170 return false; 171 } 172 173 do_runtime_substitutions(); 174 175 // create and register effect 176 light = new PointLightProxy(); 177 light->force_ghost(); 178 if (!light->registerObject()) 179 { 180 delete light; 181 light = 0; 182 Con::errorf("afxEA_T3DPointLight::ea_update() -- effect failed to register."); 183 return false; 184 } 185 deleteNotify(light); 186 187 light->initWithDataBlock(light_data); 188 189 return true; 190} 191 192bool afxEA_T3DPointLight::ea_update(F32 dt) 193{ 194 if (light) 195 { 196#if 0 // AFX_T3D_DISABLED 197 // With sgLightObject lights, the following code block would hook 198 // the constraint object up to the light in case the light was 199 // configured to exclude it from flare occusions. The code remains 200 // here in case we need to implement the same feature for T3D light. 201 202 getPosConstraint(); 203 getSceneObject() : 0; 204 light->setConstraintObject(cons_obj); 205#endif 206 207 light->setLiveColor(mUpdated_color); 208 209 if (mDo_fades) 210 light->setFadeAmount(mFade_value*mUpdated_scale.x); 211 212 light->updateTransform(mUpdated_xfm); 213 214 // scale should not be updated this way. It messes up the culling. 215 //light->setScale(updated_scale); 216 } 217 218 return true; 219} 220 221void afxEA_T3DPointLight::ea_finish(bool was_stopped) 222{ 223 if (light) 224 { 225 light->deleteObject(); 226 light = 0; 227 } 228} 229 230void afxEA_T3DPointLight::ea_set_scope_status(bool in_scope) 231{ 232 if (light) 233 light->setLightEnabled(in_scope); 234} 235 236void afxEA_T3DPointLight::onDeleteNotify(SimObject* obj) 237{ 238 if (light == dynamic_cast<PointLight*>(obj)) 239 light = 0; 240 241 Parent::onDeleteNotify(obj); 242} 243 244void afxEA_T3DPointLight::getBaseColor(LinearColorF& color) 245{ 246 if (light_data) 247 color = light_data->mColor; 248} 249 250void afxEA_T3DPointLight::do_runtime_substitutions() 251{ 252 // only clone the datablock if there are substitutions 253 if (light_data->getSubstitutionCount() > 0) 254 { 255 // clone the datablock and perform substitutions 256 afxT3DPointLightData* orig_db = light_data; 257 light_data = new afxT3DPointLightData(*orig_db, true); 258 orig_db->performSubstitutions(light_data, mChoreographer, mGroup_index); 259 } 260} 261 262//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 263 264class afxEA_T3DPointLightDesc : public afxEffectAdapterDesc, public afxEffectDefs 265{ 266 static afxEA_T3DPointLightDesc desc; 267 268public: 269 virtual bool testEffectType(const SimDataBlock*) const; 270 virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const; 271 virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; } 272 virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; } 273 274 virtual afxEffectWrapper* create() const { return new afxEA_T3DPointLight; } 275}; 276 277afxEA_T3DPointLightDesc afxEA_T3DPointLightDesc::desc; 278 279bool afxEA_T3DPointLightDesc::testEffectType(const SimDataBlock* db) const 280{ 281 return (typeid(afxT3DPointLightData) == typeid(*db)); 282} 283 284bool afxEA_T3DPointLightDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const 285{ 286 return (timing.lifetime < 0); 287} 288 289 290//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 291