| |
|
|
||||
![]() |
||||||
| |
|
|||||
|
The RIGID_BODY_STATE type
The name says it all. The RIGID_BODY_STATE keeps track of the dynamic variables of the body. It is created by deriving from COORDINATE_FRAME and including the linear velocity, the angular velocity, the inertia tensor and its inverse (see Listing 5). // Describe the dynamic
state of a rigid class RIGID_BODY_STATE : public COORD_FRAME { public:
VECTOR V; //linear velocity, meters/sec public:
}; The RIGID_BODY type Finally, we create the structure that allows use to fully describe and manipulate a rigid body in 3D space. The object hierarchy of the RIGID_BODY class allows us to perform all the fundamental operations: positioning, translation, rotation, transformation, and linear and angular acceleration. In order to perform collision detection, you also need to store the previous state of the body. The current and previous states will allow you to interpolate between states to check for overlaps with the world or other bodies. This is why we separated the state information from the actual rigid body class. In Listing 6, you’ll notice that RIGID_BODY is a class instead of a structure. Up to this point I’ve broken the object-oriented rule of data hiding because I’m lazy and I like to access members directly. The RIGID_BODY will be our interface with the rest of the world, so data hiding will do us good at this point. // Describe a rigid body // class RIGID_BODY : public RIGID_BODY_STATE { public: //previous dynamic state RIGID_BODY_STATE PrevState; //mass and rotational inertia SCALAR M; //mass, kg VECTOR Ip; //principal moments of inertia, kg m m public: RIGID_BODY() : M(1), Ip(1,1,1) {} RIGID_BODY( const SCALAR& m, const VECTOR& ip ) : M(m), Ip(ip) {} //physical properties void mass( const SCALAR& m ) { M = m; } SCALAR mass() const { return M; } void inertiaMoments( const VECTOR& ip ) { Ip = ip; } const VECTOR& inertiaMoments() const { return Ip; } }; What have we gained? So what have we gained by creating all these structures and operators? Here is an example of C++ code that will move a body under a force and a torque according to the Newton-Euler equations of rigid body motion: void RIGID_BODY::move( const SCALAR dt ) { VECTOR F, T; this->Translate( this->V * dt ); this->Rotate( this->W * dt ); ComputeForceAndTorque( F, T ); this->V += (1/this->M)* F * dt; this->W += this->I_inv * (T - W.cross(I*W)) * dt; } The equivalent C code is less elegant: void RIGID_BODY_Move( RIGID_BODY* pBody, SCALAR dt ) { VECTOR F, T, t, v; //easier to hand-inline this one pBody->State.Frame.O.x += pBody->State.V.x * dt; pBody->State.Frame.O.y += pBody->State.V.y * dt; pBody->State.Frame.O.z += pBody->State.V.z * dt; vmul( t, pBody->State.W, dt );//macro RotateBasis( pBody->State.Frame.Basis, &t ); ComputeForceAndTorque( &F, &T ); s = 1/ pBody->M; pBody->State.V.x += s * F.x * dt; pBody->State.V.y += s * F.y * dt; pBody->State.V.z += s * F.z * dt; matrix_mul( t, pBody->State.I, pBody->State.W );//t = I*W vcross( v, pBody->State.W, t ); //v = Wx(I*W) vsub( t, T, v ); //t = T - Wx(I*W) matrix_mul( v, pBody->State.I_inv, t );//v = I_inv*(T - Wx(I*W)) vmul( t, v, dt ); //t = I_inv * (T - Wx(I*W)) * dt pBody->State.W.x += t.x; pBody->State.W.y += t.y; pBody->State.W.z += t.z; } Using a good set of data structures, we’ve gained simplicity while preserving efficiency. With a little time spent up front on design, the entire physics and collision detection code base will be smaller, faster and easier to debug. Miguel Gomez is a Senior Software Engineer at Looking Glass Studios, Redmond. Since receiving a BS in Physics from the University of Washington in 1995, he has programmed physics and collision detection for PGA Tour Golf '96" Hyperblade, Baseball 3D, 1998 Edition, Destruction Derby 64, and most recently Wild Waters, a 3-D kayaking simulation title for the Nintendo 64. And if it weren’t for the computer gaming industry, he’d be unemployed. [1] Tai L. Chow, Classical Mechanics [2] Harry F. Davis, Arthur David Snider, Introduction to Vector Analysis, 6th Edition [3] Brian W. Kernighan, Dennis M. Ritchie, The C Programming Language, 2nd Edition [4] Serge Lang, Linear Algebra, 3rd Edition [5] Paul Pedriana, High Performance Game Programming in C++, Conference Proceedings 1998 Computer Game Developer’s Conference [6] Bjarne Stroustrup, The C++ Programming Language, 2nd Edition |
|
|