mirror of https://github.com/axmolengine/axmol.git
issue #2771: delay load
This commit is contained in:
parent
00acd67ff3
commit
46710c5f06
|
@ -183,6 +183,12 @@ bool PhysicsWorld::init(Scene& scene)
|
|||
{
|
||||
do
|
||||
{
|
||||
_delayAddBodies = Array::create();
|
||||
_delayRemoveBodies = Array::create();
|
||||
CC_BREAK_IF(_delayAddBodies == nullptr || _delayRemoveBodies == nullptr);
|
||||
_delayAddBodies->retain();
|
||||
_delayRemoveBodies->retain();
|
||||
|
||||
_info = new PhysicsWorldInfo();
|
||||
CC_BREAK_IF(_info == nullptr);
|
||||
_bodies = Array::create();
|
||||
|
@ -206,20 +212,99 @@ bool PhysicsWorld::init(Scene& scene)
|
|||
return false;
|
||||
}
|
||||
|
||||
void PhysicsWorld::delayTestAddBody(PhysicsBody* body)
|
||||
{
|
||||
if (_delayRemoveBodies->getIndexOfObject(body) != UINT_MAX)
|
||||
{
|
||||
_delayRemoveBodies->removeObject(body);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_info->space->locked_private)
|
||||
{
|
||||
if (_delayAddBodies->getIndexOfObject(body) == UINT_MAX)
|
||||
{
|
||||
_delayAddBodies->addObject(body);
|
||||
_delayDirty = true;
|
||||
}
|
||||
}else
|
||||
{
|
||||
realAddBody(body);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::delayTestRemoveBody(PhysicsBody* body)
|
||||
{
|
||||
if (_delayAddBodies->getIndexOfObject(body) != UINT_MAX)
|
||||
{
|
||||
_delayAddBodies->removeObject(body);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_info->space->locked_private)
|
||||
{
|
||||
if (_delayRemoveBodies->getIndexOfObject(body) == UINT_MAX)
|
||||
{
|
||||
_delayRemoveBodies->addObject(body);
|
||||
_delayDirty = true;
|
||||
}
|
||||
}else
|
||||
{
|
||||
realRemoveBody(body);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::delayTestAddJoint(PhysicsJoint* joint)
|
||||
{
|
||||
auto it = std::find(_delayRemoveJoints.begin(), _delayRemoveJoints.end(), joint);
|
||||
if (it != _delayRemoveJoints.end())
|
||||
{
|
||||
_delayRemoveJoints.erase(it);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_info->space->locked_private)
|
||||
{
|
||||
if (std::find(_delayAddJoints.begin(), _delayAddJoints.end(), joint) == _delayAddJoints.end())
|
||||
{
|
||||
_delayAddJoints.push_back(joint);
|
||||
_delayDirty = true;
|
||||
}
|
||||
}else
|
||||
{
|
||||
realAddJoint(joint);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::delayTestRemoveJoint(PhysicsJoint* joint)
|
||||
{
|
||||
auto it = std::find(_delayAddJoints.begin(), _delayAddJoints.end(), joint);
|
||||
if (it != _delayAddJoints.end())
|
||||
{
|
||||
_delayAddJoints.erase(it);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_info->space->locked_private)
|
||||
{
|
||||
if (std::find(_delayRemoveJoints.begin(), _delayRemoveJoints.end(), joint) == _delayRemoveJoints.end())
|
||||
{
|
||||
_delayRemoveJoints.push_back(joint);
|
||||
_delayDirty = true;
|
||||
}
|
||||
}else
|
||||
{
|
||||
realRemoveJoint(joint);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::addJoint(PhysicsJoint* joint)
|
||||
{
|
||||
auto it = std::find(_joints.begin(), _joints.end(), joint);
|
||||
|
||||
if (it == _joints.end())
|
||||
{
|
||||
for (auto subjoint : joint->_info->joints)
|
||||
{
|
||||
if (!cpSpaceContainsConstraint(_info->space, subjoint))
|
||||
{
|
||||
cpSpaceAddConstraint(_info->space, subjoint);
|
||||
}
|
||||
}
|
||||
|
||||
delayTestAddJoint(joint);
|
||||
_joints.push_back(joint);
|
||||
}
|
||||
|
||||
|
@ -231,14 +316,7 @@ void PhysicsWorld::removeJoint(PhysicsJoint* joint)
|
|||
|
||||
if (it != _joints.end())
|
||||
{
|
||||
for (auto subjoint : joint->_info->joints)
|
||||
{
|
||||
if (cpSpaceContainsConstraint(_info->space, subjoint))
|
||||
{
|
||||
cpSpaceRemoveConstraint(_info->space, subjoint);
|
||||
}
|
||||
}
|
||||
|
||||
delayTestRemoveJoint(*it);
|
||||
_joints.remove(joint);
|
||||
}
|
||||
}
|
||||
|
@ -247,13 +325,7 @@ void PhysicsWorld::removeAllJoints()
|
|||
{
|
||||
for (auto joint : _joints)
|
||||
{
|
||||
for (auto subjoint : joint->_info->joints)
|
||||
{
|
||||
if (!cpSpaceContainsConstraint(_info->space, subjoint))
|
||||
{
|
||||
cpSpaceRemoveConstraint(_info->space, subjoint);
|
||||
}
|
||||
}
|
||||
delayTestRemoveJoint(joint);
|
||||
}
|
||||
|
||||
_joints.clear();
|
||||
|
@ -263,28 +335,22 @@ PhysicsShape* PhysicsWorld::addShape(PhysicsShape* shape)
|
|||
{
|
||||
for (auto cps : shape->_info->shapes)
|
||||
{
|
||||
if (cpSpaceContainsShape(_info->space, cps))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cpBodyIsStatic(shape->getBody()->_info->body))
|
||||
{
|
||||
cpSpaceAddStaticShape(_info->space, cps);
|
||||
}
|
||||
else
|
||||
{
|
||||
cpSpaceAddShape(_info->space, cps);
|
||||
}
|
||||
_info->addShape(cps);
|
||||
}
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
PhysicsBody* PhysicsWorld::addBody(PhysicsBody* body)
|
||||
void PhysicsWorld::realAddJoint(PhysicsJoint *joint)
|
||||
{
|
||||
for (auto subjoint : joint->_info->joints)
|
||||
{
|
||||
_info->addJoint(subjoint);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::realAddBody(PhysicsBody* body)
|
||||
{
|
||||
CCASSERT(body != nullptr, "the body can not be nullptr");
|
||||
|
||||
if (body->getWorld() != this && body->getWorld() != nullptr)
|
||||
{
|
||||
body->removeFromWorld();
|
||||
|
@ -303,7 +369,7 @@ PhysicsBody* PhysicsWorld::addBody(PhysicsBody* body)
|
|||
// add body to space
|
||||
if (body->isDynamic())
|
||||
{
|
||||
cpSpaceAddBody(_info->space, body->_info->body);
|
||||
_info->addBody(body->_info->body);
|
||||
}
|
||||
|
||||
// add shapes to space
|
||||
|
@ -312,13 +378,38 @@ PhysicsBody* PhysicsWorld::addBody(PhysicsBody* body)
|
|||
addShape(dynamic_cast<PhysicsShape*>(shape));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PhysicsBody* PhysicsWorld::addBody(PhysicsBody* body)
|
||||
{
|
||||
CCASSERT(body != nullptr, "the body can not be nullptr");
|
||||
|
||||
delayTestAddBody(body);
|
||||
_bodies->addObject(body);
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeBody(PhysicsBody* body)
|
||||
{
|
||||
delayTestRemoveBody(body);
|
||||
_bodies->removeObject(body);
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeBodyByTag(int tag)
|
||||
{
|
||||
for (Object* obj : *_bodies)
|
||||
{
|
||||
PhysicsBody* body = dynamic_cast<PhysicsBody*>(obj);
|
||||
if (body->getTag() == tag)
|
||||
{
|
||||
removeBody(body);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::realRemoveBody(PhysicsBody* body)
|
||||
{
|
||||
CCASSERT(body != nullptr, "the body can not be nullptr");
|
||||
|
||||
|
@ -346,25 +437,16 @@ void PhysicsWorld::removeBody(PhysicsBody* body)
|
|||
}
|
||||
|
||||
// remove body
|
||||
if (cpSpaceContainsBody(_info->space, body->_info->body))
|
||||
{
|
||||
cpSpaceRemoveBody(_info->space, body->_info->body);
|
||||
}
|
||||
_info->removeBody(body->_info->body);
|
||||
|
||||
body->_world = nullptr;
|
||||
_bodies->removeObject(body);
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeBodyByTag(int tag)
|
||||
void PhysicsWorld::realRemoveJoint(PhysicsJoint* joint)
|
||||
{
|
||||
for (Object* obj : *_bodies)
|
||||
for (auto subjoint : joint->_info->joints)
|
||||
{
|
||||
PhysicsBody* body = dynamic_cast<PhysicsBody*>(obj);
|
||||
if (body->getTag() == tag)
|
||||
{
|
||||
removeBody(body);
|
||||
return;
|
||||
}
|
||||
_info->removeJoint(subjoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -372,33 +454,7 @@ void PhysicsWorld::removeAllBodies()
|
|||
{
|
||||
for (Object* obj : *_bodies)
|
||||
{
|
||||
PhysicsBody* body = dynamic_cast<PhysicsBody*>(obj);
|
||||
|
||||
// reset the gravity
|
||||
if (!body->isGravityEnable())
|
||||
{
|
||||
body->applyForce(-_gravity);
|
||||
}
|
||||
|
||||
// remove joints
|
||||
for (auto joint : body->_joints)
|
||||
{
|
||||
removeJoint(joint);
|
||||
}
|
||||
|
||||
// remove shaps
|
||||
for (auto shape : *body->getShapes())
|
||||
{
|
||||
removeShape(dynamic_cast<PhysicsShape*>(shape));
|
||||
}
|
||||
|
||||
// remove body
|
||||
if (cpSpaceContainsBody(_info->space, body->_info->body))
|
||||
{
|
||||
cpSpaceRemoveBody(_info->space, body->_info->body);
|
||||
}
|
||||
|
||||
body->_world = nullptr;
|
||||
delayTestRemoveBody(dynamic_cast<PhysicsBody*>(obj));
|
||||
}
|
||||
|
||||
_bodies->removeAllObjects();
|
||||
|
@ -416,8 +472,57 @@ void PhysicsWorld::removeShape(PhysicsShape* shape)
|
|||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::updateBodies()
|
||||
{
|
||||
if (_info->space->locked_private)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto body : *_delayAddBodies)
|
||||
{
|
||||
realAddBody(dynamic_cast<PhysicsBody*>(body));
|
||||
}
|
||||
|
||||
for (auto body : *_delayRemoveBodies)
|
||||
{
|
||||
realRemoveBody(dynamic_cast<PhysicsBody*>(body));
|
||||
}
|
||||
|
||||
_delayAddBodies->removeAllObjects();
|
||||
_delayRemoveBodies->removeAllObjects();
|
||||
}
|
||||
|
||||
void PhysicsWorld::updateJoints()
|
||||
{
|
||||
if (_info->space->locked_private)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto joint : _delayAddJoints)
|
||||
{
|
||||
realAddJoint(joint);
|
||||
}
|
||||
|
||||
for (auto joint : _delayRemoveJoints)
|
||||
{
|
||||
realRemoveJoint(joint);
|
||||
}
|
||||
|
||||
_delayAddJoints.clear();
|
||||
_delayRemoveJoints.clear();
|
||||
}
|
||||
|
||||
void PhysicsWorld::update(float delta)
|
||||
{
|
||||
if (_delayDirty)
|
||||
{
|
||||
updateBodies();
|
||||
updateJoints();
|
||||
_delayDirty = !(_delayAddBodies->count() == 0 && _delayRemoveBodies->count() == 0 && _delayAddJoints.size() == 0 && _delayRemoveJoints.size() == 0);
|
||||
}
|
||||
|
||||
for (auto body : *_bodies)
|
||||
{
|
||||
body->update(delta);
|
||||
|
@ -804,8 +909,11 @@ PhysicsWorld::PhysicsWorld()
|
|||
, _info(nullptr)
|
||||
, _bodies(nullptr)
|
||||
, _scene(nullptr)
|
||||
, _delayDirty(false)
|
||||
, _debugDraw(false)
|
||||
, _drawNode(nullptr)
|
||||
, _delayAddBodies(nullptr)
|
||||
, _delayRemoveBodies(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -814,6 +922,8 @@ PhysicsWorld::~PhysicsWorld()
|
|||
{
|
||||
removeAllBodies();
|
||||
removeAllJoints();
|
||||
CC_SAFE_RELEASE(_delayRemoveBodies);
|
||||
CC_SAFE_RELEASE(_delayAddBodies);
|
||||
CC_SAFE_DELETE(_info);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#define __CCPHYSICS_WORLD_H__
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include "CCObject.h"
|
||||
#include "CCGeometry.h"
|
||||
|
@ -86,11 +87,15 @@ class PhysicsWorld
|
|||
{
|
||||
public:
|
||||
/** Adds a joint to the physics world.*/
|
||||
void addJoint(PhysicsJoint* joint);
|
||||
virtual void addJoint(PhysicsJoint* joint);
|
||||
/** Removes a joint from the physics world.*/
|
||||
void removeJoint(PhysicsJoint* joint);
|
||||
virtual void removeJoint(PhysicsJoint* joint);
|
||||
/** Remove all joints from the physics world.*/
|
||||
void removeAllJoints();
|
||||
virtual void removeAllJoints();
|
||||
|
||||
virtual void removeBody(PhysicsBody* body);
|
||||
virtual void removeBodyByTag(int tag);
|
||||
virtual void removeAllBodies();
|
||||
|
||||
void rayCast(PhysicsRayCastCallback& callback, Point point1, Point point2, void* data);
|
||||
void rectQuery(PhysicsRectQueryCallback& callback, Rect rect, void* data);
|
||||
|
@ -115,10 +120,6 @@ public:
|
|||
/** set the debug draw */
|
||||
inline void setDebugDraw(bool debugDraw) { _debugDraw = debugDraw; }
|
||||
|
||||
virtual void removeBody(PhysicsBody* body);
|
||||
virtual void removeBodyByTag(int tag);
|
||||
virtual void removeAllBodies();
|
||||
|
||||
protected:
|
||||
static PhysicsWorld* create(Scene& scene);
|
||||
bool init(Scene& scene);
|
||||
|
@ -132,25 +133,40 @@ protected:
|
|||
virtual void drawWithShape(DrawNode* node, PhysicsShape* shape);
|
||||
virtual void drawWithJoint(DrawNode* node, PhysicsJoint* joint);
|
||||
|
||||
|
||||
virtual int collisionBeginCallback(PhysicsContact& contact);
|
||||
virtual int collisionPreSolveCallback(PhysicsContact& contact);
|
||||
virtual void collisionPostSolveCallback(PhysicsContact& contact);
|
||||
virtual void collisionSeparateCallback(PhysicsContact& contact);
|
||||
|
||||
virtual void realAddBody(PhysicsBody* body);
|
||||
virtual void realRemoveBody(PhysicsBody* body);
|
||||
virtual void realAddJoint(PhysicsJoint* joint);
|
||||
virtual void realRemoveJoint(PhysicsJoint* joint);
|
||||
virtual void delayTestAddBody(PhysicsBody* body);
|
||||
virtual void delayTestRemoveBody(PhysicsBody* body);
|
||||
virtual void delayTestAddJoint(PhysicsJoint* joint);
|
||||
virtual void delayTestRemoveJoint(PhysicsJoint* joint);
|
||||
virtual void updateBodies();
|
||||
virtual void updateJoints();
|
||||
|
||||
protected:
|
||||
Point _gravity;
|
||||
float _speed;
|
||||
PhysicsWorldInfo* _info;
|
||||
//EventListenerPhysicsContact* _listener;
|
||||
|
||||
Array* _bodies;
|
||||
std::list<PhysicsJoint*> _joints;
|
||||
Scene* _scene;
|
||||
|
||||
bool _delayDirty;
|
||||
bool _debugDraw;
|
||||
DrawNode* _drawNode;
|
||||
|
||||
Array* _delayAddBodies;
|
||||
Array* _delayRemoveBodies;
|
||||
std::vector<PhysicsJoint*> _delayAddJoints;
|
||||
std::vector<PhysicsJoint*> _delayRemoveJoints;
|
||||
|
||||
protected:
|
||||
PhysicsWorld();
|
||||
virtual ~PhysicsWorld();
|
||||
|
|
|
@ -26,6 +26,21 @@
|
|||
#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK)
|
||||
NS_CC_BEGIN
|
||||
|
||||
#define PHYSICS_WORLD_INFO_FUNCTION_IMPLEMENTS(name, type) \
|
||||
void PhysicsWorldInfo::add##name(cp##type* data) \
|
||||
{ \
|
||||
if (!cpSpaceContains##type(space, data)) cpSpaceAdd##type(space, data); \
|
||||
} \
|
||||
\
|
||||
void PhysicsWorldInfo::remove##name(cp##type* data) \
|
||||
{ \
|
||||
if (cpSpaceContains##type(space, data)) cpSpaceRemove##type(space, data); \
|
||||
} \
|
||||
|
||||
PHYSICS_WORLD_INFO_FUNCTION_IMPLEMENTS(Shape, Shape)
|
||||
PHYSICS_WORLD_INFO_FUNCTION_IMPLEMENTS(Body, Body)
|
||||
PHYSICS_WORLD_INFO_FUNCTION_IMPLEMENTS(Joint, Constraint)
|
||||
|
||||
PhysicsWorldInfo::PhysicsWorldInfo()
|
||||
{
|
||||
space = cpSpaceNew();
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "chipmunk.h"
|
||||
#include "CCPlatformMacros.h"
|
||||
#include <vector>
|
||||
NS_CC_BEGIN
|
||||
|
||||
class PhysicsWorldInfo
|
||||
|
@ -37,6 +38,13 @@ class PhysicsWorldInfo
|
|||
public:
|
||||
cpSpace* space;
|
||||
|
||||
void addShape(cpShape* shape);
|
||||
void removeShape(cpShape* shape);
|
||||
void addBody(cpBody* body);
|
||||
void removeBody(cpBody* body);
|
||||
void addJoint(cpConstraint* joint);
|
||||
void removeJoint(cpConstraint* joint);
|
||||
|
||||
private:
|
||||
PhysicsWorldInfo();
|
||||
~PhysicsWorldInfo();
|
||||
|
|
Loading…
Reference in New Issue