afxEA_Model.cpp
Engine/source/afx/ea/afxEA_Model.cpp
Classes:
class
class
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 "ts/tsShapeInstance.h" 31 32#include "afx/afxEffectDefs.h" 33#include "afx/afxEffectWrapper.h" 34#include "afx/afxChoreographer.h" 35#include "afx/afxResidueMgr.h" 36#include "afx/ce/afxModel.h" 37 38//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 39// afxEA_Model -- This is the adapter for afxModel, a lightweight animated model effect. 40 41class afxEA_Model : public afxEffectWrapper 42{ 43 typedef afxEffectWrapper Parent; 44 45 afxModelData* model_data; 46 afxModel* model; 47 48 void do_runtime_substitutions(); 49 50public: 51 /*C*/ afxEA_Model(); 52 /*D*/ ~afxEA_Model(); 53 54 virtual void ea_set_datablock(SimDataBlock*); 55 virtual bool ea_start(); 56 virtual bool ea_update(F32 dt); 57 virtual void ea_finish(bool was_stopped); 58 virtual void ea_set_scope_status(bool flag); 59 virtual void onDeleteNotify(SimObject*); 60 61 virtual void getUpdatedBoxCenter(Point3F& pos); 62 63 virtual TSShape* getTSShape(); 64 virtual TSShapeInstance* getTSShapeInstance(); 65 virtual SceneObject* ea_get_scene_object() const; 66 virtual U32 ea_get_triggers() const; 67 68 virtual U32 setAnimClip(const char* clip, F32 pos, F32 rate, F32 trans); 69 virtual void resetAnimation(U32 tag); 70 virtual F32 getAnimClipDuration(const char* clip); 71}; 72 73 74afxEA_Model::afxEA_Model() 75{ 76 model_data = 0; 77 model = 0; 78} 79 80afxEA_Model::~afxEA_Model() 81{ 82 if (model) 83 model->deleteObject(); 84 if (model_data && model_data->isTempClone()) 85 delete model_data; 86 model_data = 0; 87} 88 89void afxEA_Model::ea_set_datablock(SimDataBlock* db) 90{ 91 model_data = dynamic_cast<afxModelData*>(db); 92} 93 94bool afxEA_Model::ea_start() 95{ 96 if (!model_data) 97 { 98 Con::errorf("afxEA_Model::ea_start() -- missing or incompatible datablock."); 99 return false; 100 } 101 102 do_runtime_substitutions(); 103 104 return true; 105} 106 107bool afxEA_Model::ea_update(F32 dt) 108{ 109 if (!model) 110 { 111 // create and register effect 112 model = new afxModel(); 113 model->onNewDataBlock(model_data, false); 114 if (!model->registerObject()) 115 { 116 delete model; 117 model = 0; 118 Con::errorf("afxEA_Model::ea_update() -- effect failed to register."); 119 return false; 120 } 121 deleteNotify(model); 122 123 model->setSequenceRateFactor(mDatablock->rate_factor/ mProp_time_factor); 124 model->setSortPriority(mDatablock->sort_priority); 125 } 126 127 if (model) 128 { 129 if (mDo_fades) 130 { 131 model->setFadeAmount(mFade_value); 132 } 133 model->setTransform(mUpdated_xfm); 134 model->setScale(mUpdated_scale); 135 } 136 137 return true; 138} 139 140void afxEA_Model::ea_finish(bool was_stopped) 141{ 142 if (!model) 143 return; 144 145 if (mIn_scope && mEW_timing.residue_lifetime > 0) 146 { 147 clearNotify(model); 148 afxResidueMgr::add(mEW_timing.residue_lifetime, mEW_timing.residue_fadetime, model); 149 model = 0; 150 } 151 else 152 { 153 model->deleteObject(); 154 model = 0; 155 } 156} 157 158void afxEA_Model::ea_set_scope_status(bool in_scope) 159{ 160 if (model) 161 model->setVisibility(in_scope); 162} 163 164void afxEA_Model::onDeleteNotify(SimObject* obj) 165{ 166 if (model == dynamic_cast<afxModel*>(obj)) 167 model = 0; 168 169 Parent::onDeleteNotify(obj); 170} 171 172void afxEA_Model::getUpdatedBoxCenter(Point3F& pos) 173{ 174 if (model) 175 pos = model->getBoxCenter(); 176} 177 178TSShape* afxEA_Model::getTSShape() 179{ 180 return (model) ? model->getTSShape() : 0; 181} 182 183TSShapeInstance* afxEA_Model::getTSShapeInstance() 184{ 185 return (model) ? model->getTSShapeInstance() : 0; 186} 187 188SceneObject* afxEA_Model::ea_get_scene_object() const 189{ 190 return model; 191} 192 193U32 afxEA_Model::ea_get_triggers() const 194{ 195 TSShapeInstance* shape_inst = model->getTSShapeInstance(); 196 return (shape_inst) ? shape_inst->getTriggerStateMask() : 0; 197} 198 199void afxEA_Model::do_runtime_substitutions() 200{ 201 // only clone the datablock if there are substitutions 202 if (model_data->getSubstitutionCount() > 0) 203 { 204 // clone the datablock and perform substitutions 205 afxModelData* orig_db = model_data; 206 model_data = new afxModelData(*orig_db, true); 207 orig_db->performSubstitutions(model_data, mChoreographer, mGroup_index); 208 } 209} 210 211U32 afxEA_Model::setAnimClip(const char* clip, F32 pos, F32 rate, F32 trans) 212{ 213 return (model) ? model->setAnimClip(clip, pos, rate, trans) : 0; 214} 215 216void afxEA_Model::resetAnimation(U32 tag) 217{ 218 if (model) 219 model->resetAnimation(tag); 220} 221 222F32 afxEA_Model::getAnimClipDuration(const char* clip) 223{ 224 return (model) ? model->getAnimClipDuration(clip) : 0; 225} 226 227//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 228 229class afxEA_ModelDesc : public afxEffectAdapterDesc, public afxEffectDefs 230{ 231 static afxEA_ModelDesc desc; 232 233public: 234 virtual bool testEffectType(const SimDataBlock*) const; 235 virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const; 236 virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; } 237 virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; } 238 239 virtual afxEffectWrapper* create() const { return new afxEA_Model; } 240}; 241 242//~~~~~~~~~~~~~~~~~~~~// 243 244afxEA_ModelDesc afxEA_ModelDesc::desc; 245 246bool afxEA_ModelDesc::testEffectType(const SimDataBlock* db) const 247{ 248 return (typeid(afxModelData) == typeid(*db)); 249} 250 251bool afxEA_ModelDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const 252{ 253 return (timing.lifetime < 0); 254} 255 256//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 257