123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- /****************************************************************************
- Copyright (c) 2013-2016 Chukong Technologies Inc.
- Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
-
- 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__
- #include "base/ccConfig.h"
- #if CC_USE_PHYSICS
- #include <list>
- #include "base/CCVector.h"
- #include "math/CCGeometry.h"
- #include "physics/CCPhysicsBody.h"
- struct cpSpace;
- NS_CC_BEGIN
- class PhysicsBody;
- class PhysicsJoint;
- class PhysicsShape;
- class PhysicsContact;
- class Director;
- class Node;
- class Sprite;
- class Scene;
- class DrawNode;
- class PhysicsDebugDraw;
- class EventDispatcher;
- class PhysicsWorld;
- typedef struct PhysicsRayCastInfo
- {
- PhysicsShape* shape;
- Vec2 start;
- Vec2 end; ///< in lua, it's name is "ended"
- Vec2 contact;
- Vec2 normal;
- // FIXME: correct thing to do is use `cpFlaot` instead of float.
- // but in order to do so, we should include "chipmunk_types.h"
- // in Chipmunk v7.0, chipmunk_types includes all the mac types that
- // conflicts with cocos2d Size, Point,... etc types. And all the CocosStudio
- // lib will need to use the `cocos2d::` namespace prefix. And it is easier to do this
- // than change all the cocosstudio library (and also users code)
- 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;
- typedef std::function<bool(PhysicsWorld&, PhysicsShape&, void*)> PhysicsQueryRectCallbackFunc;
- typedef PhysicsQueryRectCallbackFunc PhysicsQueryPointCallbackFunc;
- /**
- * @addtogroup physics
- * @{
- * @addtogroup physics_2d
- * @{
- */
- /**
- * @class PhysicsWorld CCPhysicsWorld.h
- * @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.
- */
- class CC_DLL PhysicsWorld
- {
- public:
- 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
-
- public:
- /**
- * Adds a joint to this physics world.
- *
- * This joint will be added to this physics world at next frame.
- * @attention If this joint is already added to another physics world, it will be removed from that world first and then add to this world.
- * @param joint A pointer to an existing PhysicsJoint object.
- */
- virtual void addJoint(PhysicsJoint* joint);
- /**
- * Remove a joint from this physics world.
- *
- * If this world is not locked, the joint is removed immediately, otherwise at next frame.
- * If this joint is connected with a body, it will be removed from the body also.
- * @param joint A pointer to an existing PhysicsJoint object.
- * @param destroy true this joint will be destroyed after remove from this world, false otherwise.
- */
- virtual void removeJoint(PhysicsJoint* joint, bool destroy = true);
- /**
- * Remove all joints from this physics world.
- *
- * @attention This function is invoked in the destructor of this physics world, you do not use this api in common.
- * @param destroy true all joints will be destroyed after remove from this world, false otherwise.
- */
- virtual void removeAllJoints(bool destroy = true);
-
- /**
- * Remove a body from this physics world.
- *
- * If this world is not locked, the body is removed immediately, otherwise at next frame.
- * @attention If this body has joints, those joints will be removed also.
- * @param body A pointer to an existing PhysicsBody object.
- */
- virtual void removeBody(PhysicsBody* body);
-
- /**
- * Remove body by tag.
- *
- * If this world is not locked, the object is removed immediately, otherwise at next frame.
- * @attention If this body has joints, those joints will be removed also.
- * @param tag An integer number that identifies a PhysicsBody object.
- */
- virtual void removeBody(int tag);
- /**
- * Remove all bodies from physics world.
- *
- * If this world is not locked, those body are removed immediately, otherwise at next frame.
- */
- virtual void removeAllBodies();
-
- /**
- * Searches for physics shapes that intersects the ray.
- *
- * Query this physics world along the line segment from start to end.
- * @param func Func is called for each shape found.
- * @param start A Vec2 object contains the begin position of the ray.
- * @param end A Vec2 object contains the end position of the ray.
- * @param data User defined data, it is passed to func.
- */
- void rayCast(PhysicsRayCastCallbackFunc func, const Vec2& start, const Vec2& end, void* data);
-
- /**
- * Searches for physics shapes that contains in the rect.
- *
- * Query this physics world to find all shapes overlap rect.
- * @param func Func is called for each shape whose bounding box overlaps rect.
- * @param rect A Rect object contains a rectangle's x, y, width and height.
- * @param data User defined data, it is passed to func.
- */
- void queryRect(PhysicsQueryRectCallbackFunc func, const Rect& rect, void* data);
-
- /**
- * Searches for physics shapes that contains the point.
- *
- * @attention The point must lie inside a shape.
- * @param func Func is called for each shape contains the point.
- * @param point A Vec2 object contains the position of the point.
- * @param data User defined data, it is passed to func.
- */
- void queryPoint(PhysicsQueryPointCallbackFunc func, const Vec2& point, void* data);
-
- /**
- * Get physics shapes that contains the point.
- *
- * All shapes contains the point will be pushed in a Vector<PhysicsShape*> object.
- * @attention The point must lie inside a shape.
- * @param point A Vec2 object contains the position of the point.
- * @return A Vector<PhysicsShape*> object contains all found PhysicsShape pointer.
- */
- Vector<PhysicsShape*> getShapes(const Vec2& point) const;
-
- /**
- * Get the nearest physics shape that contains the point.
- *
- * Query this physics world at point and return the closest shape.
- * @param point A Vec2 object contains the position of the point.
- * @return A PhysicsShape object pointer or nullptr if no shapes were found
- */
- PhysicsShape* getShape(const Vec2& point) const;
- /**
- * Get all the bodies that in this physics world.
- *
- * @return A Vector<PhysicsBody*>& object contains all bodies in this physics world.
- */
- const Vector<PhysicsBody*>& getAllBodies() const;
- /**
- * Get a body by tag.
- *
- * @param tag An integer number that identifies a PhysicsBody object.
- * @return A PhysicsBody object pointer or nullptr if no shapes were found.
- */
- PhysicsBody* getBody(int tag) const;
-
- /**
- * Get a scene contain this physics world.
- *
- * @attention This value is initialized in constructor
- * @return A Scene object reference.
- */
- Scene& getScene() const { return *_scene; }
-
- /**
- * Get the gravity value of this physics world.
- *
- * @return A Vec2 object.
- */
- Vec2 getGravity() const { return _gravity; }
-
- /**
- * set the gravity value of this physics world.
- *
- * @param gravity A gravity value of this physics world.
- */
- void setGravity(const Vec2& gravity);
-
- /**
- * Set the speed of this physics world.
- *
- * @attention if you setAutoStep(false), this won't work.
- * @param speed A float number. Speed is the rate at which the simulation executes. default value is 1.0.
- */
- void setSpeed(float speed) { if(speed >= 0.0f) { _speed = speed; } }
-
- /**
- * Get the speed of this physics world.
- *
- * @return A float number.
- */
- float getSpeed() { return _speed; }
-
- /**
- * Set the update rate of this 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.
- * @attention if you setAutoStep(false), this won't work.
- * @param rate An integer number, default value is 1.0.
- */
- void setUpdateRate(int rate) { if(rate > 0) { _updateRate = rate; } }
- /**
- * Get the update rate of this physics world.
- *
- * @return An integer number.
- */
- int getUpdateRate() { return _updateRate; }
- /**
- * 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.
- * @param steps An integer number, default value is 1.
- */
- void setSubsteps(int steps);
- /**
- * Get the number of substeps of this physics world.
- *
- * @return An integer number.
- */
- int getSubsteps() const { return _substeps; }
-
- /**
- * set the number of update of the physics world in a second.
- * 0 - disable fixed step system
- * default value is 0
- */
- void setFixedUpdateRate(int updatesPerSecond) { if(updatesPerSecond > 0) { _fixedRate = updatesPerSecond; } }
- /** get the number of substeps */
- int getFixedUpdateRate() const { return _fixedRate; }
- /**
- * Set the debug draw mask of this physics world.
- *
- * This physics world will draw shapes and joints by DrawNode according to mask.
- * @param mask Mask has four value:DEBUGDRAW_NONE, DEBUGDRAW_SHAPE, DEBUGDRAW_JOINT, DEBUGDRAW_CONTACT and DEBUGDRAW_ALL, default is DEBUGDRAW_NONE
- */
- void setDebugDrawMask(int mask);
- /**
- * Get the debug draw mask.
- *
- * @return An integer number.
- */
- int getDebugDrawMask() { return _debugDrawMask; }
-
- /**
- * 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.
- * @attention If you set auto step to false, setSpeed setSubsteps and setUpdateRate won't work, you need to control the time step by yourself.
- * @param autoStep A bool object, default value is true.
- */
- void setAutoStep(bool autoStep){ _autoStep = autoStep; }
- /**
- * Get the auto step of this physics world.
- *
- * @return A bool object.
- */
- bool isAutoStep() { return _autoStep; }
- /**
- * The step for physics world.
- *
- * The times passing for simulate the physics.
- * @attention You need to setAutoStep(false) first before it can work.
- * @param delta A float number.
- */
- void step(float delta);
-
- protected:
- static PhysicsWorld* construct(Scene* scene);
- bool init();
-
-
- virtual void addBody(PhysicsBody* body);
- virtual void addShape(PhysicsShape* shape);
- virtual void removeShape(PhysicsShape* shape);
- virtual void update(float delta, bool userCall = false);
-
- virtual void debugDraw();
-
- virtual bool collisionBeginCallback(PhysicsContact& contact);
- virtual bool collisionPreSolveCallback(PhysicsContact& contact);
- virtual void collisionPostSolveCallback(PhysicsContact& contact);
- virtual void collisionSeparateCallback(PhysicsContact& contact);
-
- 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);
- virtual void updateBodies();
- virtual void updateJoints();
-
- protected:
- Vec2 _gravity;
- float _speed;
- int _updateRate;
- int _updateRateCount;
- float _updateTime;
- int _substeps;
- int _fixedRate;
- cpSpace* _cpSpace;
-
- bool _updateBodyTransform;
- Vector<PhysicsBody*> _bodies;
- std::list<PhysicsJoint*> _joints;
- Scene* _scene;
-
- bool _autoStep;
- DrawNode* _debugDraw;
- int _debugDrawMask;
-
- EventDispatcher* _eventDispatcher;
- Vector<PhysicsBody*> _delayAddBodies;
- Vector<PhysicsBody*> _delayRemoveBodies;
- std::vector<PhysicsJoint*> _delayAddJoints;
- std::vector<PhysicsJoint*> _delayRemoveJoints;
-
- protected:
- PhysicsWorld();
- virtual ~PhysicsWorld();
-
- void beforeSimulation(Node *node, const Mat4& parentToWorldTransform, float nodeParentScaleX, float nodeParentScaleY, float parentRotation);
- void afterSimulation(Node* node, const Mat4& parentToWorldTransform, float parentRotation);
- friend class Node;
- friend class Sprite;
- friend class Scene;
- friend class Director;
- friend class PhysicsBody;
- friend class PhysicsShape;
- friend class PhysicsJoint;
- friend class PhysicsWorldCallback;
- friend class PhysicsDebugDraw;
- };
- extern const float CC_DLL PHYSICS_INFINITY;
- /** @} */
- /** @} */
- NS_CC_END
- #endif // CC_USE_PHYSICS
- #endif // __CCPHYSICS_WORLD_H__
|