MezzanineEngine March 18, 2012

physicsmanager.h

00001 //© Copyright 2010 - 2011 BlackTopp Studios Inc.
00002 /* This file is part of The Mezzanine Engine.
00003 
00004     The Mezzanine Engine is free software: you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation, either version 3 of the License, or
00007     (at your option) any later version.
00008 
00009     The Mezzanine Engine is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with The Mezzanine Engine.  If not, see <http://www.gnu.org/licenses/>.
00016 */
00017 /* The original authors have included a copy of the license specified above in the
00018    'Docs' folder. See 'gpl.txt'
00019 */
00020 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
00021    Build professional software and charge for their product.
00022 
00023    However there are some practical restrictions, so if your project involves
00024    any of the following you should contact us and we will try to work something
00025    out:
00026     - DRM or Copy Protection of any kind(except Copyrights)
00027     - Software Patents You Do Not Wish to Freely License
00028     - Any Kind of Linking to Non-GPL licensed Works
00029     - Are Currently In Violation of Another Copyright Holder's GPL License
00030     - If You want to change our code and not add a few hundred MB of stuff to
00031         your distribution
00032 
00033    These and other limitations could cause serious legal problems if you ignore
00034    them, so it is best to simply contact us or the Free Software Foundation, if
00035    you have any questions.
00036 
00037    Joseph Toppi - toppij@gmail.com
00038    John Blackwood - makoenergy02@gmail.com
00039 */
00040 #ifndef _physicsmanager_h
00041 #define _physicsmanager_h
00042 
00043 //forward Declarations so that we do not need #include "btBulletDynamicsCommon.h"
00044 class btAxisSweep3;
00045 class btDefaultCollisionConfiguration;
00046 class btCollisionDispatcher;
00047 class btSequentialImpulseConstraintSolver;
00048 class btSoftRigidDynamicsWorld;
00049 class btDynamicsWorld;
00050 class btCollisionShape;
00051 class btSoftBodyRigidBodyCollisionConfiguration;
00052 class btGhostPairCallback;
00053 class btBroadphaseInterface;
00054 class btCollisionConfiguration;
00055 
00056 typedef float btScalar;
00057 
00058 #include <map>
00059 #include <vector>
00060 
00061 #include "constraint.h"
00062 #include "datatypes.h"
00063 #include "managerbase.h"
00064 #include "singleton.h"
00065 #include "objectpair.h"
00066 
00067 namespace Mezzanine
00068 {
00069     // internal forward declarations
00070     class World;
00071     class ActorBase;
00072     class Vector3WActor;
00073     class AreaEffect;
00074     class WorldTrigger;
00075     class Collision;
00076     class CollisionDispatcher;
00077     class BroadphaseCache;
00078     namespace debug {
00079         class InternalDebugDrawer;
00080     }
00081 
00082     ///////////////////////////////////////////////////////////////////////////////
00083     /// @class PhysicsConstructionInfo
00084     /// @headerfile physicsmanager.h
00085     /// @brief
00086     /// @details
00087     ///////////////////////////////////////
00088     class MEZZ_LIB PhysicsConstructionInfo
00089     {
00090         public:
00091             /// @enum PhysicsConstructionFlags
00092             /// @brief This is an enum used by the physics manager to determine what internal
00093             /// classes should be used when creating the world.
00094             enum PhysicsConstructionFlags
00095             {
00096                 //World type flags
00097                 PCF_SoftRigidWorld = 1,
00098 
00099                 //broadphase flags
00100                 PCF_LimitlessWorld = 2,
00101             };
00102 
00103             /// @brief Class constructor.
00104             PhysicsConstructionInfo();
00105             /// @brief Class destructor.
00106             ~PhysicsConstructionInfo();
00107             /// @brief Assignment Operator.
00108             /// @param Other The other PhysicsConstructionInfo to be copied.
00109             /// @return Returns a reference to this.
00110             PhysicsConstructionInfo& operator=(const PhysicsConstructionInfo& Other);
00111 
00112             /// @brief The flags to initialize the physics system with.
00113             Whole PhysicsFlags;
00114             /// @brief The lower limits of the worlds AABB.
00115             /// @note This member is ignored if the "PCF_LimitlessWorld" flag is passed in.
00116             Vector3 GeographyLowerBounds;
00117             /// @brief The upper limits of the worlds AABB.
00118             /// @note This member is ignored if the "PCF_LimitlessWorld" flag is passed in.
00119             Vector3 GeographyUpperBounds;
00120             /// @brief The maximum number of Actors and Area Effects you expect to have in the world at one time.
00121             /// @note This member is ignored if the "PCF_LimitlessWorld" flag is passed in.
00122             Whole MaxProxies;
00123             /// @brief The gravity to set for the world.
00124             Vector3 Gravity;
00125             /// @brief The age a collision contact has to have(number of simulation steps) to generate an event for it.
00126             Whole EventFilterAge;
00127             /// @brief The amount of force a collision has to have to generate an event for it.
00128             Real EventFilterImpulse;
00129     };
00130 
00131     // Used by the scripting language binder to help create bindgings for this class. SWIG does know to creation template instances
00132     #ifdef SWIG
00133     %template(SingletonPhysicsManager) Singleton<PhysicsManager>;
00134     #endif
00135 
00136     ///////////////////////////////////////////////////////////////////////////////
00137     /// @class PhysicsManager
00138     /// @headerfile physicsmanager.h
00139     /// @brief This is simply a place for storing all the Physics Related functions
00140     /// @details This is a place for storing items related to Debug physics
00141     /// drawing, Adding constraints, screwing with gravity and doing other physics
00142     /// Related features.
00143     ///////////////////////////////////////
00144     class MEZZ_LIB PhysicsManager : public ManagerBase, public Singleton<PhysicsManager>
00145     {
00146         private:
00147             // needed for collision processing
00148             friend class CollisionDispatcher;
00149             //Some Data Items
00150             PhysicsConstructionInfo WorldConstructionInfo;
00151             unsigned short int CollisionAge;
00152             Real Impulse;
00153             bool SimulationPaused;
00154             Whole SubstepModifier;
00155             std::vector< TypedConstraint* > Constraints;
00156             std::vector< AreaEffect* > AreaEffects;
00157             std::vector< WorldTrigger* > Triggers;
00158             std::map< ObjectPair,Collision* > Collisions;
00159 
00160             // Some Items bullet requires
00161             btGhostPairCallback* GhostCallback;
00162             btBroadphaseInterface* BulletBroadphase;
00163             btCollisionConfiguration* BulletCollisionConfiguration;
00164             btCollisionDispatcher* BulletDispatcher;
00165             btSequentialImpulseConstraintSolver* BulletSolver;
00166             btSoftRigidDynamicsWorld* BulletDynamicsWorld;
00167             debug::InternalDebugDrawer* BulletDrawer;
00168 
00169             /// @brief This takes care of all the real work in contructing this
00170             /// @details This method is called by all the constructors to insure consistent behavior.
00171             /// @param Info The construction info class with all the settings you wish the world to have.
00172             void Construct(const PhysicsConstructionInfo& Info);
00173 
00174             /// @brief Calls the ApplyEffects() and UpdateActorList() function of every stored AreaEffect.
00175             /// @details This function is automatically called every step.
00176             void ProcessAllEffects();
00177 
00178             /// @brief Calls the ConditionsAreMet() and ApplyTrigger() functions of every stored trigger.
00179             /// @details This function is automatically called every step.
00180             void ProcessAllTriggers();
00181 
00182             /// @brief Checks the internal collision data and generates/updates collisions as necessary.
00183             /// @details This function is automatically called every step.
00184             void ProcessAllCollisions();
00185 
00186             /// @brief Internal Callback that is called each substep of the simulation.
00187             static void InternalTickCallback(btDynamicsWorld* world, btScalar timeStep);
00188         public:
00189             /// @brief Simple Constructor
00190             /// @details This constructor will assign some sane default values and will create a physics
00191             /// world that can be used immediately
00192             PhysicsManager();
00193             /// @brief Simple Constructor
00194             /// @details This constructor will assign some sane default values and will create a physics
00195             /// world that can be used immediately
00196             /// @param Info The construction info class with all the settings you wish the world to have.
00197             PhysicsManager(const PhysicsConstructionInfo& Info);
00198             /// @brief Deconstructor
00199             /// @details This deletes all those crazy pointers that Bullet, the physics subsystem need.
00200             virtual ~PhysicsManager();
00201 
00202             ///////////////////////////////////////////////////////////////////////////////
00203             // Simulation Management
00204 
00205             /// @brief Pauses the simulation, preventing the physics world from taking action.
00206             /// @param Pause Wether or not to pause the simulation.
00207             void PauseSimulation(bool Pause);
00208             /// @brief Gets Whether or not the simulation is currently paused.
00209             /// @return Returns whether or not the simulation is paused.
00210             bool SimulationIsPaused();
00211 
00212             ///////////////////////////////////////////////////////////////////////////////
00213             // Gravity Management
00214 
00215             /// @brief Sets the gravity.
00216             /// @details Sets the strength and direction of gravity within the world.
00217             /// @param pgrav Vector3 representing the strength and direction of gravity.
00218             void SetGravity(const Vector3& pgrav);
00219             /// @brief Gets the gravity.
00220             /// @details Gets the currently set world gravity.
00221             /// @return Returns the currently set world gravity.
00222             Vector3 GetGravity();
00223             /// @brief Sets the gravity for soft bodies.
00224             /// @details Gravity for soft bodies is stored separately from rigid bodies.  So if you plan to use soft bodies in your game/simulation
00225             /// you need to call this function otherwise they won't fall.
00226             /// @param sgrav Vector3 representing the strength and direction of gravity.
00227             void SetSoftGravity(const Vector3& sgrav);
00228             /// @brief Gets the soft body gravity.
00229             /// @details Gets the currently set soft body world gravity.
00230             /// @return Returns the currently set soft body world gravity.
00231             Vector3 GetSoftGravity();
00232             /// @brief Sets the gravity to be applied to a single object.
00233             /// @details This function does not change the global gravity, only how gravity behaves for this specific object.  Note: This function only works on ActorRigid's.
00234             /// @param Actor The actor whos gravity is to be changed.
00235             /// @param igrav The value of the gravity to be applied.
00236             void SetIndividualGravity(ActorBase* Actor, const Vector3& igrav);
00237 
00238             ///////////////////////////////////////////////////////////////////////////////
00239             // Constraint Management
00240 
00241             /// @brief Adds a constraint to the world.
00242             /// @details Adds the constraint to the world so that it can/will take effect.
00243             /// @param Constraint The constraint to be added.
00244             /// @param DisableCollisions Sets whether or not the linked bodies collide with each other.
00245             void AddConstraint(TypedConstraint* Constraint, bool DisableCollisions = false);
00246             /// @brief Gets a constraint by index.
00247             /// @param Index The index of the constraint you want.
00248             /// @return Returns a pointer to the specified constraint.
00249             TypedConstraint* GetConstraint(const Whole& Index);
00250             /// @brief Gets the number of constraints currently in the world.
00251             /// @return Returns a whole representing the number of constraints in the world.
00252             Whole GetNumConstraints();
00253             /// @brief Removes a constraint from the world.
00254             /// @details Removes a constraint from the world so that it will have no effect.
00255             /// @param Constraint The constraint to be removed.
00256             void RemoveConstraint(TypedConstraint* Constraint);
00257             /// @brief Destroys all constraints currently in the manager.
00258             /// @details In practice it is cleaner to remove constraints from the world before removing any constrained actors.
00259             void DestroyAllConstraints();
00260 
00261             ///////////////////////////////////////////////////////////////////////////////
00262             // AreaEffect Management
00263 
00264             /// @brief Adds an area effect to the world.
00265             /// @details Adds an area effect to the world so that it can/will take effect.
00266             /// @param AE The area effect to be added.
00267             void AddAreaEffect(AreaEffect* AE);
00268             /// @brief Gets an Area Effect by name.
00269             /// @param Name The name of the area effect to find.
00270             /// @return Returns a pointer to the named area effect, or NULL if it doesn't exist.
00271             AreaEffect* GetAreaEffect(const String& Name);
00272             /// @brief Gets an Area Effect by index.
00273             /// @param Index The index of the area effect you want.
00274             /// @return Returns a pointer to the area effect at the specified index.
00275             AreaEffect* GetAreaEffect(const Whole& Index);
00276             /// @brief Gets the number of Area Effects currently in the world.
00277             /// @return Returns a whole representing the number of Area Effects in the world.
00278             Whole GetNumAreaEffects();
00279             /// @brief Removes an area effect from the world.
00280             /// @details Removes an area effect from the world so that it will have no effect.
00281             /// @param AE The area effect to be removed.
00282             void RemoveAreaEffect(AreaEffect* AE);
00283             /// @brief Destroys all area effects currently in the manager.
00284             void DestroyAllAreaEffects();
00285 
00286             ///////////////////////////////////////////////////////////////////////////////
00287             // Trigger Management
00288 
00289             /// @brief Adds a trigger to the world.
00290             /// @details Adds a trigger to the world so that it can/will take effect.
00291             /// @param Trig The trigger to be added.
00292             void AddWorldTrigger(WorldTrigger* Trig);
00293             /// @brief Gets a trigger by name.
00294             /// @param Name The name of the trigger to find.
00295             /// @return Returns a pointer to the named trigger, or NULL if it doesn't exist.
00296             WorldTrigger* GetWorldTrigger(const String& Name);
00297             /// @brief Gets a trigger by index.
00298             /// @param Index The index of the trigger you want.
00299             /// @return Returns a pointer to the trigger at the specified index.
00300             WorldTrigger* GetWorldTrigger(const Whole& Index);
00301             /// @brief Gets the number of triggers currently in the world.
00302             /// @return Returns a whole representing the number of triggers in the world.
00303             Whole GetNumWorldTriggers();
00304             /// @brief Removes a trigger from the world.
00305             /// @details Removes a trigger from the world so that it will have no effect.
00306             /// @param Trig The trigger to be removed.
00307             void RemoveWorldTrigger(WorldTrigger* Trig);
00308             /// @brief Destroys all triggers currently in the manager.
00309             void DestroyAllWorldTriggers();
00310 
00311             ///////////////////////////////////////////////////////////////////////////////
00312             // Collision Management
00313 
00314             /// @brief Gets a Collision by object pair.
00315             /// @param Pair A pair of objects.
00316             /// @return Returns a pointer to the Collision if a collision for the provided pair exists, NULL otherwise.
00317             Collision* GetCollision(ObjectPair* Pair);
00318             /// @brief Gets the number of Collisions currently in the world.
00319             /// @return Returns a whole representing the number of Collisions in the world.
00320             Whole GetNumCollisions();
00321             /// @brief Removes an existing collision from the world.
00322             /// @remarks In general it's not a great idea to call on this manually, but there are some situations where you would.
00323             /// Mostly this function exists to facilitate removal of objects from the world before the simulation ends.
00324             /// In such cases you have to clean up traces of the collision.
00325             /// @param Col The collision to be removed.
00326             void RemoveCollision(Collision* Col);
00327             /// @brief Removes all stored collisions that involve the specified Object.
00328             /// @param Object The Object which will have all of it's collisions removed.
00329             void RemoveCollisionsContainingObject(WorldObject* Object);
00330             /// @brief Destroys all collisions currently being stored and processed in the manager.
00331             void DestroyAllCollisions();
00332 
00333             /// @brief Used to make working with the Collisions easier.
00334             typedef std::map< ObjectPair,Collision* >::iterator CollisionIterator;
00335             /// @brief Used to make working with the Collisions easier, and avoid the risk of accidentally changing them.
00336             typedef std::map< ObjectPair,Collision* >::const_iterator ConstCollisionIterator;
00337             /// @brief Get an CollisionIterator to the first Collision.
00338             /// @return An CollisionIterator to the first Collision.
00339             CollisionIterator BeginCollision();
00340             /// @brief Get a CollisionIterator to one past the last Collision.
00341             /// @return A CollisionIterator to one past the last Collision.
00342             CollisionIterator EndCollision();
00343             /// @brief Get a ConstCollisionIterator to the first Collision.
00344             /// @return A ConstCollisionIterator to the first Collision.
00345             ConstCollisionIterator BeginCollision() const;
00346             /// @brief Get a ConstCollisionIterator to one past the last Collision.
00347             /// @return A ConstCollisionIterator to one past the last Collision.
00348             ConstCollisionIterator EndCollision() const;
00349 
00350             ///////////////////////////////////////////////////////////////////////////////
00351             // Collision Event Filtering Management
00352 
00353             /// @brief Sets the Collision Parameters.
00354             /// @details Sets the Collision Age and Force Filters used in filtering out collision contacts used to make events.  The lower these numbers, the more events will be generated.  @n
00355             /// These numbers both default to 1.
00356             /// @param Age The number of physics ticks the collision has to have existed to be used.  Usually you want 1 or 2.  Default: 1
00357             /// @param Force The amount of force applied in the collision to filter by.  This amount can vary more then the other param based on what you need.  Default: 1.0
00358             void SetCollisionParams(const unsigned short int Age, Real Force);
00359             /// @brief Gets the Collision Age limit.
00360             /// @details Gets the CollisionAge used in filtering out collision contacts used to make events.
00361             /// @return This function will return the number of physics ticks the collision has to have existed to be used.
00362             unsigned short int GetCollisionAge();
00363             /// @brief Gets the Collision Impulse limit.
00364             /// @details Gets the Collision Impulse used in filtering out collision contacts used to make events.
00365             /// @return This function will return the lower limit of the allowed force of the collision to generate an event.
00366             Real GetImpulse();
00367 
00368             ///////////////////////////////////////////////////////////////////////////////
00369             // Debug Management
00370 
00371             /// @brief Enables and Disables Physics Debug Drawing
00372             /// @details Enables and Disables Physics Debug Drawing using default wireframes. This will force renderings that match the physics
00373             /// subsytem pixel for pixel.
00374             /// @param ToBeEnabled 1 to turn it on, 0 to turn it off. There may be other options in the future, to enable fine tuned control
00375             void SetDebugPhysicsRendering(int ToBeEnabled);
00376             /// @brief Is Physics Debug Drawing currently enabled?
00377             /// @details lets you check if Physics Debug Drawing is enabled or not.
00378             /// @return 1 for it is on, and 0 for it is not. The may be other options later for selectively cnacking certain features
00379             int GetDebugPhysicsRendering();
00380             /// @brief How many Wireframes do you want drawn from previous events
00381             /// @details Each frame of the action gets its own wire frame, and how many of those back did you want to see? To see a minimal amount
00382             /// set this to 2, as the first wireframe is commonly entirely inside the  the rendered 3d mesh. You can use World::GetTargetFrameTime()
00383             /// In conjunction with this to specify an amout of seconds worth of wireframes.
00384             /// @param WireFrameCount_ This is a whole number that is the amount of wire frames you wan to see. Don't forget to be mindful of the framerate,
00385             /// Any amount more than just a few seconds worth can be cumbersome.
00386             void SetDebugPhysicsWireCount(Whole WireFrameCount_);
00387             /// @brief This gets how many WireFrames are being drawn.
00388             /// @details This will tell you how many frames worth of previous in game events are being drawn.
00389             /// @return This returns either 2 or the last amount passed into World::SetDebugPhysicsWireCount .
00390             Whole GetDebugPhysicsWireCount();
00391 
00392             ///////////////////////////////////////////////////////////////////////////////
00393             // Utility
00394 
00395             /// @brief Resets all the internal physics structures in this manager.
00396             /// @warning This should only be called while the world is emtpy and objects have be unloaded from it.
00397             /// @param Info If you want to change the configuration of the world when restarting, you can optionally
00398             /// provide a new set of parameters to build the world with.
00399             void ResetPhysicsWorld(PhysicsConstructionInfo* Info = 0);
00400             /// @brief Clears all data relating to actors and other simulation objects from the physics world.
00401             /// @details This is best used with simulation cleanup.
00402             void ClearPhysicsMetaData();
00403             /// @brief Sets the modifier to be used when stepping the physics simulation.
00404             /// @remarks For the most part, the simulation tick is determined by your target framerate set on Mezzanine::World.  However
00405             /// there are some occasions when you will want to have it tick more often, in particular with sensative simulation setups
00406             /// involving many constraints, or small objects, or fast moving objects, or any combination of those.  In order to make your
00407             /// simulation more stable you have to tick in smaller intervals, making it less likely for the engine to miss something or
00408             /// become unstable.  When you pass in a modifier it'll ensure it ticks faster by that amount.  For example, if you pass in 2
00409             /// to this as the modifier, the physics simulation will take 2 smaller steps (the time being based on the target framerate)
00410             /// instead of one big one during the course of one frame.
00411             /// @param Modifier The amount of substeps per frame to perform.
00412             void SetSimulationSubstepModifier(const Whole& Modifier);
00413             /// @brief This does all the work reuired for the main loop to process physics
00414             /// @details
00415             /// @param TimeElapsed This is a real that represents the amount of time we need to simulate
00416             void DoMainLoopItems(const Real &TimeElapsed);
00417             /// @internal
00418             /// @brief This returns a pointer to the bullet physics world. This is for internal use only
00419             btSoftRigidDynamicsWorld* GetPhysicsWorldPointer();
00420 
00421             ///////////////////////////////////////////////////////////////////////////////
00422             // Inherited from Managerbase
00423 
00424             /// @copydoc Mezzanine::ManagerBase::Initialize()
00425             virtual void Initialize();
00426             /// @copydoc Mezzanine::ManagerBase::DoMainLoopItems()
00427             virtual void DoMainLoopItems();
00428             /// @copydoc Mezzanine::ManagerBase::GetType()
00429             virtual ManagerBase::ManagerTypeName GetType() const;
00430     };//physics manager
00431 }//Mezzanine
00432 
00433 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines