fysxasteroids/engine/PhysicsBase.h

149 lines
5.0 KiB
C++

#ifndef _PHYSICSBASE_H
#define _PHYSICSBASE_H
#include "Engine.h"
#include "EntityBase.h"
namespace coll2d {
struct CollisionInfo;
}
/// \todo get rid of this forward declaration somehow
struct vector3d;
namespace Engine {
class Module;
class Events;
class EntityPhysicState;
/** \brief Performs the physical simulation of all Entities
*
* This class defines how the physical simulation is performed. Especially how
* collisions are treated is defined in the function
* Physics::ResolveCollision() . This function can be modified to simulate
* dynamics effects such as friction, bouncing, stacking etc..
*
* \todo When running along multiple boxes that are perfectly aligned one hangs from time to time at the last box
*/
class PhysicsBase : public Module {
public:
/** \brief Performs the simulation for the next msec milliseconds
* \param msec The amount of time that is to be simulated
* \param model A pointer to the model that will be used to pass on collision events.*/
virtual int Simulate (float msec, ModelBase* model = NULL);
/** \brief Registers the physical state of an Entity */
virtual void RegisterEntity (EntityPhysicState* entity);
/** \brief Unregisters the physical state of an Entity */
virtual void UnregisterEntity (const unsigned int id);
/** \brief Calculates the next pair of Entities that will collide */
bool CalcNextCollision (float stepsize,
unsigned int &reference_entity_id,
unsigned int &incidence_entity_id,
coll2d::CollisionInfo &info);
/** \brief Modes for warping entities when they reach the world boundaries
*
* \todo add entity warping along the y direction
*
* */
enum WorldWarp {
WorldWarpModeX = 0,
WorldWarpModeZ,
WorldWarpModeLast
};
/** \brief Enables wrapping of entities at the given world boundary */
void EnableWorldWarp (WorldWarp mode) {
mWorldWarp.set(mode, true);
}
/** \brief Disables wrapping of entities at the given world boundary */
void DisableWorldWarp (WorldWarp mode) {
mWorldWarp.set(mode, false);
}
/** \brief Sets world boundaries (needed for Entity warping) */
void SetWorldBounds (const vector3d &min_bound, const vector3d &max_bound) {
mWorldMin = min_bound;
mWorldMax = max_bound;
}
/** \brief Returns the boundaries for the world */
void GetWorldBounds (vector3d &min_bound, vector3d &max_bound) {
min_bound = mWorldMin;
max_bound = mWorldMax;
}
protected:
/** \brief Initializes the system */
virtual int OnInit (int argc, char* argv[]);
/** \brief Destroys the system (must be called!) */
virtual void OnDestroy ();
/** \brief Moves all Entities for delta_msec milliseconds (can be
* negative!) */
void Move (float delta_msec);
/** \brief Checks whether two given Entities can collide */
bool CheckPossibleCollisionPair (EntityPhysicState* entity_a, EntityPhysicState* entity_b);
/** \brief Resolves the collision that CalcNextCollision has found
* It resolves a found collision and prevents interpenetration of cached contacts.
*/
void ResolveCollision (float stepsize,
unsigned int reference_entity_id,
unsigned int incidence_entity_id,
coll2d::CollisionInfo &info);
/** \brief Contains all Entities with a physical state */
std::map<unsigned int, EntityPhysicState*> mEntities;
private:
/** \brief Caches the contact information between two entities
*/
void ContactCacheAdd (EntityPhysicState* incidence_entity, EntityPhysicState* reference_entity, vector3d normal);
/** \brief Removes the contact cache information of two entities in contact
*/
void ContactCacheRemove (unsigned int entity_a_id, unsigned int entity_b_id);
/** \brief Checks whether the entries in the contact cache are still valid
*/
void CheckContactCache (EntityPhysicState* entity);
/** \brief Checks whether the entity has to be warped from one world boundary to the other
*
* \returns The directions in which the entity should be warped
* */
vector3d CheckEntityWarp (EntityPhysicState* entity, float stepsize);
/** \brief Performs collision checks for all candidates of warped positions
*
* \returns >0 for collisions, = 0 for no collisions, < 0 coll2d error
*/
int PerformWarpedCollisionChecks (float stepsize,
EntityPhysicState* entity_a,
EntityPhysicState* entity_b,
vector3d warp_directions,
coll2d::CollisionInfo &info);
/** \brief Allows to ignore certain kinds of errors reported by coll2d
*/
bool HandleColl2dError (int coll2d_result, float stepsize,
EntityPhysicState* entity_a, EntityPhysicState* entity_b, coll2d::CollisionInfo &info);
/** \brief Contains information for which boundaries there should be an entity warp
*/
std::bitset<WorldWarpModeLast> mWorldWarp;
/** \brief Lower bound of the world coordinates
*/
vector3d mWorldMin;
/** \brief Upper bound of the world coordinates
*/
vector3d mWorldMax;
};
/** \brief Creates an EntityPhysicState with all the required information */
EntityPhysicState* CreateEntityPhysicState (EntityBaseType type, unsigned int id);
}
#endif // _PHYSICSBASE_H