bool DropCapsid::onContactAstroObj(ContactInfo& cinfo) { if (cinfo.contact.getEventCode() == PhysicsContact::EventCode::POSTSOLVE) { if (cpArbiter* arb = static_cast<cpArbiter*>(cinfo.contact.getContactInfo())) { cpContactPointSet cps = cpArbiterGetContactPointSet(arb); bool moving = false; for (int i = 0; i < cps.count; ++i) { cpVect va = cpBodyGetVelocityAtWorldPoint(arb->body_a, cps.points[i].pointA); cpVect vb = cpBodyGetVelocityAtWorldPoint(arb->body_b, cps.points[i].pointB); cpVect rv = cpvsub(va, vb); cpFloat wa = cpBodyGetAngularVelocity(arb->body_a); cpFloat wb = cpBodyGetAngularVelocity(arb->body_b); cpFloat rw = wa - wb; //if (cpvlengthsq(rv) > 1e-6 || fabs(rw) > 0.5) { if (cpvlengthsq(rv) > 1.0 || fabs(rw) > 5) { moving = true; break; } } if (!moving) { Unit* created = onLandCreate(_game); Player* player = _player; replaceWith(created); // this is destroyed float up = (cinfo.thisBody->getPosition() - cinfo.thatBody->getPosition()).getAngle() / (M_PI / 180.0); created->getNode()->getPhysicsBody()->setRotation(90 - up); created->setPlayer(player); // CCLOG("LANDING up# %f", up); return true; } } } return true; }
static int l_physics_getBodyAngularVelocity(lua_State* state) { l_tools_checkUserDataPlusErrMsg(state, 1, "You must provide a body"); l_physics_Body* body = (l_physics_Body*)lua_touserdata(state, 1); lua_pushnumber(state, cpBodyGetAngularVelocity(body->body)); return 1; }
void RigidBody2D::CopyBodyData(cpBody* body) { cpBodySetAngle(m_handle, cpBodyGetAngle(body)); cpBodySetAngularVelocity(m_handle, cpBodyGetAngularVelocity(body)); cpBodySetCenterOfGravity(m_handle, cpBodyGetCenterOfGravity(body)); cpBodySetForce(m_handle, cpBodyGetForce(body)); cpBodySetPosition(m_handle, cpBodyGetPosition(body)); cpBodySetTorque(m_handle, cpBodyGetTorque(body)); cpBodySetVelocity(m_handle, cpBodyGetVelocity(body)); }
void RigidBody2D::CopyBodyData(cpBody* from, cpBody* to) { cpBodySetAngle(to, cpBodyGetAngle(from)); cpBodySetAngularVelocity(to, cpBodyGetAngularVelocity(from)); cpBodySetCenterOfGravity(to, cpBodyGetCenterOfGravity(from)); cpBodySetForce(to, cpBodyGetForce(from)); cpBodySetPosition(to, cpBodyGetPosition(from)); cpBodySetTorque(to, cpBodyGetTorque(from)); cpBodySetVelocity(to, cpBodyGetVelocity(from)); }
int update_brain(Ship* s) { float* inputs = new float[NINPUTS]; float noseang = cpBodyGetAngle(s->body) + s->nose_angle; cpVect rpos = cpBodyGetPosition(s->target->body) - cpBodyGetPosition(s->body); inputs[0] = cpvlength(rpos); inputs[1] = restrictangle(cpvtoangle(rpos)-noseang); cpVect rvel = cpBodyGetVelocity(s->target->body) - cpBodyGetVelocity(s->body); inputs[2] = (rpos.x * rvel.x + rpos.y * rvel.y)/inputs[0]; inputs[3] = (rpos.x * rvel.y - rpos.y * rvel.x)/(inputs[0]*inputs[0]) - cpBodyGetAngularVelocity(s->body); inputs[4] = restrictangle(cpBodyGetAngle(s->target->body) + s->target->nose_angle - noseang); inputs[5] = cpBodyGetAngularVelocity(s->target->body); s->brain->update(inputs); delete inputs; return 0; }
void Slice::ClipPoly(cpSpace *space, cpShape *shape, cpVect n, cpFloat dist) { cpBody *body = cpShapeGetBody(shape); int count = cpPolyShapeGetCount(shape); int clippedCount = 0; cpVect *clipped = (cpVect *)alloca((count + 1)*sizeof(cpVect)); for(int i=0, j=count-1; i<count; j=i, i++){ cpVect a = cpBodyLocalToWorld(body, cpPolyShapeGetVert(shape, j)); cpFloat a_dist = cpvdot(a, n) - dist; if(a_dist < 0.0){ clipped[clippedCount] = a; clippedCount++; } cpVect b = cpBodyLocalToWorld(body, cpPolyShapeGetVert(shape, i)); cpFloat b_dist = cpvdot(b, n) - dist; if(a_dist*b_dist < 0.0f){ cpFloat t = cpfabs(a_dist)/(cpfabs(a_dist) + cpfabs(b_dist)); clipped[clippedCount] = cpvlerp(a, b, t); clippedCount++; } } cpVect centroid = cpCentroidForPoly(clippedCount, clipped); cpFloat mass = cpAreaForPoly(clippedCount, clipped, 0.0f)*DENSITY; cpFloat moment = cpMomentForPoly(mass, clippedCount, clipped, cpvneg(centroid), 0.0f); cpBody *new_body = cpSpaceAddBody(space, cpBodyNew(mass, moment)); cpBodySetPosition(new_body, centroid); cpBodySetVelocity(new_body, cpBodyGetVelocityAtWorldPoint(body, centroid)); cpBodySetAngularVelocity(new_body, cpBodyGetAngularVelocity(body)); cpTransform transform = cpTransformTranslate(cpvneg(centroid)); cpShape *new_shape = cpSpaceAddShape(space, cpPolyShapeNew(new_body, clippedCount, clipped, transform, 0.0)); // Copy whatever properties you have set on the original shape that are important cpShapeSetFriction(new_shape, cpShapeGetFriction(shape)); }
float PhysicsBody::getAngularVelocity() { return PhysicsHelper::cpfloat2float(cpBodyGetAngularVelocity(_cpBody)); }
float RigidBody2D::GetAngularVelocity() const { return FromRadians(static_cast<float>(cpBodyGetAngularVelocity(m_handle))); }
RadianAnglef RigidBody2D::GetAngularVelocity() const { return float(cpBodyGetAngularVelocity(m_handle)); }
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; }