Torque3D Documentation / _generateds / physicsForce.cpp

physicsForce.cpp

Engine/source/T3D/physics/physicsForce.cpp

More...

Public Functions

ConsoleDocClass(PhysicsForce , "@brief Helper object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> gameplay physical <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">forces.\n\n</a>" "%PhysicsForces can be created and \"attached\" to other @link <a href="/coding/class/classphysicsbody/">PhysicsBody</a> PhysicsBodies@endlink " "<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> attract them <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the position of the PhysicsForce." "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Physics\n</a>" )
DefineEngineMethod(PhysicsForce , attach , void , (Point3F start, Point3F direction, F32 maxDist) , "@brief Attempts <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> associate the <a href="/coding/class/classphysicsforce/">PhysicsForce</a> with <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">PhysicsBody.\n\n</a>" "Performs <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> physics ray cast of the provided length and direction. The %<a href="/coding/class/classphysicsforce/">PhysicsForce</a> " "will attach itself <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the first dynamic <a href="/coding/class/classphysicsbody/">PhysicsBody</a> the ray collides with. " "On every tick, the attached body will be attracted towards the position of the %<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">PhysicsForce.\n\n</a>" "A %<a href="/coding/class/classphysicsforce/">PhysicsForce</a> can only be attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> one body at <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">time.\n\n</a>" " @note To determine <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> an %attach was successful, check isAttached() immediately after " "calling this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function.n\n</a>" )
DefineEngineMethod(PhysicsForce , detach , void , (Point3F force) , (Point3F::Zero) , "@brief Disassociates the <a href="/coding/class/classphysicsforce/">PhysicsForce</a> from any attached <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">PhysicsBody.\n\n</a>" "@param force Optional force <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> apply <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the attached <a href="/coding/class/classphysicsbody/">PhysicsBody</a> " "before <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">detaching.\n\n</a>" "@note Has no effect <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the %<a href="/coding/class/classphysicsforce/">PhysicsForce</a> is not attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">anything.\n\n</a>" )
DefineEngineMethod(PhysicsForce , isAttached , bool , () , "@brief Returns true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the %<a href="/coding/class/classphysicsforce/">PhysicsForce</a> is currently attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "@see <a href="/coding/class/classphysicsforce/#classphysicsforce_1a75a89178a0bcf6cb288b18a3a23170f5">PhysicsForce::attach</a>()" )

Detailed Description

Public Functions

ConsoleDocClass(PhysicsForce , "@brief Helper object <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> gameplay physical <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">forces.\n\n</a>" "%PhysicsForces can be created and \"attached\" to other @link <a href="/coding/class/classphysicsbody/">PhysicsBody</a> PhysicsBodies@endlink " "<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> attract them <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the position of the PhysicsForce." "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Physics\n</a>" )

DefineEngineMethod(PhysicsForce , attach , void , (Point3F start, Point3F direction, F32 maxDist) , "@brief Attempts <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> associate the <a href="/coding/class/classphysicsforce/">PhysicsForce</a> with <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">PhysicsBody.\n\n</a>" "Performs <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> physics ray cast of the provided length and direction. The %<a href="/coding/class/classphysicsforce/">PhysicsForce</a> " "will attach itself <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the first dynamic <a href="/coding/class/classphysicsbody/">PhysicsBody</a> the ray collides with. " "On every tick, the attached body will be attracted towards the position of the %<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">PhysicsForce.\n\n</a>" "A %<a href="/coding/class/classphysicsforce/">PhysicsForce</a> can only be attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> one body at <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">time.\n\n</a>" " @note To determine <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> an %attach was successful, check isAttached() immediately after " "calling this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">function.n\n</a>" )

DefineEngineMethod(PhysicsForce , detach , void , (Point3F force) , (Point3F::Zero) , "@brief Disassociates the <a href="/coding/class/classphysicsforce/">PhysicsForce</a> from any attached <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">PhysicsBody.\n\n</a>" "@param force Optional force <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> apply <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the attached <a href="/coding/class/classphysicsbody/">PhysicsBody</a> " "before <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">detaching.\n\n</a>" "@note Has no effect <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the %<a href="/coding/class/classphysicsforce/">PhysicsForce</a> is not attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">anything.\n\n</a>" )

DefineEngineMethod(PhysicsForce , isAttached , bool , () , "@brief Returns true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the %<a href="/coding/class/classphysicsforce/">PhysicsForce</a> is currently attached <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">object.\n\n</a>" "@see <a href="/coding/class/classphysicsforce/#classphysicsforce_1a75a89178a0bcf6cb288b18a3a23170f5">PhysicsForce::attach</a>()" )

IMPLEMENT_CONOBJECT(PhysicsForce )

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  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 "platform/platform.h"
 25#include "T3D/physics/physicsForce.h"
 26
 27#include "T3D/physics/physicsPlugin.h"
 28#include "T3D/physics/physicsWorld.h"
 29#include "T3D/physics/physicsBody.h"
 30#include "console/engineAPI.h"
 31
 32
 33IMPLEMENT_CONOBJECT(PhysicsForce);
 34
 35
 36ConsoleDocClass( PhysicsForce,
 37   "@brief Helper object for gameplay physical forces.\n\n"
 38   "%PhysicsForces can be created and \"attached\" to other @link PhysicsBody PhysicsBodies@endlink "
 39   "to attract them to the position of the PhysicsForce."
 40   "@ingroup Physics\n"
 41);
 42
 43
 44PhysicsForce::PhysicsForce()
 45   :
 46      mWorld( NULL ),
 47      mForce(0.0f),
 48      mPhysicsTick( false ),
 49      mBody( NULL )
 50{
 51}
 52
 53PhysicsForce::~PhysicsForce()
 54{
 55}
 56
 57void PhysicsForce::initPersistFields()
 58{   
 59   Parent::initPersistFields();   
 60}
 61
 62
 63bool PhysicsForce::onAdd()
 64{
 65   if ( !Parent::onAdd() )
 66      return false;
 67
 68   // Find the physics world we're in.
 69   if ( PHYSICSMGR )
 70      mWorld = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" );
 71
 72   setProcessTick( true );
 73   getProcessList()->preTickSignal().notify( this, &PhysicsForce::_preTick );
 74
 75   return true;
 76}
 77
 78void PhysicsForce::onRemove()
 79{
 80   mWorld = NULL;
 81   mBody = NULL;
 82   getProcessList()->preTickSignal().remove( this, &PhysicsForce::_preTick );
 83   setProcessTick( false );
 84
 85   Parent::onRemove();
 86}
 87
 88void PhysicsForce::attach( const Point3F &start, const Point3F &direction, F32 maxDist )
 89{
 90   detach();
 91
 92   // If there is no physics world then we cannot apply any forces.
 93   if ( !mWorld )
 94      return;
 95
 96   PhysicsBody *body = mWorld->castRay( start, start + ( direction * maxDist ), PhysicsWorld::BT_Dynamic );
 97   if ( !body )
 98      return;
 99
100   mBody = body;
101}
102
103void PhysicsForce::detach( const Point3F &force )
104{
105   if ( mBody && !force.isZero() )
106   {
107      Point3F cMass = mBody->getCMassPosition();      
108      F32 mass = mBody->getMass();
109
110      Point3F impulse = ( mass * force ) / TickSec;
111      mBody->applyImpulse( cMass, impulse );
112   }
113
114   mBody = NULL;
115}
116
117void PhysicsForce::onMount( SceneObject *obj, S32 node )
118{      
119   Parent::onMount( obj, node );
120
121   processAfter( obj );
122
123   MatrixF mat( true );
124   mMount.object->getMountTransform( mMount.node, mMount.xfm, &mat );
125   setTransform( mat );   
126}
127
128void PhysicsForce::onUnmount( SceneObject *obj, S32 node )
129{
130   clearProcessAfter();
131   Parent::onUnmount( obj, node );
132}
133
134void PhysicsForce::_preTick()
135{
136   // How Torque works we sometimes get double or more
137   // ticks within a single simulation step.  This occurs
138   // for various reasons including odd timesteps and low
139   // framerate.
140   //
141   // In order to keep performance from plumeting we do
142   // not tick physics multiple times... instead it just
143   // looses time.
144   //
145   // We set this variable below to let processTick know
146   // that physics hasn't stepped yet and to skip processing.
147   //
148   // This doesn't completely solve the issue, but it does
149   // make things much better.
150   //
151   mPhysicsTick = true;
152}
153
154void PhysicsForce::processTick( const Move * )
155{
156   if ( isMounted() )
157   {
158      MatrixF test( true );
159      test.setPosition( Point3F( 0, 4, 0 ) );
160      AssertFatal( test != mMount.xfm, "Error!" );
161
162      MatrixF mat( true );
163      mMount.object->getMountTransform( mMount.node, mMount.xfm, &mat );
164      setTransform( mat );
165   }
166
167   // Nothing to do without a body or if physics hasn't ticked.
168   if ( !mBody || !mPhysicsTick )
169      return;
170
171   mPhysicsTick = false;
172
173   // If we lost the body then release it.
174   if ( !mBody->isDynamic() || !mBody->isSimulationEnabled() )
175   {
176      detach();
177      return;
178   }
179
180   // Get our distance to the body.
181   Point3F cMass = mBody->getCMassPosition();
182   Point3F vector = getPosition() - cMass;
183
184   // Apply the force!
185   F32 mass = mBody->getMass();
186   Point3F impulse = ( mass * vector ) / TickSec;
187
188   // Counter balance the linear impulse.
189   Point3F linVel = mBody->getLinVelocity();
190   Point3F currentForce = linVel * mass;
191
192   // Apply it.
193   mBody->applyImpulse( cMass, impulse - currentForce );
194}
195
196DefineEngineMethod( PhysicsForce, attach, void, ( Point3F start, Point3F direction, F32 maxDist ),,
197   "@brief Attempts to associate the PhysicsForce with a PhysicsBody.\n\n"
198   "Performs a physics ray cast of the provided length and direction. The %PhysicsForce " 
199   "will attach itself to the first dynamic PhysicsBody the ray collides with. "
200   "On every tick, the attached body will be attracted towards the position of the %PhysicsForce.\n\n"
201   "A %PhysicsForce can only be attached to one body at a time.\n\n"
202   "@note To determine if an %attach was successful, check isAttached() immediately after "
203   "calling this function.n\n")
204{
205   object->attach( start, direction, maxDist );
206}
207
208DefineEngineMethod( PhysicsForce, detach, void, ( Point3F force ), ( Point3F::Zero ),
209   "@brief Disassociates the PhysicsForce from any attached PhysicsBody.\n\n"
210   "@param force Optional force to apply to the attached PhysicsBody "
211   "before detaching.\n\n"
212   "@note Has no effect if the %PhysicsForce is not attached to anything.\n\n")
213{
214   object->detach( force );
215}
216
217DefineEngineMethod( PhysicsForce, isAttached, bool, (),,
218   "@brief Returns true if the %PhysicsForce is currently attached to an object.\n\n"
219   "@see PhysicsForce::attach()")
220{
221   return object->isAttached();
222}
223
224