afxF_Drag.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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 "afx/forces/afxForce.h"
  27. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  28. class afxF_DragData : public afxForceData
  29. {
  30. typedef afxForceData Parent;
  31. public:
  32. F32 drag_coefficient;
  33. F32 air_density;
  34. F32 cross_sectional_area;
  35. public:
  36. /*C*/ afxF_DragData();
  37. /*C*/ afxF_DragData(const afxF_DragData&, bool = false);
  38. virtual void packData(BitStream* stream);
  39. virtual void unpackData(BitStream* stream);
  40. virtual afxForceData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
  41. static void initPersistFields();
  42. DECLARE_CONOBJECT(afxF_DragData);
  43. DECLARE_CATEGORY("AFX");
  44. };
  45. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  46. class afxF_Drag : public afxForce
  47. {
  48. typedef afxForce Parent;
  49. private:
  50. afxF_DragData* mDatablock;
  51. F32 air_friction_constant;
  52. public:
  53. /*C*/ afxF_Drag();
  54. virtual bool onNewDataBlock(afxForceData* dptr, bool reload);
  55. virtual void start();
  56. virtual Point3F evaluate(Point3F pos, Point3F v, F32 mass);
  57. };
  58. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  59. // afxDragData
  60. IMPLEMENT_CO_DATABLOCK_V1(afxF_DragData);
  61. ConsoleDocClass( afxF_DragData,
  62. "@brief A datablock for specifiying AFX drag forces.\n\n"
  63. "@ingroup afxExperimental\n"
  64. "@ingroup AFX\n"
  65. "@ingroup Datablocks\n"
  66. );
  67. afxF_DragData::afxF_DragData()
  68. {
  69. air_density = 1.2250f;
  70. cross_sectional_area = 0.75f; // this variable isn't exposed to the user to keep things simple
  71. drag_coefficient = 1.0f;
  72. }
  73. afxF_DragData::afxF_DragData(const afxF_DragData& other, bool temp_clone) : afxForceData(other, temp_clone)
  74. {
  75. air_density = other.air_density;
  76. cross_sectional_area = other.cross_sectional_area;
  77. drag_coefficient = other.drag_coefficient;
  78. }
  79. #define myOffset(field) Offset(field, afxF_DragData)
  80. void afxF_DragData::initPersistFields()
  81. {
  82. addField("drag", TypeF32, myOffset(drag_coefficient),
  83. "...");
  84. addField("airDensity", TypeF32, myOffset(air_density),
  85. "...");
  86. addField("crossSectionalArea", TypeF32, myOffset(cross_sectional_area),
  87. "...");
  88. Parent::initPersistFields();
  89. }
  90. void afxF_DragData::packData(BitStream* stream)
  91. {
  92. Parent::packData(stream);
  93. stream->write(drag_coefficient);
  94. stream->write(air_density);
  95. stream->write(cross_sectional_area);
  96. }
  97. void afxF_DragData::unpackData(BitStream* stream)
  98. {
  99. Parent::unpackData(stream);
  100. stream->read(&drag_coefficient);
  101. stream->read(&air_density);
  102. stream->read(&cross_sectional_area);
  103. }
  104. afxForceData* afxF_DragData::cloneAndPerformSubstitutions(const SimObject* owner, S32 index)
  105. {
  106. afxF_DragData* drag_data = this;
  107. // only clone the datablock if there are substitutions
  108. if (this->getSubstitutionCount() > 0)
  109. {
  110. // clone the datablock and perform substitutions
  111. afxF_DragData* orig_db = this;
  112. drag_data = new afxF_DragData(*orig_db, true);
  113. orig_db->performSubstitutions(drag_data, owner, index);
  114. }
  115. return drag_data;
  116. }
  117. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  118. afxF_Drag::afxF_Drag() : afxForce()
  119. {
  120. mDatablock = NULL;
  121. air_friction_constant = 1.0f;
  122. }
  123. bool afxF_Drag::onNewDataBlock(afxForceData* dptr, bool reload)
  124. {
  125. mDatablock = dynamic_cast<afxF_DragData*>(dptr);
  126. if (!mDatablock || !Parent::onNewDataBlock(dptr, reload))
  127. return false;
  128. return true;
  129. }
  130. void afxF_Drag::start()
  131. {
  132. air_friction_constant = 0.5f * mDatablock->drag_coefficient
  133. * mDatablock->air_density
  134. * mDatablock->cross_sectional_area;
  135. //Con::printf("Air Friction: %f", air_friction_constant);
  136. }
  137. Point3F afxF_Drag::evaluate(Point3F pos, Point3F velocity, F32 mass)
  138. {
  139. // This implements the standard drag equation for object's at high speeds.
  140. // F-drag = 1/2pACv^2
  141. // p = medium (air) density
  142. // A = cross-sectional area of moving object (plane perpendicular to direction of motion)
  143. // C = coefficient of drag
  144. // -- Velocity here should actually be relative to the velocity of the fluid... (relative speed)
  145. // (is it already?)
  146. F32 drag = air_friction_constant*velocity.magnitudeSafe();
  147. // Here, velocity is normalized just to get a direction vector.
  148. // Drag is in the direction opposite velocity. Is this right?
  149. velocity.normalizeSafe();
  150. return (velocity*-drag*mass);
  151. }
  152. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  153. class afxF_DragDesc : public afxForceDesc
  154. {
  155. static afxF_DragDesc desc;
  156. public:
  157. virtual bool testForceType(const SimDataBlock*) const;
  158. virtual afxForce* create() const { return new afxF_Drag; }
  159. };
  160. afxF_DragDesc afxF_DragDesc::desc;
  161. bool afxF_DragDesc::testForceType(const SimDataBlock* db) const
  162. {
  163. return (typeid(afxF_DragData) == typeid(*db));
  164. }
  165. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//