2013-09-09 10:29:02 +08:00
|
|
|
/****************************************************************************
|
2014-01-07 11:47:11 +08:00
|
|
|
Copyright (c) 2013 Chukong Technologies Inc.
|
2013-09-09 10:29:02 +08:00
|
|
|
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifndef __CCPHYSICS_WORLD_H__
|
|
|
|
#define __CCPHYSICS_WORLD_H__
|
|
|
|
|
2014-04-30 08:37:36 +08:00
|
|
|
#include "base/ccConfig.h"
|
2013-12-26 23:55:05 +08:00
|
|
|
#if CC_USE_PHYSICS
|
2013-11-06 14:51:56 +08:00
|
|
|
|
2014-04-27 01:35:57 +08:00
|
|
|
#include "base/CCVector.h"
|
2014-04-27 01:11:22 +08:00
|
|
|
#include "base/CCRef.h"
|
2014-04-30 08:37:36 +08:00
|
|
|
#include "math/CCGeometry.h"
|
2014-07-15 10:55:40 +08:00
|
|
|
#include "physics/CCPhysicsBody.h"
|
2013-12-07 10:48:02 +08:00
|
|
|
#include <list>
|
|
|
|
|
2015-01-06 10:29:07 +08:00
|
|
|
struct cpSpace;
|
|
|
|
|
2013-09-09 10:29:02 +08:00
|
|
|
NS_CC_BEGIN
|
|
|
|
|
|
|
|
class PhysicsBody;
|
|
|
|
class PhysicsJoint;
|
2013-09-16 21:22:22 +08:00
|
|
|
class PhysicsShape;
|
|
|
|
class PhysicsContact;
|
2013-09-09 10:29:02 +08:00
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
typedef Vec2 Vect;
|
2013-11-26 17:29:09 +08:00
|
|
|
|
2015-01-07 17:08:04 +08:00
|
|
|
class Director;
|
2014-02-26 10:53:41 +08:00
|
|
|
class Node;
|
2013-09-09 16:36:19 +08:00
|
|
|
class Sprite;
|
2014-05-02 07:42:35 +08:00
|
|
|
class Scene;
|
2013-09-16 21:22:22 +08:00
|
|
|
class DrawNode;
|
2013-11-08 14:25:03 +08:00
|
|
|
class PhysicsDebugDraw;
|
2013-09-16 21:22:22 +08:00
|
|
|
|
2013-10-21 23:16:21 +08:00
|
|
|
class PhysicsWorld;
|
|
|
|
|
2013-11-07 16:23:50 +08:00
|
|
|
typedef struct PhysicsRayCastInfo
|
2013-10-21 23:16:21 +08:00
|
|
|
{
|
2013-11-07 16:23:50 +08:00
|
|
|
PhysicsShape* shape;
|
2014-05-15 01:07:09 +08:00
|
|
|
Vec2 start;
|
|
|
|
Vec2 end; //< in lua, it's name is "ended"
|
|
|
|
Vec2 contact;
|
2013-11-07 16:23:50 +08:00
|
|
|
Vect normal;
|
|
|
|
float fraction;
|
|
|
|
void* data;
|
|
|
|
}PhysicsRayCastInfo;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Called for each fixture found in the query. You control how the ray cast
|
|
|
|
* proceeds by returning a float:
|
|
|
|
* return true: continue
|
|
|
|
* return false: terminate the ray cast
|
|
|
|
* @param fixture the fixture hit by the ray
|
|
|
|
* @param point the point of initial intersection
|
|
|
|
* @param normal the normal vector at the point of intersection
|
|
|
|
* @return true to continue, false to terminate
|
|
|
|
*/
|
|
|
|
typedef std::function<bool(PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data)> PhysicsRayCastCallbackFunc;
|
2013-12-13 16:26:26 +08:00
|
|
|
typedef std::function<bool(PhysicsWorld&, PhysicsShape&, void*)> PhysicsQueryRectCallbackFunc;
|
|
|
|
typedef PhysicsQueryRectCallbackFunc PhysicsQueryPointCallbackFunc;
|
2013-10-21 23:16:21 +08:00
|
|
|
|
2013-09-17 16:27:43 +08:00
|
|
|
/**
|
|
|
|
* @brief An PhysicsWorld object simulates collisions and other physical properties. You do not create PhysicsWorld objects directly; instead, you can get it from an Scene object.
|
|
|
|
*/
|
2014-07-15 10:55:40 +08:00
|
|
|
class CC_DLL PhysicsWorld
|
2013-09-09 10:29:02 +08:00
|
|
|
{
|
2013-11-18 10:10:37 +08:00
|
|
|
public:
|
2013-12-13 17:36:58 +08:00
|
|
|
static const int DEBUGDRAW_NONE; ///< draw nothing
|
|
|
|
static const int DEBUGDRAW_SHAPE; ///< draw shapes
|
|
|
|
static const int DEBUGDRAW_JOINT; ///< draw joints
|
|
|
|
static const int DEBUGDRAW_CONTACT; ///< draw contact
|
|
|
|
static const int DEBUGDRAW_ALL; ///< draw all
|
2013-11-18 10:10:37 +08:00
|
|
|
|
2013-09-09 10:29:02 +08:00
|
|
|
public:
|
2013-09-17 16:27:43 +08:00
|
|
|
/** Adds a joint to the physics world.*/
|
2013-11-04 19:26:34 +08:00
|
|
|
virtual void addJoint(PhysicsJoint* joint);
|
2013-12-13 17:36:58 +08:00
|
|
|
/** Remove a joint from physics world.*/
|
2014-02-26 10:53:41 +08:00
|
|
|
virtual void removeJoint(PhysicsJoint* joint, bool destroy = true);
|
2013-12-13 17:36:58 +08:00
|
|
|
/** Remove all joints from physics world.*/
|
2014-02-26 10:53:41 +08:00
|
|
|
virtual void removeAllJoints(bool destroy = true);
|
2013-11-04 19:26:34 +08:00
|
|
|
|
2013-12-13 17:36:58 +08:00
|
|
|
/** Remove a body from physics world. */
|
2013-11-04 19:26:34 +08:00
|
|
|
virtual void removeBody(PhysicsBody* body);
|
2013-12-13 17:36:58 +08:00
|
|
|
/** Remove body by tag. */
|
2013-11-05 20:02:58 +08:00
|
|
|
virtual void removeBody(int tag);
|
2013-12-13 17:36:58 +08:00
|
|
|
/** Remove all bodies from physics world. */
|
2013-11-04 19:26:34 +08:00
|
|
|
virtual void removeAllBodies();
|
2013-09-09 10:29:02 +08:00
|
|
|
|
2013-12-13 17:36:58 +08:00
|
|
|
/** Searches for physics shapes that intersects the ray. */
|
2014-05-15 01:07:09 +08:00
|
|
|
void rayCast(PhysicsRayCastCallbackFunc func, const Vec2& start, const Vec2& end, void* data);
|
2013-12-13 17:36:58 +08:00
|
|
|
/** Searches for physics shapes that contains in the rect. */
|
2013-12-13 16:26:26 +08:00
|
|
|
void queryRect(PhysicsQueryRectCallbackFunc func, const Rect& rect, void* data);
|
2013-12-13 17:36:58 +08:00
|
|
|
/** Searches for physics shapes that contains the point. */
|
2014-05-15 01:07:09 +08:00
|
|
|
void queryPoint(PhysicsQueryPointCallbackFunc func, const Vec2& point, void* data);
|
2013-12-13 17:36:58 +08:00
|
|
|
/** Get phsyics shapes that contains the point. */
|
2014-05-15 01:07:09 +08:00
|
|
|
Vector<PhysicsShape*> getShapes(const Vec2& point) const;
|
2013-12-13 17:36:58 +08:00
|
|
|
/** return physics shape that contains the point. */
|
2014-05-15 01:07:09 +08:00
|
|
|
PhysicsShape* getShape(const Vec2& point) const;
|
2013-12-13 17:36:58 +08:00
|
|
|
/** Get all the bodys that in the physics world. */
|
2013-12-07 10:48:02 +08:00
|
|
|
const Vector<PhysicsBody*>& getAllBodies() const;
|
2013-12-13 17:36:58 +08:00
|
|
|
/** Get body by tag */
|
2013-11-05 20:02:58 +08:00
|
|
|
PhysicsBody* getBody(int tag) const;
|
2013-09-09 10:29:02 +08:00
|
|
|
|
2014-05-02 07:42:35 +08:00
|
|
|
/** Get scene contain this physics world */
|
|
|
|
inline Scene& getScene() const { return *_scene; }
|
2013-09-17 16:27:43 +08:00
|
|
|
/** get the gravity value */
|
2013-11-07 14:17:57 +08:00
|
|
|
inline Vect getGravity() const { return _gravity; }
|
2013-09-17 16:27:43 +08:00
|
|
|
/** set the gravity value */
|
2013-11-07 14:17:57 +08:00
|
|
|
void setGravity(const Vect& gravity);
|
2014-06-12 12:45:21 +08:00
|
|
|
/**
|
|
|
|
* Set the speed of physics world, speed is the rate at which the simulation executes. default value is 1.0
|
|
|
|
* Note: if you setAutoStep(false), this won't work.
|
|
|
|
*/
|
2013-12-13 16:26:26 +08:00
|
|
|
inline void setSpeed(float speed) { if(speed >= 0.0f) { _speed = speed; } }
|
|
|
|
/** get the speed of physics world */
|
|
|
|
inline float getSpeed() { return _speed; }
|
2014-06-12 12:45:21 +08:00
|
|
|
/**
|
2013-12-13 16:26:26 +08:00
|
|
|
* set the update rate of physics world, update rate is the value of EngineUpdateTimes/PhysicsWorldUpdateTimes.
|
|
|
|
* set it higher can improve performance, set it lower can improve accuracy of physics world simulation.
|
|
|
|
* default value is 1.0
|
2014-06-12 12:45:21 +08:00
|
|
|
* Note: if you setAutoStep(false), this won't work.
|
2013-12-13 16:26:26 +08:00
|
|
|
*/
|
|
|
|
inline void setUpdateRate(int rate) { if(rate > 0) { _updateRate = rate; } }
|
|
|
|
/** get the update rate */
|
|
|
|
inline int getUpdateRate() { return _updateRate; }
|
2014-09-08 06:14:40 +08:00
|
|
|
/**
|
|
|
|
* set the number of substeps in an update of the physics world.
|
|
|
|
* One physics update will be divided into several substeps to increase its accuracy.
|
|
|
|
* default value is 1
|
|
|
|
*/
|
|
|
|
void setSubsteps(int steps);
|
|
|
|
/** get the number of substeps */
|
|
|
|
inline int getSubsteps() const { return _substeps; }
|
|
|
|
|
2013-12-13 17:36:58 +08:00
|
|
|
/** set the debug draw mask */
|
2013-11-08 14:25:03 +08:00
|
|
|
void setDebugDrawMask(int mask);
|
2013-12-13 17:36:58 +08:00
|
|
|
/** get the bebug draw mask */
|
2013-11-08 14:25:03 +08:00
|
|
|
inline int getDebugDrawMask() { return _debugDrawMask; }
|
2013-09-16 21:22:22 +08:00
|
|
|
|
2014-06-12 12:45:21 +08:00
|
|
|
/**
|
|
|
|
* To control the step of physics, if you want control it by yourself( fixed-timestep for example ), you can set this to false and call step by yourself.
|
|
|
|
* Defaut value is true.
|
2014-09-08 06:14:40 +08:00
|
|
|
* Note: if you set auto step to false, setSpeed setSubsteps and setUpdateRate won't work, you need to control the time step by yourself.
|
2014-06-12 12:45:21 +08:00
|
|
|
*/
|
|
|
|
void setAutoStep(bool autoStep){ _autoStep = autoStep; }
|
|
|
|
/** Get the auto step */
|
|
|
|
bool isAutoStep() { return _autoStep; }
|
|
|
|
/**
|
|
|
|
* The step for physics world, The times passing for simulate the physics.
|
|
|
|
* Note: you need to setAutoStep(false) first before it can work.
|
|
|
|
*/
|
|
|
|
void step(float delta);
|
|
|
|
|
2013-09-09 10:29:02 +08:00
|
|
|
protected:
|
2014-05-02 07:42:35 +08:00
|
|
|
static PhysicsWorld* construct(Scene& scene);
|
|
|
|
bool init(Scene& scene);
|
2013-09-16 21:22:22 +08:00
|
|
|
|
2013-11-07 14:40:09 +08:00
|
|
|
virtual void addBody(PhysicsBody* body);
|
|
|
|
virtual void addShape(PhysicsShape* shape);
|
2013-09-29 09:39:20 +08:00
|
|
|
virtual void removeShape(PhysicsShape* shape);
|
2014-06-12 12:45:21 +08:00
|
|
|
virtual void update(float delta, bool userCall = false);
|
2013-09-16 21:22:22 +08:00
|
|
|
|
|
|
|
virtual void debugDraw();
|
|
|
|
|
2013-10-18 15:34:13 +08:00
|
|
|
virtual int collisionBeginCallback(PhysicsContact& contact);
|
2013-10-25 10:31:22 +08:00
|
|
|
virtual int collisionPreSolveCallback(PhysicsContact& contact);
|
|
|
|
virtual void collisionPostSolveCallback(PhysicsContact& contact);
|
2013-10-18 15:34:13 +08:00
|
|
|
virtual void collisionSeparateCallback(PhysicsContact& contact);
|
2013-09-09 10:29:02 +08:00
|
|
|
|
2013-11-07 15:12:13 +08:00
|
|
|
virtual void doAddBody(PhysicsBody* body);
|
|
|
|
virtual void doRemoveBody(PhysicsBody* body);
|
|
|
|
virtual void doRemoveJoint(PhysicsJoint* joint);
|
|
|
|
virtual void addBodyOrDelay(PhysicsBody* body);
|
|
|
|
virtual void removeBodyOrDelay(PhysicsBody* body);
|
2013-11-04 19:26:34 +08:00
|
|
|
virtual void updateBodies();
|
|
|
|
virtual void updateJoints();
|
|
|
|
|
2013-09-09 10:29:02 +08:00
|
|
|
protected:
|
2013-11-07 14:17:57 +08:00
|
|
|
Vect _gravity;
|
2013-09-09 10:29:02 +08:00
|
|
|
float _speed;
|
2013-12-13 16:26:26 +08:00
|
|
|
int _updateRate;
|
|
|
|
int _updateRateCount;
|
|
|
|
float _updateTime;
|
2014-09-08 06:14:40 +08:00
|
|
|
int _substeps;
|
2015-01-06 10:29:07 +08:00
|
|
|
cpSpace* _cpSpace;
|
2013-09-09 10:29:02 +08:00
|
|
|
|
2013-12-07 10:48:02 +08:00
|
|
|
Vector<PhysicsBody*> _bodies;
|
2013-09-29 09:39:20 +08:00
|
|
|
std::list<PhysicsJoint*> _joints;
|
2014-05-02 07:42:35 +08:00
|
|
|
Scene* _scene;
|
2013-09-16 21:22:22 +08:00
|
|
|
|
2013-11-04 19:26:34 +08:00
|
|
|
bool _delayDirty;
|
2014-06-12 12:45:21 +08:00
|
|
|
bool _autoStep;
|
2013-11-08 14:25:03 +08:00
|
|
|
PhysicsDebugDraw* _debugDraw;
|
|
|
|
int _debugDrawMask;
|
|
|
|
|
2013-09-09 10:29:02 +08:00
|
|
|
|
2013-12-07 10:48:02 +08:00
|
|
|
Vector<PhysicsBody*> _delayAddBodies;
|
|
|
|
Vector<PhysicsBody*> _delayRemoveBodies;
|
2013-11-04 19:26:34 +08:00
|
|
|
std::vector<PhysicsJoint*> _delayAddJoints;
|
|
|
|
std::vector<PhysicsJoint*> _delayRemoveJoints;
|
|
|
|
|
2013-09-09 10:29:02 +08:00
|
|
|
protected:
|
|
|
|
PhysicsWorld();
|
|
|
|
virtual ~PhysicsWorld();
|
2013-09-09 16:36:19 +08:00
|
|
|
|
2014-02-26 10:53:41 +08:00
|
|
|
friend class Node;
|
2013-09-09 16:36:19 +08:00
|
|
|
friend class Sprite;
|
2014-05-02 07:42:35 +08:00
|
|
|
friend class Scene;
|
2015-01-07 17:08:04 +08:00
|
|
|
friend class Director;
|
2013-09-16 21:22:22 +08:00
|
|
|
friend class PhysicsBody;
|
2013-09-29 09:39:20 +08:00
|
|
|
friend class PhysicsShape;
|
2013-11-07 14:17:57 +08:00
|
|
|
friend class PhysicsJoint;
|
2013-10-21 23:16:21 +08:00
|
|
|
friend class PhysicsWorldCallback;
|
2013-11-08 14:25:03 +08:00
|
|
|
friend class PhysicsDebugDraw;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-07-17 20:58:50 +08:00
|
|
|
class CC_DLL PhysicsDebugDraw
|
2013-11-08 14:25:03 +08:00
|
|
|
{
|
2013-11-08 16:17:56 +08:00
|
|
|
protected:
|
2013-11-08 14:25:03 +08:00
|
|
|
virtual bool begin();
|
|
|
|
virtual void end();
|
|
|
|
virtual void drawShape(PhysicsShape& shape);
|
|
|
|
virtual void drawJoint(PhysicsJoint& joint);
|
|
|
|
virtual void drawContact();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
PhysicsDebugDraw(PhysicsWorld& world);
|
|
|
|
virtual ~PhysicsDebugDraw();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
DrawNode* _drawNode;
|
|
|
|
PhysicsWorld& _world;
|
|
|
|
|
|
|
|
friend class PhysicsWorld;
|
2013-09-09 10:29:02 +08:00
|
|
|
};
|
2014-07-15 12:00:31 +08:00
|
|
|
extern const float CC_DLL PHYSICS_INFINITY;
|
2013-09-09 10:29:02 +08:00
|
|
|
|
|
|
|
NS_CC_END
|
|
|
|
|
2013-09-10 17:36:49 +08:00
|
|
|
#endif // CC_USE_PHYSICS
|
2013-11-06 14:51:56 +08:00
|
|
|
#endif // __CCPHYSICS_WORLD_H__
|