afxAnimClip.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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 "afx/arcaneFX.h"
  25. #include "console/consoleTypes.h"
  26. #include "core/stream/bitStream.h"
  27. #include "afx/ce/afxAnimClip.h"
  28. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  29. // afxAnimClipData
  30. IMPLEMENT_CO_DATABLOCK_V1(afxAnimClipData);
  31. ConsoleDocClass( afxAnimClipData,
  32. "@brief A datablock that specifies an Animation Clip effect.\n\n"
  33. "An Animation Clip forces a target ShapeBase-derived object, such as Player or AIPlayer, to perform a particular "
  34. "animation sequence. Animation Clip does not supply any new animation data, but simply selects, by name, a "
  35. "sequence that is already defined in the target. Animation Clip can also target afxModel effects within the same "
  36. "choreographer."
  37. "\n\n"
  38. "The target of an Animation Clip is the constraint source object specified by the posConstraint field of the enclosing "
  39. "effect wrapper. The target must be a ShapeBase-derived object, or an afxModel and it must contain an animation "
  40. "sequence with the same name as the clipName field."
  41. "\n\n"
  42. "Animation Clip controls the rate of animation playback and can even play a sequence in reverse. When an Animation "
  43. "Clip selects a blended animation sequence, it is mixed with the current animation instead of replacing it. Animation "
  44. "Clips can be used to activate multiple, overlapping blend sequences."
  45. "\n\n"
  46. "Normally when an Animation Clip is applied to a user-controlled Player, any interactive user actions will override the "
  47. "animation selected by the clip, but Animation Clips can be configured to temporarily block out some user actions for "
  48. "the duration of the clip."
  49. "\n\n"
  50. "@ingroup afxEffects\n"
  51. "@ingroup AFX\n"
  52. "@ingroup Datablocks\n"
  53. );
  54. afxAnimClipData::afxAnimClipData()
  55. {
  56. clip_name = ST_NULLSTRING;
  57. rate = 1.0f;
  58. pos_offset = 0.0;
  59. trans = 0.12f;
  60. flags = 0;
  61. ignore_disabled = false;
  62. ignore_enabled = false;
  63. is_death_anim = false;
  64. lock_anim = false;
  65. ignore_first_person = false;
  66. ignore_third_person = false;
  67. }
  68. afxAnimClipData::afxAnimClipData(const afxAnimClipData& other, bool temp_clone) : GameBaseData(other, temp_clone)
  69. {
  70. clip_name = other.clip_name;
  71. rate = other.rate;
  72. pos_offset = other.pos_offset;
  73. trans = other.trans;
  74. flags = other.flags;
  75. expand_flags();
  76. }
  77. void afxAnimClipData::onStaticModified(const char* slot, const char* newValue)
  78. {
  79. Parent::onStaticModified(slot, newValue);
  80. merge_flags();
  81. }
  82. #define myOffset(field) Offset(field, afxAnimClipData)
  83. void afxAnimClipData::initPersistFields()
  84. {
  85. docsURL;
  86. addField("clipName", TYPEID< StringTableEntry >(), myOffset(clip_name),
  87. "The name of an animation sequence to be played by a ShapeBase-derived object to which this effect is "
  88. "constrained. Also works on afxModel effects.\n"
  89. "default: \"\"\n");
  90. addField("rate", TYPEID< F32 >(), myOffset(rate),
  91. "The desired playback speed for the sequence. A value of 1.0 indicates forward playback at a normal rate. Negative "
  92. "values cause the sequence to play backwards.\n"
  93. "default: 1.0\n");
  94. addField("posOffset", TYPEID< F32 >(), myOffset(pos_offset),
  95. "Sets a starting offset for the selected animation clip. It directly specifies an animation thread position in the 0.0 to "
  96. "1.0 range as a fraction of the clip's duration.\n"
  97. "default: 1.0\n");
  98. addField("transitionTime", TYPEID< F32 >(), myOffset(trans),
  99. "The duration in which the active animation overlaps and blends into the sequence selected by the animation clip.\n"
  100. "default: 0.12\n");
  101. addField("ignoreCorpse", TYPEID< bool >(), myOffset(ignore_disabled),
  102. "Specifies if the animation clip should not be applied to corpses or anything else with a disabled damage state.\n"
  103. "default: false\n");
  104. addField("ignoreLiving", TYPEID< bool >(), myOffset(ignore_enabled),
  105. "Specifies if the animation clip should not be applied to living objects or anything else with an enabled damage "
  106. "state.\n"
  107. "default: false\n");
  108. addField("treatAsDeathAnim", TYPEID< bool >(), myOffset(is_death_anim),
  109. "Indicates if the animation clip is a death animation. If the target object dies during the effect, this will prevent "
  110. "the object from playing another standard death animation after this clip finishes.\n"
  111. "default: false\n");
  112. addField("lockAnimation", TYPEID< bool >(), myOffset(lock_anim),
  113. "Indicates if user control of a Player should be temporarily blocked during the clip. (See afxAnimLockData.)\n"
  114. "default: false\n");
  115. addField("ignoreFirstPerson", TYPEID< bool >(), myOffset(ignore_first_person),
  116. "If true, the clip will not be played on targets that are the control object and the camera is in first person mode.\n"
  117. "default: false\n");
  118. addField("ignoreThirdPerson", TYPEID< bool >(), myOffset(ignore_third_person),
  119. "If true, the clip will not be played on targets that are the control object and the camera is in third person mode.\n"
  120. "default: false\n");
  121. // synonyms
  122. addField("ignoreDisabled", TYPEID< bool >(), myOffset(ignore_disabled),
  123. "A synonym for ignoreLiving.");
  124. addField("ignoreEnabled", TYPEID< bool >(), myOffset(ignore_enabled),
  125. "A synonym for ignoreCorpse.");
  126. Parent::initPersistFields();
  127. }
  128. bool afxAnimClipData::onAdd()
  129. {
  130. if (Parent::onAdd() == false)
  131. return false;
  132. return true;
  133. }
  134. void afxAnimClipData::packData(BitStream* stream)
  135. {
  136. Parent::packData(stream);
  137. merge_flags();
  138. stream->writeString(clip_name);
  139. stream->write(rate);
  140. stream->write(pos_offset);
  141. stream->write(trans);
  142. stream->write(flags);
  143. }
  144. void afxAnimClipData::unpackData(BitStream* stream)
  145. {
  146. Parent::unpackData(stream);
  147. clip_name = stream->readSTString();
  148. stream->read(&rate);
  149. stream->read(&pos_offset);
  150. stream->read(&trans);
  151. stream->read(&flags);
  152. expand_flags();
  153. }
  154. bool afxAnimClipData::writeField(StringTableEntry fieldname, const char* value)
  155. {
  156. if (!Parent::writeField(fieldname, value))
  157. return false;
  158. // don't write the synonyms
  159. if( fieldname == StringTable->insert("ignoreDisabled") )
  160. return false;
  161. if( fieldname == StringTable->insert("ignoreEnabled") )
  162. return false;
  163. return true;
  164. }
  165. void afxAnimClipData::expand_flags()
  166. {
  167. ignore_disabled = ((flags & IGNORE_DISABLED) != 0);
  168. ignore_enabled = ((flags & IGNORE_ENABLED) != 0);
  169. lock_anim = ((flags & BLOCK_USER_CONTROL) != 0);
  170. is_death_anim = ((flags & IS_DEATH_ANIM) != 0);
  171. ignore_first_person = ((flags & IGNORE_FIRST_PERSON) != 0);
  172. ignore_third_person = ((flags & IGNORE_THIRD_PERSON) != 0);
  173. }
  174. void afxAnimClipData::merge_flags()
  175. {
  176. flags = (((ignore_disabled) ? IGNORE_DISABLED : 0) |
  177. ((ignore_enabled) ? IGNORE_ENABLED : 0) |
  178. ((lock_anim) ? BLOCK_USER_CONTROL : 0) |
  179. ((ignore_first_person) ? IGNORE_FIRST_PERSON : 0) |
  180. ((ignore_third_person) ? IGNORE_THIRD_PERSON : 0) |
  181. ((is_death_anim) ? IS_DEATH_ANIM : 0));
  182. }
  183. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//