static cpFloat getImpulse(cpPinJoint *joint) { return cpfabs(joint->jnAcc); }
static cpFloat getImpulse(cpRatchetJoint *joint) { return cpfabs(joint->jAcc); }
static cpFloat getImpulse(cpSimpleMotor *joint) { return cpfabs(joint->jAcc); }
cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2) { return (cpFloat)M_PI*cpfabs(r1*r1 - r2*r2); }
static cpFloat getImpulse(cpGearJoint *joint) { return cpfabs(joint->jAcc); }
iBOOL mwInitLevel015( void ) { mwInitSpace(CurrLevelNum); cpBody *body; cpBody *staticBody = &(mwSpace->staticBody); cpShape *shape; cpFloat radius = WATER_RADIUS; for(int i=0; i<2; i++){ for(int j=0; j<5; j++){ cpVect pos = cpv((j)*8+31,(i)*8+83); body = cpSpaceAddBody(mwSpace, cpBodyNew(40.0f, cpMomentForCircle(40.0f, 0.0f, radius, cpvzero))); cpBodySetPos(body, pos); cpBodySetID(body,i*50+j); body->v = cpv(body->v.x,-(cpfabs(body->v.y))); shape = cpSpaceAddShape(mwSpace, cpCircleShapeNew(body, radius, cpvzero)); shape->e = WATER_E; shape->u = WATER_U; } } for(int i=0; i<2; i++){ for(int j=0; j<10; j++){ cpVect pos = cpv((j)*8+20,(i)*8+211); body = cpSpaceAddBody(mwSpace, cpBodyNew(40.0f, cpMomentForCircle(40.0f, 0.0f, radius, cpvzero))); cpBodySetPos(body, pos); cpBodySetID(body,i*50+j); body->v = cpv(body->v.x,-(cpfabs(body->v.y))); shape = cpSpaceAddShape(mwSpace, cpCircleShapeNew(body, radius, cpvzero)); shape->e = WATER_E; shape->u = WATER_U; } } mwLevelWordInit(CurrLevelNum); mwLevelDuckInit(CurrLevelNum); mwLevelPipeInit(CurrLevelNum); mwLevelWaitInit(CurrLevelNum); mwLevelDrawBKwall(); i51KitG2DrawImage(mwContainer, MudLevel015, iNULL, iNULL); i51KitG2DrawImage(mwContainer, RockLevel015, iNULL, iNULL); mwLevelDrawPause(); mwLevelDrawRestart(); mwLevelOrganInit(CurrLevelNum); i51AdeStdMemcpy16( (void *)TempScreenBuf, (void *)mwScreenBuffer, SCREEN_HEIGHT*SCREEN_WIDTH*2); mwTempScreenBufUpdate(CurrLevelNum); mwLevelSpeedKeepInit(CurrLevelNum); mwLevelDrawDuck(); mwLevelDrawOrgan(); TimeLevelStart = i51AdeOsGetTick(); return iTRUE; }
static cpFloat getImpulse(cpConstraint *joint) { return cpfabs(((cpSlideJoint *)joint)->jnAcc); }
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; }
static inline cpFloat cpBBProximity(cpBB a, cpBB b) { return cpfabs(a.l + a.r - b.l - b.r) + cpfabs(a.b + b.t - b.b - b.t); }
static cpFloat getImpulse(cpRotaryLimitJoint *joint) { return cpfabs(joint->jAcc); }