CUGL 2.1
Cornell University Game Library
|
#include <CUObstacleWorld.h>
Public Member Functions | |
ObstacleWorld () | |
~ObstacleWorld () | |
void | dispose () |
bool | init (const Rect bounds) |
bool | init (const Rect bounds, const Vec2 gravity) |
b2World * | getWorld () |
bool | isLockStep () const |
void | setLockStep (bool flag) |
float | getStepsize () const |
void | setStepsize (float step) |
int | getVelocityIterations () const |
void | setVelocityIterations (int velocity) |
int | getPositionIterations () const |
void | setPositionIterations (int position) |
const Vec2 | getGravity () const |
void | setGravity (const Vec2 gravity) |
void | update (float dt) |
const Rect | getBounds () const |
bool | inBounds (Obstacle *obj) |
const std::vector< std::shared_ptr< Obstacle > > & | getObstacles () |
void | addObstacle (const std::shared_ptr< Obstacle > &obj) |
void | removeObstacle (Obstacle *obj) |
void | garbageCollect () |
void | clear () |
void | activateCollisionCallbacks (bool flag) |
bool | enabledCollisionCallbacks () const |
void | BeginContact (b2Contact *contact) override |
void | EndContact (b2Contact *contact) override |
void | PreSolve (b2Contact *contact, const b2Manifold *oldManifold) override |
void | PostSolve (b2Contact *contact, const b2ContactImpulse *impulse) override |
void | activateFilterCallbacks (bool flag) |
bool | enabledFilterCallbacks () const |
bool | ShouldCollide (b2Fixture *fixtureA, b2Fixture *fixtureB) override |
void | activateDestructionCallbacks (bool flag) |
bool | enabledDestructionCallbacks () const |
void | SayGoodbye (b2Joint *joint) override |
void | SayGoodbye (b2Fixture *fixture) override |
void | queryAABB (std::function< bool(b2Fixture *fixture)> callback, const Rect aabb) const |
void | rayCast (std::function< float(b2Fixture *fixture, const Vec2 point, const Vec2 normal, float fraction)> callback, const Vec2 point1, const Vec2 point2) const |
Static Public Member Functions | |
static std::shared_ptr< ObstacleWorld > | alloc (const Rect bounds) |
static std::shared_ptr< ObstacleWorld > | alloc (const Rect bounds, const Vec2 gravity) |
Public Attributes | |
std::function< void(b2Contact *contact)> | onBeginContact |
std::function< void(b2Contact *contact)> | onEndContact |
std::function< void(b2Contact *contact, const b2Manifold *oldManifold)> | beforeSolve |
std::function< void(b2Contact *contact, const b2ContactImpulse *impulse)> | afterSolve |
std::function< bool(b2Fixture *fixtureA, b2Fixture *fixtureB)> | shouldCollide |
std::function< void(b2Fixture *fixture)> | destroyFixture |
std::function< void(b2Joint *joint)> | destroyJoint |
Protected Attributes | |
b2World * | _world |
bool | _lockstep |
float | _stepssize |
int | _itvelocity |
int | _itposition |
Vec2 | _gravity |
std::vector< std::shared_ptr< Obstacle > > | _objects |
Rect | _bounds |
bool | _collide |
bool | _filters |
bool | _destroy |
A CUGL wrapper for a Box2d world.
This module provides a wrapper to Box2d that for use with CUGL obstacle heirarchy. Obstacles provide a simple and direct way to create physics objects that does not require the multi-step approach of Box2D. It also supports shared pointers for simply memory management.
In addition, this class provides a modern callback approach supporting closures assigned to attributes. This allows you to modify the callback functions while the program is running.
cugl::physics2::ObstacleWorld::ObstacleWorld | ( | ) |
Creates a new degenerate ObstacleWorld on the stack.
The scene has no backing Box2d world and must be initialized.
NEVER USE A CONSTRUCTOR WITH NEW. If you want to allocate an object on the heap, use one of the static constructors instead.
|
inline |
Deletes this world, disposing all resources
void cugl::physics2::ObstacleWorld::activateCollisionCallbacks | ( | bool | flag | ) |
Activates the collision callbacks.
If flag is false, then the collision callbacks (even if defined) will be ignored. Otherwise, the callbacks will be executed (on collision) if they are defined.
flag | whether to activate the collision callbacks. |
void cugl::physics2::ObstacleWorld::activateDestructionCallbacks | ( | bool | flag | ) |
Activates the destruction callbacks.
If flag is false, then the destruction callbacks (even if defined) will be ignored. Otherwise, the callbacks will be executed (on body destruction) if they are defined.
flag | whether to activate the collision callbacks. |
void cugl::physics2::ObstacleWorld::activateFilterCallbacks | ( | bool | flag | ) |
Activates the collision filter callbacks.
If flag is false, then the collision filter callbacks (even if defined) will be ignored. Otherwise, the callbacks will be executed (to test a collision) if they are defined.
flag | whether to activate the collision callbacks. |
void cugl::physics2::ObstacleWorld::addObstacle | ( | const std::shared_ptr< Obstacle > & | obj | ) |
Immediately adds the obstacle to the physics world
Adding an obstacle activates the underlying physics. It will now have a body. In the case of a ComplexObstacle, joints will be added between the obstacles. The physics world will include the obstacle in its next call to update.
The obstacle will be retained by this world, preventing it from being garbage collected.
param obj The obstacle to add
|
inlinestatic |
Returns a newly allocated physics world
The specified bounds are in terms of the Box2d world, not the screen. A few attached to this Box2d world should have ways to convert between the coordinate systems.
This constructor will use the default gravitational value.
bounds | The game bounds in Box2d coordinates |
|
inlinestatic |
Returns a newly allocated physics world
The specified bounds are in terms of the Box2d world, not the screen. A few attached to this Box2d world should have ways to convert between the coordinate systems.
bounds | The game bounds in Box2d coordinates |
gravity | The gravitational force on this Box2d world |
|
inlineoverride |
Called when two fixtures begin to touch
This method is the static callback required by the Box2d API. It should not be altered.
contact | the contact information |
void cugl::physics2::ObstacleWorld::clear | ( | ) |
Remove all objects, emptying this physics world.
This method is different from dispose() in that the world can still receive new objects.
void cugl::physics2::ObstacleWorld::dispose | ( | ) |
Disposes all of the resources used by this world.
A disposed ObstacleWorld can be safely reinitialized. Any obstacles owned by this world will be deactivates. They will be deleted if no other object owns them.
|
inline |
Returns true if the collision callbacks are active
If this value is false, then the collision callbacks (even if defined) will be ignored. Otherwise, the callbacks will be executed (on collision) if they are defined.
|
inline |
Returns true if the destruction callbacks are active
If this value is false, then the destruction callbacks (even if defined) will be ignored. Otherwise, the callbacks will be executed (on body destruction) if they are defined.
|
inline |
Returns true if the collision filter callbacks are active
If this value is false, then the collision filter callbacks (even if defined) will be ignored. Otherwise, the callbacks will be executed (to test a collision) if they are defined.
|
inlineoverride |
Called when two fixtures cease to touch
This method is the static callback required by the Box2d API. It should not be altered.
contact | the contact information |
void cugl::physics2::ObstacleWorld::garbageCollect | ( | ) |
Remove all objects marked for removal.
The obstacles will be released immediately. The physics will be deactivated and they will be removed from the Box2D world.
Removing an obstacle does not automatically delete the obstacle itself. However, this world releases ownership, which may lead to it being garbage collected.
This method is the efficient, preferred way to remove objects.
|
inline |
Returns the bounds for the world controller.
|
inline |
Returns the global gravity vector.
|
inline |
Returns a read-only reference to the list of active obstacles.
|
inline |
Returns number of position iterations for the constrain solvers
|
inline |
Returns the amount of time for a single engine step.
This attribute is only relevant if isLockStep() is true.
|
inline |
Returns number of velocity iterations for the constrain solvers
|
inline |
Returns a (weak) reference to the Box2d world.
This accessor is for any world methods that are not encapsulated by this constroller. We have largely limited the controller to functionality that requires b2WorldCallbacks, as those classes are antiquated in the face of modern closures.
As a weak reference, this physics world does not transfer ownership of this object. In addition, the value may be a nullptr.
bool cugl::physics2::ObstacleWorld::inBounds | ( | Obstacle * | obj | ) |
Returns true if the object is in bounds.
This assertion is useful for debugging the physics.
obj | The object to check. |
bool cugl::physics2::ObstacleWorld::init | ( | const Rect | bounds | ) |
Initializes a new physics world
The specified bounds are in terms of the Box2d world, not the screen. A few attached to this Box2d world should have ways to convert between the coordinate systems.
This constructor will use the default gravitational value.
bounds | The game bounds in Box2d coordinates |
Initializes a new physics world
The specified bounds are in terms of the Box2d world, not the screen. A few attached to this Box2d world should have ways to convert between the coordinate systems.
bounds | The game bounds in Box2d coordinates |
gravity | The gravitational force on this Box2d world |
|
inline |
Returns true if the physics is locked to a constant timestep.
If this is false, the physics timestep will vary with the graphics framerate.
|
inlineoverride |
Called after the solver is finished.
This callback lets you inspect a contact after the solver is finished. This is useful for inspecting impulses.
Note: the contact manifold does not include time of impact impulses, which can be arbitrarily large if the sub-step is small. Hence the impulse is provided explicitly in a separate data structure. Note: this is only called for contacts that are touching, solid, and awake.
This method is the static callback required by the Box2d API. It should not be altered.
contact | the contact information |
impulse | the impulse produced by the solver |
|
inlineoverride |
Called after a contact is updated.
This callback allows you to inspect a contact before it goes to the solver. If you are careful, you can modify the contact manifold (e.g. disable contact).
A copy of the old manifold is provided so that you can detect changes.
Note: this is called only for awake bodies. Note: this is called even when the number of contact points is zero. Note: this is not called for sensors. Note: if you set the number of contact points to zero, you will not get an EndContact callback. However, you may get a BeginContact callback the next step.
This method is the static callback required by the Box2d API. It should not be altered.
contact | the contact information |
oldManifold | the contact manifold last iteration |
void cugl::physics2::ObstacleWorld::queryAABB | ( | std::function< bool(b2Fixture *fixture)> | callback, |
const Rect | aabb | ||
) | const |
Query the world for all fixtures that potentially overlap the provided AABB.
The AABB is specified by a Cocos2d rectangle.
callback | A user implemented callback function. |
aabb | The axis-aligned bounding box |
void cugl::physics2::ObstacleWorld::rayCast | ( | std::function< float(b2Fixture *fixture, const Vec2 point, const Vec2 normal, float fraction)> | callback, |
const Vec2 | point1, | ||
const Vec2 | point2 | ||
) | const |
Ray-cast the world for all fixtures in the path of the ray.
The callback controls whether you get the closest point, any point, or n-points. The ray-cast ignores shapes that contain the starting point.
callback | a user implemented callback function. |
point1 | The ray starting point |
point2 | The ray ending point |
void cugl::physics2::ObstacleWorld::removeObstacle | ( | Obstacle * | obj | ) |
Immediately removes an obstacle from the physics world
The obstacle will be released immediately. The physics will be deactivated and it will be removed from the Box2D world. This method of removing objects is very heavy weight, and should only be used for single object removal. If you want to remove multiple objects, then you should mark them for removal and call garbageCollect.
Removing an obstacle does not automatically delete the obstacle itself. However, this world releases ownership, which may lead to it being garbage collected.
param obj The obstacle to remove
|
inlineoverride |
Called when a fixture is about to be destroyed.
This function is only called when the destruction is the result of the destruction of its parent body.
fixture | the fixture to be destroyed |
|
inlineoverride |
Called when a joint is about to be destroyed.
This function is only called when the destruction is the result of the destruction of one of its attached bodies.
joint | the joint to be destroyed |
void cugl::physics2::ObstacleWorld::setGravity | ( | const Vec2 | gravity | ) |
Sets the global gravity vector.
Any change will take effect at the time of the next call to update.
gravity | the global gravity vector. |
|
inline |
Sets whether the physics is locked to a constant timestep.
If this is false, the physics timestep will vary with the graphics framerate. Any change will take effect at the time of the next call to update.
flag | whether the physics is locked to a constant timestep. |
|
inline |
Sets number of position iterations for the constrain solvers
Any change will take effect at the time of the next call to update.
position | number of position iterations for the constrain solvers |
|
inline |
Sets the amount of time for a single engine step.
This attribute is only relevant if isLockStep() is true. Any change will take effect at the time of the next call to update.
step | the amount of time for a single engine step. |
|
inline |
Sets number of velocity iterations for the constrain solvers
Any change will take effect at the time of the next call to update.
velocity | number of velocity iterations for the constrain solvers |
|
inlineoverride |
Return true if contact calculations should be performed between these two shapes.
For performance reasons this is only called when the AABBs begin to overlap.
fixtureA | the first colliding shape |
fixtureB | the second colliding shape |
void cugl::physics2::ObstacleWorld::update | ( | float | dt | ) |
Executes a single step of the physics engine.
This method contains the specific update code for this mini-game. It does not handle collisions, as those are managed by the parent class WorldController. This method is called after input is read, but before collisions are resolved. The very last thing that it should do is apply forces to the appropriate objects.
Once the update phase is over, but before we draw, we are ready to handle physics. The primary method is the step() method in world. This implementation works for all applications and should not need to be overwritten.
dt | Number of seconds since last animation frame |
|
protected |
The boundary of the world
|
protected |
Whether or not to activate the collision listener
|
protected |
Whether or not to activate the destruction listener
|
protected |
Whether or not to activate the filter listener
|
protected |
The current gravitational value of the world
|
protected |
The number of position iterations for the constrain solvers
|
protected |
The number of velocity iterations for the constrain solvers
|
protected |
Whether to lock the physic timestep to a constant amount
|
protected |
The list of objects in this world
|
protected |
The amount of time for a single engine step
|
protected |
Reference to the Box2D world
std::function<void(b2Contact* contact, const b2ContactImpulse* impulse)> cugl::physics2::ObstacleWorld::afterSolve |
Called after the solver is finished.
This callback lets you inspect a contact after the solver is finished. This is useful for inspecting impulses.
Note: the contact manifold does not include time of impact impulses, which can be arbitrarily large if the sub-step is small. Hence the impulse is provided explicitly in a separate data structure. Note: this is only called for contacts that are touching, solid, and awake.
This attribute is a dynamically assignable callback and may be changed at any given time.
contact | the contact information |
impulse | the impulse produced by the solver |
std::function<void(b2Contact* contact, const b2Manifold* oldManifold)> cugl::physics2::ObstacleWorld::beforeSolve |
Called after a contact is updated.
This callback allows you to inspect a contact before it goes to the solver. If you are careful, you can modify the contact manifold (e.g. disable contact).
A copy of the old manifold is provided so that you can detect changes.
Note: this is called only for awake bodies. Note: this is called even when the number of contact points is zero. Note: this is not called for sensors. Note: if you set the number of contact points to zero, you will not get an EndContact callback. However, you may get a BeginContact callback the next step.
This attribute is a dynamically assignable callback and may be changed at any given time.
contact | the contact information |
oldManifold | the contact manifold last iteration |
std::function<void(b2Fixture* fixture)> cugl::physics2::ObstacleWorld::destroyFixture |
Called when a fixture is about to be destroyed.
This function is only called when the destruction is the result of the destruction of its parent body.
fixture | the fixture to be destroyed |
std::function<void(b2Joint* joint)> cugl::physics2::ObstacleWorld::destroyJoint |
Called when a joint is about to be destroyed.
This function is only called when the destruction is the result of the destruction of one of its attached bodies.
joint | the joint to be destroyed |
std::function<void(b2Contact* contact)> cugl::physics2::ObstacleWorld::onBeginContact |
Called when two fixtures begin to touch
This attribute is a dynamically assignable callback and may be changed at any given time.
contact | the contact information |
std::function<void(b2Contact* contact)> cugl::physics2::ObstacleWorld::onEndContact |
Called when two fixtures cease to touch
This attribute is a dynamically assignable callback and may be changed at any given time.
contact | the contact information |
std::function<bool(b2Fixture* fixtureA, b2Fixture* fixtureB)> cugl::physics2::ObstacleWorld::shouldCollide |
Return true if contact calculations should be performed between these two shapes.
For performance reasons this is only called when the AABBs begin to overlap.
fixtureA | the first colliding shape |
fixtureB | the second colliding shape |