void PhysicsWorld::removeJoint(PhysicsJoint* joint, bool destroy)
{
    if (joint)
    {
        if (joint->getWorld() != this && destroy)
        {
            CCLOG("physics warning: the joint is not in this world, it won't be destroyed until the body it connects is destroyed");
            return;
        }

        joint->_destoryMark = destroy;

        bool removedFromDelayAdd = false;
        auto it = std::find(_delayAddJoints.begin(), _delayAddJoints.end(), joint);
        if (it != _delayAddJoints.end())
        {
            _delayAddJoints.erase(it);
            removedFromDelayAdd = true;
        }

        if (cpSpaceIsLocked(_cpSpace))
        {
            if (removedFromDelayAdd)
                return;
            if (std::find(_delayRemoveJoints.rbegin(), _delayRemoveJoints.rend(), joint) == _delayRemoveJoints.rend())
            {
                _delayRemoveJoints.push_back(joint);
            }
        }
        else
        {
            doRemoveJoint(joint);
        }
    }
}
void PhysicsWorld::updateJoints()
{
    if (cpSpaceIsLocked(_cpSpace))
    {
        return;
    }
    
    for (auto joint : _delayAddJoints)
    {
        joint->_world = this;
        if (joint->initJoint())
        {
            _joints.push_back(joint);
        }
        else
        {
            delete joint;
        }
    }
    _delayAddJoints.clear();

    for (auto joint : _delayRemoveJoints)
    {
        doRemoveJoint(joint);
    }
    _delayRemoveJoints.clear();
}
		bool shape::removeFromSpace( void )
		{
			if( this->m_space == NULL ) return false;
			if( cpSpaceIsLocked( this->m_space ) == cpTrue ) return false;
			cpSpaceRemoveShape( this->m_space, this->m_shape );
			this->m_space = NULL;
		}
		bool shape::addToSpace( cpSpace *space )
		{
			if( space == NULL ) return false;
			if( cpSpaceIsLocked( space ) == cpTrue ) return false;
			this->m_space = space;
			cpSpaceAddShape( space, this->m_shape );
			return true;
		}
示例#5
0
static cpBody *
rb_cpBodySleepValidate(VALUE vbody) {
  cpBody * body  = BODY(vbody);
  cpSpace *space = body->CP_PRIVATE(space);
  if(!space) {
    rb_raise(rb_eArgError, "Cannot put a body to sleep that has not been added to a space.");
    return NULL;
  }
  if (cpBodyIsStatic(body) && cpBodyIsRogue(body)) {
    rb_raise(rb_eArgError, "Rogue AND static bodies cannot be put to sleep.");
    return NULL;
  }
  if(cpSpaceIsLocked(space)) {
    rb_raise(rb_eArgError, "Bodies can not be put to sleep during a query or a call to Space#add_collision_func. Put these calls into a post-step callback using Space#add_collision_handler.");
    return NULL;
  }
  return body;
}
void PhysicsWorld::removeBodyOrDelay(PhysicsBody* body)
{
    if (_delayAddBodies.getIndex(body) != CC_INVALID_INDEX)
    {
        _delayAddBodies.eraseObject(body);
        return;
    }
    
    if (cpSpaceIsLocked(_cpSpace))
    {
        if (_delayRemoveBodies.getIndex(body) == CC_INVALID_INDEX)
        {
            _delayRemoveBodies.pushBack(body);
        }
    }else
    {
        doRemoveBody(body);
    }
}
void PhysicsWorld::updateBodies()
{
    if (cpSpaceIsLocked(_cpSpace))
    {
        return;
    }
    
    // issue #4944, contact callback will be invoked when add/remove body, _delayAddBodies maybe changed, so we need make a copy.
    auto addCopy = _delayAddBodies;
    _delayAddBodies.clear();
    for (auto& body : addCopy)
    {
        doAddBody(body);
    }
    
    auto removeCopy = _delayRemoveBodies;
    _delayRemoveBodies.clear();
    for (auto& body : removeCopy)
    {
        doRemoveBody(body);
    }
}