afxXM_Oscillate.cpp
Engine/source/afx/xm/afxXM_Oscillate.cpp
Classes:
class
class
class
Public Functions
ConsoleDocClass(afxXM_OscillateData , "@brief An xmod <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablock.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxXMods\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )
Detailed Description
Public Functions
ConsoleDocClass(afxXM_OscillateData , "@brief An xmod <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablock.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxXMods\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )
IMPLEMENT_CO_DATABLOCK_V1(afxXM_OscillateData )
lerp(F32 t, F32 a, F32 b)
lerpV(F32 t, const Point3F & a, const Point3F & b)
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 "afx/arcaneFX.h" 28 29#include "math/mathIO.h" 30#include "math/mathUtils.h" 31 32#include "afx/afxEffectWrapper.h" 33#include "afx/afxChoreographer.h" 34#include "afx/xm/afxXfmMod.h" 35 36//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 37 38class afxXM_OscillateData : public afxXM_WeightedBaseData 39{ 40 typedef afxXM_WeightedBaseData Parent; 41 42public: 43 U32 mask; 44 Point3F min; 45 Point3F max; 46 F32 speed; 47 Point3F axis; 48 bool additive_scale; 49 bool local_offset; 50 51public: 52 /*C*/ afxXM_OscillateData(); 53 /*C*/ afxXM_OscillateData(const afxXM_OscillateData&, bool = false); 54 55 void packData(BitStream* stream); 56 void unpackData(BitStream* stream); 57 58 virtual bool allowSubstitutions() const { return true; } 59 60 static void initPersistFields(); 61 62 afxXM_Base* create(afxEffectWrapper* fx, bool on_server); 63 64 DECLARE_CONOBJECT(afxXM_OscillateData); 65 DECLARE_CATEGORY("AFX"); 66}; 67 68class afxXM_Oscillate_rot : public afxXM_WeightedBase 69{ 70 typedef afxXM_WeightedBase Parent; 71 72 afxXM_OscillateData* db; 73 74public: 75 /*C*/ afxXM_Oscillate_rot(afxXM_OscillateData*, afxEffectWrapper*); 76 77 virtual void updateParams(F32 dt, F32 elapsed, afxXM_Params& params); 78}; 79 80class afxXM_Oscillate_scale : public afxXM_WeightedBase 81{ 82 typedef afxXM_WeightedBase Parent; 83 84 afxXM_OscillateData* db; 85 86public: 87 /*C*/ afxXM_Oscillate_scale(afxXM_OscillateData*, afxEffectWrapper*); 88 89 virtual void updateParams(F32 dt, F32 elapsed, afxXM_Params& params); 90}; 91 92class afxXM_Oscillate_position : public afxXM_WeightedBase 93{ 94 typedef afxXM_WeightedBase Parent; 95 96 afxXM_OscillateData* db; 97 98public: 99 /*C*/ afxXM_Oscillate_position(afxXM_OscillateData*, afxEffectWrapper*); 100 101 virtual void updateParams(F32 dt, F32 elapsed, afxXM_Params& params); 102}; 103 104class afxXM_Oscillate_position2 : public afxXM_WeightedBase 105{ 106 typedef afxXM_WeightedBase Parent; 107 108 afxXM_OscillateData* db; 109 110public: 111 /*C*/ afxXM_Oscillate_position2(afxXM_OscillateData*, afxEffectWrapper*); 112 113 virtual void updateParams(F32 dt, F32 elapsed, afxXM_Params& params); 114}; 115 116class afxXM_Oscillate : public afxXM_WeightedBase 117{ 118 typedef afxXM_WeightedBase Parent; 119 120 afxXM_OscillateData* db; 121 122public: 123 /*C*/ afxXM_Oscillate(afxXM_OscillateData*, afxEffectWrapper*); 124 125 virtual void updateParams(F32 dt, F32 elapsed, afxXM_Params& params); 126}; 127 128//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 129 130IMPLEMENT_CO_DATABLOCK_V1(afxXM_OscillateData); 131 132ConsoleDocClass( afxXM_OscillateData, 133 "@brief An xmod datablock.\n\n" 134 135 "@ingroup afxXMods\n" 136 "@ingroup AFX\n" 137 "@ingroup Datablocks\n" 138); 139 140afxXM_OscillateData::afxXM_OscillateData() 141{ 142 mask = POSITION; 143 min.set(0,0,0); 144 max.set(1,1,1); 145 speed = 1.0f; 146 axis.set(0,0,1); 147 additive_scale = false; 148 local_offset = true; 149} 150 151afxXM_OscillateData::afxXM_OscillateData(const afxXM_OscillateData& other, bool temp_clone) : afxXM_WeightedBaseData(other, temp_clone) 152{ 153 mask = other.mask; 154 min = other.min; 155 max = other.max; 156 speed = other.speed; 157 axis = other.axis; 158 additive_scale = other.additive_scale; 159 local_offset = other.local_offset; 160} 161 162void afxXM_OscillateData::initPersistFields() 163{ 164 addField("mask", TypeS32, Offset(mask, afxXM_OscillateData), 165 "..."); 166 addField("min", TypePoint3F, Offset(min, afxXM_OscillateData), 167 "..."); 168 addField("max", TypePoint3F, Offset(max, afxXM_OscillateData), 169 "..."); 170 addField("speed", TypeF32, Offset(speed, afxXM_OscillateData), 171 "..."); 172 addField("axis", TypePoint3F, Offset(axis, afxXM_OscillateData), 173 "..."); 174 addField("additiveScale", TypeBool, Offset(additive_scale, afxXM_OscillateData), 175 "..."); 176 addField("localOffset", TypeBool, Offset(local_offset, afxXM_OscillateData), 177 "..."); 178 179 Parent::initPersistFields(); 180} 181 182void afxXM_OscillateData::packData(BitStream* stream) 183{ 184 Parent::packData(stream); 185 stream->write(mask); 186 mathWrite(*stream, min); 187 mathWrite(*stream, max); 188 stream->write(speed); 189 mathWrite(*stream, axis); 190 stream->writeFlag(additive_scale); 191 stream->writeFlag(local_offset); 192} 193 194void afxXM_OscillateData::unpackData(BitStream* stream) 195{ 196 Parent::unpackData(stream); 197 stream->read(&mask); 198 mathRead(*stream, &min); 199 mathRead(*stream, &max); 200 stream->read(&speed); 201 mathRead(*stream, &axis); 202 additive_scale = stream->readFlag(); 203 local_offset = stream->readFlag(); 204} 205 206afxXM_Base* afxXM_OscillateData::create(afxEffectWrapper* fx, bool on_server) 207{ 208 afxXM_OscillateData* datablock = this; 209 210 if (getSubstitutionCount() > 0) 211 { 212 datablock = new afxXM_OscillateData(*this, true); 213 this->performSubstitutions(datablock, fx->getChoreographer(), fx->getGroupIndex()); 214 } 215 216 if (datablock->mask == ORIENTATION) 217 return new afxXM_Oscillate_rot(datablock, fx); 218 if (datablock->mask == SCALE) 219 return new afxXM_Oscillate_scale(datablock, fx); 220 if (datablock->mask == POSITION) 221 return new afxXM_Oscillate_position(datablock, fx); 222 if (datablock->mask == POSITION2) 223 return new afxXM_Oscillate_position2(datablock, fx); 224 return new afxXM_Oscillate(datablock, fx); 225} 226 227//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~// 228 229inline F32 lerp(F32 t, F32 a, F32 b) 230{ 231 return a + t * (b - a); 232} 233 234inline Point3F lerpV(F32 t, const Point3F& a, const Point3F& b) 235{ 236 return Point3F( a.x + t * (b.x - a.x), 237 a.y + t * (b.y - a.y), 238 a.z + t * (b.z - a.z) ); 239} 240 241//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~// 242 243afxXM_Oscillate_rot::afxXM_Oscillate_rot(afxXM_OscillateData* db, afxEffectWrapper* fxw) 244: afxXM_WeightedBase(db, fxw) 245{ 246 this->db = db; 247} 248 249void afxXM_Oscillate_rot::updateParams(F32 dt, F32 elapsed, afxXM_Params& params) 250{ 251 F32 wt_factor = calc_weight_factor(elapsed); 252 253 F32 t = mSin(db->speed*elapsed); // [-1,1] 254 F32 theta = lerp((t+1)/2, db->min.x*wt_factor, db->max.x*wt_factor); 255 theta = mDegToRad(theta); 256 257 AngAxisF rot_aa(db->axis, theta); 258 MatrixF rot_xfm; rot_aa.setMatrix(&rot_xfm); 259 260 params.ori.mul(rot_xfm); 261} 262 263//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~// 264 265afxXM_Oscillate_scale::afxXM_Oscillate_scale(afxXM_OscillateData* db, afxEffectWrapper* fxw) 266: afxXM_WeightedBase(db, fxw) 267{ 268 this->db = db; 269} 270 271void afxXM_Oscillate_scale::updateParams(F32 dt, F32 elapsed, afxXM_Params& params) 272{ 273 F32 wt_factor = calc_weight_factor(elapsed); 274 275 F32 t = mSin(db->speed*elapsed); // [-1,1] 276 F32 s = lerp((t+1)/2, db->min.x*wt_factor, db->max.x*wt_factor); 277 Point3F xm_scale = db->axis*s; 278 279 if (db->additive_scale) 280 params.scale += xm_scale; 281 else 282 params.scale *= xm_scale; 283} 284 285//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~// 286 287afxXM_Oscillate_position::afxXM_Oscillate_position(afxXM_OscillateData* db, afxEffectWrapper* fxw) 288: afxXM_WeightedBase(db, fxw) 289{ 290 this->db = db; 291} 292 293void afxXM_Oscillate_position::updateParams(F32 dt, F32 elapsed, afxXM_Params& params) 294{ 295 F32 wt_factor = calc_weight_factor(elapsed); 296 297 F32 t = mSin(db->speed*elapsed); // [-1,1] 298 Point3F offset = lerpV(t, db->min*wt_factor, db->max*wt_factor); 299 300 if (db->local_offset) 301 { 302 params.ori.mulV(offset); 303 params.pos += offset; 304 } 305 else 306 params.pos += offset; 307} 308 309//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~// 310 311afxXM_Oscillate_position2::afxXM_Oscillate_position2(afxXM_OscillateData* db, afxEffectWrapper* fxw) 312: afxXM_WeightedBase(db, fxw) 313{ 314 this->db = db; 315} 316 317void afxXM_Oscillate_position2::updateParams(F32 dt, F32 elapsed, afxXM_Params& params) 318{ 319 F32 wt_factor = calc_weight_factor(elapsed); 320 321 F32 t = mSin(db->speed*elapsed); // [-1,1] 322 Point3F offset = lerpV(t, db->min*wt_factor, db->max*wt_factor); 323 324 params.pos2 += offset; 325} 326 327//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~// 328 329afxXM_Oscillate::afxXM_Oscillate(afxXM_OscillateData* db, afxEffectWrapper* fxw) 330: afxXM_WeightedBase(db, fxw) 331{ 332 this->db = db; 333} 334 335void afxXM_Oscillate::updateParams(F32 dt, F32 elapsed, afxXM_Params& params) 336{ 337 F32 wt_factor = calc_weight_factor(elapsed); 338 339 F32 t = mSin(db->speed*elapsed); // [-1,1] 340 341 if (db->mask & POSITION) 342 { 343 Point3F offset = lerpV(t, db->min*wt_factor, db->max*wt_factor); 344 if (db->local_offset) 345 { 346 params.ori.mulV(offset); 347 params.pos += offset; 348 } 349 else 350 params.pos += offset; 351 } 352 353 if (db->mask & POSITION2) 354 { 355 Point3F offset = lerpV(t, db->min*wt_factor, db->max*wt_factor); 356 params.pos2 += offset; 357 } 358 359 if (db->mask & SCALE) 360 { 361 F32 s = lerp((t+1)/2, db->min.x*wt_factor, db->max.x*wt_factor); 362 Point3F xm_scale = db->axis*s; 363 if (db->additive_scale) 364 params.scale += xm_scale; 365 else 366 params.scale *= xm_scale; 367 } 368 369 if (db->mask & ORIENTATION) 370 { 371 F32 theta = lerp((t+1)/2, db->min.x*wt_factor, db->max.x*wt_factor); 372 theta = mDegToRad(theta); 373 AngAxisF rot_aa(db->axis, theta); 374 MatrixF rot_xfm; rot_aa.setMatrix(&rot_xfm); 375 params.ori.mul(rot_xfm); 376 } 377} 378 379//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 380 381