issue #2771: add tag and enable functions to physics classes

This commit is contained in:
boyu0 2013-09-29 09:39:20 +08:00
parent 2bffc959fd
commit dbfd05ef77
10 changed files with 260 additions and 31 deletions

View File

@ -137,7 +137,7 @@ void Scene::addChildToPhysicsWorld(Node* child)
if (sp->getPhysicsBody()) if (sp->getPhysicsBody())
{ {
_physicsWorld->addChild(sp->getPhysicsBody()); _physicsWorld->addBody(sp->getPhysicsBody());
} }
} }
}; };

View File

@ -63,12 +63,14 @@ PhysicsBody::PhysicsBody()
, _world(nullptr) , _world(nullptr)
, _info(nullptr) , _info(nullptr)
, _dynamic(false) , _dynamic(false)
, _enable(true)
, _massDefault(true) , _massDefault(true)
, _angularDampingDefault(true) , _angularDampingDefault(true)
, _mass(MASS_DEFAULT) , _mass(MASS_DEFAULT)
, _area(0.0) , _area(0.0)
, _density(DENSITY_DEFAULT) , _density(DENSITY_DEFAULT)
, _angularDamping(ANGULARDAMPING_DEFAULT) , _angularDamping(ANGULARDAMPING_DEFAULT)
, _tag(0)
{ {
} }
@ -76,10 +78,7 @@ PhysicsBody::~PhysicsBody()
{ {
CC_SAFE_DELETE(_info); CC_SAFE_DELETE(_info);
for (auto it = _shapes.begin(); it != _shapes.end(); ++it) removeAllShapes();
{
delete *it;
}
for (auto it = _joints.begin(); it != _joints.end(); ++it) for (auto it = _joints.begin(); it != _joints.end(); ++it)
{ {
@ -375,6 +374,81 @@ void PhysicsBody::setAngularDamping(float angularDamping)
cpBodySetMoment(_info->body, _angularDamping); cpBodySetMoment(_info->body, _angularDamping);
} }
PhysicsShape* PhysicsBody::getShapeByTag(int tag)
{
for (auto shape : _shapes)
{
if (shape->getTag() == tag)
{
return shape;
}
}
return nullptr;
}
void PhysicsBody::removeShapeByTag(int tag)
{
for (auto shape : _shapes)
{
if (shape->getTag() == tag)
{
removeShape(shape);
return;
}
}
}
void PhysicsBody::removeShape(PhysicsShape* shape)
{
auto it = std::find(_shapes.begin(), _shapes.end(), shape);
if (it != _shapes.end())
{
if (_world)
{
_world->removeShape(shape);
}
_shapes.erase(it);
delete shape;
}
}
void PhysicsBody::removeAllShapes()
{
for (auto shape : _shapes)
{
if (_world)
{
_world->removeShape(shape);
}
delete shape;
}
_shapes.clear();
}
void PhysicsBody::setEnable(bool enable)
{
if (_enable != enable)
{
_enable = enable;
if (_world)
{
if (enable)
{
_world->addBody(this);
}else
{
_world->removeBody(this);
}
}
}
}
//Clonable* PhysicsBody::clone() const //Clonable* PhysicsBody::clone() const
//{ //{
// PhysicsBody* body = new PhysicsBody(); // PhysicsBody* body = new PhysicsBody();

View File

@ -145,10 +145,12 @@ public:
* @brief get the first body shapes. * @brief get the first body shapes.
*/ */
inline PhysicsShape* getShape() { return _shapes.size() >= 1 ? _shapes.front() : nullptr; } inline PhysicsShape* getShape() { return _shapes.size() >= 1 ? _shapes.front() : nullptr; }
PhysicsShape* getShapeByTag(int tag);
/* /*
* @brief remove a shape from body * @brief remove a shape from body
*/ */
void removeShape(PhysicsShape* shape); void removeShape(PhysicsShape* shape);
void removeShapeByTag(int tag);
/* /*
* @brief remove all shapes * @brief remove all shapes
*/ */
@ -215,6 +217,12 @@ public:
//virtual Clonable* clone() const override; //virtual Clonable* clone() const override;
inline bool isEnable() { return _enable; }
void setEnable(bool enable);
inline int getTag() { return _tag; }
inline void setTag(int tag) { _tag = tag; }
protected: protected:
bool init(); bool init();
@ -235,12 +243,14 @@ protected:
PhysicsWorld* _world; PhysicsWorld* _world;
PhysicsBodyInfo* _info; PhysicsBodyInfo* _info;
bool _dynamic; bool _dynamic;
bool _enable;
bool _massDefault; bool _massDefault;
bool _angularDampingDefault; bool _angularDampingDefault;
float _mass; float _mass;
float _area; float _area;
float _density; float _density;
float _angularDamping; float _angularDamping;
int _tag;
int _categoryBitmask; int _categoryBitmask;
int _contactTestBitmask; int _contactTestBitmask;

View File

@ -46,6 +46,8 @@ PhysicsJoint::PhysicsJoint()
: _bodyA(nullptr) : _bodyA(nullptr)
, _bodyB(nullptr) , _bodyB(nullptr)
, _info(nullptr) , _info(nullptr)
, _enable(false)
, _tag(0)
{ {
} }
@ -79,6 +81,21 @@ bool PhysicsJoint::init(cocos2d::PhysicsBody *a, cocos2d::PhysicsBody *b)
return false; return false;
} }
void PhysicsJoint::setEnable(bool enable)
{
if (_enable != enable)
{
_enable = enable;
if (enable)
{
}else
{
}
}
}
PhysicsJointPin::PhysicsJointPin() PhysicsJointPin::PhysicsJointPin()
{ {

View File

@ -49,6 +49,10 @@ protected:
public: public:
PhysicsBody* getBodyA() { return _bodyA; } PhysicsBody* getBodyA() { return _bodyA; }
PhysicsBody* getBodyB() { return _bodyB; } PhysicsBody* getBodyB() { return _bodyB; }
inline int getTag() { return _tag; }
inline void setTag(int tag) { _tag = tag; }
inline bool isEnable() { return _enable; }
void setEnable(bool enable);
protected: protected:
bool init(PhysicsBody* a, PhysicsBody* b); bool init(PhysicsBody* a, PhysicsBody* b);
@ -62,8 +66,11 @@ protected:
PhysicsBody* _bodyA; PhysicsBody* _bodyA;
PhysicsBody* _bodyB; PhysicsBody* _bodyB;
PhysicsJointInfo* _info; PhysicsJointInfo* _info;
bool _enable;
int _tag;
friend class PhysicsBody; friend class PhysicsBody;
friend class PhysicsWorld;
}; };
/* /*

View File

@ -32,6 +32,7 @@
#endif #endif
#include "CCPhysicsBody.h" #include "CCPhysicsBody.h"
#include "CCPhysicsWorld.h"
#include "chipmunk/CCPhysicsBodyInfo.h" #include "chipmunk/CCPhysicsBodyInfo.h"
#include "Box2D/CCPhysicsBodyInfo.h" #include "Box2D/CCPhysicsBodyInfo.h"
@ -45,6 +46,8 @@ PhysicsShape::PhysicsShape()
: _body(nullptr) : _body(nullptr)
, _info(nullptr) , _info(nullptr)
, _type(Type::UNKNOWN) , _type(Type::UNKNOWN)
, _tag(0)
, _enable(true)
{ {
} }
@ -68,6 +71,25 @@ bool PhysicsShape::init(PhysicsBody* body, Type type)
return true; return true;
} }
void PhysicsShape::setEnable(bool enable)
{
if (_enable != enable)
{
_enable = enable;
if (_body->getWorld() && _body->isEnable())
{
if (enable)
{
_body->getWorld()->addShape(this);
}else
{
_body->getWorld()->removeShape(this);
}
}
}
}
void PhysicsShape::addToBody() void PhysicsShape::addToBody()
{ {
if(_body != nullptr) _body->addShape(this); if(_body != nullptr) _body->addShape(this);

View File

@ -58,6 +58,10 @@ public:
public: public:
inline PhysicsBody* getBody(){ return _body; } inline PhysicsBody* getBody(){ return _body; }
inline Type getType() { return _type; } inline Type getType() { return _type; }
inline void setTag(int tag) { _tag = tag; }
inline int getTag() { return _tag; }
void setEnable(bool enable);
inline bool isEnable() { return _enable; }
protected: protected:
bool init(PhysicsBody* body, Type type); bool init(PhysicsBody* body, Type type);
@ -77,6 +81,8 @@ protected:
PhysicsBody* _body; PhysicsBody* _body;
PhysicsShapeInfo* _info; PhysicsShapeInfo* _info;
Type _type; Type _type;
int _tag;
bool _enable;
friend class PhysicsWorld; friend class PhysicsWorld;
friend class PhysicsBody; friend class PhysicsBody;

View File

@ -34,6 +34,7 @@
#include "CCPhysicsBody.h" #include "CCPhysicsBody.h"
#include "CCPhysicsShape.h" #include "CCPhysicsShape.h"
#include "CCPhysicsContact.h" #include "CCPhysicsContact.h"
#include "CCPhysicsJoint.h"
#include "chipmunk/CCPhysicsWorldInfo.h" #include "chipmunk/CCPhysicsWorldInfo.h"
#include "Box2D/CCPhysicsWorldInfo.h" #include "Box2D/CCPhysicsWorldInfo.h"
@ -43,6 +44,8 @@
#include "Box2D/CCPhysicsShapeInfo.h" #include "Box2D/CCPhysicsShapeInfo.h"
#include "chipmunk/CCPhysicsContactInfo.h" #include "chipmunk/CCPhysicsContactInfo.h"
#include "Box2D/CCPhysicsContactInfo.h" #include "Box2D/CCPhysicsContactInfo.h"
#include "chipmunk/CCPhysicsJointInfo.h"
#include "Box2D/CCPhysicsJointInfo.h"
#include "chipmunk/CCPhysicsHelper.h" #include "chipmunk/CCPhysicsHelper.h"
#include "draw_nodes/CCDrawNode.h" #include "draw_nodes/CCDrawNode.h"
@ -110,34 +113,69 @@ bool PhysicsWorld::init()
return true; return true;
} }
void PhysicsWorld::addJoint(PhysicsJoint* joint)
{
auto it = std::find(_joints.begin(), _joints.end(), joint);
if (it == _joints.end())
{
_joints.push_back(joint);
if (!cpSpaceContainsConstraint(_info->space, joint->_info->joint))
{
cpSpaceAddConstraint(_info->space, joint->_info->joint);
}
}
}
void PhysicsWorld::removeJoint(PhysicsJoint* joint)
{
}
void PhysicsWorld::removeAllJoints()
{
}
void PhysicsWorld::addShape(PhysicsShape* shape) void PhysicsWorld::addShape(PhysicsShape* shape)
{ {
for (auto it = shape->_info->shapes.begin(); it != shape->_info->shapes.end(); it++) for (auto cps : shape->_info->shapes)
{ {
if (cpSpaceContainsShape(_info->space, cps))
{
continue;
}
if (cpBodyIsStatic(shape->getBody()->_info->body)) if (cpBodyIsStatic(shape->getBody()->_info->body))
{ {
cpSpaceAddStaticShape(_info->space, *it); cpSpaceAddStaticShape(_info->space, cps);
}else }else
{ {
cpSpaceAddShape(_info->space, *it); cpSpaceAddShape(_info->space, cps);
} }
} }
} }
void PhysicsWorld::addChild(PhysicsBody* body) void PhysicsWorld::addBody(PhysicsBody* body)
{ {
auto shapes = body->getShapes(); if (body->isEnable())
// add body to space
if (body->isDynamic())
{ {
cpSpaceAddBody(_info->space, body->_info->body); // add body to space
} if (body->isDynamic())
{
cpSpaceAddBody(_info->space, body->_info->body);
}
// add shapes to space // add shapes to space
for (auto it = shapes.begin(); it != shapes.end(); it++) for (auto shape : body->getShapes())
{ {
addShape(*it); if (shape->isEnable())
{
addShape(shape);
}
}
} }
if (_bodys == nullptr) if (_bodys == nullptr)
@ -150,6 +188,54 @@ void PhysicsWorld::addChild(PhysicsBody* body)
} }
} }
void PhysicsWorld::removeBody(PhysicsBody* body)
{
for (auto shape : body->getShapes())
{
for (auto cps : shape->_info->shapes)
{
if (cpSpaceContainsShape(_info->space, cps))
{
cpSpaceRemoveShape(_info->space, cps);
}
}
}
if (cpSpaceContainsBody(_info->space, body->_info->body))
{
cpSpaceRemoveBody(_info->space, body->_info->body);
}
if (_bodys != nullptr)
{
_bodys->removeObject(body);
}
}
void PhysicsWorld::removeBodyByTag(int tag)
{
for (Object* obj : *_bodys)
{
PhysicsBody* body = dynamic_cast<PhysicsBody*>(obj);
if (body->getTag() == tag)
{
removeBody(body);
return;
}
}
}
void PhysicsWorld::removeShape(PhysicsShape* shape)
{
for (auto cps : shape->_info->shapes)
{
if (cpSpaceContainsShape(_info->space, cps))
{
cpSpaceRemoveShape(_info->space, cps);
}
}
}
void PhysicsWorld::update(float delta) void PhysicsWorld::update(float delta)
{ {
cpSpaceStep(_info->space, delta); cpSpaceStep(_info->space, delta);
@ -172,16 +258,15 @@ void PhysicsWorld::debugDraw()
{ {
_drawNode= DrawNode::create(); _drawNode= DrawNode::create();
Object* child = nullptr; for (Object* obj : *_bodys)
CCARRAY_FOREACH(_bodys, child)
{ {
PhysicsBody* body = dynamic_cast<PhysicsBody*>(child); PhysicsBody* body = dynamic_cast<PhysicsBody*>(obj);
std::vector<PhysicsShape*> shapes = body->getShapes(); std::vector<PhysicsShape*> shapes = body->getShapes();
for (auto it = shapes.begin(); it != shapes.end(); ++it) for (auto shape : shapes)
{ {
drawWithShape(_drawNode, *it); drawWithShape(_drawNode, shape);
} }
} }

View File

@ -28,6 +28,8 @@
#ifndef __CCPHYSICS_WORLD_H__ #ifndef __CCPHYSICS_WORLD_H__
#define __CCPHYSICS_WORLD_H__ #define __CCPHYSICS_WORLD_H__
#include <list>
#include "cocoa/CCObject.h" #include "cocoa/CCObject.h"
#include "cocoa/CCGeometry.h" #include "cocoa/CCGeometry.h"
@ -86,14 +88,18 @@ public:
/** set the debug draw */ /** set the debug draw */
inline void setDebugDraw(bool debugDraw) { _debugDraw = debugDraw; } inline void setDebugDraw(bool debugDraw) { _debugDraw = debugDraw; }
virtual void removeBody(PhysicsBody* body);
virtual void removeBodyByTag(int tag);
protected: protected:
static PhysicsWorld* create(); static PhysicsWorld* create();
bool init(); bool init();
void setScene(Scene* scene); void setScene(Scene* scene);
virtual void addChild(PhysicsBody* body); virtual void addBody(PhysicsBody* body);
virtual void addShape(PhysicsShape* shape); virtual void addShape(PhysicsShape* shape);
virtual void removeShape(PhysicsShape* shape);
virtual void update(float delta); virtual void update(float delta);
virtual void debugDraw(); virtual void debugDraw();
@ -120,6 +126,7 @@ protected:
Array* _bodys; Array* _bodys;
std::list<PhysicsJoint*> _joints;
Scene* _scene; Scene* _scene;
bool _debugDraw; bool _debugDraw;
@ -132,6 +139,7 @@ protected:
friend class Sprite; friend class Sprite;
friend class Scene; friend class Scene;
friend class PhysicsBody; friend class PhysicsBody;
friend class PhysicsShape;
}; };
NS_CC_END NS_CC_END

View File

@ -36,12 +36,12 @@ PhysicsShapeInfo::PhysicsShapeInfo(PhysicsShape* shape)
PhysicsShapeInfo::~PhysicsShapeInfo() PhysicsShapeInfo::~PhysicsShapeInfo()
{ {
for (auto it = shapes.begin(); it != shapes.end(); it++) for (auto shape : shapes)
{ {
cpShapeFree(*it); auto it = map.find(shape);
if (it != map.end()) map.erase(shape);
auto mit = map.find(*it); cpShapeFree(shape);
if (mit != map.end()) map.erase(*it);
} }
} }