Torque3D Documentation / _generateds / afxEA_Zodiac.cpp

afxEA_Zodiac.cpp

Engine/source/afx/ea/afxEA_Zodiac.cpp

More...

Classes:

Public Defines

define
myOffset(field) (field, )

Detailed Description

Public Defines

myOffset(field) (field, )
  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 "math/mathUtils.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/util/afxEase.h"
 37#include "afx/ce/afxZodiacMgr.h"
 38
 39//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 40// afxEA_Zodiac 
 41
 42class afxEA_Zodiac : public afxEffectWrapper
 43{
 44  typedef afxEffectWrapper Parent;
 45
 46  afxZodiacData*    zode_data;
 47  Point3F           zode_pos;
 48  F32               zode_radius;
 49  Point2F           zode_vrange;
 50  LinearColorF            zode_color;
 51  F32               zode_angle;
 52  F32               zode_angle_offset;
 53
 54  F32               live_color_factor;
 55  LinearColorF            live_color;
 56  bool              became_residue;
 57  bool              do_altitude_bias;
 58  F32               altitude_falloff_range;
 59
 60  F32               calc_facing_angle();
 61  F32               calc_terrain_alt_bias();
 62  F32               calc_interior_alt_bias();
 63  void              do_runtime_substitutions();
 64
 65public:
 66  /*C*/             afxEA_Zodiac();
 67  /*C*/             ~afxEA_Zodiac();
 68
 69  virtual void      ea_set_datablock(SimDataBlock*);
 70  virtual bool      ea_start();
 71  virtual bool      ea_update(F32 dt);
 72  virtual void      ea_finish(bool was_stopped);
 73
 74  virtual bool      ea_is_enabled() { return true; }
 75
 76  virtual void      getBaseColor(LinearColorF& color) { color = zode_data->color; }
 77
 78  static void       initPersistFields();
 79
 80  //DECLARE_CONOBJECT(afxEA_Zodiac);
 81  DECLARE_CATEGORY("AFX");
 82};
 83
 84//IMPLEMENT_CONOBJECT(afxEA_Zodiac);
 85
 86//~~~~~~~~~~~~~~~~~~~~//
 87
 88F32 afxEA_Zodiac::calc_facing_angle() 
 89{
 90  // get direction player is facing
 91  VectorF shape_vec;
 92  MatrixF shape_xfm;
 93
 94  afxConstraint* orient_constraint = getOrientConstraint();
 95  if (orient_constraint)
 96    orient_constraint->getTransform(shape_xfm);
 97  else
 98    shape_xfm.identity();
 99
100  shape_xfm.getColumn(1, &shape_vec);
101  shape_vec.z = 0.0f;
102  shape_vec.normalize();
103
104  F32 pitch, yaw;
105  MathUtils::getAnglesFromVector(shape_vec, yaw, pitch);
106
107  return mRadToDeg(yaw); 
108}
109
110inline F32 afxEA_Zodiac::calc_terrain_alt_bias()
111{
112  if (mTerrain_altitude >= zode_data->altitude_max)
113    return 0.0f;
114  return 1.0f - (mTerrain_altitude - zode_data->altitude_falloff)/altitude_falloff_range;
115}
116
117inline F32 afxEA_Zodiac::calc_interior_alt_bias()
118{
119  if (mInterior_altitude >= zode_data->altitude_max)
120    return 0.0f;
121  return 1.0f - (mInterior_altitude - zode_data->altitude_falloff)/altitude_falloff_range;
122}
123
124afxEA_Zodiac::afxEA_Zodiac()
125{
126  zode_data = 0;
127  zode_pos.zero();
128  zode_radius = 1;
129  zode_vrange.set(1,1);
130  zode_color.set(1,1,1,1);
131  zode_angle = 0;
132  zode_angle_offset = 0;
133  live_color.set(1,1,1,1);
134  live_color_factor = 0.0f;
135  do_altitude_bias = false;
136  altitude_falloff_range = 0.0f;
137  became_residue = false;
138}
139
140afxEA_Zodiac::~afxEA_Zodiac()
141{
142  if (!became_residue && zode_data && zode_data->isTempClone())
143    delete zode_data;
144  zode_data = 0;
145}
146
147void afxEA_Zodiac::ea_set_datablock(SimDataBlock* db)
148{
149  zode_data = dynamic_cast<afxZodiacData*>(db);
150  if (zode_data)
151  {
152    do_altitude_bias = (zode_data->altitude_max > 0.0f && (zode_data->altitude_shrinks || zode_data->altitude_fades));
153    altitude_falloff_range = zode_data->altitude_max - zode_data->altitude_falloff;
154  }
155}
156
157bool afxEA_Zodiac::ea_start()
158{
159  if (!zode_data)
160  {
161    Con::errorf("afxEA_Zodiac::ea_start() -- missing or incompatible datablock.");
162    return false;
163  }
164
165  do_runtime_substitutions();
166
167  zode_angle_offset = calc_facing_angle();
168
169  return true;
170}
171
172bool afxEA_Zodiac::ea_update(F32 dt)
173{
174  if (!mIn_scope)
175    return true;
176
177  //~~~~~~~~~~~~~~~~~~~~//
178  // Zodiac Color
179
180  zode_color = mUpdated_color;
181
182  if (live_color_factor > 0.0)
183  {
184     zode_color.interpolate(zode_color, live_color, live_color_factor);
185     //Con::printf("LIVE-COLOR %g %g %g %g  FACTOR is %g", 
186     //   live_color.red, live_color.green, live_color.blue, live_color.alpha, 
187     //   live_color_factor);
188  }
189  else
190  {
191     //Con::printf("LIVE-COLOR-FACTOR is ZERO");
192  }
193
194  if (mDo_fades)
195  {
196    if (mFade_value < 0.01f)
197      return true; // too transparent
198
199    if (zode_data->blend_flags == afxZodiacDefs::BLEND_SUBTRACTIVE)
200      zode_color *= mFade_value * mLive_fade_factor;
201    else
202      zode_color.alpha *= mFade_value * mLive_fade_factor;
203  }
204
205  if (zode_color.alpha < 0.01f)
206    return true;
207
208  //~~~~~~~~~~~~~~~~~~~~//
209  // Zodiac
210
211  // scale and grow zode
212  zode_radius = zode_data->radius_xy*mUpdated_scale.x + mLife_elapsed *zode_data->growth_rate;
213
214  // zode is growing
215  if (mLife_elapsed < zode_data->grow_in_time)
216  {
217    F32 t = mLife_elapsed /zode_data->grow_in_time;
218    zode_radius = afxEase::eq(t, 0.001f, zode_radius, 0.2f, 0.8f);
219  }
220  // zode is shrinking
221  else if (mFull_lifetime - mLife_elapsed < zode_data->shrink_out_time)
222  {
223    F32 t = (mFull_lifetime - mLife_elapsed)/zode_data->shrink_out_time;
224    zode_radius = afxEase::eq(t, 0.001f, zode_radius, 0.0f, 0.9f);
225  }
226
227  zode_radius *= mLive_scale_factor;
228
229  if (zode_radius < 0.001f)
230    return true; // too small
231
232  zode_vrange = zode_data->vert_range;
233  if (zode_data->scale_vert_range)
234  {
235    F32 scale_factor = zode_radius/zode_data->radius_xy;
236    zode_vrange *= scale_factor;
237  }
238
239  //~~~~~~~~~~~~~~~~~~~~//
240  // Zodiac Position
241
242  zode_pos = mUpdated_pos;
243
244  //~~~~~~~~~~~~~~~~~~~~//
245  // Zodiac Rotation 
246
247  if (zode_data->respect_ori_cons)
248  {
249    afxConstraint* orient_constraint = getOrientConstraint();
250    if (orient_constraint)
251    {
252      VectorF shape_vec;
253     mUpdated_xfm.getColumn(1, &shape_vec);
254      shape_vec.z = 0.0f;
255      shape_vec.normalize();
256      F32 pitch, yaw;
257      MathUtils::getAnglesFromVector(shape_vec, yaw, pitch);
258      zode_angle_offset = mRadToDeg(yaw); 
259    }
260  }
261
262  zode_angle = zode_data->calcRotationAngle(mLife_elapsed, mDatablock->rate_factor/ mProp_time_factor);
263  zode_angle = mFmod(zode_angle + zode_angle_offset, 360.0f);     
264
265  //~~~~~~~~~~~~~~~~~~~~//
266  // post zodiac
267  if ((zode_data->zflags & afxZodiacDefs::SHOW_ON_TERRAIN) != 0)
268  {
269    if (do_altitude_bias && mTerrain_altitude > zode_data->altitude_falloff)
270    {
271      F32 alt_bias = calc_terrain_alt_bias();
272      if (alt_bias > 0.0f)
273      {
274        F32 alt_rad = zode_radius;
275        if (zode_data->altitude_shrinks)
276          alt_rad *= alt_bias;
277        LinearColorF alt_clr(zode_color.red, zode_color.green, zode_color.blue, zode_color.alpha);
278        if (zode_data->altitude_fades)
279          alt_clr.alpha *= alt_bias;
280        afxZodiacMgr::addTerrainZodiac(zode_pos, alt_rad, alt_clr, zode_angle, zode_data);
281      }
282    }
283    else
284    {
285      afxZodiacMgr::addTerrainZodiac(zode_pos, zode_radius, zode_color, zode_angle, zode_data);
286    }
287  }
288
289  if ((zode_data->zflags & afxZodiacDefs::SHOW_ON_INTERIORS) != 0)
290  {
291    if (do_altitude_bias && mInterior_altitude > zode_data->altitude_falloff)
292    {
293      F32 alt_bias = calc_interior_alt_bias();
294      if (alt_bias > 0.0f)
295      {
296        F32 alt_rad = zode_radius;
297        if (zode_data->altitude_shrinks)
298          alt_rad *= alt_bias;
299        LinearColorF alt_clr(zode_color.red, zode_color.green, zode_color.blue, zode_color.alpha);
300        if (zode_data->altitude_fades)
301          alt_clr.alpha *= alt_bias;
302        afxZodiacMgr::addInteriorZodiac(zode_pos, alt_rad, zode_vrange, alt_clr, zode_angle, zode_data);
303      }
304    }
305    else    
306      afxZodiacMgr::addInteriorZodiac(zode_pos, zode_radius, zode_vrange, zode_color, zode_angle, zode_data);
307  }
308
309  return true;
310}
311
312void afxEA_Zodiac::ea_finish(bool was_stopped)
313{
314  if (mIn_scope && mEW_timing.residue_lifetime > 0)
315  {
316    if (mDo_fades)
317    {
318      if (mFade_value < 0.01f)
319        return;
320      zode_color.alpha *= mFade_value;
321    }
322    if ((zode_data->zflags & afxZodiacDefs::SHOW_ON_TERRAIN) != 0)
323    {
324      if (do_altitude_bias && mTerrain_altitude > zode_data->altitude_falloff)
325      {
326        F32 alt_bias = calc_terrain_alt_bias();
327        if (alt_bias > 0.0f)
328        {
329          F32 alt_rad = zode_radius;
330          if (zode_data->altitude_shrinks)
331            alt_rad *= alt_bias;
332          LinearColorF alt_clr(zode_color.red, zode_color.green, zode_color.blue, zode_color.alpha);
333          if (zode_data->altitude_fades)
334            zode_color.alpha *= alt_bias;
335          became_residue = true;
336          afxResidueMgr::add_terrain_zodiac(mEW_timing.residue_lifetime, mEW_timing.residue_fadetime, zode_data, zode_pos, alt_rad,
337                                            alt_clr, zode_angle);
338        }
339      }
340      else
341      {
342        became_residue = true;
343        afxResidueMgr::add_terrain_zodiac(mEW_timing.residue_lifetime, mEW_timing.residue_fadetime, zode_data, zode_pos, zode_radius,
344                                          zode_color, zode_angle);
345      }
346    }
347    if ((zode_data->zflags & afxZodiacDefs::SHOW_ON_INTERIORS) != 0)
348    {
349      if (do_altitude_bias && mInterior_altitude > zode_data->altitude_falloff)
350      {
351        F32 alt_bias = calc_interior_alt_bias();
352        if (alt_bias > 0.0f)
353        {
354          F32 alt_rad = zode_radius;
355          if (zode_data->altitude_shrinks)
356            alt_rad *= alt_bias;
357          LinearColorF alt_clr(zode_color.red, zode_color.green, zode_color.blue, zode_color.alpha);
358          if (zode_data->altitude_fades)
359            zode_color.alpha *= alt_bias;
360
361          afxZodiacData* temp_zode = zode_data;
362          if (became_residue)
363            temp_zode = new afxZodiacData(*zode_data, true);
364          became_residue = true;
365          afxResidueMgr::add_interior_zodiac(mEW_timing.residue_lifetime, mEW_timing.residue_fadetime, temp_zode, zode_pos, alt_rad,
366                                             zode_vrange, alt_clr, zode_angle);
367        }
368
369      }
370      else
371      {
372        afxZodiacData* temp_zode = zode_data;
373        if (became_residue)
374          temp_zode = new afxZodiacData(*zode_data, true);
375        became_residue = true;
376        afxResidueMgr::add_interior_zodiac(mEW_timing.residue_lifetime, mEW_timing.residue_fadetime, temp_zode, zode_pos, zode_radius,
377                                           zode_vrange, zode_color, zode_angle);
378      }
379    }
380  }
381}
382
383void afxEA_Zodiac::do_runtime_substitutions()
384{
385  // only clone the datablock if there are substitutions
386  if (zode_data->getSubstitutionCount() > 0)
387  {
388    // clone the datablock and perform substitutions
389    afxZodiacData* orig_db = zode_data;
390    zode_data = new afxZodiacData(*orig_db, true);
391    orig_db->performSubstitutions(zode_data, mChoreographer, mGroup_index);
392  }
393}
394
395#undef myOffset
396#define myOffset(field) Offset(field, afxEA_Zodiac)
397
398void afxEA_Zodiac::initPersistFields()
399{
400  addField("liveColor",         TypeColorF,     myOffset(live_color),
401    "...");
402  addField("liveColorFactor",   TypeF32,        myOffset(live_color_factor),
403    "...");
404
405  Parent::initPersistFields();
406}
407
408//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
409
410class afxEA_ZodiacDesc : public afxEffectAdapterDesc, public afxEffectDefs 
411{
412  static afxEA_ZodiacDesc desc;
413
414public:
415  virtual bool  testEffectType(const SimDataBlock*) const;
416  virtual bool  requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
417  virtual bool  runsOnServer(const afxEffectWrapperData*) const { return false; }
418  virtual bool  runsOnClient(const afxEffectWrapperData*) const { return true; }
419
420  virtual afxEffectWrapper* create() const { return new afxEA_Zodiac; }
421};
422
423afxEA_ZodiacDesc afxEA_ZodiacDesc::desc;
424
425bool afxEA_ZodiacDesc::testEffectType(const SimDataBlock* db) const
426{
427  return (typeid(afxZodiacData) == typeid(*db));
428}
429
430bool afxEA_ZodiacDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
431{
432  return (timing.lifetime < 0);
433}
434
435//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
436