afxEA_Model.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  2. // Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
  3. // Copyright (C) 2015 Faust Logic, Inc.
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to
  7. // deal in the Software without restriction, including without limitation the
  8. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9. // sell copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. // IN THE SOFTWARE.
  22. //
  23. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  24. #include <typeinfo>
  25. #include "afx/arcaneFX.h"
  26. #include "ts/tsShapeInstance.h"
  27. #include "afx/afxEffectDefs.h"
  28. #include "afx/afxEffectWrapper.h"
  29. #include "afx/afxChoreographer.h"
  30. #include "afx/afxResidueMgr.h"
  31. #include "afx/ce/afxModel.h"
  32. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  33. // afxEA_Model -- This is the adapter for afxModel, a lightweight animated model effect.
  34. class afxEA_Model : public afxEffectWrapper
  35. {
  36. typedef afxEffectWrapper Parent;
  37. afxModelData* model_data;
  38. afxModel* model;
  39. void do_runtime_substitutions();
  40. public:
  41. /*C*/ afxEA_Model();
  42. /*D*/ ~afxEA_Model();
  43. virtual void ea_set_datablock(SimDataBlock*);
  44. virtual bool ea_start();
  45. virtual bool ea_update(F32 dt);
  46. virtual void ea_finish(bool was_stopped);
  47. virtual void ea_set_scope_status(bool flag);
  48. virtual void onDeleteNotify(SimObject*);
  49. virtual void getUpdatedBoxCenter(Point3F& pos);
  50. virtual TSShape* getTSShape();
  51. virtual TSShapeInstance* getTSShapeInstance();
  52. virtual SceneObject* ea_get_scene_object() const;
  53. virtual U32 ea_get_triggers() const;
  54. virtual U32 setAnimClip(const char* clip, F32 pos, F32 rate, F32 trans);
  55. virtual void resetAnimation(U32 tag);
  56. virtual F32 getAnimClipDuration(const char* clip);
  57. };
  58. afxEA_Model::afxEA_Model()
  59. {
  60. model_data = 0;
  61. model = 0;
  62. }
  63. afxEA_Model::~afxEA_Model()
  64. {
  65. if (model)
  66. model->deleteObject();
  67. if (model_data && model_data->isTempClone())
  68. delete model_data;
  69. model_data = 0;
  70. }
  71. void afxEA_Model::ea_set_datablock(SimDataBlock* db)
  72. {
  73. model_data = dynamic_cast<afxModelData*>(db);
  74. }
  75. bool afxEA_Model::ea_start()
  76. {
  77. if (!model_data)
  78. {
  79. Con::errorf("afxEA_Model::ea_start() -- missing or incompatible datablock.");
  80. return false;
  81. }
  82. do_runtime_substitutions();
  83. return true;
  84. }
  85. bool afxEA_Model::ea_update(F32 dt)
  86. {
  87. if (!model)
  88. {
  89. // create and register effect
  90. model = new afxModel();
  91. model->onNewDataBlock(model_data, false);
  92. if (!model->registerObject())
  93. {
  94. delete model;
  95. model = 0;
  96. Con::errorf("afxEA_Model::ea_update() -- effect failed to register.");
  97. return false;
  98. }
  99. deleteNotify(model);
  100. model->setSequenceRateFactor(mDatablock->rate_factor/ mProp_time_factor);
  101. model->setSortPriority(mDatablock->sort_priority);
  102. }
  103. if (model)
  104. {
  105. if (mDo_fades)
  106. {
  107. model->setFadeAmount(mFade_value);
  108. }
  109. model->setTransform(mUpdated_xfm);
  110. model->setScale(mUpdated_scale);
  111. }
  112. return true;
  113. }
  114. void afxEA_Model::ea_finish(bool was_stopped)
  115. {
  116. if (!model)
  117. return;
  118. if (mIn_scope && mEW_timing.residue_lifetime > 0)
  119. {
  120. clearNotify(model);
  121. afxResidueMgr::add(mEW_timing.residue_lifetime, mEW_timing.residue_fadetime, model);
  122. model = 0;
  123. }
  124. else
  125. {
  126. model->deleteObject();
  127. model = 0;
  128. }
  129. }
  130. void afxEA_Model::ea_set_scope_status(bool in_scope)
  131. {
  132. if (model)
  133. model->setVisibility(in_scope);
  134. }
  135. void afxEA_Model::onDeleteNotify(SimObject* obj)
  136. {
  137. if (model == dynamic_cast<afxModel*>(obj))
  138. model = 0;
  139. Parent::onDeleteNotify(obj);
  140. }
  141. void afxEA_Model::getUpdatedBoxCenter(Point3F& pos)
  142. {
  143. if (model)
  144. pos = model->getBoxCenter();
  145. }
  146. TSShape* afxEA_Model::getTSShape()
  147. {
  148. return (model) ? model->getTSShape() : 0;
  149. }
  150. TSShapeInstance* afxEA_Model::getTSShapeInstance()
  151. {
  152. return (model) ? model->getTSShapeInstance() : 0;
  153. }
  154. SceneObject* afxEA_Model::ea_get_scene_object() const
  155. {
  156. return model;
  157. }
  158. U32 afxEA_Model::ea_get_triggers() const
  159. {
  160. TSShapeInstance* shape_inst = model->getTSShapeInstance();
  161. return (shape_inst) ? shape_inst->getTriggerStateMask() : 0;
  162. }
  163. void afxEA_Model::do_runtime_substitutions()
  164. {
  165. // only clone the datablock if there are substitutions
  166. if (model_data->getSubstitutionCount() > 0)
  167. {
  168. // clone the datablock and perform substitutions
  169. afxModelData* orig_db = model_data;
  170. model_data = new afxModelData(*orig_db, true);
  171. orig_db->performSubstitutions(model_data, mChoreographer, mGroup_index);
  172. }
  173. }
  174. U32 afxEA_Model::setAnimClip(const char* clip, F32 pos, F32 rate, F32 trans)
  175. {
  176. return (model) ? model->setAnimClip(clip, pos, rate, trans) : 0;
  177. }
  178. void afxEA_Model::resetAnimation(U32 tag)
  179. {
  180. if (model)
  181. model->resetAnimation(tag);
  182. }
  183. F32 afxEA_Model::getAnimClipDuration(const char* clip)
  184. {
  185. return (model) ? model->getAnimClipDuration(clip) : 0;
  186. }
  187. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  188. class afxEA_ModelDesc : public afxEffectAdapterDesc, public afxEffectDefs
  189. {
  190. static afxEA_ModelDesc desc;
  191. public:
  192. virtual bool testEffectType(const SimDataBlock*) const;
  193. virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const;
  194. virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; }
  195. virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; }
  196. virtual afxEffectWrapper* create() const { return new afxEA_Model; }
  197. };
  198. //~~~~~~~~~~~~~~~~~~~~//
  199. afxEA_ModelDesc afxEA_ModelDesc::desc;
  200. bool afxEA_ModelDesc::testEffectType(const SimDataBlock* db) const
  201. {
  202. return (typeid(afxModelData) == typeid(*db));
  203. }
  204. bool afxEA_ModelDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const
  205. {
  206. return (timing.lifetime < 0);
  207. }
  208. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//