issue #2771: Implement the minimum set of physical API. Improve the PhysicsTest

This commit is contained in:
boyu0 2013-09-16 21:22:22 +08:00
parent d161c6a576
commit 2c66f1b95e
45 changed files with 3379 additions and 227 deletions

View File

@ -1 +1 @@
cbb5290ea17f6020e0249818c08c9d94a17dd073
f64b17366179be63ab250b6a65922b95efbd9712

View File

@ -126,8 +126,8 @@ THE SOFTWARE.
// physics
#include "physics/CCPhysicsBody.h"
#include "physics/CCPhysicsContactDelegate.h"
#include "physics/CCPhysicsFixture.h"
#include "physics/CCPhysicsContact.h"
#include "physics/CCPhysicsShape.h"
#include "physics/CCPhysicsJoint.h"
#include "physics/CCPhysicsWorld.h"

View File

@ -38,6 +38,7 @@ THE SOFTWARE.
// extern
#include "kazmath/GL/matrix.h"
#include "keyboard_dispatcher/CCKeyboardDispatcher.h"
#include "CCScene.h"
NS_CC_BEGIN
@ -499,6 +500,30 @@ void Layer::ccTouchesCancelled(Set *pTouches, Event *pEvent)
CC_UNUSED_PARAM(pEvent);
}
#ifdef CC_USE_PHYSICS
void Layer::addChild(Node* child)
{
Node::addChild(child);
}
void Layer::addChild(Node* child, int zOrder)
{
Node::addChild(child, zOrder);
}
void Layer::addChild(Node* child, int zOrder, int tag)
{
Node::addChild(child, zOrder, tag);
if (this->getParent() &&
dynamic_cast<Scene*>(this->getParent()) != nullptr)
{
dynamic_cast<Scene*>(this->getParent())->addChildToPhysicsWorld(child);
}
}
#endif
// LayerRGBA
LayerRGBA::LayerRGBA()
: _displayedOpacity(255)

View File

@ -36,6 +36,7 @@ THE SOFTWARE.
#ifdef EMSCRIPTEN
#include "base_nodes/CCGLBufferedNode.h"
#endif // EMSCRIPTEN
#include "physics/CCPhysicsSetting.h"
NS_CC_BEGIN
@ -138,6 +139,12 @@ public:
virtual void onEnter() override;
virtual void onExit() override;
virtual void onEnterTransitionDidFinish() override;
#ifdef CC_USE_PHYSICS
virtual void addChild(Node* child) override;
virtual void addChild(Node* child, int zOrder) override;
virtual void addChild(Node* child, int zOrder, int tag) override;
#endif // CC_USE_PHYSICS
protected:
bool _touchEnabled;

View File

@ -99,12 +99,14 @@ bool Scene::initWithPhysics()
CC_BREAK_IF( ! (pDirector = Director::getInstance()) );
this->setContentSize(pDirector->getWinSize());
CC_BREAK_IF(! (_physicsWorld = PhysicsWorld::create()));
_physicsWorld->setScene(this);
this->scheduleUpdate();
// success
bRet = true;
} while (0);
return bRet;
}
#endif
void Scene::addChild(Node* child)
{
@ -120,23 +122,27 @@ void Scene::addChild(Node* child, int zOrder, int tag)
{
Node::addChild(child, zOrder, tag);
#ifdef CC_USE_PHYSICS
addChildToPhysicsWorld(child);
}
void Scene::addChildToPhysicsWorld(Node* child)
{
if (_physicsWorld)
{
auto addToPhysicsWorldFunc = [this](Object* node) -> void
{
if (typeid(Sprite).hash_code() == typeid(node).hash_code())
if (dynamic_cast<Sprite*>(node) != nullptr)
{
Sprite* sp = dynamic_cast<Sprite*>(node);
if (sp && sp->getPhysicsBody())
if (sp->getPhysicsBody())
{
_physicsWorld->addChild(sp->getPhysicsBody());
}
}
};
if(typeid(Layer).hash_code() == typeid(child).hash_code())
if(dynamic_cast<Layer*>(child) != nullptr)
{
Object* subChild = nullptr;
CCARRAY_FOREACH(child->getChildren(), subChild)
@ -148,8 +154,15 @@ void Scene::addChild(Node* child, int zOrder, int tag)
addToPhysicsWorldFunc(child);
}
}
#endif
}
void Scene::update(float delta)
{
Node::update(delta);
_physicsWorld->update(delta);
}
#endif
NS_CC_END

View File

@ -60,22 +60,30 @@ public:
virtual ~Scene();
bool init();
#ifdef CC_USE_PHYSICS
public:
bool initWithPhysics();
#endif
virtual void addChild(Node* child) override;
virtual void addChild(Node* child, int zOrder) override;
virtual void addChild(Node* child, int zOrder, int tag) override;
#ifdef CC_USE_PHYSICS
/*
* Update method will be called automatically every frame if "scheduleUpdate" is called, and the node is "live"
*/
virtual void update(float delta) override;
inline PhysicsWorld* getPhysicsWorld() { return _physicsWorld; }
#endif
protected:
#ifdef CC_USE_PHYSICS
virtual void addChildToPhysicsWorld(Node* child);
protected:
PhysicsWorld* _physicsWorld;
#endif
#endif // CC_USE_PHYSICS
friend class Layer;
};
// end of scene group

View File

@ -21,3 +21,19 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "CCPhysicsBodyInfo.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
NS_CC_BEGIN
PhysicsBodyInfo::PhysicsBodyInfo()
{
}
PhysicsBodyInfo::~PhysicsBodyInfo()
{
}
NS_CC_END
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D

View File

@ -0,0 +1,43 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "../CCPhysicsSetting.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
#ifndef __CCPHYSICS_BODY_INFO_H__
#define __CCPHYSICS_BODY_INFO_H__
#include "platform/CCPlatformMacros.h"
NS_CC_BEGIN
class PhysicsBodyInfo
{
public:
PhysicsBodyInfo();
~PhysicsBodyInfo();
};
NS_CC_END
#endif // __CCPHYSICS_BODY_INFO_H__
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D

View File

@ -0,0 +1,39 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "CCPhysicsContactInfo.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
NS_CC_BEGIN
PhysicsContactInfo::PhysicsContactInfo()
{
}
PhysicsContactInfo::~PhysicsContactInfo()
{
}
NS_CC_END
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D

View File

@ -0,0 +1,43 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "../CCPhysicsSetting.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
#ifndef __CCPHYSICS_CONTACT_INFO_H__
#define __CCPHYSICS_CONTACT_INFO_H__
#include "platform/CCPlatformMacros.h"
NS_CC_BEGIN
class PhysicsContactInfo
{
public:
PhysicsContactInfo();
~PhysicsContactInfo();
};
NS_CC_END
#endif // __CCPHYSICS_CONTACT_INFO_H__
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D

View File

@ -22,42 +22,22 @@
THE SOFTWARE.
****************************************************************************/
#include "CCPhysicsSetting.h"
#ifdef CC_USE_PHYSICS
#include "../CCPhysicsSetting.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
#ifndef __CCPHYSICS_FIXTURE_H__
#define __CCPHYSICS_FIXTURE_H__
#ifndef __CCPHYSICS_HELPER_H__
#define __CCPHYSICS_HELPER_H__
#include "cocoa/CCObject.h"
#include "platform/CCPlatformMacros.h"
#include "cocoa/CCGeometry.h"
NS_CC_BEGIN
class PhysicsFixture : public Object
class PhysicsHelper
{
public:
static PhysicsFixture* createCircle(Point centre, float radius);
static PhysicsFixture* createRectangle(Rect rect);
static PhysicsFixture* createPolygon(Array* points);
static PhysicsFixture* createEdgeSegment(Point x, Point y);
static PhysicsFixture* createEdgeCircle(Point centre, float radius);
static PhysicsFixture* createEdgeRectangle(Rect rect);
static PhysicsFixture* createEdgePolygon(Array* points);
protected:
bool init();
protected:
PhysicsFixture();
virtual ~PhysicsFixture();
protected:
float _density;
float _friction;
};
NS_CC_END
#endif // __CCPHYSICS_FIXTURE_H__
#endif // __CCPHYSICS_HELPER_H__
#endif // CC_USE_PHYSICS
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D

View File

@ -21,3 +21,19 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "CCPhysicsJointInfo.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
NS_CC_BEGIN
PhysicsJointInfo::PhysicsJointInfo()
{
}
PhysicsJointInfo::~PhysicsJointInfo()
{
}
NS_CC_END
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D

View File

@ -0,0 +1,43 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "../CCPhysicsSetting.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
#ifndef __CCPHYSICS_JOINT_INFO_H__
#define __CCPHYSICS_JOINT_INFO_H__
#include "platform/CCPlatformMacros.h"
NS_CC_BEGIN
class PhysicsJointInfo
{
public:
PhysicsJointInfo();
~PhysicsJointInfo();
};
NS_CC_END
#endif // __CCPHYSICS_JOINT_INFO_H__
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D

View File

@ -0,0 +1,39 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "CCPhysicsShapeInfo.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
NS_CC_BEGIN
PhysicsShapeInfo::PhysicsShapeInfo()
{
}
PhysicsShapeInfo::~PhysicsShapeInfo()
{
}
NS_CC_END
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D

View File

@ -0,0 +1,43 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "../CCPhysicsSetting.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
#ifndef __CCPHYSICS_SHAPE_INFO_H__
#define __CCPHYSICS_SHAPE_INFO_H__
#include "platform/CCPlatformMacros.h"
NS_CC_BEGIN
class PhysicsShapeInfo
{
public:
PhysicsShapeInfo();
~PhysicsShapeInfo();
};
NS_CC_END
#endif // __CCPHYSICS_SHAPE_INFO_H__
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D

View File

@ -0,0 +1,39 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "CCPhysicsWorldInfo.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
NS_CC_BEGIN
PhysicsWorldInfo::PhysicsWorldInfo()
{
}
PhysicsWorldInfo::~PhysicsWorldInfo()
{
}
NS_CC_END
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D

View File

@ -0,0 +1,43 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "../CCPhysicsSetting.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
#ifndef __CCPHYSICS_WORLD_INFO_H__
#define __CCPHYSICS_WORLD_INFO_H__
#include "platform/CCPlatformMacros.h"
NS_CC_BEGIN
class PhysicsWorldInfo
{
public:
PhysicsWorldInfo();
~PhysicsWorldInfo();
};
NS_CC_END
#endif // __CCPHYSICS_WORLD_INFO_H__
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D

View File

@ -22,51 +22,74 @@
THE SOFTWARE.
****************************************************************************/
#include "CCPhysicsBody.h"
#ifdef CC_USE_PHYSICS
#include "CCPhysicsShape.h"
#include "CCPhysicsJoint.h"
#include "CCPhysicsWorld.h"
#include "chipmunk/CCPhysicsBodyInfo.h"
#include "Box2D/CCPhysicsBodyInfo.h"
#include "chipmunk/CCPhysicsJointInfo.h"
#include "Box2D/CCPhysicsJointInfo.h"
#include "chipmunk/CCPhysicsWorldInfo.h"
#include "Box2D/CCPhysicsWorldInfo.h"
#include "chipmunk/CCPhysicsHelper.h"
#include "Box2D/CCPhysicsHelper.h"
NS_CC_BEGIN
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
class PhysicsBodyInfo
namespace
{
public:
PhysicsBodyInfo();
~PhysicsBodyInfo();
public:
cpBody* body;
cpShape* shape;
};
PhysicsBodyInfo::PhysicsBodyInfo()
: body(nullptr)
, shape(nullptr)
{
}
PhysicsBodyInfo::~PhysicsBodyInfo()
{
if (body) cpBodyFree(body);
if (shape) cpShapeFree(shape);
static const float MASS_DEFAULT = 1.0;
static const float DENSITY_DEFAULT = 1.0;
static const float ANGULARDAMPING_DEFAULT = 200;
}
PhysicsBody::PhysicsBody()
: _owner(nullptr)
, _world(nullptr)
, _info(nullptr)
, _dynamic(false)
, _massDefault(true)
, _angularDampingDefault(true)
, _mass(MASS_DEFAULT)
, _area(0.0)
, _density(DENSITY_DEFAULT)
, _angularDamping(ANGULARDAMPING_DEFAULT)
{
}
PhysicsBody::~PhysicsBody()
{
CC_SAFE_DELETE(_info);
for (auto it = _shapes.begin(); it != _shapes.end(); ++it)
{
delete *it;
}
for (auto it = _joints.begin(); it != _joints.end(); ++it)
{
PhysicsJoint* joint = *it;
PhysicsBody* other = joint->getBodyA() == this ? joint->getBodyA() : joint->getBodyB();
other->_joints.erase(std::find(other->_joints.begin(), other->_joints.end(), joint));
delete joint;
}
}
PhysicsBody* PhysicsBody::create()
PhysicsBody* PhysicsBody::createCircle(float radius)
{
PhysicsBody * body = new PhysicsBody();
if(body && body->init())
PhysicsBody* body = new PhysicsBody();
if (body && body->init())
{
body->addCircle(radius);
body->autorelease();
return body;
}
@ -74,6 +97,156 @@ PhysicsBody* PhysicsBody::create()
return nullptr;
}
PhysicsBody* PhysicsBody::createBox(Size size)
{
PhysicsBody* body = new PhysicsBody();
if (body && body->init())
{
body->addBox(size);
body->autorelease();
return body;
}
CC_SAFE_DELETE(body);
return nullptr;
}
PhysicsBody* PhysicsBody::createPolygon(Point* points, int count)
{
PhysicsBody* body = new PhysicsBody();
if (body && body->init())
{
body->addPolygon(points, count);
body->autorelease();
return body;
}
CC_SAFE_DELETE(body);
return nullptr;
}
PhysicsBody* PhysicsBody::createEdgeSegment(Point a, Point b, float border/* = 1*/)
{
PhysicsBody* body = new PhysicsBody();
if (body && body->initStatic())
{
body->addEdgeSegment(a, b, border);
body->autorelease();
return body;
}
CC_SAFE_DELETE(body);
return nullptr;
}
PhysicsBody* PhysicsBody::createEdgeBox(Size size, float border/* = 1*/)
{
PhysicsBody* body = new PhysicsBody();
if (body && body->initStatic())
{
body->addEdgeBox(size, border);
body->autorelease();
return body;
}
CC_SAFE_DELETE(body);
return nullptr;
}
PhysicsBody* PhysicsBody::createEdgePolygon(Point* points, int count, float border/* = 1*/)
{
PhysicsBody* body = new PhysicsBody();
if (body && body->initStatic())
{
body->addEdgePolygon(points, count, border);
body->autorelease();
return body;
}
CC_SAFE_DELETE(body);
return nullptr;
}
PhysicsBody* PhysicsBody::createEdgeChain(Point* points, int count, float border/* = 1*/)
{
PhysicsBody* body = new PhysicsBody();
if (body && body->initStatic())
{
body->addEdgeChain(points, count);
body->autorelease();
return body;
}
CC_SAFE_DELETE(body);
return nullptr;
}
PhysicsShapeCircle* PhysicsBody::addCircle(float radius, Point offset/* = Point(0, 0)*/)
{
_area = PhysicsHelper::cpfloat2float(cpAreaForCircle(0, radius));
setMass((_massDefault ? 0 : getMass()) + _area * _density);
setAngularDamping((_angularDampingDefault ? 0 : getAngularDamping())
+ PhysicsHelper::cpfloat2float(cpMomentForCircle(getMass(), 0, radius, PhysicsHelper::point2cpv(offset))));
return PhysicsShapeCircle::create(this, radius, offset);
}
PhysicsShapeBox* PhysicsBody::addBox(Size size, Point offset/* = Point(0, 0)*/)
{
cpVect cpOffset = PhysicsHelper::size2cpv(size);
cpVect vec[4] = {};
vec[0] = cpv(0, 0);
vec[1] = cpv(0, cpOffset.y);
vec[2] = cpv(cpOffset.x, cpOffset.y);
vec[3] = cpv(cpOffset.x, 0);
_area = PhysicsHelper::cpfloat2float(cpAreaForPoly(4, vec));
setMass((_massDefault ? 0 : getMass()) + _area * _density);
setAngularDamping((_angularDampingDefault ? 0 : getAngularDamping())
+ PhysicsHelper::cpfloat2float(cpMomentForBox(getMass(), PhysicsHelper::float2cpfloat(size.width), PhysicsHelper::float2cpfloat(size.height))));
return PhysicsShapeBox::create(this, size, offset);
}
PhysicsShapePolygon* PhysicsBody::addPolygon(Point* points, int count, Point offset/* = Point(0, 0)*/)
{
cpVect* vec = new cpVect[count];
PhysicsHelper::points2cpvs(points, vec, count);
_area = PhysicsHelper::cpfloat2float(cpAreaForPoly(count, vec));
setAngularDamping((_angularDampingDefault ? 0 : getAngularDamping())
+ PhysicsHelper::cpfloat2float(cpMomentForPoly(getMass(), count, vec, PhysicsHelper::point2cpv(offset))));
delete[] vec;
return PhysicsShapePolygon::create(this, points, count, offset);
}
PhysicsShapeEdgeSegment* PhysicsBody::addEdgeSegment(Point a, Point b, float border/* = 1*/)
{
return PhysicsShapeEdgeSegment::create(this, a, b, border);
}
PhysicsShapeEdgeBox* PhysicsBody::addEdgeBox(Size size, float border/* = 1*/, Point offset/* = Point(0, 0)*/)
{
return PhysicsShapeEdgeBox::create(this, size, border, offset);
}
PhysicsShapeEdgePolygon* PhysicsBody::addEdgePolygon(Point* points, int count, float border/* = 1*/)
{
return PhysicsShapeEdgePolygon::create(this, points, count);
}
PhysicsShapeEdgeChain* PhysicsBody::addEdgeChain(Point* points, int count, float border/* = 1*/)
{
return PhysicsShapeEdgeChain::create(this, points, count, border);
}
bool PhysicsBody::init()
{
do
@ -81,8 +254,9 @@ bool PhysicsBody::init()
_info = new PhysicsBodyInfo();
CC_BREAK_IF(_info == nullptr);
_info->body = cpBodyNew(1.0, 1.0);
_info->body = cpBodyNew(PhysicsHelper::float2cpfloat(_mass), PhysicsHelper::float2cpfloat(_angularDamping));
CC_BREAK_IF(_info->body == nullptr);
_dynamic = true;
return true;
} while (false);
@ -90,26 +264,118 @@ bool PhysicsBody::init()
return false;
}
PhysicsBody* PhysicsBody::createCircle(Point centre, float radius)
void PhysicsBody::setDynamic(bool dynamic)
{
PhysicsBody* body = PhysicsBody::create();
if (body == nullptr)
_dynamic = dynamic;
if (_world != nullptr && cpBodyIsStatic(_info->body) == (cpBool)_dynamic)
{
return nullptr;
if (dynamic)
{
cpSpaceConvertBodyToDynamic(_world->_info->space, _info->body, _mass, _angularDamping);
}else
{
cpSpaceConvertBodyToStatic(_world->_info->space, _info->body);
}
}
cpBodySetPos(body->_info->body, cpv(centre.x, centre.y));
body->_info->shape = cpCircleShapeNew(body->_info->body, radius, cpvzero);
if (body->_info->shape == nullptr)
{
return nullptr;
}
return body;
}
bool PhysicsBody::initStatic()
{
do
{
_info = new PhysicsBodyInfo();
CC_BREAK_IF(_info == nullptr);
_info->body = cpBodyNewStatic();
CC_BREAK_IF(_info->body == nullptr);
_dynamic = false;
return true;
} while (false);
return false;
}
void PhysicsBody::setPosition(Point position)
{
cpBodySetPos(_info->body, PhysicsHelper::point2cpv(position));
}
void PhysicsBody::setRotation(float rotation)
{
cpBodySetAngle(_info->body, PhysicsHelper::float2cpfloat(rotation));
}
Point PhysicsBody::getPosition() const
{
cpVect vec = cpBodyGetPos(_info->body);
return PhysicsHelper::cpv2point(vec);
}
float PhysicsBody::getRotation() const
{
return -PhysicsHelper::cpfloat2float(cpBodyGetAngle(_info->body) / 3.14f * 180.0f);
}
void PhysicsBody::addShape(PhysicsShape* shape)
{
if (shape == nullptr) return;
_shapes.push_back(shape);
if (_world != nullptr) _world->addShape(shape);
}
void PhysicsBody::applyForce(Point force)
{
applyForce(force, Point());
}
void PhysicsBody::applyForce(Point force, Point offset)
{
cpBodyApplyForce(_info->body, PhysicsHelper::point2cpv(force), PhysicsHelper::point2cpv(offset));
}
void PhysicsBody::applyImpulse(Point impulse)
{
applyImpulse(impulse, Point());
}
void PhysicsBody::applyImpulse(Point impulse, Point offset)
{
cpBodyApplyImpulse(_info->body, PhysicsHelper::point2cpv(impulse), PhysicsHelper::point2cpv(offset));
}
void PhysicsBody::applyTorque(float torque)
{
cpBodySetTorque(_info->body, PhysicsHelper::float2cpfloat(torque));
}
void PhysicsBody::setMass(float mass)
{
_mass = mass;
_massDefault = false;
cpBodySetMass(_info->body, PhysicsHelper::float2cpfloat(_mass));
}
void PhysicsBody::setAngularDamping(float angularDamping)
{
_angularDamping = angularDamping;
_angularDampingDefault = false;
cpBodySetMoment(_info->body, _angularDamping);
}
//Clonable* PhysicsBody::clone() const
//{
// PhysicsBody* body = new PhysicsBody();
//
// body->autorelease();
//
// return body;
//}
#elif (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)

View File

@ -36,33 +36,48 @@ NS_CC_BEGIN
class Sprite;
class PhysicsWorld;
class PhysicsJoint;
class PhysicsFixture;
class PhysicsShape;
class PhysicsShapeCircle;
class PhysicsShapeBox;
class PhysicsShapePolygon;
class PhysicsShapeEdgeSegment;
class PhysicsShapeEdgeBox;
class PhysicsShapeEdgePolygon;
class PhysicsShapeEdgeChain;
class PhysicsBodyInfo;
class PhysicsBody : public Object, public Clonable
class PhysicsBody : public Object//, public Clonable
{
public:
static PhysicsBody* createCircle(Point centre, float radius);
static PhysicsBody* createRectangle(Rect rect);
static PhysicsBody* createPolygon(Array* points);
static PhysicsBody* createCircle(float radius);
static PhysicsBody* createBox(Size size);
static PhysicsBody* createPolygon(Point* points, int count);
static PhysicsBody* createEdgeSegment(Point x, Point y);
static PhysicsBody* createEdgeCircle(Point centre, float radius);
static PhysicsBody* createEdgeRectangle(Rect rect);
static PhysicsBody* createEdgePolygon(Array* points);
static PhysicsBody* createEdgeChain(Array* points);
static PhysicsBody* createEdgeSegment(Point a, Point b, float border = 1);
static PhysicsBody* createEdgeBox(Size size, float border = 1);
static PhysicsBody* createEdgePolygon(Point* points, int count, float border = 1);
static PhysicsBody* createEdgeChain(Point* points, int count, float border = 1);
virtual PhysicsShapeCircle* addCircle(float radius, Point offset = Point(0, 0));
virtual PhysicsShapeBox* addBox(Size size, Point offset = Point(0, 0));
virtual PhysicsShapePolygon* addPolygon(Point* points, int count, Point offset = Point(0, 0));
virtual PhysicsShapeEdgeSegment* addEdgeSegment(Point a, Point b, float border = 1);
virtual PhysicsShapeEdgeBox* addEdgeBox(Size size, float border = 1, Point offset = Point(0, 0));
virtual PhysicsShapeEdgePolygon* addEdgePolygon(Point* points, int count, float border = 1);
virtual PhysicsShapeEdgeChain* addEdgeChain(Point* points, int count, float border = 1);
virtual void applyForce(Point force);
virtual void applyForce(Point force, Point point);
virtual void applyForce(Point force, Point offset);
virtual void applyImpulse(Point impulse);
virtual void applyImpulse(Point impulse, Point point);
virtual void applyImpulse(Point impulse, Point offset);
virtual void applyTorque(float torque);
virtual void applyAngularImpulse(float impulse);
void addFixture(PhysicsFixture* fixture);
inline Array* getFixtures() const { return _fixtures; }
void removeFixture(PhysicsFixture* fixture);
void removeAllFixtures();
inline std::vector<PhysicsShape*>& getShapes() { return _shapes; }
inline PhysicsShape* getShape() { return _shapes.size() >= 1 ? _shapes.front() : nullptr; }
void removeShape(PhysicsShape* shape);
void removeAllShapes();
inline PhysicsWorld* getWorld() const { return _world; }
inline const std::vector<PhysicsJoint*>* getJoints() const { return &_joints; }
@ -76,34 +91,55 @@ public:
void setCollisionBitmask(int bitmask);
inline int getCollisionBitmask() const { return _collisionBitmask; }
virtual Clonable* clone() const override;
Point getPosition() const;
float getRotation() const;
inline bool isDynamic() { return _dynamic; }
void setDynamic(bool dynamic);
void setMass(float mass);
inline float getMass() { return _mass; }
void setAngularDamping(float angularDamping);
inline float getAngularDamping() { return _angularDamping; }
//virtual Clonable* clone() const override;
protected:
static PhysicsBody* create();
bool init();
bool initStatic();
virtual void setPosition(Point position);
virtual void setRotation(float rotation);
virtual void addShape(PhysicsShape* shape);
protected:
PhysicsBody();
virtual ~PhysicsBody();
protected:
float _mass;
float _density;
float _area;
float _friction;
Sprite* _owner;
Point _velocity;
float _angularVelocity;
bool _resting;
std::vector<PhysicsJoint*> _joints;
std::vector<PhysicsShape*> _shapes;
PhysicsWorld* _world;
PhysicsBodyInfo* _info;
bool _dynamic;
bool _massDefault;
bool _angularDampingDefault;
float _mass;
float _area;
float _density;
float _angularDamping;
int _categoryBitmask;
int _contactTestBitmask;
int _collisionBitmask;
std::vector<PhysicsJoint*> _joints;
Array* _fixtures;
PhysicsWorld* _world;
PhysicsBodyInfo* _info;
friend class PhysicsWorld;
friend class PhysicsShape;
friend class PhysicsJoint;
friend class Sprite;
};
NS_CC_END

View File

@ -0,0 +1,137 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "CCPhysicsContact.h"
#ifdef CC_USE_PHYSICS
#include "chipmunk/CCPhysicsContactInfo.h"
#include "Box2D/CCPhysicsContactInfo.h"
NS_CC_BEGIN
PhysicsContact::PhysicsContact()
: _shapeA(nullptr)
, _shapeB(nullptr)
, _info(nullptr)
, _data(nullptr)
{
}
PhysicsContact::~PhysicsContact()
{
CC_SAFE_DELETE(_info);
}
PhysicsContact* PhysicsContact::create(PhysicsShape* a, PhysicsShape* b)
{
PhysicsContact * contact = new PhysicsContact();
if(contact && contact->init(a, b))
{
return contact;
}
CC_SAFE_DELETE(contact);
return nullptr;
}
bool PhysicsContact::init(PhysicsShape* a, PhysicsShape* b)
{
do
{
CC_BREAK_IF(a == nullptr || b == nullptr);
CC_BREAK_IF(!(_info = new PhysicsContactInfo(this)));
_shapeA = a;
_shapeB = b;
return true;
} while(false);
return false;
}
// PhysicsContactPreSolve implementation
PhysicsContactPreSolve::PhysicsContactPreSolve()
{
}
PhysicsContactPreSolve::~PhysicsContactPreSolve()
{
}
PhysicsContactPreSolve* PhysicsContactPreSolve::create()
{
PhysicsContactPreSolve * solve = new PhysicsContactPreSolve();
if(solve && solve->init())
{
return solve;
}
CC_SAFE_DELETE(solve);
return nullptr;
}
bool PhysicsContactPreSolve::init()
{
return true;
}
// PhysicsContactPostSolve implementation
PhysicsContactPostSolve::PhysicsContactPostSolve()
{
}
PhysicsContactPostSolve::~PhysicsContactPostSolve()
{
}
PhysicsContactPostSolve* PhysicsContactPostSolve::create()
{
PhysicsContactPostSolve * solve = new PhysicsContactPostSolve();
if(solve && solve->init())
{
return solve;
}
CC_SAFE_DELETE(solve);
return nullptr;
}
bool PhysicsContactPostSolve::init()
{
return true;
}
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
#elif (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
#endif
NS_CC_END
#endif // CC_USE_PHYSICS

View File

@ -0,0 +1,136 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "CCPhysicsSetting.h"
#ifdef CC_USE_PHYSICS
#ifndef __CCPHYSICS_CONTACT_H__
#define __CCPHYSICS_CONTACT_H__
#include "cocoa/CCObject.h"
#include "cocoa/CCGeometry.h"
NS_CC_BEGIN
class PhysicsShape;
class PhysicsWorld;
namespace PhysicsInnerCallbackFunctions
{
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
int collisionBeginCallbackFunc(cpArbiter *arb, struct cpSpace *space, void *data);
int collisionPreSolveCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
void collisionPostSolveCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
void collisionSeparateCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
#endif
}
class PhysicsContactInfo;
class PhysicsContact
{
public:
inline PhysicsShape* getShapeA() { return _shapeA; }
inline PhysicsShape* getShapeB() { return _shapeB; }
inline void* getData() { return _data; }
private:
static PhysicsContact* create(PhysicsShape* a, PhysicsShape* b);
bool init(PhysicsShape* a, PhysicsShape* b);
private:
PhysicsContact();
~PhysicsContact();
private:
PhysicsShape* _shapeA;
PhysicsShape* _shapeB;
PhysicsContactInfo* _info;
void* _data;
friend class PhysicsWorld;
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
friend int PhysicsInnerCallbackFunctions::collisionBeginCallbackFunc(cpArbiter *arb, struct cpSpace *space, void *data);
friend int PhysicsInnerCallbackFunctions::collisionPreSolveCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
friend void PhysicsInnerCallbackFunctions::collisionPostSolveCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
friend void PhysicsInnerCallbackFunctions::collisionSeparateCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
#endif
};
class PhysicsContactPreSolve
{
private:
PhysicsContactPreSolve();
~PhysicsContactPreSolve();
static PhysicsContactPreSolve* create();
bool init();
friend class PhysicsWorld;
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
friend int PhysicsInnerCallbackFunctions::collisionBeginCallbackFunc(cpArbiter *arb, struct cpSpace *space, void *data);
friend int PhysicsInnerCallbackFunctions::collisionPreSolveCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
friend void PhysicsInnerCallbackFunctions::collisionPostSolveCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
friend void PhysicsInnerCallbackFunctions::collisionSeparateCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
#endif
};
class PhysicsContactPostSolve
{
private:
PhysicsContactPostSolve();
~PhysicsContactPostSolve();
static PhysicsContactPostSolve* create();
bool init();
friend class PhysicsWorld;
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
friend int PhysicsInnerCallbackFunctions::collisionBeginCallbackFunc(cpArbiter *arb, struct cpSpace *space, void *data);
friend int PhysicsInnerCallbackFunctions::collisionPreSolveCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
friend void PhysicsInnerCallbackFunctions::collisionPostSolveCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
friend void PhysicsInnerCallbackFunctions::collisionSeparateCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
#endif
};
class PhysicsContactDelegate
{
public:
PhysicsContactDelegate();
virtual ~PhysicsContactDelegate();
public:
virtual bool onContactBegin(const PhysicsContact& contact) = 0;
virtual bool onContactPreSolve(const PhysicsContact& contact, const PhysicsContactPreSolve& solve) = 0;
virtual void onContactPostSove(const PhysicsContact& contact, const PhysicsContactPostSolve& solve)= 0;
virtual void onContactEnd(const PhysicsContact& contact) = 0;
};
NS_CC_END
#endif //__CCPHYSICS_CONTACT_H__
#endif // CC_USE_PHYSICS

View File

@ -21,3 +21,198 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "CCPhysicsJoint.h"
#ifdef CC_USE_PHYSICS
#include "CCPhysicsBody.h"
#include "chipmunk/CCPhysicsJointInfo.h"
#include "Box2D/CCPhysicsJointInfo.h"
#include "chipmunk/CCPhysicsBodyInfo.h"
#include "Box2D/CCPhysicsBodyInfo.h"
#include "chipmunk/CCPhysicsHelper.h"
#include "Box2D/CCPhysicsHelper.h"
NS_CC_BEGIN
PhysicsJoint::PhysicsJoint()
: _bodyA(nullptr)
, _bodyB(nullptr)
, _info(nullptr)
{
}
PhysicsJoint::~PhysicsJoint()
{
CC_SAFE_DELETE(_info);
CC_SAFE_RELEASE(_bodyA);
CC_SAFE_RELEASE(_bodyB);
}
bool PhysicsJoint::init(cocos2d::PhysicsBody *a, cocos2d::PhysicsBody *b)
{
do
{
CC_BREAK_IF(a == nullptr || b == nullptr);
CC_BREAK_IF(!(_info = new PhysicsJointInfo()));
_bodyA = a;
_bodyA->retain();
_bodyA->_joints.push_back(this);
_bodyB = b;
_bodyB->retain();
_bodyB->_joints.push_back(this);
return true;
} while (false);
return false;
}
PhysicsJointPin::PhysicsJointPin()
{
}
PhysicsJointPin::~PhysicsJointPin()
{
}
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
PhysicsBodyInfo* PhysicsJoint::bodyInfo(PhysicsBody* body) const
{
return body->_info;
}
PhysicsJointFixed* PhysicsJointFixed::create(PhysicsBody* a, PhysicsBody* b, const Point& anchr)
{
PhysicsJointFixed* joint = new PhysicsJointFixed();
if (joint && joint->init(a, b, anchr))
{
joint->autorelease();
return joint;
}
CC_SAFE_DELETE(joint);
return nullptr;
}
bool PhysicsJointFixed::init(PhysicsBody* a, PhysicsBody* b, const Point& anchr)
{
do
{
CC_BREAK_IF(!PhysicsJoint::init(a, b));
_info->joint = cpPivotJointNew(bodyInfo(a)->body, bodyInfo(b)->body,
PhysicsHelper::point2cpv(anchr));
return true;
} while (false);
return false;
}
PhysicsJointPin* PhysicsJointPin::create(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2)
{
PhysicsJointPin* joint = new PhysicsJointPin();
if (joint && joint->init(a, b, anchr1, anchr2))
{
joint->autorelease();
return joint;
}
CC_SAFE_DELETE(joint);
return nullptr;
}
bool PhysicsJointPin::init(PhysicsBody *a, PhysicsBody *b, const Point& anchr1, const Point& anchr2)
{
do
{
CC_BREAK_IF(!PhysicsJoint::init(a, b));
_info->joint = cpPinJointNew(bodyInfo(a)->body, bodyInfo(b)->body, PhysicsHelper::point2cpv(anchr1), PhysicsHelper::point2cpv(anchr2));
return true;
} while (false);
return false;
}
PhysicsJointSliding* PhysicsJointSliding::create(PhysicsBody* a, PhysicsBody* b, const Point& grooveA, const Point& grooveB, const Point& anchr)
{
PhysicsJointSliding* joint = new PhysicsJointSliding();
if (joint && joint->init(a, b, grooveA, grooveB, anchr))
{
return joint;
}
CC_SAFE_DELETE(joint);
return nullptr;
}
bool PhysicsJointSliding::init(PhysicsBody* a, PhysicsBody* b, const Point& grooveA, const Point& grooveB, const Point& anchr)
{
do
{
CC_BREAK_IF(!PhysicsJoint::init(a, b));
_info->joint = cpGrooveJointNew(bodyInfo(a)->body, bodyInfo(b)->body,
PhysicsHelper::point2cpv(grooveA),
PhysicsHelper::point2cpv(grooveB),
PhysicsHelper::point2cpv(anchr));
return true;
} while (false);
return false;
}
PhysicsJointLimit* PhysicsJointLimit::create(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2, float min, float max)
{
PhysicsJointLimit* joint = new PhysicsJointLimit();
if (joint && joint->init(a, b, anchr1, anchr2, min, max))
{
return joint;
}
CC_SAFE_DELETE(joint);
return nullptr;
}
bool PhysicsJointLimit::init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2, float min, float max)
{
do
{
CC_BREAK_IF(!PhysicsJoint::init(a, b));
_info->joint = cpSlideJointNew(bodyInfo(a)->body, bodyInfo(b)->body,
PhysicsHelper::point2cpv(anchr1),
PhysicsHelper::point2cpv(anchr2),
PhysicsHelper::float2cpfloat(min),
PhysicsHelper::float2cpfloat(max));
return true;
} while (false);
return false;
}
#elif (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
#endif
NS_CC_END
#endif // CC_USE_PHYSICS

View File

@ -34,42 +34,59 @@
NS_CC_BEGIN
class PhysicsBody;
class PhysicsJointInfo;
class PhysicsBodyInfo;
class PhysicsJoint
class PhysicsJoint : public Object
{
protected:
PhysicsJoint();
virtual ~PhysicsJoint();
virtual ~PhysicsJoint() = 0;
public:
PhysicsBody* getBodyA() { return _bodyA; }
PhysicsBody* getBodyB() { return _bodyB; }
private:
protected:
bool init(PhysicsBody* a, PhysicsBody* b);
/**
* PhysicsShape is PhysicsBody's friend class, but all the subclasses isn't. so this method is use for subclasses to catch the bodyInfo from PhysicsBody.
*/
PhysicsBodyInfo* bodyInfo(PhysicsBody* body) const;
protected:
PhysicsBody* _bodyA;
PhysicsBody* _bodyB;
PhysicsJointInfo* _info;
friend class PhysicsBody;
};
class PhysicsJointFixed : public PhysicsJoint
{
public:
PhysicsJointFixed* create();
PhysicsJointFixed* create(PhysicsBody* a, PhysicsBody* b, const Point& anchr);
protected:
bool init();
bool init(PhysicsBody* a, PhysicsBody* b, const Point& anchr);
protected:
PhysicsJointFixed();
~PhysicsJointFixed();
virtual ~PhysicsJointFixed();
};
class PhysicsJointSliding : public PhysicsJoint
{
public:
PhysicsJointSliding* create();
PhysicsJointSliding* create(PhysicsBody* a, PhysicsBody* b, const Point& grooveA, const Point& grooveB, const Point& anchr);
protected:
bool init();
bool init(PhysicsBody* a, PhysicsBody* b, const Point& grooveA, const Point& grooveB, const Point& anchr);
protected:
PhysicsJointSliding();
~PhysicsJointSliding();
virtual ~PhysicsJointSliding();
};
class PhysicsJointSpring : public PhysicsJoint
@ -82,33 +99,33 @@ protected:
protected:
PhysicsJointSpring();
~PhysicsJointSpring();
virtual ~PhysicsJointSpring();
};
class PhysicsJointLimit : public PhysicsJoint
{
public:
PhysicsJointLimit* create();
PhysicsJointLimit* create(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2, float min, float max);
protected:
bool init();
bool init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2, float min, float max);
protected:
PhysicsJointLimit();
~PhysicsJointLimit();
virtual ~PhysicsJointLimit();
};
class PhysicsJointPin : public PhysicsJoint
{
public:
PhysicsJointPin* create();
static PhysicsJointPin* create(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2);
protected:
bool init();
bool init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2);
protected:
PhysicsJointPin();
~PhysicsJointPin();
virtual ~PhysicsJointPin();
};
NS_CC_END

View File

@ -29,7 +29,15 @@
#define CC_PHYSICS_BOX2D 1
#define CC_PHYSICS_CHIPMUNK 2
#define CC_USE_CHIPMUNK
#ifdef CC_USE_BOX2D
#define CC_PHYSICS_ENGINE CC_PHYSICS_BOX2D
#elif defined(CC_USE_CHIPMUNK)
#define CC_PHYSICS_ENGINE CC_PHYSICS_CHIPMUNK
#else
#define CC_PHYSICS_ENGINE CC_PHYSICS_UNKNOWN
#endif
#if (CC_PHYSICS_ENGINE != CC_PHYSICS_UNKNOWN)
#define CC_USE_PHYSICS

View File

@ -0,0 +1,426 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "CCPhysicsShape.h"
#ifdef CC_USE_PHYSICS
#include "CCPhysicsBody.h"
#include "chipmunk/CCPhysicsBodyInfo.h"
#include "Box2D/CCPhysicsBodyInfo.h"
#include "chipmunk/CCPhysicsShapeInfo.h"
#include "Box2D/CCPhysicsShapeInfo.h"
#include "chipmunk/CCPhysicsHelper.h"
NS_CC_BEGIN
PhysicsShape::PhysicsShape()
: _body(nullptr)
, _info(nullptr)
, _type(Type::UNKNOWN)
{
}
PhysicsShape::~PhysicsShape()
{
CC_SAFE_DELETE(_info);
}
bool PhysicsShape::init(PhysicsBody* body, Type type)
{
if (body == nullptr) return false;
_body = body;
_info = new PhysicsShapeInfo(this);
if (_info == nullptr) return false;
_type = type;
return true;
}
void PhysicsShape::addToBody()
{
if(_body != nullptr) _body->addShape(this);
}
PhysicsBodyInfo* PhysicsShape::bodyInfo() const
{
return _body->_info;
}
PhysicsShapeCircle::PhysicsShapeCircle()
{
}
PhysicsShapeCircle::~PhysicsShapeCircle()
{
}
PhysicsShapeBox::PhysicsShapeBox()
{
}
PhysicsShapeBox::~PhysicsShapeBox()
{
}
PhysicsShapePolygon::PhysicsShapePolygon()
{
}
PhysicsShapePolygon::~PhysicsShapePolygon()
{
}
PhysicsShapeEdgeBox::PhysicsShapeEdgeBox()
{
}
PhysicsShapeEdgeBox::~PhysicsShapeEdgeBox()
{
}
PhysicsShapeEdgeChain::PhysicsShapeEdgeChain()
{
}
PhysicsShapeEdgeChain::~PhysicsShapeEdgeChain()
{
}
PhysicsShapeEdgePolygon::PhysicsShapeEdgePolygon()
{
}
PhysicsShapeEdgePolygon::~PhysicsShapeEdgePolygon()
{
}
PhysicsShapeEdgeSegment::PhysicsShapeEdgeSegment()
{
}
PhysicsShapeEdgeSegment::~PhysicsShapeEdgeSegment()
{
}
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
// PhysicsShapeCircle
PhysicsShapeCircle* PhysicsShapeCircle::create(PhysicsBody* body, float radius, Point offset/* = Point(0, 0)*/)
{
PhysicsShapeCircle* shape = new PhysicsShapeCircle();
if (shape && shape->init(body, radius, offset))
{
return shape;
}
CC_SAFE_DELETE(shape);
return nullptr;
}
bool PhysicsShapeCircle::init(PhysicsBody* body, float radius, Point offset /*= Point(0, 0)*/)
{
do
{
CC_BREAK_IF(!PhysicsShape::init(body, Type::CIRCLE));
cpShape* shape = cpCircleShapeNew(bodyInfo()->body, radius, PhysicsHelper::point2cpv(offset));
CC_BREAK_IF(shape == nullptr);
_info->add(shape);
addToBody();
return true;
} while (false);
return false;
}
// PhysicsShapeEdgeSegment
PhysicsShapeEdgeSegment* PhysicsShapeEdgeSegment::create(PhysicsBody* body, Point a, Point b, float border/* = 1*/)
{
PhysicsShapeEdgeSegment* shape = new PhysicsShapeEdgeSegment();
if (shape && shape->init(body, a, b, border))
{
return shape;
}
CC_SAFE_DELETE(shape);
return nullptr;
}
bool PhysicsShapeEdgeSegment::init(PhysicsBody* body, Point a, Point b, float border/* = 1*/)
{
do
{
CC_BREAK_IF(!PhysicsShape::init(body, Type::EDGESEGMENT));
cpShape* shape = cpSegmentShapeNew(bodyInfo()->body,
PhysicsHelper::point2cpv(a),
PhysicsHelper::point2cpv(b),
PhysicsHelper::float2cpfloat(border));
CC_BREAK_IF(shape == nullptr);
_info->add(shape);
addToBody();
return true;
} while (false);
return false;
}
// PhysicsShapeBox
PhysicsShapeBox* PhysicsShapeBox::create(PhysicsBody* body, Size size, Point offset/* = Point(0, 0)*/)
{
PhysicsShapeBox* shape = new PhysicsShapeBox();
if (shape && shape->init(body, size, offset))
{
return shape;
}
CC_SAFE_DELETE(shape);
return nullptr;
}
bool PhysicsShapeBox::init(PhysicsBody* body, Size size, Point offset /*= Point(0, 0)*/)
{
do
{
CC_BREAK_IF(!PhysicsShape::init(body, Type::BOX));
cpShape* shape = cpBoxShapeNew(bodyInfo()->body, PhysicsHelper::float2cpfloat(size.width), PhysicsHelper::float2cpfloat(size.height));
CC_BREAK_IF(shape == nullptr);
_info->add(shape);
addToBody();
return true;
} while (false);
return false;
}
// PhysicsShapeCircle
PhysicsShapePolygon* PhysicsShapePolygon::create(PhysicsBody* body, Point* points, int count, Point offset/* = Point(0, 0)*/)
{
PhysicsShapePolygon* shape = new PhysicsShapePolygon();
if (shape && shape->init(body, points, count, offset))
{
return shape;
}
CC_SAFE_DELETE(shape);
return nullptr;
}
bool PhysicsShapePolygon::init(PhysicsBody* body, Point* points, int count, Point offset /*= Point(0, 0)*/)
{
do
{
CC_BREAK_IF(!PhysicsShape::init(body, Type::POLYGEN));
cpVect* vecs = new cpVect[count];
PhysicsHelper::points2cpvs(points, vecs, count);
cpShape* shape = cpPolyShapeNew(bodyInfo()->body, count, vecs, PhysicsHelper::point2cpv(offset));
CC_BREAK_IF(shape == nullptr);
_info->add(shape);
addToBody();
return true;
} while (false);
return false;
}
// PhysicsShapeEdgeBox
PhysicsShapeEdgeBox* PhysicsShapeEdgeBox::create(PhysicsBody* body, Size size, float border/* = 1*/, Point offset/* = Point(0, 0)*/)
{
PhysicsShapeEdgeBox* shape = new PhysicsShapeEdgeBox();
if (shape && shape->init(body, size, border, offset))
{
return shape;
}
CC_SAFE_DELETE(shape);
return nullptr;
}
bool PhysicsShapeEdgeBox::init(PhysicsBody* body, Size size, float border/* = 1*/, Point offset/*= Point(0, 0)*/)
{
do
{
CC_BREAK_IF(!PhysicsShape::init(body, Type::EDGEBOX));
Point bodyPos = body->getPosition();
cpVect vec[4] = {};
vec[0] = PhysicsHelper::point2cpv(Point(bodyPos.x-size.width/2+offset.x, bodyPos.y-size.height/2+offset.y));
vec[1] = PhysicsHelper::point2cpv(Point(bodyPos.x+size.width/2+offset.x, bodyPos.y-size.height/2+offset.y));
vec[2] = PhysicsHelper::point2cpv(Point(bodyPos.x+size.width/2+offset.x, bodyPos.y+size.height/2+offset.y));
vec[3] = PhysicsHelper::point2cpv(Point(bodyPos.x-size.width/2+offset.x, bodyPos.y+size.height/2+offset.y));
int i = 0;
for (; i < 4; ++i)
{
cpShape* shape = cpSegmentShapeNew(bodyInfo()->body, vec[i], vec[(i+1)%4],
PhysicsHelper::float2cpfloat(border));
CC_BREAK_IF(shape == nullptr);
cpShapeSetElasticity(shape, 1.0f);
cpShapeSetFriction(shape, 1.0f);
_info->add(shape);
}
CC_BREAK_IF(i < 4);
addToBody();
return true;
} while (false);
return false;
}
// PhysicsShapeEdgeBox
PhysicsShapeEdgePolygon* PhysicsShapeEdgePolygon::create(PhysicsBody* body, Point* points, int count, float border/* = 1*/)
{
PhysicsShapeEdgePolygon* shape = new PhysicsShapeEdgePolygon();
if (shape && shape->init(body, points, count, border))
{
return shape;
}
CC_SAFE_DELETE(shape);
return nullptr;
}
bool PhysicsShapeEdgePolygon::init(PhysicsBody* body, Point* points, int count, float border/* = 1*/)
{
cpVect* vec = nullptr;
do
{
CC_BREAK_IF(!PhysicsShape::init(body, Type::EDGEPOLYGEN));
vec = new cpVect[count];
PhysicsHelper::points2cpvs(points, vec, count);
int i = 0;
for (; i < count; ++i)
{
cpShape* shape = cpSegmentShapeNew(bodyInfo()->body, vec[i], vec[(i+1)%count],
PhysicsHelper::float2cpfloat(border));
CC_BREAK_IF(shape == nullptr);
cpShapeSetElasticity(shape, 1.0f);
cpShapeSetFriction(shape, 1.0f);
_info->add(shape);
}
CC_BREAK_IF(i < count);
addToBody();
if (vec != nullptr) delete[] vec;
return true;
} while (false);
if (vec != nullptr) delete[] vec;
return false;
}
// PhysicsShapeEdgeChain
PhysicsShapeEdgeChain* PhysicsShapeEdgeChain::create(PhysicsBody* body, Point* points, int count, float border/* = 1*/)
{
PhysicsShapeEdgeChain* shape = new PhysicsShapeEdgeChain();
if (shape && shape->init(body, points, count, border))
{
return shape;
}
CC_SAFE_DELETE(shape);
return nullptr;
}
bool PhysicsShapeEdgeChain::init(PhysicsBody* body, Point* points, int count, float border/* = 1*/)
{
cpVect* vec = nullptr;
do
{
CC_BREAK_IF(!PhysicsShape::init(body, Type::EDGECHAIN));
vec = new cpVect[count];
PhysicsHelper::points2cpvs(points, vec, count);
int i = 0;
for (; i < count - 1; ++i)
{
cpShape* shape = cpSegmentShapeNew(bodyInfo()->body, vec[i], vec[i+1],
PhysicsHelper::float2cpfloat(border));
CC_BREAK_IF(shape == nullptr);
cpShapeSetElasticity(shape, 1.0f);
cpShapeSetFriction(shape, 1.0f);
_info->add(shape);
}
CC_BREAK_IF(i < count);
addToBody();
if (vec != nullptr) delete[] vec;
return true;
} while (false);
if (vec != nullptr) delete[] vec;
return false;
}
#elif (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
#endif
NS_CC_END
#endif // CC_USE_PHYSICS

View File

@ -0,0 +1,182 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "CCPhysicsSetting.h"
#ifdef CC_USE_PHYSICS
#ifndef __CCPHYSICS_SHAPE_H__
#define __CCPHYSICS_SHAPE_H__
#include "cocoa/CCObject.h"
#include "cocoa/CCGeometry.h"
NS_CC_BEGIN
class PhysicsShapeInfo;
class PhysicsBody;
class PhysicsBodyInfo;
class PhysicsShape : public Object
{
public:
enum class Type
{
UNKNOWN,
CIRCLE,
BOX,
POLYGEN,
EDGESEGMENT,
EDGEBOX,
EDGEPOLYGEN,
EDGECHAIN,
};
public:
inline PhysicsBody* getBody(){ return _body; }
inline Type getType() { return _type; }
protected:
bool init(PhysicsBody* body, Type type);
/**
* PhysicsShape is PhysicsBody's friend class, but all the subclasses isn't. so this method is use for subclasses to catch the bodyInfo from PhysicsBody.
*/
PhysicsBodyInfo* bodyInfo() const;
void addToBody();
protected:
PhysicsShape();
virtual ~PhysicsShape();
protected:
PhysicsBody* _body;
PhysicsShapeInfo* _info;
Type _type;
friend class PhysicsWorld;
friend class PhysicsBody;
};
class PhysicsShapeCircle : public PhysicsShape
{
protected:
static PhysicsShapeCircle* create(PhysicsBody* body, float radius, Point offset = Point(0, 0));
bool init(PhysicsBody* body, float radius, Point offset = Point(0, 0));
protected:
PhysicsShapeCircle();
virtual ~PhysicsShapeCircle();
friend class PhysicsBody;
};
class PhysicsShapeBox : public PhysicsShape
{
protected:
static PhysicsShapeBox* create(PhysicsBody* body, Size size, Point offset = Point(0, 0));
bool init(PhysicsBody* body, Size size, Point offset = Point(0, 0));
protected:
PhysicsShapeBox();
virtual ~PhysicsShapeBox();
friend class PhysicsBody;
};
class PhysicsShapePolygon : public PhysicsShape
{
protected:
static PhysicsShapePolygon* create(PhysicsBody* body, Point* points, int count, Point offset = Point(0, 0));
bool init(PhysicsBody* body, Point* points, int count, Point offset = Point(0, 0));
protected:
PhysicsShapePolygon();
virtual ~PhysicsShapePolygon();
friend class PhysicsBody;
};
class PhysicsShapeEdgeSegment : public PhysicsShape
{
protected:
static PhysicsShapeEdgeSegment* create(PhysicsBody* body, Point a, Point b, float border = 1);
bool init(PhysicsBody* body, Point a, Point b, float border = 1);
protected:
PhysicsShapeEdgeSegment();
virtual ~PhysicsShapeEdgeSegment();
friend class PhysicsBody;
};
class PhysicsShapeEdgeBox : public PhysicsShape
{
public:
static PhysicsShapeEdgeBox* create(PhysicsBody* body, Size size, float border = 0, Point offset = Point(0, 0));
protected:
bool init(PhysicsBody* body, Size size, float border = 1, Point offset = Point(0, 0));
protected:
PhysicsShapeEdgeBox();
virtual ~PhysicsShapeEdgeBox();
friend class PhysicsBody;
};
class PhysicsShapeEdgePolygon : public PhysicsShape
{
public:
static PhysicsShapeEdgePolygon* create(PhysicsBody* body, Point* points, int count, float border = 1);
protected:
bool init(PhysicsBody* body, Point* points, int count, float border = 1);
protected:
PhysicsShapeEdgePolygon();
virtual ~PhysicsShapeEdgePolygon();
friend class PhysicsBody;
};
class PhysicsShapeEdgeChain : public PhysicsShape
{
public:
static PhysicsShapeEdgeChain* create(PhysicsBody* body, Point* points, int count, float border = 1);
protected:
bool init(PhysicsBody* body, Point* points, int count, float border = 1);
protected:
PhysicsShapeEdgeChain();
virtual ~PhysicsShapeEdgeChain();
friend class PhysicsBody;
};
NS_CC_END
#endif // __CCPHYSICS_FIXTURE_H__
#endif // CC_USE_PHYSICS

View File

@ -23,51 +23,265 @@
****************************************************************************/
#include "CCPhysicsWorld.h"
#ifdef CC_USE_PHYSICS
#include "CCPhysicsBody.h"
#include "CCPhysicsShape.h"
#include "CCPhysicsContact.h"
#include "chipmunk/CCPhysicsWorldInfo.h"
#include "Box2D/CCPhysicsWorldInfo.h"
#include "chipmunk/CCPhysicsBodyInfo.h"
#include "Box2D/CCPhysicsBodyInfo.h"
#include "chipmunk/CCPhysicsShapeInfo.h"
#include "Box2D/CCPhysicsShapeInfo.h"
#include "chipmunk/CCPhysicsContactInfo.h"
#include "Box2D/CCPhysicsContactInfo.h"
#include "chipmunk/CCPhysicsHelper.h"
#include "draw_nodes/CCDrawNode.h"
#include "cocoa/CCArray.h"
#include "layers_scenes_transitions_nodes/CCScene.h"
#include "CCDirector.h"
NS_CC_BEGIN
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
class PhysicsWorldInfo
namespace PhysicsInnerCallbackFunctions
{
public:
cpSpace* space;
int collisionBeginCallbackFunc(cpArbiter *arb, struct cpSpace *space, void *data)
{
PhysicsWorld* world = static_cast<PhysicsWorld*>(data);
CP_ARBITER_GET_SHAPES(arb, a, b);
auto ita = PhysicsShapeInfo::map.find(a);
auto itb = PhysicsShapeInfo::map.find(b);
CC_ASSERT(ita != PhysicsShapeInfo::map.end() && itb != PhysicsShapeInfo::map.end());
PhysicsContact* contact = PhysicsContact::create(ita->second->shape, itb->second->shape);
arb->data = contact;
return world->collisionBeginCallback(*static_cast<PhysicsContact*>(arb->data));
}
public:
PhysicsWorldInfo();
~PhysicsWorldInfo();
};
PhysicsWorldInfo::PhysicsWorldInfo()
{
space = cpSpaceNew();
}
PhysicsWorldInfo::~PhysicsWorldInfo()
{
cpSpaceFree(space);
int collisionPreSolveCallbackFunc(cpArbiter *arb, cpSpace *space, void *data)
{
PhysicsWorld* world = static_cast<PhysicsWorld*>(data);
return world->collisionPreSolveCallback(*static_cast<PhysicsContact*>(arb->data),
PhysicsContactPreSolve());
}
void collisionPostSolveCallbackFunc(cpArbiter *arb, cpSpace *space, void *data)
{
PhysicsWorld* world = static_cast<PhysicsWorld*>(data);
world->collisionPostSolveCallback(*static_cast<PhysicsContact*>(arb->data),
PhysicsContactPostSolve());
}
void collisionSeparateCallbackFunc(cpArbiter *arb, cpSpace *space, void *data)
{
PhysicsWorld* world = static_cast<PhysicsWorld*>(data);
PhysicsContact* contact = static_cast<PhysicsContact*>(arb->data);
world->collisionSeparateCallback(*contact);
delete contact;
}
}
bool PhysicsWorld::init()
{
_worldInfo = new PhysicsWorldInfo();
_info = new PhysicsWorldInfo();
cpSpaceSetGravity(_worldInfo->space, cpv(_gravity.x, _gravity.y));
cpSpaceSetGravity(_info->space, PhysicsHelper::point2cpv(_gravity));
cpSpaceSetDefaultCollisionHandler(_info->space,
PhysicsInnerCallbackFunctions::collisionBeginCallbackFunc,
PhysicsInnerCallbackFunctions::collisionPreSolveCallbackFunc,
PhysicsInnerCallbackFunctions::collisionPostSolveCallbackFunc,
PhysicsInnerCallbackFunctions::collisionSeparateCallbackFunc,
this);
return true;
}
void PhysicsWorld::addShape(PhysicsShape* shape)
{
for (auto it = shape->_info->shapes.begin(); it != shape->_info->shapes.end(); it++)
{
if (cpBodyIsStatic(shape->getBody()->_info->body))
{
cpSpaceAddStaticShape(_info->space, *it);
}else
{
cpSpaceAddShape(_info->space, *it);
}
}
}
void PhysicsWorld::addChild(PhysicsBody* body)
{
auto shapes = body->getShapes();
// add body to space
if (body->isDynamic())
{
cpSpaceAddBody(_info->space, body->_info->body);
}
// add shapes to space
for (auto it = shapes.begin(); it != shapes.end(); it++)
{
addShape(*it);
}
if (_bodys == nullptr)
{
_bodys = Array::create(body, NULL);
_bodys->retain();
}else
{
_bodys->addObject(body);
}
}
void PhysicsWorld::update(float delta)
{
cpSpaceStep(_info->space, delta);
if (_drawNode)
{
_drawNode->removeFromParent();
_drawNode = nullptr;
}
if (_debugDraw)
{
debugDraw();
}
}
void PhysicsWorld::debugDraw()
{
if (_debugDraw && _bodys != nullptr)
{
_drawNode= DrawNode::create();
Object* child = nullptr;
CCARRAY_FOREACH(_bodys, child)
{
PhysicsBody* body = dynamic_cast<PhysicsBody*>(child);
std::vector<PhysicsShape*> shapes = body->getShapes();
for (auto it = shapes.begin(); it != shapes.end(); ++it)
{
drawWithShape(_drawNode, *it);
}
}
if (_scene)
{
_scene->addChild(_drawNode);
}
}
}
void PhysicsWorld::setScene(Scene *scene)
{
_scene = scene;
scene->retain();
}
void PhysicsWorld::drawWithShape(DrawNode* node, PhysicsShape* shape)
{
for (auto it = shape->_info->shapes.begin(); it != shape->_info->shapes.end(); ++it)
{
cpShape *shape = *it;
switch ((*it)->klass_private->type)
{
case CP_CIRCLE_SHAPE:
{
float radius = PhysicsHelper::cpfloat2float(cpCircleShapeGetRadius(shape));
Point centre = PhysicsHelper::cpv2point(cpBodyGetPos(cpShapeGetBody(shape)))
+ PhysicsHelper::cpv2point(cpCircleShapeGetOffset(shape));
Point seg[4] = {};
seg[0] = Point(centre.x - radius, centre.y - radius);
seg[1] = Point(centre.x - radius, centre.y + radius);
seg[2] = Point(centre.x + radius, centre.y + radius);
seg[3] = Point(centre.x + radius, centre.y - radius);
node->drawPolygon(seg, 4, Color4F(), 1, Color4F(1, 0, 0, 1));
break;
}
case CP_SEGMENT_SHAPE:
{
cpSegmentShape *seg = (cpSegmentShape *)shape;
node->drawSegment(PhysicsHelper::cpv2point(seg->ta),
PhysicsHelper::cpv2point(seg->tb),
PhysicsHelper::cpfloat2float(seg->r==0 ? 1 : seg->r), Color4F(1, 0, 0, 1));
break;
}
case CP_POLY_SHAPE:
{
cpPolyShape* poly = (cpPolyShape*)shape;
int num = poly->numVerts;
Point* seg = new Point[num];
PhysicsHelper::cpvs2points(poly->tVerts, seg, num);
node->drawPolygon(seg, num, Color4F(1, 0, 0, 0.3), 1, Color4F(1, 0, 0, 1));
delete[] seg;
break;
}
default:
break;
}
}
}
int PhysicsWorld::collisionBeginCallback(const PhysicsContact& contact)
{
if (_delegate)
{
return _delegate->onContactBegin(contact);
}
return true;
}
int PhysicsWorld::collisionPreSolveCallback(const PhysicsContact& contact, const PhysicsContactPreSolve& solve)
{
if (_delegate)
{
return _delegate->onContactPreSolve(contact, solve);
}
return true;
}
void PhysicsWorld::collisionPostSolveCallback(const PhysicsContact& contact, const PhysicsContactPostSolve& solve)
{
if (_delegate)
{
_delegate->onContactPostSove(contact, solve);
}
}
void PhysicsWorld::collisionSeparateCallback(const PhysicsContact& contact)
{
if (_delegate)
{
_delegate->onContactEnd(contact);
}
}
#elif (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D)
struct PhysicsInfo
{
};
#endif
PhysicsWorld* PhysicsWorld::create()
@ -83,16 +297,25 @@ PhysicsWorld* PhysicsWorld::create()
}
PhysicsWorld::PhysicsWorld()
: _gravity(Point(0, -9.8))
, _speed(1.0)
, _worldInfo(nullptr)
: _gravity(Point(0.0f, -98.0f))
, _speed(1.0f)
, _info(nullptr)
, _delegate(nullptr)
, _bodys(nullptr)
, _scene(nullptr)
, _debugDraw(false)
, _drawNode(nullptr)
{
}
PhysicsWorld::~PhysicsWorld()
{
CC_SAFE_DELETE(_worldInfo);
CC_SAFE_DELETE(_info);
CC_SAFE_RELEASE(_bodys);
CC_SAFE_RELEASE(_scene);
}
NS_CC_END
#endif // CC_USE_PHYSICS

View File

@ -36,10 +36,26 @@ NS_CC_BEGIN
class PhysicsBody;
class PhysicsJoint;
class PhysicsWorldInfo;
class PhysicsShape;
class PhysicsContact;
class PhysicsContactPreSolve;
class PhysicsContactPostSolve;
class PhysicsContactDelegate;
class Array;
class Sprite;
class Scene;
class DrawNode;
namespace PhysicsInnerCallbackFunctions
{
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
int collisionBeginCallbackFunc(cpArbiter *arb, struct cpSpace *space, void *data);
int collisionPreSolveCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
void collisionPostSolveCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
void collisionSeparateCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
#endif
}
class PhysicsWorld
{
@ -53,21 +69,46 @@ public:
Array* getBodysInRect(Rect rect) const;
Array* getAllBody() const;
void registerContactDelegate(PhysicsContactDelegate* delegate);
inline void registerContactDelegate(PhysicsContactDelegate* delegate) { _delegate = delegate; }
inline void unregisterContactDelegate() { _delegate = nullptr; }
inline Point getGravity() { return _gravity; }
inline void setGravity(Point gravity) { _gravity = gravity; }
inline bool getDebugDraw() { return _debugDraw; }
inline void setDebugDraw(bool debugDraw) { _debugDraw = debugDraw; }
protected:
static PhysicsWorld* create();
bool init();
void setScene(Scene* scene);
virtual void addChild(PhysicsBody* body);
virtual void addShape(PhysicsShape* shape);
virtual void update(float delta);
virtual void debugDraw();
virtual void drawWithShape(DrawNode* node, PhysicsShape* shape);
virtual int collisionBeginCallback(const PhysicsContact& contact);
virtual int collisionPreSolveCallback(const PhysicsContact& contact, const PhysicsContactPreSolve& solve);
virtual void collisionPostSolveCallback(const PhysicsContact& contact, const PhysicsContactPostSolve& solve);
virtual void collisionSeparateCallback(const PhysicsContact& contact);
protected:
Point _gravity;
float _speed;
PhysicsWorldInfo* _info;
PhysicsContactDelegate* _delegate;
PhysicsWorldInfo* _worldInfo;
Array* _bodys;
Scene* _scene;
bool _debugDraw;
DrawNode* _drawNode;
protected:
PhysicsWorld();
@ -75,6 +116,14 @@ protected:
friend class Sprite;
friend class Scene;
friend class PhysicsBody;
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
friend int PhysicsInnerCallbackFunctions::collisionBeginCallbackFunc(cpArbiter *arb, struct cpSpace *space, void *data);
friend int PhysicsInnerCallbackFunctions::collisionPreSolveCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
friend void PhysicsInnerCallbackFunctions::collisionPostSolveCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
friend void PhysicsInnerCallbackFunctions::collisionSeparateCallbackFunc(cpArbiter *arb, cpSpace *space, void *data);
#endif
};
NS_CC_END

View File

@ -0,0 +1,45 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "CCPhysicsBodyInfo.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
NS_CC_BEGIN
PhysicsBodyInfo::PhysicsBodyInfo()
: body(nullptr)
{
}
PhysicsBodyInfo::~PhysicsBodyInfo()
{
if (body) cpBodyFree(body);
}
Clonable* PhysicsBodyInfo::clone() const
{
}
NS_CC_END
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK

View File

@ -22,31 +22,31 @@
THE SOFTWARE.
****************************************************************************/
#include "CCPhysicsSetting.h"
#ifdef CC_USE_PHYSICS
#ifndef __CCPHYSICS_CONTACTDELEGATE_H__
#define __CCPHYSICS_CONTACTDELEGATE_H__
#include "../CCPhysicsSetting.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
#ifndef __CCPHYSICS_BODY_INFO_H__
#define __CCPHYSICS_BODY_INFO_H__
#include "platform/CCPlatformMacros.h"
#include "cocoa/CCObject.h"
#include "cocoa/CCGeometry.h"
NS_CC_BEGIN
class PhysicsBody;
class PhysicsContactDelegate
class PhysicsBodyInfo : public Clonable
{
public:
PhysicsContactDelegate();
virtual ~PhysicsContactDelegate();
cpBody* body;
public:
virtual void onContactBegin(PhysicsBody* bodyA, PhysicsBody* bodyB, float collisionImpulse, Point contactPoint) = 0;
virtual void onContactEnd(PhysicsBody* bodyA, PhysicsBody* bodyB, float collisionImpulse, Point contactPoint) = 0;
private:
PhysicsBodyInfo();
~PhysicsBodyInfo();
Clonable* clone() const override;
friend class PhysicsBody;
};
NS_CC_END
#endif //__CCPHYSICS_CONTACTDELEGATE_H__
#endif // __CCPHYSICS_BODY_INFO_H__
#endif // CC_USE_PHYSICS
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK

View File

@ -0,0 +1,39 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "CCPhysicsContactInfo.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
NS_CC_BEGIN
PhysicsContactInfo::PhysicsContactInfo(PhysicsContact* contact)
: contact(contact)
{
}
PhysicsContactInfo::~PhysicsContactInfo()
{
}
NS_CC_END
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK

View File

@ -0,0 +1,49 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "../CCPhysicsSetting.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
#ifndef __CCPHYSICS_CONTACT_INFO_H__
#define __CCPHYSICS_CONTACT_INFO_H__
#include "platform/CCPlatformMacros.h"
NS_CC_BEGIN
class PhysicsContact;
class PhysicsContactInfo
{
public:
PhysicsContact* contact;
private:
PhysicsContactInfo(PhysicsContact* contact);
~PhysicsContactInfo();
friend class PhysicsContact;
};
NS_CC_END
#endif // __CCPHYSICS_WORLD_INFO_H__
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK

View File

@ -0,0 +1,68 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "../CCPhysicsSetting.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
#ifndef __CCPHYSICS_HELPER_H__
#define __CCPHYSICS_HELPER_H__
#include "platform/CCPlatformMacros.h"
#include "cocoa/CCGeometry.h"
NS_CC_BEGIN
class PhysicsHelper
{
public:
static Point cpv2point(const cpVect& vec) { return Point(vec.x, vec.y); }
static cpVect point2cpv(const Point& point) { return cpv(point.x, point.y); }
static Size cpv2size(const cpVect& vec) { return Size(vec.x, vec.y); }
static cpVect size2cpv(const Size& size) { return cpv(size.width, size.height); }
static float cpfloat2float(cpFloat f) { return f; }
static cpFloat float2cpfloat(float f) { return f; }
static void cpvs2points(const cpVect* cpvs, Point* points, int count)
{
for (int i = 0; i < count; ++i)
{
points[i] = cpv2point(cpvs[i]);
}
}
static cpVect* points2cpvs(const Point* points, cpVect* cpvs, int count)
{
for (int i = 0; i < count; ++i)
{
cpvs[i] = point2cpv(points[i]);
}
return cpvs;
}
};
NS_CC_END
#endif // __CCPHYSICS_HELPER_H__
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK

View File

@ -0,0 +1,43 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "CCPhysicsJointInfo.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
NS_CC_BEGIN
PhysicsJointInfo::PhysicsJointInfo()
: joint(nullptr)
{
}
PhysicsJointInfo::~PhysicsJointInfo()
{
if (joint)
{
cpConstraintFree(joint);
}
}
NS_CC_END
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK

View File

@ -0,0 +1,50 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "../CCPhysicsSetting.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
#ifndef __CCPHYSICS_JOINT_INFO_H__
#define __CCPHYSICS_JOINT_INFO_H__
#include "platform/CCPlatformMacros.h"
NS_CC_BEGIN
class PhysicsJointInfo
{
public:
cpConstraint* joint;
private:
PhysicsJointInfo();
~PhysicsJointInfo();
friend class PhysicsJoint;
};
NS_CC_END
#endif // __CCPHYSICS_SHAPE_INFO_H__
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK

View File

@ -0,0 +1,70 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "CCPhysicsShapeInfo.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
NS_CC_BEGIN
std::map<cpShape*, PhysicsShapeInfo*> PhysicsShapeInfo::map;
PhysicsShapeInfo::PhysicsShapeInfo(PhysicsShape* shape)
: shape(shape)
{
}
PhysicsShapeInfo::~PhysicsShapeInfo()
{
for (auto it = shapes.begin(); it != shapes.end(); it++)
{
cpShapeFree(*it);
auto mit = map.find(*it);
if (mit != map.end()) map.erase(*it);
}
}
void PhysicsShapeInfo::add(cpShape* shape)
{
if (shape == nullptr) return;
shapes.push_back(shape);
map.insert(std::pair<cpShape*, PhysicsShapeInfo*>(shape, this));
}
void PhysicsShapeInfo::remove(cpShape* shape)
{
if (shape == nullptr) return;
auto it = find(shapes.begin(), shapes.end(), shape);
if (it != shapes.end())
{
shapes.erase(it);
auto mit = map.find(shape);
if (mit != map.end()) map.erase(mit);
}
}
NS_CC_END
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK

View File

@ -0,0 +1,61 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "../CCPhysicsSetting.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
#ifndef __CCPHYSICS_SHAPE_INFO_H__
#define __CCPHYSICS_SHAPE_INFO_H__
#include <vector>
#include "platform/CCPlatformMacros.h"
#include <map>
NS_CC_BEGIN
class PhysicsShape;
class PhysicsShapeInfo
{
public:
void add(cpShape* shape);
void remove(cpShape* shape);
void removeall();
public:
std::vector<cpShape*> shapes;
static std::map<cpShape*, PhysicsShapeInfo*> map;
PhysicsShape* shape;
private:
PhysicsShapeInfo(PhysicsShape* shape);
~PhysicsShapeInfo();
friend class PhysicsShape;
};
NS_CC_END
#endif // __CCPHYSICS_SHAPE_INFO_H__
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK

View File

@ -0,0 +1,40 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "CCPhysicsWorldInfo.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
NS_CC_BEGIN
PhysicsWorldInfo::PhysicsWorldInfo()
{
space = cpSpaceNew();
}
PhysicsWorldInfo::~PhysicsWorldInfo()
{
cpSpaceFree(space);
}
NS_CC_END
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK

View File

@ -0,0 +1,48 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
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.
****************************************************************************/
#include "../CCPhysicsSetting.h"
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
#ifndef __CCPHYSICS_WORLD_INFO_H__
#define __CCPHYSICS_WORLD_INFO_H__
#include "platform/CCPlatformMacros.h"
NS_CC_BEGIN
class PhysicsWorldInfo
{
public:
cpSpace* space;
private:
PhysicsWorldInfo();
~PhysicsWorldInfo();
friend class PhysicsWorld;
};
NS_CC_END
#endif // __CCPHYSICS_WORLD_INFO_H__
#endif // CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK

View File

@ -0,0 +1,446 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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.
*/
#include <limits.h>
#include <string.h>
#ifdef __APPLE__
#include "OpenGL/gl.h"
#include "OpenGL/glu.h"
#include <GLUT/glut.h>
#else
#ifdef WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#endif
#include "chipmunk_private.h"
#include "ChipmunkDebugDraw.h"
/*
IMPORTANT - READ ME!
This file sets up a simple interface that the individual demos can use to get
a Chipmunk space running and draw what's in it. In order to keep the Chipmunk
examples clean and simple, they contain no graphics code. All drawing is done
by accessing the Chipmunk structures at a very low level. It is NOT
recommended to write a game or application this way as it does not scale
beyond simple shape drawing and is very dependent on implementation details
about Chipmunk which may change with little to no warning.
*/
const Color LINE_COLOR = {200.0/255.0, 210.0/255.0, 230.0/255.0, 1.0};
const Color CONSTRAINT_COLOR = {0.0, 0.75, 0.0, 1.0};
const float SHAPE_ALPHA = 1.0;
float ChipmunkDebugDrawPointLineScale = 1.0;
static Color
ColorFromHash(cpHashValue hash, float alpha)
{
unsigned long val = (unsigned long)hash;
// scramble the bits up using Robert Jenkins' 32 bit integer hash function
val = (val+0x7ed55d16) + (val<<12);
val = (val^0xc761c23c) ^ (val>>19);
val = (val+0x165667b1) + (val<<5);
val = (val+0xd3a2646c) ^ (val<<9);
val = (val+0xfd7046c5) + (val<<3);
val = (val^0xb55a4f09) ^ (val>>16);
GLfloat r = (val>>0) & 0xFF;
GLfloat g = (val>>8) & 0xFF;
GLfloat b = (val>>16) & 0xFF;
GLfloat max = cpfmax(cpfmax(r, g), b);
GLfloat min = cpfmin(cpfmin(r, g), b);
GLfloat intensity = 0.75;
// Saturate and scale the color
if(min == max){
return RGBAColor(intensity, 0.0, 0.0, alpha);
} else {
GLfloat coef = alpha*intensity/(max - min);
return RGBAColor(
(r - min)*coef,
(g - min)*coef,
(b - min)*coef,
alpha
);
}
}
static inline void
glColor_from_color(Color color){
glColor4fv((GLfloat *)&color);
}
static Color
ColorForShape(cpShape *shape)
{
if(cpShapeGetSensor(shape)){
return LAColor(1, 0);
} else {
cpBody *body = shape->body;
if(cpBodyIsSleeping(body)){
return LAColor(0.2, 1);
} else if(body->node.idleTime > shape->space->sleepTimeThreshold) {
return LAColor(0.66, 1);
} else {
return ColorFromHash(shape->hashid, SHAPE_ALPHA);
}
}
}
static const GLfloat circleVAR[] = {
0.0000f, 1.0000f,
0.2588f, 0.9659f,
0.5000f, 0.8660f,
0.7071f, 0.7071f,
0.8660f, 0.5000f,
0.9659f, 0.2588f,
1.0000f, 0.0000f,
0.9659f, -0.2588f,
0.8660f, -0.5000f,
0.7071f, -0.7071f,
0.5000f, -0.8660f,
0.2588f, -0.9659f,
0.0000f, -1.0000f,
-0.2588f, -0.9659f,
-0.5000f, -0.8660f,
-0.7071f, -0.7071f,
-0.8660f, -0.5000f,
-0.9659f, -0.2588f,
-1.0000f, -0.0000f,
-0.9659f, 0.2588f,
-0.8660f, 0.5000f,
-0.7071f, 0.7071f,
-0.5000f, 0.8660f,
-0.2588f, 0.9659f,
0.0000f, 1.0000f,
0.0f, 0.0f, // For an extra line to see the rotation.
};
static const int circleVAR_count = sizeof(circleVAR)/sizeof(GLfloat)/2;
void ChipmunkDebugDrawCircle(cpVect center, cpFloat angle, cpFloat radius, Color lineColor, Color fillColor)
{
glVertexPointer(2, GL_FLOAT, 0, circleVAR);
glPushMatrix(); {
glTranslatef(center.x, center.y, 0.0f);
glRotatef(angle*180.0f/M_PI, 0.0f, 0.0f, 1.0f);
glScalef(radius, radius, 1.0f);
if(fillColor.a > 0){
glColor_from_color(fillColor);
glDrawArrays(GL_TRIANGLE_FAN, 0, circleVAR_count - 1);
}
if(lineColor.a > 0){
glColor_from_color(lineColor);
glDrawArrays(GL_LINE_STRIP, 0, circleVAR_count);
}
} glPopMatrix();
}
static const GLfloat pillVAR[] = {
0.0000f, 1.0000f, 1.0f,
0.2588f, 0.9659f, 1.0f,
0.5000f, 0.8660f, 1.0f,
0.7071f, 0.7071f, 1.0f,
0.8660f, 0.5000f, 1.0f,
0.9659f, 0.2588f, 1.0f,
1.0000f, 0.0000f, 1.0f,
0.9659f, -0.2588f, 1.0f,
0.8660f, -0.5000f, 1.0f,
0.7071f, -0.7071f, 1.0f,
0.5000f, -0.8660f, 1.0f,
0.2588f, -0.9659f, 1.0f,
0.0000f, -1.0000f, 1.0f,
0.0000f, -1.0000f, 0.0f,
-0.2588f, -0.9659f, 0.0f,
-0.5000f, -0.8660f, 0.0f,
-0.7071f, -0.7071f, 0.0f,
-0.8660f, -0.5000f, 0.0f,
-0.9659f, -0.2588f, 0.0f,
-1.0000f, -0.0000f, 0.0f,
-0.9659f, 0.2588f, 0.0f,
-0.8660f, 0.5000f, 0.0f,
-0.7071f, 0.7071f, 0.0f,
-0.5000f, 0.8660f, 0.0f,
-0.2588f, 0.9659f, 0.0f,
0.0000f, 1.0000f, 0.0f,
};
static const int pillVAR_count = sizeof(pillVAR)/sizeof(GLfloat)/3;
void ChipmunkDebugDrawSegment(cpVect a, cpVect b, Color color)
{
GLfloat verts[] = {
a.x, a.y,
b.x, b.y,
};
glVertexPointer(2, GL_FLOAT, 0, verts);
glColor_from_color(color);
glDrawArrays(GL_LINES, 0, 2);
}
void ChipmunkDebugDrawFatSegment(cpVect a, cpVect b, cpFloat radius, Color lineColor, Color fillColor)
{
if(radius){
glVertexPointer(3, GL_FLOAT, 0, pillVAR);
glPushMatrix(); {
cpVect d = cpvsub(b, a);
cpVect r = cpvmult(d, radius/cpvlength(d));
const GLfloat matrix[] = {
r.x, r.y, 0.0f, 0.0f,
-r.y, r.x, 0.0f, 0.0f,
d.x, d.y, 0.0f, 0.0f,
a.x, a.y, 0.0f, 1.0f,
};
glMultMatrixf(matrix);
if(fillColor.a > 0){
glColor_from_color(fillColor);
glDrawArrays(GL_TRIANGLE_FAN, 0, pillVAR_count);
}
if(lineColor.a > 0){
glColor_from_color(lineColor);
glDrawArrays(GL_LINE_LOOP, 0, pillVAR_count);
}
} glPopMatrix();
} else {
ChipmunkDebugDrawSegment(a, b, lineColor);
}
}
void ChipmunkDebugDrawPolygon(int count, cpVect *verts, Color lineColor, Color fillColor)
{
#if CP_USE_DOUBLES
glVertexPointer(2, GL_DOUBLE, 0, verts);
#else
glVertexPointer(2, GL_FLOAT, 0, verts);
#endif
if(fillColor.a > 0){
glColor_from_color(fillColor);
glDrawArrays(GL_TRIANGLE_FAN, 0, count);
}
if(lineColor.a > 0){
glColor_from_color(lineColor);
glDrawArrays(GL_LINE_LOOP, 0, count);
}
}
void ChipmunkDebugDrawPoints(cpFloat size, int count, cpVect *verts, Color color)
{
#if CP_USE_DOUBLES
glVertexPointer(2, GL_DOUBLE, 0, verts);
#else
glVertexPointer(2, GL_FLOAT, 0, verts);
#endif
glPointSize(size*ChipmunkDebugDrawPointLineScale);
glColor_from_color(color);
glDrawArrays(GL_POINTS, 0, count);
}
void ChipmunkDebugDrawBB(cpBB bb, Color color)
{
cpVect verts[] = {
cpv(bb.l, bb.b),
cpv(bb.l, bb.t),
cpv(bb.r, bb.t),
cpv(bb.r, bb.b),
};
ChipmunkDebugDrawPolygon(4, verts, color, LAColor(0, 0));
}
static void
drawShape(cpShape *shape, void *unused)
{
cpBody *body = shape->body;
Color color = ColorForShape(shape);
switch(shape->klass->type){
case CP_CIRCLE_SHAPE: {
cpCircleShape *circle = (cpCircleShape *)shape;
ChipmunkDebugDrawCircle(circle->tc, body->a, circle->r, LINE_COLOR, color);
break;
}
case CP_SEGMENT_SHAPE: {
cpSegmentShape *seg = (cpSegmentShape *)shape;
ChipmunkDebugDrawFatSegment(seg->ta, seg->tb, seg->r, LINE_COLOR, color);
break;
}
case CP_POLY_SHAPE: {
cpPolyShape *poly = (cpPolyShape *)shape;
ChipmunkDebugDrawPolygon(poly->numVerts, poly->tVerts, LINE_COLOR, color);
break;
}
default: break;
}
}
void ChipmunkDebugDrawShape(cpShape *shape)
{
drawShape(shape, NULL);
}
void ChipmunkDebugDrawShapes(cpSpace *space)
{
cpSpaceEachShape(space, drawShape, NULL);
}
static const GLfloat springVAR[] = {
0.00f, 0.0f,
0.20f, 0.0f,
0.25f, 3.0f,
0.30f,-6.0f,
0.35f, 6.0f,
0.40f,-6.0f,
0.45f, 6.0f,
0.50f,-6.0f,
0.55f, 6.0f,
0.60f,-6.0f,
0.65f, 6.0f,
0.70f,-3.0f,
0.75f, 6.0f,
0.80f, 0.0f,
1.00f, 0.0f,
};
static const int springVAR_count = sizeof(springVAR)/sizeof(GLfloat)/2;
static void
drawSpring(cpDampedSpring *spring, cpBody *body_a, cpBody *body_b)
{
cpVect a = cpvadd(body_a->p, cpvrotate(spring->anchr1, body_a->rot));
cpVect b = cpvadd(body_b->p, cpvrotate(spring->anchr2, body_b->rot));
cpVect points[] = {a, b};
ChipmunkDebugDrawPoints(5, 2, points, CONSTRAINT_COLOR);
cpVect delta = cpvsub(b, a);
glVertexPointer(2, GL_FLOAT, 0, springVAR);
glPushMatrix(); {
GLfloat x = a.x;
GLfloat y = a.y;
GLfloat cos = delta.x;
GLfloat sin = delta.y;
GLfloat s = 1.0f/cpvlength(delta);
const GLfloat matrix[] = {
cos, sin, 0.0f, 0.0f,
-sin*s, cos*s, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
x, y, 0.0f, 1.0f,
};
glMultMatrixf(matrix);
glDrawArrays(GL_LINE_STRIP, 0, springVAR_count);
} glPopMatrix();
}
static void
drawConstraint(cpConstraint *constraint, void *unused)
{
cpBody *body_a = constraint->a;
cpBody *body_b = constraint->b;
const cpConstraintClass *klass = constraint->klass;
if(klass == cpPinJointGetClass()){
cpPinJoint *joint = (cpPinJoint *)constraint;
cpVect a = cpvadd(body_a->p, cpvrotate(joint->anchr1, body_a->rot));
cpVect b = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot));
cpVect points[] = {a, b};
ChipmunkDebugDrawPoints(5, 2, points, CONSTRAINT_COLOR);
ChipmunkDebugDrawSegment(a, b, CONSTRAINT_COLOR);
} else if(klass == cpSlideJointGetClass()){
cpSlideJoint *joint = (cpSlideJoint *)constraint;
cpVect a = cpvadd(body_a->p, cpvrotate(joint->anchr1, body_a->rot));
cpVect b = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot));
cpVect points[] = {a, b};
ChipmunkDebugDrawPoints(5, 2, points, CONSTRAINT_COLOR);
ChipmunkDebugDrawSegment(a, b, CONSTRAINT_COLOR);
} else if(klass == cpPivotJointGetClass()){
cpPivotJoint *joint = (cpPivotJoint *)constraint;
cpVect a = cpvadd(body_a->p, cpvrotate(joint->anchr1, body_a->rot));
cpVect b = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot));
cpVect points[] = {a, b};
ChipmunkDebugDrawPoints(10, 2, points, CONSTRAINT_COLOR);
} else if(klass == cpGrooveJointGetClass()){
cpGrooveJoint *joint = (cpGrooveJoint *)constraint;
cpVect a = cpvadd(body_a->p, cpvrotate(joint->grv_a, body_a->rot));
cpVect b = cpvadd(body_a->p, cpvrotate(joint->grv_b, body_a->rot));
cpVect c = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot));
ChipmunkDebugDrawPoints(5, 1, &c, CONSTRAINT_COLOR);
ChipmunkDebugDrawSegment(a, b, CONSTRAINT_COLOR);
} else if(klass == cpDampedSpringGetClass()){
drawSpring((cpDampedSpring *)constraint, body_a, body_b);
}
}
void ChipmunkDebugDrawConstraint(cpConstraint *constraint)
{
drawConstraint(constraint, NULL);
}
void ChipmunkDebugDrawConstraints(cpSpace *space)
{
cpSpaceEachConstraint(space, drawConstraint, NULL);
}
void ChipmunkDebugDrawCollisionPoints(cpSpace *space)
{
cpArray *arbiters = space->arbiters;
glColor3f(1.0f, 0.0f, 0.0f);
glPointSize(4.0f*ChipmunkDebugDrawPointLineScale);
glBegin(GL_POINTS); {
for(int i=0; i<arbiters->num; i++){
cpArbiter *arb = (cpArbiter*)arbiters->arr[i];
for(int j=0; j<arb->numContacts; j++){
cpVect v = arb->contacts[j].p;
glVertex2f(v.x, v.y);
}
}
} glEnd();
}

View File

@ -0,0 +1,50 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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.
*/
typedef struct Color {
float r, g, b, a;
} Color;
static inline Color RGBAColor(float r, float g, float b, float a){
Color color = {r, g, b, a};
return color;
}
static inline Color LAColor(float l, float a){
Color color = {l, l, l, a};
return color;
}
extern float ChipmunkDebugDrawPointLineScale;
void ChipmunkDebugDrawCircle(cpVect center, cpFloat angle, cpFloat radius, Color lineColor, Color fillColor);
void ChipmunkDebugDrawSegment(cpVect a, cpVect b, Color color);
void ChipmunkDebugDrawFatSegment(cpVect a, cpVect b, cpFloat radius, Color lineColor, Color fillColor);
void ChipmunkDebugDrawPolygon(int count, cpVect *verts, Color lineColor, Color fillColor);
void ChipmunkDebugDrawPoints(cpFloat size, int count, cpVect *verts, Color color);
void ChipmunkDebugDrawBB(cpBB bb, Color color);
void ChipmunkDebugDrawConstraint(cpConstraint *constraint);
void ChipmunkDebugDrawShape(cpShape *shape);
void ChipmunkDebugDrawShapes(cpSpace *space);
void ChipmunkDebugDrawConstraints(cpSpace *space);
void ChipmunkDebugDrawCollisionPoints(cpSpace *space);

View File

@ -296,13 +296,18 @@ Sprite* Sprite::initWithCGImage(CGImageRef pImage, const char *pszKey)
Sprite::Sprite(void)
: _shouldBeHidden(false)
, _texture(nullptr)
#ifdef CC_USE_PHYSICS
, _physicsBody(nullptr)
#endif
{
}
Sprite::~Sprite(void)
{
CC_SAFE_RELEASE(_texture);
#ifdef CC_USE_PHYSICS
CC_SAFE_RELEASE(_physicsBody);
#endif
}
void Sprite::setTextureRect(const Rect& rect)
@ -447,16 +452,6 @@ void Sprite::setTextureCoords(Rect rect)
}
}
void Sprite::setPhysicsBody(PhysicsBody* body)
{
_physicsBody = body;
}
PhysicsBody* Sprite::getPhysicsBody() const
{
return _physicsBody;
}
void Sprite::updateTransform(void)
{
CCASSERT(_batchNode, "updateTransform is only valid when Sprite is being rendered using an SpriteBatchNode");
@ -795,12 +790,27 @@ void Sprite::setPosition(const Point& pos)
{
Node::setPosition(pos);
SET_DIRTY_RECURSIVELY();
#ifdef CC_USE_PHYSICS
if (_physicsBody)
{
_physicsBody->setPosition(pos);
}
#endif
}
void Sprite::setRotation(float fRotation)
void Sprite::setRotation(float rotation)
{
Node::setRotation(fRotation);
Node::setRotation(rotation);
SET_DIRTY_RECURSIVELY();
#ifdef CC_USE_PHYSICS
if (_physicsBody)
{
_physicsBody->setRotation(rotation);
}
#endif
}
void Sprite::setRotationX(float fRotationX)
@ -897,6 +907,33 @@ bool Sprite::isFlipY(void) const
return _flipY;
}
#ifdef CC_USE_PHYSICS
void Sprite::setPhysicsBody(PhysicsBody* body)
{
_physicsBody = body;
_physicsBody->retain();
_physicsBody->setPosition(getPosition());
_physicsBody->setRotation(getRotation());
}
PhysicsBody* Sprite::getPhysicsBody() const
{
return _physicsBody;
}
void Sprite::visit()
{
if (_physicsBody)
{
Node::setPosition(_physicsBody->getPosition());
Node::setRotation(_physicsBody->getRotation());
SET_DIRTY_RECURSIVELY();
}
Node::visit();
}
#endif //CC_USE_PHYSICS
//
// RGBA protocol
//

View File

@ -454,6 +454,8 @@ public:
* get the PhysicsBody the sprite have
*/
PhysicsBody* getPhysicsBody() const;
virtual void visit() override;
#endif
/// @} End of Sprite properties getter/setters

View File

@ -1,25 +1,42 @@
#include "PhysicsTest.h"
#include "../testResource.h"
#include "cocos-ext.h"
USING_NS_CC_EXT;
USING_NS_CC;
PhysicsTestLayer::PhysicsTestLayer()
: _spriteTexture(NULL)
{
#ifdef CC_USE_PHYSICS
//Set up sprite
#if 1
// Use batch node. Faster
auto parent = SpriteBatchNode::create("Images/blocks.png", 100);
setTouchEnabled(true);
setAccelerometerEnabled(true);
// title
auto label = LabelTTF::create("Multi touch the screen", "Marker Felt", 36);
label->setPosition(Point( VisibleRect::center().x, VisibleRect::top().y - 30));
this->addChild(label, -1);
// menu for debug layer
MenuItemFont::setFontSize(18);
auto item = MenuItemFont::create("Toggle debug", CC_CALLBACK_1(PhysicsTestLayer::toggleDebugCallback, this));
auto menu = Menu::create(item, NULL);
this->addChild(menu);
menu->setPosition(Point(VisibleRect::right().x-100, VisibleRect::top().y-60));
auto sp = Sprite::create();
auto body = PhysicsBody::createEdgeBox(VisibleRect::getVisibleRect().size);
sp->setPhysicsBody(body);
this->addChild(sp);
sp->setPosition(VisibleRect::center());
auto parent = SpriteBatchNode::create("Images/grossini_dance_atlas.png", 100);
_spriteTexture = parent->getTexture();
#else
// doesn't use batch node. Slower
_spriteTexture = TextureCache::getInstance()->addImage("Images/blocks.png");
auto parent = Node::create();
#endif
addNewSpriteAtPosition(VisibleRect::center());
createResetButton();
#else
auto label = LabelTTF::create("Should define CC_ENABLE_BOX2D_INTEGRATION=1\n to run this test case",
auto label = LabelTTF::create("Should define CC_USE_BOX2D or CC_USE_CHIPMUNK\n to run this test case",
"Arial",
18);
auto size = Director::getInstance()->getWinSize();
@ -29,11 +46,18 @@ PhysicsTestLayer::PhysicsTestLayer()
#endif
}
PhysicsTestLayer::~PhysicsTestLayer()
void PhysicsTestLayer::toggleDebugCallback(Object* sender)
{
#ifdef CC_USE_PHYSICS
if (dynamic_cast<Scene*>(this->getParent()) != nullptr)
{
PhysicsWorld* world = dynamic_cast<Scene*>(this->getParent())->getPhysicsWorld();
world->setDebugDraw(!world->getDebugDraw());
}
#endif
}
void PhysicsTestLayer::initPhysics()
PhysicsTestLayer::~PhysicsTestLayer()
{
}
@ -41,6 +65,7 @@ void PhysicsTestLayer::createResetButton()
{
auto reset = MenuItemImage::create("Images/r1.png", "Images/r2.png", [](Object *sender) {
auto s = new PhysicsTestScene();
s->initTest();
auto child = new PhysicsTestLayer();
s->addChild(child);
child->release();
@ -55,37 +80,13 @@ void PhysicsTestLayer::createResetButton()
}
void PhysicsTestLayer::addNewSpriteAtPosition(Point p)
{
CCLOG("Add sprite %0.2f x %02.f",p.x,p.y);
#if CC_ENABLE_BOX2D_INTEGRATION
auto parent = this->getChildByTag(kTagParentNode);
//We have a 64x64 sprite sheet with 4 different 32x32 images. The following code is
//just randomly picking one of the images
int idx = (CCRANDOM_0_1() > .5 ? 0:1);
int idy = (CCRANDOM_0_1() > .5 ? 0:1);
auto sprite = PhysicsSprite::createWithTexture(_spriteTexture,Rect(32 * idx,32 * idy,32,32));
parent->addChild(sprite);
sprite->setB2Body(body);
sprite->setPTMRatio(PTM_RATIO);
sprite->setPosition( Point( p.x, p.y) );
#endif
}
void PhysicsTestLayer::ccTouchesEnded(Set* touches, Event* event)
{
//Add a new body/atlas sprite at the touched location
SetIterator it;
Touch* touch;
for( it = touches->begin(); it != touches->end(); it++)
for( auto &item: *touches)
{
touch = static_cast<Touch*>(*it);
if(!touch)
break;
auto touch = static_cast<Touch*>(item);
auto location = touch->getLocation();
@ -93,9 +94,40 @@ void PhysicsTestLayer::ccTouchesEnded(Set* touches, Event* event)
}
}
void PhysicsTestLayer::addNewSpriteAtPosition(Point p)
{
#ifdef CC_USE_PHYSICS
CCLOG("Add sprite %0.2f x %02.f",p.x,p.y);
int posx, posy;
posx = CCRANDOM_0_1() * 200.0f;
posy = CCRANDOM_0_1() * 200.0f;
posx = (posx % 4) * 85;
posy = (posy % 3) * 121;
auto sp = Sprite::createWithTexture(_spriteTexture, Rect(posx, posy, 85, 121));
auto body = PhysicsBody::createBox(Size(48, 108));
sp->setPhysicsBody(body);
sp->setPosition(p);
this->addChild(sp);
#endif
}
bool PhysicsTestScene::initTest()
{
return TestScene::initWithPhysics();
#ifdef CC_USE_PHYSICS
if (TestScene::initWithPhysics())
{
this->getPhysicsWorld()->setDebugDraw(true);
return true;
}
#else
return TestScene::init();
#endif
return false;
}
void PhysicsTestScene::runThisTest()

View File

@ -11,10 +11,10 @@ class PhysicsTestLayer : public Layer
public:
PhysicsTestLayer();
~PhysicsTestLayer();
void initPhysics();
void createResetButton();
void toggleDebugCallback(Object* sender);
void addNewSpriteAtPosition(Point p);
virtual void ccTouchesEnded(Set* touches, Event* event);
} ;