Solid.cpp

Go to the documentation of this file.
00001 /*************************************************************************
00002 *                                                                       *
00003 * Open Physics Abstraction Layer                                        *
00004 * Copyright (C) 2004-2005                                               *
00005 * Alan Fischer  alan.fischer@gmail.com                                  *
00006 * Andres Reinot  andres@reinot.com                                      *
00007 * Tyler Streeter  tylerstreeter@gmail.com                               *
00008 * All rights reserved.                                                  *
00009 * Web: opal.sourceforge.net                                             *
00010 *                                                                       *
00011 * This library is free software; you can redistribute it and/or         *
00012 * modify it under the terms of EITHER:                                  *
00013 *   (1) The GNU Lesser General Public License as published by the Free  *
00014 *       Software Foundation; either version 2.1 of the License, or (at  *
00015 *       your option) any later version. The text of the GNU Lesser      *
00016 *       General Public License is included with this library in the     *
00017 *       file license-LGPL.txt.                                          *
00018 *   (2) The BSD-style license that is included with this library in     *
00019 *       the file license-BSD.txt.                                       *
00020 *                                                                       *
00021 * This library is distributed in the hope that it will be useful,       *
00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
00024 * license-LGPL.txt and license-BSD.txt for more details.                *
00025 *                                                                       *
00026 *************************************************************************/
00027 
00028 #include "Solid.h"
00029 
00030 namespace opal
00031 {
00032         Solid::Solid()
00033         {
00034                 // "mData" is initialized in its own constructor.
00035                 setCollisionEventHandler( 0 );
00036                 setUserData( 0 );
00037                 resetAABB();
00038 
00039                 setMovingState( true );
00040                 setMovementEventHandler( 0 );
00041         }
00042 
00043         Solid::~Solid()
00044         {
00045                 mForceList.clear();
00046         }
00047 
00048         bool Solid::isMoving() const
00049         {
00050                 if ( mIsMoving )
00051                 {
00052                         mIsMoving = false;
00053                         return true;
00054                 }
00055                 else
00056                 {
00057                         return false;
00058                 }
00059         }
00060 
00061         void Solid::setMovingState( bool moving )
00062         {
00063                 mIsMoving = moving;
00064         }
00065 
00066         void Solid::setMovementEventHandler( MovementEventHandler* eventHandler )
00067         {
00068                 mMovementEventHandler = eventHandler;
00069         }
00070 
00071         MovementEventHandler* Solid::getMovementEventHandler() const
00072         {
00073                 return mMovementEventHandler;
00074         }
00075 
00076         void Solid::internal_destroy()
00077         {
00078                 delete this;
00079         }
00080 
00081         const SolidData& Solid::getData()
00082         {
00083                 // Update parameters that don't get updated automatically.
00084                 mData.sleeping = isSleeping();
00085 
00086                 return mData;
00087         }
00088 
00089         void Solid::setName( const std::string& name )
00090         {
00091                 mData.name = name;
00092         }
00093 
00094         const std::string& Solid::getName() const
00095         {
00096                 return mData.name;
00097         }
00098 
00099         bool Solid::isEnabled() const
00100         {
00101                 return mData.enabled;
00102         }
00103 
00104         void Solid::setEnabled( bool e )
00105         {
00106                 mData.enabled = e;
00107         }
00108 
00109         bool Solid::isStatic() const
00110         {
00111                 return mData.isStatic;
00112         }
00113 
00114         void Solid::setSleepiness( real s )
00115         {
00116                 assert( s >= 0.0 && s <= 1.0 );
00117                 mData.sleepiness = s;
00118         }
00119 
00120         real Solid::getSleepiness() const
00121         {
00122                 return mData.sleepiness;
00123         }
00124 
00125         void Solid::setLinearDamping( real ld )
00126         {
00127                 assert( ld >= 0.0 );
00128                 mData.linearDamping = ld;
00129         }
00130 
00131         real Solid::getLinearDamping() const
00132         {
00133                 return mData.linearDamping;
00134         }
00135 
00136         void Solid::setAngularDamping( real ad )
00137         {
00138                 assert( ad >= 0.0 );
00139                 mData.angularDamping = ad;
00140         }
00141 
00142         real Solid::getAngularDamping() const
00143         {
00144                 return mData.angularDamping;
00145         }
00146 
00147         void Solid::setUserData( void* data )
00148         {
00149                 mUserData = data;
00150         }
00151 
00152         void* Solid::getUserData() const
00153         {
00154                 return mUserData;
00155         }
00156 
00157         void Solid::setTransform( const Matrix44r& t )
00158         {
00159                 mData.transform = t;
00160                 internal_updateEngineTransform();
00161         }
00162 
00163         const Matrix44r& Solid::getTransform() const
00164         {
00165                 return mData.transform;
00166         }
00167 
00168         void Solid::setPosition( real x, real y, real z )
00169         {
00170                 mIsMoving = true;
00171                 mData.transform.setPosition( x, y, z );
00172                 internal_updateEngineTransform();
00173         }
00174 
00175         void Solid::setPosition( const Point3r & p )
00176         {
00177                 setPosition( p[ 0 ], p[ 1 ], p[ 2 ] );
00178         }
00179 
00180         Point3r Solid::getPosition() const
00181         {
00182                 return mData.transform.getPosition();
00183         }
00184 
00185         Vec3r Solid::getEulerXYZ() const
00186         {
00187                 return mData.transform.getEulerXYZ();
00188         }
00189 
00190         Quaternion Solid::getQuaternion() const
00191         {
00192                 return mData.transform.getQuaternion();
00193         }
00194 
00195         void Solid::setQuaternion( const Quaternion & q )
00196         {
00197                 setQuaternion( q[ 0 ], q[ 1 ], q[ 2 ], q[ 3 ] );
00198         }
00199 
00200         void Solid::setQuaternion( real w, real x, real y, real z )
00201         {
00202                 mIsMoving = true;
00203                 mData.transform.setQuaternion( w, x, y, z );
00204                 internal_updateEngineTransform();
00205         }
00206 
00207         void Solid::getLocalAABB( real aabb[ 6 ] ) const
00208         {
00209                 for ( unsigned int i = 0; i < 6; ++i )
00210                 {
00211                         aabb[ i ] = mLocalAABB[ i ];
00212                 }
00213         }
00214 
00215         void Solid::getGlobalAABB( real aabb[ 6 ] ) const
00216         {
00217                 Point3r minExtents( mLocalAABB[ 0 ], mLocalAABB[ 2 ], mLocalAABB[ 4 ] );
00218                 Point3r maxExtents( mLocalAABB[ 1 ], mLocalAABB[ 3 ], mLocalAABB[ 5 ] );
00219 
00220                 // Transform the AABB extents to global coordinates.
00221                 minExtents = mData.transform * minExtents;
00222                 maxExtents = mData.transform * maxExtents;
00223 
00224                 aabb[ 0 ] = minExtents[ 0 ];
00225                 aabb[ 1 ] = maxExtents[ 0 ];
00226                 aabb[ 2 ] = minExtents[ 1 ];
00227                 aabb[ 3 ] = maxExtents[ 1 ];
00228                 aabb[ 4 ] = minExtents[ 2 ];
00229                 aabb[ 5 ] = maxExtents[ 2 ];
00230         }
00231 
00232         //void Solid::addPlane(const Point3r& point, const Vec3r& normal, const Material& m)
00233         //{
00234         //      Point3r origin(0, 0, 0);
00235         //      Vec3r n = normal;
00236         //      n.normalize();
00237         //      Vec3r v = point - origin;
00238         //
00239         //      real angle = 0;
00240         //      if (0 != v.length())
00241         //      {
00242         //              v.normalize();
00243         //              angle = acos(dot(n,v)); // note: this only works when the two vectors are normalized
00244         //      }
00245         //
00246         //      real length = distance(point, origin);
00247         //      real D = length * cos(angle);
00248         //      real abcd[4] = {n[0], n[1], n[2], D};
00249         //      addPlane(abcd, m);
00250         //}
00251 
00252         void Solid::addForce( const Force& f )
00253         {
00254                 if ( mData.enabled && !mData.isStatic &&
00255                         !areEqual( f.vec.lengthSquared(), 0 ) )
00256                 {
00257                         mForceList.push_back( f );
00258                 }
00259         }
00260 
00261         void Solid::internal_applyForces( real stepSize )
00262         {
00263                 if ( mData.isStatic )
00264                 {
00265                         return ;
00266                 }
00267 
00268                 // If there are Forces to apply and the Solid is asleep, wake it up.
00269                 if ( !mForceList.empty() && isSleeping() )
00270                 {
00271                         setSleeping( false );
00272                 }
00273 
00274                 real invStepSize = 1 / stepSize;
00275 
00276                 for ( unsigned int i = 0; i < mForceList.size(); )
00277                 {
00278                         if ( true == mForceList[ i ].singleStep )
00279                         {
00280                                 mForceList[ i ].duration = stepSize;
00281                         }
00282                         else if ( mForceList[ i ].duration < stepSize )
00283                         {
00284                                 // Scale the size of the force/torque.
00285                                 mForceList[ i ].vec *= ( mForceList[ i ].duration * invStepSize );
00286                         }
00287 
00288                         // Apply the actual force/torque.
00289                         applyForce( mForceList[ i ] );
00290 
00291                         // The following is ok for all cases (even when duration is
00292                         // < mStepSize).
00293                         mForceList[ i ].duration -= stepSize;
00294 
00295                         if ( mForceList[ i ].duration <= 0 )
00296                         {
00297                                 // Delete this force.
00298                                 mForceList[ i ] = mForceList.back();
00299                                 mForceList.pop_back();
00300                         }
00301                         else
00302                         {
00303                                 ++i;
00304                         }
00305                 }
00306         }
00307 
00308         void Solid::setCollisionEventHandler( CollisionEventHandler* eventHandler )
00309         {
00310                 mCollisionEventHandler = eventHandler;
00311         }
00312 
00313         CollisionEventHandler* Solid::getCollisionEventHandler() const
00314         {
00315                 return mCollisionEventHandler;
00316         }
00317 
00318         void Solid::addToLocalAABB( const real aabb[ 6 ] )
00319         {
00320                 // Loop over the 3 dimensions of the AABB's extents.
00321                 for ( unsigned int i = 0; i < 3; ++i )
00322                 {
00323                         if ( aabb[ i * 2 ] < mLocalAABB[ i * 2 ] )
00324                         {
00325                                 mLocalAABB[ i * 2 ] = aabb[ i * 2 ];
00326                         }
00327 
00328                         if ( aabb[ i * 2 + 1 ] > mLocalAABB[ i * 2 + 1 ] )
00329                         {
00330                                 mLocalAABB[ i * 2 + 1 ] = aabb[ i * 2 + 1 ];
00331                         }
00332                 }
00333         }
00334 
00335         void Solid::resetAABB()
00336         {
00337                 for ( unsigned int i = 0; i < 6; ++i )
00338                 {
00339                         mLocalAABB[ i ] = 0;
00340                 }
00341         }
00342 
00343         //void Solid::internal_updateSleeping()
00344         //{
00345         //      mData.sleeping = isSleeping();
00346         //}
00347 
00350         //void Solid::setFastRotation(bool fast)
00351         //{
00352         //}
00353 
00354         //bool Solid::getFastRotation()const
00355         //{
00356         //      return false;
00357         //}
00358 
00359         //void Solid::setFastRotationAxis(Vec3r axis)
00360         //{
00361         //}
00362 }

Generated on Tue May 16 17:49:52 2006 for OPAL by  doxygen 1.4.6-NO