afxXM_GroundConform.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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 "afx/afxEffectWrapper.h"
  26. #include "afx/afxChoreographer.h"
  27. #include "afx/xm/afxXfmMod.h"
  28. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  29. class afxXM_GroundConformData : public afxXM_WeightedBaseData
  30. {
  31. typedef afxXM_WeightedBaseData Parent;
  32. public:
  33. F32 height;
  34. bool do_terrain;
  35. bool do_interiors;
  36. bool do_orientation;
  37. public:
  38. /*C*/ afxXM_GroundConformData();
  39. /*C*/ afxXM_GroundConformData(const afxXM_GroundConformData&, bool = false);
  40. void packData(BitStream* stream);
  41. void unpackData(BitStream* stream);
  42. virtual bool allowSubstitutions() const { return true; }
  43. static void initPersistFields();
  44. afxXM_Base* create(afxEffectWrapper* fx, bool on_server);
  45. DECLARE_CONOBJECT(afxXM_GroundConformData);
  46. DECLARE_CATEGORY("AFX");
  47. };
  48. class afxXM_GroundConform : public afxXM_WeightedBase
  49. {
  50. typedef afxXM_WeightedBase Parent;
  51. afxXM_GroundConformData* db;
  52. SceneContainer* container;
  53. public:
  54. /*C*/ afxXM_GroundConform(afxXM_GroundConformData*, afxEffectWrapper*, bool on_server);
  55. virtual void updateParams(F32 dt, F32 elapsed, afxXM_Params& params);
  56. };
  57. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  58. IMPLEMENT_CO_DATABLOCK_V1(afxXM_GroundConformData);
  59. ConsoleDocClass( afxXM_GroundConformData,
  60. "@brief An xmod datablock.\n\n"
  61. "@ingroup afxXMods\n"
  62. "@ingroup AFX\n"
  63. "@ingroup Datablocks\n"
  64. );
  65. afxXM_GroundConformData::afxXM_GroundConformData()
  66. {
  67. height = 0.0f;
  68. do_terrain = true;
  69. do_interiors = true;
  70. do_orientation = false;
  71. }
  72. afxXM_GroundConformData::afxXM_GroundConformData(const afxXM_GroundConformData& other, bool temp_clone) : afxXM_WeightedBaseData(other, temp_clone)
  73. {
  74. height = other.height;
  75. do_terrain = other.do_terrain;
  76. do_interiors = other.do_interiors;
  77. do_orientation = other.do_orientation;
  78. }
  79. void afxXM_GroundConformData::initPersistFields()
  80. {
  81. docsURL;
  82. addField("height", TypeF32, Offset(height, afxXM_GroundConformData),
  83. "...");
  84. addField("conformToTerrain", TypeBool, Offset(do_terrain, afxXM_GroundConformData),
  85. "...");
  86. addField("conformToInteriors", TypeBool, Offset(do_interiors, afxXM_GroundConformData),
  87. "...");
  88. addField("conformOrientation", TypeBool, Offset(do_orientation, afxXM_GroundConformData),
  89. "...");
  90. Parent::initPersistFields();
  91. }
  92. void afxXM_GroundConformData::packData(BitStream* stream)
  93. {
  94. Parent::packData(stream);
  95. stream->write(height);
  96. stream->write(do_terrain);
  97. stream->write(do_interiors);
  98. stream->write(do_orientation);
  99. }
  100. void afxXM_GroundConformData::unpackData(BitStream* stream)
  101. {
  102. Parent::unpackData(stream);
  103. stream->read(&height);
  104. stream->read(&do_terrain);
  105. stream->read(&do_interiors);
  106. stream->read(&do_orientation);
  107. }
  108. afxXM_Base* afxXM_GroundConformData::create(afxEffectWrapper* fx, bool on_server)
  109. {
  110. afxXM_GroundConformData* datablock = this;
  111. if (getSubstitutionCount() > 0)
  112. {
  113. datablock = new afxXM_GroundConformData(*this, true);
  114. this->performSubstitutions(datablock, fx->getChoreographer(), fx->getGroupIndex());
  115. }
  116. return new afxXM_GroundConform(datablock, fx, on_server);
  117. }
  118. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
  119. afxXM_GroundConform::afxXM_GroundConform(afxXM_GroundConformData* db, afxEffectWrapper* fxw, bool on_server)
  120. : afxXM_WeightedBase(db, fxw)
  121. {
  122. this->db = db;
  123. this->container = (on_server) ? &gServerContainer : &gClientContainer;
  124. }
  125. void afxXM_GroundConform::updateParams(F32 dt, F32 elapsed, afxXM_Params& params)
  126. {
  127. RayInfo rInfo;
  128. bool hit = false;
  129. if (db->do_interiors)
  130. {
  131. U32 mask = InteriorLikeObjectType;
  132. if (db->do_terrain)
  133. {
  134. mask |= TerrainObjectType | TerrainLikeObjectType;
  135. }
  136. Point3F above_pos(params.pos); above_pos.z += 0.1f;
  137. Point3F below_pos(params.pos); below_pos.z -= 10000;
  138. hit = container->castRay(above_pos, below_pos, mask, &rInfo);
  139. if (!hit)
  140. {
  141. above_pos.z = params.pos.z + 10000;
  142. below_pos.z = params.pos.z - 0.1f;
  143. hit = container->castRay(below_pos, above_pos, mask, &rInfo);
  144. }
  145. }
  146. else if (db->do_terrain)
  147. {
  148. U32 mask = TerrainObjectType | TerrainLikeObjectType;
  149. Point3F above_pos(params.pos); above_pos.z += 10000;
  150. Point3F below_pos(params.pos); below_pos.z -= 10000;
  151. hit = container->castRay(above_pos, below_pos, mask, &rInfo);
  152. }
  153. if (hit)
  154. {
  155. F32 terrain_z = rInfo.point.z;
  156. F32 wt_factor = calc_weight_factor(elapsed);
  157. F32 old_z = params.pos.z;
  158. F32 new_z = terrain_z + db->height;
  159. params.pos.z = ((1-wt_factor)*old_z) + ((wt_factor)*new_z);
  160. if (db->do_orientation)
  161. {
  162. Point3F x,y,z;
  163. z = rInfo.normal;
  164. z.normalize();
  165. params.ori.getColumn(1,&y);
  166. mCross(y,z,&x);
  167. x.normalize();
  168. mCross(z,x,&y);
  169. params.ori.setColumn(0,x);
  170. params.ori.setColumn(1,y);
  171. params.ori.setColumn(2,z);
  172. }
  173. }
  174. }
  175. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//