2010-04-05 23:38:59 +02:00
|
|
|
#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);
|
2011-02-01 17:14:25 +01:00
|
|
|
/** \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 */
|
|
|
|
enum WorldWarp {
|
|
|
|
WorldWarpModeX = 0,
|
|
|
|
WorldWarpModeY,
|
|
|
|
WorldWarpModeZ,
|
|
|
|
WorldWarpModeLast
|
|
|
|
};
|
|
|
|
|
|
|
|
void EnableWorldWarp (WorldWarp mode) {
|
|
|
|
mWorldWarp.set(mode, true);
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
2010-04-05 23:38:59 +02:00
|
|
|
|
|
|
|
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:
|
2011-02-01 17:14:25 +01:00
|
|
|
/** \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,
|
2010-04-05 23:38:59 +02:00
|
|
|
EntityPhysicState* entity_a, EntityPhysicState* entity_b, coll2d::CollisionInfo &info);
|
2011-02-01 17:14:25 +01:00
|
|
|
|
|
|
|
std::bitset<WorldWarpModeLast> mWorldWarp;
|
|
|
|
|
|
|
|
vector3d mWorldMin;
|
|
|
|
vector3d mWorldMax;
|
2010-04-05 23:38:59 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/** \brief Creates an EntityPhysicState with all the required information */
|
|
|
|
EntityPhysicState* CreateEntityPhysicState (EntityBaseType type, unsigned int id);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // _PHYSICSBASE_H
|