Torque3D Documentation / _generateds / afxEA_CollisionEvent.cpp

afxEA_CollisionEvent.cpp

Engine/source/afx/ea/afxEA_CollisionEvent.cpp

More...

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#include "afx/afxEffectDefs.h"
 30#include "afx/afxEffectWrapper.h"
 31#include "afx/afxChoreographer.h"
 32#include "afx/ce/afxCollisionEvent.h"
 33
 34//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 35// afxEA_CollisionEvent 
 36
 37class afxEA_CollisionEvent : public afxEffectWrapper, ShapeBase::CollisionEventCallback
 38{
 39  typedef afxEffectWrapper Parent;
 40
 41  afxCollisionEventData*  script_data;
 42  ShapeBase*              shape;
 43  U32                     trigger_mask;
 44  bool                    triggered;
 45
 46  void              do_runtime_substitutions();
 47  void              set_shape(ShapeBase*);
 48
 49public:
 50  /*C*/             afxEA_CollisionEvent();
 51  /*D*/             ~afxEA_CollisionEvent();
 52
 53  virtual void      ea_set_datablock(SimDataBlock*);
 54  virtual bool      ea_start();
 55  virtual bool      ea_update(F32 dt);
 56  virtual void      ea_finish(bool was_stopped);
 57
 58  virtual void      collisionNotify(SceneObject* obj0, SceneObject* obj1, const VectorF& vel);
 59  virtual void      onDeleteNotify(SimObject*);
 60};
 61
 62//~~~~~~~~~~~~~~~~~~~~//
 63
 64afxEA_CollisionEvent::afxEA_CollisionEvent()
 65{
 66  script_data = 0;
 67  shape = 0;
 68  trigger_mask = 0;
 69  triggered = false;
 70}
 71
 72afxEA_CollisionEvent::~afxEA_CollisionEvent()
 73{
 74  if (shape)
 75    clearNotify(shape);
 76  if (script_data && script_data->isTempClone())
 77    delete script_data;
 78  script_data = 0;
 79}
 80
 81void afxEA_CollisionEvent::ea_set_datablock(SimDataBlock* db)
 82{
 83  script_data = dynamic_cast<afxCollisionEventData*>(db);
 84}
 85
 86bool afxEA_CollisionEvent::ea_start()
 87{
 88  if (!script_data)
 89  {
 90    Con::errorf("afxEA_CollisionEvent::ea_start() -- missing or incompatible datablock.");
 91    return false;
 92  }
 93
 94  do_runtime_substitutions();
 95
 96  if (script_data->gen_trigger && script_data->trigger_bit < 32)
 97    trigger_mask = 1 << script_data->trigger_bit;
 98  else
 99    trigger_mask = 0;
100
101  triggered = false;
102
103  return true;
104}
105
106bool afxEA_CollisionEvent::ea_update(F32 dt)
107{
108  afxConstraint* pos_constraint = getPosConstraint();
109  set_shape((pos_constraint) ? dynamic_cast<ShapeBase*>(pos_constraint->getSceneObject()) : 0);
110
111  if (mChoreographer && trigger_mask != 0)
112  {
113    if (triggered)
114    {
115      mChoreographer->setTriggerMask(trigger_mask | mChoreographer->getTriggerMask());
116      triggered = false;
117    }
118    else
119    {
120      mChoreographer->setTriggerMask(~trigger_mask & mChoreographer->getTriggerMask());
121    }
122  }
123
124  return true;
125}
126
127void afxEA_CollisionEvent::ea_finish(bool was_stopped)
128{
129  set_shape(0);
130}
131
132void afxEA_CollisionEvent::do_runtime_substitutions()
133{
134  // only clone the datablock if there are substitutions
135  if (script_data->getSubstitutionCount() > 0)
136  {
137    // clone the datablock and perform substitutions
138    afxCollisionEventData* orig_db = script_data;
139    script_data = new afxCollisionEventData(*orig_db, true);
140    orig_db->performSubstitutions(script_data, mChoreographer, mGroup_index);
141  }
142}
143
144void afxEA_CollisionEvent::set_shape(ShapeBase* new_shape)
145{
146  if (shape == new_shape)
147    return;
148
149  if (shape)
150  {
151    shape->unregisterCollisionCallback(this);
152    clearNotify(shape);
153  }
154  
155  shape = new_shape;
156
157  if (shape)
158  {
159   deleteNotify(shape);
160   shape->registerCollisionCallback(this);
161  }
162}
163
164void afxEA_CollisionEvent::collisionNotify(SceneObject* obj0, SceneObject* obj1, const VectorF& vel)
165{
166  if (obj0 != shape || !mChoreographer || !mChoreographer->getDataBlock())
167    return;
168
169  if (script_data->method_name != ST_NULLSTRING)
170  {
171    char *arg_buf = Con::getArgBuffer(64);
172    dSprintf(arg_buf, 256, "%g %g %g", vel.x, vel.y, vel.z);
173
174    // CALL SCRIPT afxChoreographerData::method(%spell, %obj0, %obj1, %velocity)
175    Con::executef(mChoreographer->getDataBlock(), script_data->method_name,
176                  mChoreographer->getIdString(),
177                  (obj0) ? obj0->getIdString() : "", 
178                  (obj1) ? obj1->getIdString() : "",
179                  arg_buf,
180                  script_data->script_data);
181  }
182
183  if (!triggered && trigger_mask != 0)
184    triggered = true;
185}
186
187void afxEA_CollisionEvent::onDeleteNotify(SimObject* obj)
188{
189  if (obj == shape)
190  {
191    shape->unregisterCollisionCallback(this);
192    shape = 0;
193  }
194
195  Parent::onDeleteNotify(obj);
196}
197
198//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
199
200class afxEA_CollisionEventDesc : public afxEffectAdapterDesc, public afxEffectDefs 
201{
202  static afxEA_CollisionEventDesc desc;
203
204public:
205  virtual bool  testEffectType(const SimDataBlock*) const;
206  virtual bool  requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
207  virtual bool  runsOnServer(const afxEffectWrapperData*) const { return true; }
208  virtual bool  runsOnClient(const afxEffectWrapperData*) const { return false; }
209  virtual bool  isPositional(const afxEffectWrapperData*) const { return false; }
210
211  virtual afxEffectWrapper* create() const { return new afxEA_CollisionEvent; }
212};
213
214afxEA_CollisionEventDesc afxEA_CollisionEventDesc::desc;
215
216bool afxEA_CollisionEventDesc::testEffectType(const SimDataBlock* db) const
217{
218  return (typeid(afxCollisionEventData) == typeid(*db));
219}
220
221bool afxEA_CollisionEventDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
222{
223  return (timing.lifetime < 0);
224}
225
226//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
227