afxXM_GroundConform.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. addField("height", TypeF32, Offset(height, afxXM_GroundConformData),
  82. "...");
  83. addField("conformToTerrain", TypeBool, Offset(do_terrain, afxXM_GroundConformData),
  84. "...");
  85. addField("conformToInteriors", TypeBool, Offset(do_interiors, afxXM_GroundConformData),
  86. "...");
  87. addField("conformOrientation", TypeBool, Offset(do_orientation, afxXM_GroundConformData),
  88. "...");
  89. Parent::initPersistFields();
  90. }
  91. void afxXM_GroundConformData::packData(BitStream* stream)
  92. {
  93. Parent::packData(stream);
  94. stream->write(height);
  95. stream->write(do_terrain);
  96. stream->write(do_interiors);
  97. stream->write(do_orientation);
  98. }
  99. void afxXM_GroundConformData::unpackData(BitStream* stream)
  100. {
  101. Parent::unpackData(stream);
  102. stream->read(&height);
  103. stream->read(&do_terrain);
  104. stream->read(&do_interiors);
  105. stream->read(&do_orientation);
  106. }
  107. afxXM_Base* afxXM_GroundConformData::create(afxEffectWrapper* fx, bool on_server)
  108. {
  109. afxXM_GroundConformData* datablock = this;
  110. if (getSubstitutionCount() > 0)
  111. {
  112. datablock = new afxXM_GroundConformData(*this, true);
  113. this->performSubstitutions(datablock, fx->getChoreographer(), fx->getGroupIndex());
  114. }
  115. return new afxXM_GroundConform(datablock, fx, on_server);
  116. }
  117. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
  118. afxXM_GroundConform::afxXM_GroundConform(afxXM_GroundConformData* db, afxEffectWrapper* fxw, bool on_server)
  119. : afxXM_WeightedBase(db, fxw)
  120. {
  121. this->db = db;
  122. this->container = (on_server) ? &gServerContainer : &gClientContainer;
  123. }
  124. void afxXM_GroundConform::updateParams(F32 dt, F32 elapsed, afxXM_Params& params)
  125. {
  126. RayInfo rInfo;
  127. bool hit = false;
  128. if (db->do_interiors)
  129. {
  130. U32 mask = InteriorLikeObjectType;
  131. if (db->do_terrain)
  132. {
  133. mask |= TerrainObjectType | TerrainLikeObjectType;
  134. }
  135. Point3F above_pos(params.pos); above_pos.z += 0.1f;
  136. Point3F below_pos(params.pos); below_pos.z -= 10000;
  137. hit = container->castRay(above_pos, below_pos, mask, &rInfo);
  138. if (!hit)
  139. {
  140. above_pos.z = params.pos.z + 10000;
  141. below_pos.z = params.pos.z - 0.1f;
  142. hit = container->castRay(below_pos, above_pos, mask, &rInfo);
  143. }
  144. }
  145. else if (db->do_terrain)
  146. {
  147. U32 mask = TerrainObjectType | TerrainLikeObjectType;
  148. Point3F above_pos(params.pos); above_pos.z += 10000;
  149. Point3F below_pos(params.pos); below_pos.z -= 10000;
  150. hit = container->castRay(above_pos, below_pos, mask, &rInfo);
  151. }
  152. if (hit)
  153. {
  154. F32 terrain_z = rInfo.point.z;
  155. F32 wt_factor = calc_weight_factor(elapsed);
  156. F32 old_z = params.pos.z;
  157. F32 new_z = terrain_z + db->height;
  158. params.pos.z = ((1-wt_factor)*old_z) + ((wt_factor)*new_z);
  159. if (db->do_orientation)
  160. {
  161. Point3F x,y,z;
  162. z = rInfo.normal;
  163. z.normalize();
  164. params.ori.getColumn(1,&y);
  165. mCross(y,z,&x);
  166. x.normalize();
  167. mCross(z,x,&y);
  168. params.ori.setColumn(0,x);
  169. params.ori.setColumn(1,y);
  170. params.ori.setColumn(2,z);
  171. }
  172. }
  173. }
  174. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//