void Player::SeparateCollision(cpArbiter *arb, struct cpSpace *space, void *data) { // Get the collision shapes CP_ARBITER_GET_SHAPES(arb, a, b); // Delimit collision types for both shapes if (a->collision_type == COLLISION_TYPE_GO && b->collision_type == COLLISION_TYPE_ACTIVATOR) { // Retrieve the activator object Activator *activator = (Activator*) b->data; // Retrieve the player object Player *player = (Player*) a->data; // Check if the right one is triggering if (player == activator->Owner) { // Delegate switch(activator->ActivatorType) { case ACTIVATOR_TYPE_BOOST: activator->Owner->EndBoost(); break; } } } }
static cpBool stoneAndTruckStrikeSlove(cpArbiter *arb, cpSpace *space, void *ignore) { if (!g_sound_enabled) { return true; } CP_ARBITER_GET_SHAPES(arb, a, b); cpVect stone_v; cpVect truck_v; if (a->collision_type == STONE_COLLISION) { stone_v = a->body->v; truck_v = b->body->v; } else { stone_v = b->body->v; truck_v = a->body->v; } float v_z = sqrtf(pow(stone_v.x - truck_v.x, 2.0f) + pow(stone_v.y - truck_v.y, 2.0f)); if (v_z > V_LIMIT_STONE_TRUCK_STRIKE) ;//playStrikeSound(); return cpTrue; }
void TestColliderDetector::endHit(cpArbiter *arb, cpSpace *space, void *unused) { CP_ARBITER_GET_SHAPES(arb, a, b); CCBone *bone = (CCBone*)a->data; bone->getArmature()->setVisible(true); }
static void blockerSeparate(cpArbiter *arb, cpSpace *space, void *unused) { CP_ARBITER_GET_SHAPES(arb, a, b); Emitter *emitter = (Emitter *) a->data; emitter->blocked--; }
// collision arbiter function static int core_begin_collision ( cpArbiter *arb, cpSpace *space, void *unused ) { CP_ARBITER_GET_SHAPES ( arb, a, b ); ((GameInfo *)space->data)->destroyed_planet = ((BodyInfo *)(b->body->data))->index; cpSpaceAddPostStepCallback (space, (cpPostStepFunc)postStepRemoveBody, b->body, NULL); cpSpaceAddPostStepCallback ( space, (cpPostStepFunc)post_step_game_over, NULL, NULL ); return 0; }
int TestColliderDetector::beginHit(cpArbiter *arb, cpSpace *space, void *unused) { CP_ARBITER_GET_SHAPES(arb, a, b); CCBone *bone = (CCBone*)a->data; bone->getArmature()->setVisible(false); return 0; }
static cpBool blockerBegin(cpArbiter *arb, cpSpace *space, void *unused) { CP_ARBITER_GET_SHAPES(arb, a, b); Emitter *emitter = (Emitter *) a->data; emitter->blocked++; return cpFalse; // Return values from sensors callbacks are ignored, }
int MagneticGripperGrippableCollisionBegin(cpArbiter* pt_arb, cpSpace* pt_space, void* p_data) { /* Get the shapes involved */ CP_ARBITER_GET_SHAPES(pt_arb, ptGripperShape, ptGrippableShape); /* Get a reference to the gripper data */ SDynamics2DEngineGripperData& sGripperData = *reinterpret_cast<SDynamics2DEngineGripperData*>(ptGripperShape->data); /* Get a reference to the gripped entity */ CEmbodiedEntity& cGrippedEntity = *reinterpret_cast<CEmbodiedEntity*>(ptGrippableShape->data); /* If the entities match, ignore the collision forever */ return (sGripperData.GripperEntity.GetId() != cGrippedEntity.GetId()); }
static void BallIterator(cpBody *body, cpArbiter *arb, int *count) { // body is the body we are iterating the arbiters for. // CP_ARBITER_GET_*() in an arbiter iterator always returns the body/shape for the iterated body first. CP_ARBITER_GET_SHAPES(arb, ball, other); ChipmunkDebugDrawBB(cpShapeGetBB(other), RGBAColor(1, 0, 0, 1)); (*count)++; }
int fff::explosive::Begin(cpArbiter *arb, cpSpace *space, void *pengine){ CP_ARBITER_GET_SHAPES(arb, explosiveshape, kittyshape); fff::explosive *explosive = static_cast<fff::explosive *>( cpShapeGetUserData(explosiveshape) ); fff::kitty *kitty = static_cast<fff::kitty *>( cpShapeGetUserData(kittyshape) ); kitty->applyImpulse(explosive->impulse); explosive->setExploding(); game.playExplosion(explosive->soundbuffer, explosive->sprite.GetPosition() ); cpSpaceAddPostStepCallback(space, fff::explosive::postStep, explosiveshape, NULL); game.startTheme(); return 0; }
static cpBool PreSolve(cpArbiter *arb, cpSpace *space, void *ignore) { CP_ARBITER_GET_SHAPES(arb, a, b); OneWayPlatform *platform = (OneWayPlatform *)cpShapeGetUserData(a); if(cpvdot(cpArbiterGetNormal(arb), platform->n) < 0){ return cpArbiterIgnore(arb); } return cpTrue; }
int Player::BeginCollision(cpArbiter *arb, struct cpSpace *space, void *data) { // Get the collision shapes CP_ARBITER_GET_SHAPES(arb, a, b); // Delimit collision types for both shapes if (a->collision_type == COLLISION_TYPE_GO && b->collision_type == COLLISION_TYPE_ACTIVATOR) { // Retrieve the activator object Activator *activator = (Activator*) b->data; // Retrieve the player object Player *player = (Player*) a->data; // Check if the right player is triggering if (player == activator->Owner) { // Delegate switch(activator->ActivatorType) { case ACTIVATOR_TYPE_FIRE: activator->Owner->Shoot(); break; case ACTIVATOR_TYPE_BOOST: activator->Owner->Boost(); break; case ACTIVATOR_TYPE_WEAPON: activator->Owner->TransferWeapon((Weapon*) activator->Data); activator->Data = 0; break; } } else { // No need to continue return false; } } else if (a->collision_type == COLLISION_TYPE_GO && b->collision_type == COLLISION_TYPE_BULLET) { // Retrieve the associated objects Player *player = (Player*) a->data; Bullet *bullet = (Bullet*) b->data; // Check if it's not own bullet if (player != bullet->GetOwner()) { bullet->HandleDamage(player); } } return true; }
static void separate(cpArbiter *arb, cpSpace *space, void *ignore) { CP_ARBITER_GET_SHAPES(arb, a, b); PlayerStruct *player = a->data; cpArrayDeleteObj(player->groundShapes, b); if(player->groundShapes->num == 0){ a->u = 0.0f; } }
static int cpArbiter_getShapes(lua_State *L) { cpArbiter *arb = toarbiter(L); CP_ARBITER_GET_SHAPES(arb, a, b); lua_pushliteral(L, "cpShape_ptrs"); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushlightuserdata(L, a); lua_rawget(L, -2); lua_pushlightuserdata(L, b); lua_rawget(L, -3); return 2; }
static int begin(cpArbiter *arb, cpSpace *space, void *ignore) { CP_ARBITER_GET_SHAPES(arb, a, b); PlayerStruct *player = a->data; cpVect n = cpvneg(cpArbiterGetNormal(arb, 0)); if(n.y > 0.0f){ cpArrayPush(player->groundShapes, b); } return 1; }
static cpBool preSolve(cpArbiter *arb, cpSpace *space, void *ignore) { CP_ARBITER_GET_SHAPES(arb, a, b); OneWayPlatform *platform = (OneWayPlatform *)a->data; if(cpvdot(cpArbiterGetNormal(arb, 0), platform->n) < 0){ cpArbiterIgnore(arb); return cpFalse; } return cpTrue; }
int PhysicsWorldCallback::collisionBeginCallbackFunc(cpArbiter *arb, struct cpSpace *space, PhysicsWorld *world) { CP_ARBITER_GET_SHAPES(arb, a, b); auto ita = PhysicsShapeInfo::getMap().find(a); auto itb = PhysicsShapeInfo::getMap().find(b); CC_ASSERT(ita != PhysicsShapeInfo::getMap().end() && itb != PhysicsShapeInfo::getMap().end()); PhysicsContact* contact = PhysicsContact::construct(ita->second->getShape(), itb->second->getShape()); arb->data = contact; contact->_contactInfo = arb; return world->collisionBeginCallback(*contact); }
cpBool PhysicsWorldCallback::collisionBeginCallbackFunc(cpArbiter *arb, struct cpSpace *space, PhysicsWorld *world) { CP_ARBITER_GET_SHAPES(arb, a, b); PhysicsShape *shapeA = static_cast<PhysicsShape*>(cpShapeGetUserData(a)); PhysicsShape *shapeB = static_cast<PhysicsShape*>(cpShapeGetUserData(b)); CC_ASSERT(shapeA != nullptr && shapeB != nullptr); auto contact = PhysicsContact::construct(shapeA, shapeB); cpArbiterSetUserData(arb, contact); contact->_contactInfo = arb; return world->collisionBeginCallback(*contact); }
void RCPCollision::separateFunc(cpArbiter *arb, cpSpace *space, cpDataPointer userData) { RCPCollision * collision = (RCPCollision *)userData; if (collision && collision->mSeparateFunc) { CP_ARBITER_GET_SHAPES(arb, cpsA, cpsB); RItem * itemA = (RItem *)cpShapeGetUserData(cpsA); RItem * itemB = (RItem *)cpShapeGetUserData(cpsB); RCPShapeItem * shapeA = dynamic_cast<RCPShapeItem *>(itemA); RCPShapeItem * shapeB = dynamic_cast<RCPShapeItem *>(itemB); collision->mSeparateFunc->handle(RCollisionEvent(shapeA, shapeB)); } }
static cpBool stoneAndGroundStrikeSlove(cpArbiter *arb, cpSpace *space, void *ignore) { CP_ARBITER_GET_SHAPES(arb, a, b); cpVect stone_v; if (a->collision_type == STONE_COLLISION) { stone_v = a->body->v; } else { stone_v = b->body->v; } float v_z = sqrtf(pow(stone_v.x, 2.0f) + pow(stone_v.y, 2.0f)); if (v_z > V_LIMIT_STONE_GROUND_STRIKE) ;//playGroundStrikeSound(); return cpTrue; }
static void BallIterator(cpBody *body, cpArbiter *arb, int *count) { // body is the body we are iterating the arbiters for. // CP_ARBITER_GET_*() in an arbiter iterator always returns the body/shape for the iterated body first. CP_ARBITER_GET_SHAPES(arb, ball, other); // Grab the bounding box, expand it slightly (for visibility) and draw it. cpBB bb = cpShapeGetBB(other); bb.l -= 5.0; bb.b -= 5.0; bb.r += 5.0; bb.t += 5.0; ChipmunkDebugDrawBB(bb, RGBAColor(1, 0, 0, 1)); (*count)++; }
static int preSolve(cpArbiter *arb, cpSpace *space, void *ignore) { CP_ARBITER_GET_SHAPES(arb, a, b); PlayerStruct *player = a->data; if(arb->stamp > 0){ a->u = player->u; // pick the most upright jump normal each frame cpVect n = cpvneg(cpArbiterGetNormal(arb, 0)); if(n.y >= player->groundNormal.y){ player->groundNormal = n; } } return 1; }
NS_CC_BEGIN #if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK) int PhysicsWorld::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)); }
int MagneticGripperGrippableCollisionPreSolve(cpArbiter* pt_arb, cpSpace* pt_space, void* p_data) { /* Get the shapes involved */ CP_ARBITER_GET_SHAPES(pt_arb, ptGripperShape, ptGrippableShape); /* Get a reference to the gripper data */ SDynamics2DEngineGripperData& sGripperData = *reinterpret_cast<SDynamics2DEngineGripperData*>(ptGripperShape->data); /* The gripper is locked or unlocked? */ if(sGripperData.GripperEntity.IsUnlocked()) { /* The gripper is locked. If it was gripping an object, * release it. Then, process the collision normally */ if(sGripperData.GripperEntity.IsGripping()) { sGripperData.ClearConstraints(); } return 1; } else if(! sGripperData.GripperEntity.IsGripping()) { /* The gripper is unlocked and free, create the joints */ /* Prevent gripper from slipping */ pt_arb->e = 0.0f; // No elasticity pt_arb->u = 1.0f; // Max friction pt_arb->surface_vr = cpvzero; // No surface velocity /* Calculate the anchor point on the grippable body as the centroid of the contact points */ cpVect tGrippableAnchor = cpvzero; for(SInt32 i = 0; i < pt_arb->numContacts; ++i) { tGrippableAnchor = cpvadd(tGrippableAnchor, cpArbiterGetPoint(pt_arb, i)); } tGrippableAnchor = cpvmult(tGrippableAnchor, 1.0f / pt_arb->numContacts); /* Create a constraint */ sGripperData.GripConstraint = cpSpaceAddConstraint(pt_space, cpPivotJointNew( ptGripperShape->body, ptGrippableShape->body, tGrippableAnchor)); sGripperData.GripConstraint->biasCoef = 0.95f; // Correct overlap sGripperData.GripConstraint->maxBias = 0.01f; // Max correction speed sGripperData.GripperEntity.SetGrippedEntity(*reinterpret_cast<CEmbodiedEntity*>(ptGrippableShape->data)); } /* Ignore the collision, the objects are gripped already */ return 0; }
void cpArbiterGetBodies(const cpArbiter *arb, cpBody **a, cpBody **b) { CP_ARBITER_GET_SHAPES(arb, shape_a, shape_b); (*a) = shape_a->body; (*b) = shape_b->body; }
cpBool Buoyancy::WaterPreSolve(cpArbiter *arb, cpSpace *space, void *ptr) { CP_ARBITER_GET_SHAPES(arb, water, poly); cpBody *body = cpShapeGetBody(poly); // Get the top of the water sensor bounding box to use as the water level. cpFloat level = cpShapeGetBB(water).t; // Clip the polygon against the water level int count = cpPolyShapeGetCount(poly); int clippedCount = 0; #ifdef _MSC_VER // MSVC is pretty much the only compiler in existence that doesn't support variable sized arrays. cpVect clipped[10]; #else cpVect clipped[count + 1]; #endif for(int i=0, j=count-1; i<count; j=i, i++){ cpVect a = cpBodyLocalToWorld(body, cpPolyShapeGetVert(poly, j)); cpVect b = cpBodyLocalToWorld(body, cpPolyShapeGetVert(poly, i)); if(a.y < level){ clipped[clippedCount] = a; clippedCount++; } cpFloat a_level = a.y - level; cpFloat b_level = b.y - level; if(a_level*b_level < 0.0f){ cpFloat t = cpfabs(a_level)/(cpfabs(a_level) + cpfabs(b_level)); clipped[clippedCount] = cpvlerp(a, b, t); clippedCount++; } } // Calculate buoyancy from the clipped polygon area cpFloat clippedArea = cpAreaForPoly(clippedCount, clipped, 0.0f); cpFloat displacedMass = clippedArea*FLUID_DENSITY; cpVect centroid = cpCentroidForPoly(clippedCount, clipped); cpDataPointer data = ptr; DrawPolygon(clippedCount, clipped, 0.0f, RGBAColor(0, 0, 1, 1), RGBAColor(0, 0, 1, 0.1f), data); DrawDot(5, centroid, RGBAColor(0, 0, 1, 1), data); cpFloat dt = cpSpaceGetCurrentTimeStep(space); cpVect g = cpSpaceGetGravity(space); // Apply the buoyancy force as an impulse. cpBodyApplyImpulseAtWorldPoint(body, cpvmult(g, -displacedMass*dt), centroid); // Apply linear damping for the fluid drag. cpVect v_centroid = cpBodyGetVelocityAtWorldPoint(body, centroid); cpFloat k = k_scalar_body(body, centroid, cpvnormalize(v_centroid)); cpFloat damping = clippedArea*FLUID_DRAG*FLUID_DENSITY; cpFloat v_coef = cpfexp(-damping*dt*k); // linear drag // cpFloat v_coef = 1.0/(1.0 + damping*dt*cpvlength(v_centroid)*k); // quadratic drag cpBodyApplyImpulseAtWorldPoint(body, cpvmult(cpvsub(cpvmult(v_centroid, v_coef), v_centroid), 1.0/k), centroid); // Apply angular damping for the fluid drag. cpVect cog = cpBodyLocalToWorld(body, cpBodyGetCenterOfGravity(body)); cpFloat w_damping = cpMomentForPoly(FLUID_DRAG*FLUID_DENSITY*clippedArea, clippedCount, clipped, cpvneg(cog), 0.0f); cpBodySetAngularVelocity(body, cpBodyGetAngularVelocity(body)*cpfexp(-w_damping*dt/cpBodyGetMoment(body))); return cpTrue; }
/** * Called when a bubble and popper (bullet) collide. * The bubble will be split in two. */ int bubble_popper_collision(cpArbiter *arb, struct cpSpace *space, void *data) { CP_ARBITER_GET_SHAPES(arb, shape_a, shape_b); struct bubble *p = shape_b->data; cpSpaceAddPostStepCallback(space, bubble_collision_pop, p, data); return 0; }
int player_bubble_collision(cpArbiter *arb, struct cpSpace *space, void *data) { CP_ARBITER_GET_SHAPES(arb, shape_a, shape_b); struct player *p = shape_b->data; cpSpaceAddPostStepCallback(space, player_remove_collision, p, data); return 0; }