afxF_Drag.cpp

Engine/source/afx/forces/afxF_Drag.cpp

More...

Classes:

Public Defines

define
myOffset(field) (field, )

Public Functions

ConsoleDocClass(afxF_DragData , "@brief A datablock <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> specifiying AFX drag <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">forces.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxExperimental\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )

Detailed Description

Public Defines

myOffset(field) (field, )

Public Functions

ConsoleDocClass(afxF_DragData , "@brief A datablock <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> specifiying AFX drag <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">forces.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxExperimental\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )

IMPLEMENT_CO_DATABLOCK_V1(afxF_DragData )

  1
  2
  3//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  4// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
  5// Copyright (C) 2015 Faust Logic, Inc.
  6//
  7// Permission is hereby granted, free of charge, to any person obtaining a copy
  8// of this software and associated documentation files (the "Software"), to
  9// deal in the Software without restriction, including without limitation the
 10// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 11// sell copies of the Software, and to permit persons to whom the Software is
 12// furnished to do so, subject to the following conditions:
 13//
 14// The above copyright notice and this permission notice shall be included in
 15// all copies or substantial portions of the Software.
 16//
 17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 23// IN THE SOFTWARE.
 24//
 25//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 26
 27#include <typeinfo>
 28#include "afx/arcaneFX.h"
 29
 30#include "afx/forces/afxForce.h"
 31
 32//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 33
 34class afxF_DragData : public afxForceData
 35{
 36  typedef afxForceData Parent;
 37
 38public:
 39  F32             drag_coefficient;
 40  F32             air_density;
 41  F32             cross_sectional_area;
 42
 43public:
 44  /*C*/           afxF_DragData();
 45  /*C*/           afxF_DragData(const afxF_DragData&, bool = false);
 46  
 47  virtual void    packData(BitStream* stream);
 48  virtual void    unpackData(BitStream* stream);
 49  virtual afxForceData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
 50
 51  static void     initPersistFields();
 52
 53  DECLARE_CONOBJECT(afxF_DragData);
 54  DECLARE_CATEGORY("AFX");
 55};
 56
 57//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 58
 59class afxF_Drag : public afxForce
 60{
 61  typedef afxForce Parent;
 62
 63private:
 64  afxF_DragData*  mDatablock;
 65  F32             air_friction_constant;
 66
 67public:
 68  /*C*/           afxF_Drag();
 69
 70  virtual bool    onNewDataBlock(afxForceData* dptr, bool reload);
 71
 72  virtual void    start();
 73  virtual Point3F evaluate(Point3F pos, Point3F v, F32 mass);
 74};
 75
 76//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 77// afxDragData
 78
 79IMPLEMENT_CO_DATABLOCK_V1(afxF_DragData);
 80
 81ConsoleDocClass( afxF_DragData,
 82   "@brief A datablock for specifiying AFX drag forces.\n\n"
 83
 84   "@ingroup afxExperimental\n"
 85   "@ingroup AFX\n"
 86   "@ingroup Datablocks\n"
 87);
 88
 89afxF_DragData::afxF_DragData()
 90{
 91  air_density = 1.2250f; 
 92  cross_sectional_area = 0.75f;  // this variable isn't exposed to the user to keep things simple
 93  drag_coefficient = 1.0f;
 94}
 95
 96afxF_DragData::afxF_DragData(const afxF_DragData& other, bool temp_clone) : afxForceData(other, temp_clone)
 97{
 98  air_density = other.air_density;
 99  cross_sectional_area = other.cross_sectional_area;
100  drag_coefficient = other.drag_coefficient;
101}
102
103#define myOffset(field) Offset(field, afxF_DragData)
104
105void afxF_DragData::initPersistFields()
106{
107  addField("drag",                TypeF32,      myOffset(drag_coefficient),
108    "...");
109  addField("airDensity",          TypeF32,      myOffset(air_density),
110    "...");
111  addField("crossSectionalArea",  TypeF32,      myOffset(cross_sectional_area),
112    "...");
113
114  Parent::initPersistFields();
115}
116
117void afxF_DragData::packData(BitStream* stream)
118{
119   Parent::packData(stream);
120  stream->write(drag_coefficient);
121  stream->write(air_density);
122  stream->write(cross_sectional_area);
123}
124
125void afxF_DragData::unpackData(BitStream* stream)
126{
127  Parent::unpackData(stream);
128  stream->read(&drag_coefficient);
129  stream->read(&air_density);
130  stream->read(&cross_sectional_area);
131}
132
133afxForceData* afxF_DragData::cloneAndPerformSubstitutions(const SimObject* owner, S32 index)
134{
135  afxF_DragData* drag_data = this;
136
137  // only clone the datablock if there are substitutions
138  if (this->getSubstitutionCount() > 0)
139  {
140    // clone the datablock and perform substitutions
141    afxF_DragData* orig_db = this;
142    drag_data = new afxF_DragData(*orig_db, true);
143    orig_db->performSubstitutions(drag_data, owner, index);
144  }
145
146  return drag_data;
147}
148
149//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
150
151afxF_Drag::afxF_Drag() : afxForce()
152{
153  mDatablock = NULL;
154  air_friction_constant = 1.0f;
155}
156
157bool afxF_Drag::onNewDataBlock(afxForceData* dptr, bool reload)
158{
159   mDatablock = dynamic_cast<afxF_DragData*>(dptr);
160  if (!mDatablock || !Parent::onNewDataBlock(dptr, reload))
161    return false;
162
163  return true;
164}
165
166void afxF_Drag::start()
167{
168  air_friction_constant = 0.5f * mDatablock->drag_coefficient
169                               * mDatablock->air_density
170                               * mDatablock->cross_sectional_area;
171  //Con::printf("Air Friction: %f", air_friction_constant);
172}
173
174Point3F afxF_Drag::evaluate(Point3F pos, Point3F velocity, F32 mass)
175{
176  // This implements the standard drag equation for object's at high speeds.
177  // F-drag = 1/2pACv^2
178  //   p = medium (air) density
179  //   A = cross-sectional area of moving object (plane perpendicular to direction of motion)
180  //   C = coefficient of drag
181
182  // -- Velocity here should actually be relative to the velocity of the fluid... (relative speed)
183  //      (is it already?)
184  F32 drag = air_friction_constant*velocity.magnitudeSafe();
185
186  // Here, velocity is normalized just to get a direction vector.
187  //  Drag is in the direction opposite velocity.  Is this right?
188  velocity.normalizeSafe();
189
190  return (velocity*-drag*mass);
191}
192
193//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
194
195class afxF_DragDesc : public afxForceDesc
196{
197  static afxF_DragDesc desc;
198
199public:
200  virtual bool testForceType(const SimDataBlock*) const;
201  virtual afxForce* create() const { return new afxF_Drag; }
202};
203
204afxF_DragDesc afxF_DragDesc::desc;
205
206bool afxF_DragDesc::testForceType(const SimDataBlock* db) const
207{
208  return (typeid(afxF_DragData) == typeid(*db));
209}
210
211//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
212