static void add_box(cpSpace *space) { const cpFloat size = 10.0f; const cpFloat mass = 1.0f; cpVect verts[] = { cpv(-size,-size), cpv(-size, size), cpv( size, size), cpv( size,-size), }; cpFloat radius = cpvlength(cpv(size, size)); cpVect pos = rand_pos(radius); cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForPoly(mass, 4, verts, cpvzero))); body->velocity_func = planetGravityVelocityFunc; cpBodySetPos(body, pos); // Set the box's velocity to put it into a circular orbit from its // starting position. cpFloat r = cpvlength(pos); cpFloat v = cpfsqrt(gravityStrength / r) / r; cpBodySetVel(body, cpvmult(cpvperp(pos), v)); // Set the box's angular velocity to match its orbital period and // align its initial angle with its position. cpBodySetAngVel(body, v); cpBodySetAngle(body, cpfatan2(pos.y, pos.x)); cpShape *shape = cpSpaceAddShape(space, cpPolyShapeNew(body, 4, verts, cpvzero)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 0.7f); }
void update_friction(int n) { // kill lateral velocity const cpFloat max_lateral_impulse = 300; cpVect impulse = cpvmult(cpvneg(lateral_velocity(n)), cpBodyGetMass(tire[n])); //printf("%f\n", cpvlength(impulse)); if(cpvlength(impulse) > max_lateral_impulse) impulse = cpvmult(impulse, max_lateral_impulse / cpvlength(impulse)); cpBodyApplyImpulse(tire[n], impulse, cpvzero); // TODO - kill angular velocity? cpFloat inertia = cpBodyGetMoment(tire[n]); cpFloat av = cpBodyGetAngVel(tire[n]); if(av != 0) cpBodySetAngVel(tire[n], av / 1.2); // apply drag cpVect forward_normal = forward_velocity(n); cpFloat forward_speed = cpvlength(forward_normal); if(forward_speed < 1) { cpBodySetVel(tire[n], cpvzero); } else { forward_normal = cpvnormalize(forward_normal); cpFloat drag = -1 * forward_speed; cpBodyApplyImpulse(tire[n], cpvmult(forward_normal, drag), cpvzero); } }
void PhysicsBody::setDynamic(bool dynamic) { if (dynamic != _dynamic) { _dynamic = dynamic; if (dynamic) { if (_world && _cpBody->CP_PRIVATE(space)) { cpSpaceConvertBodyToDynamic(_world->_cpSpace, _cpBody, _mass, _moment); cpSpaceAddBody(_world->_cpSpace, _cpBody); } else { cpBodySetMass(_cpBody, _mass); cpBodySetMoment(_cpBody, _moment); } } else { if (_world && _cpBody->CP_PRIVATE(space)) { cpSpaceRemoveBody(_world->_cpSpace, _cpBody); cpSpaceConvertBodyToStatic(_world->_cpSpace, _cpBody); } else { cpBodySetMass(_cpBody, PHYSICS_INFINITY); cpBodySetMoment(_cpBody, PHYSICS_INFINITY); cpBodySetVel(_cpBody, cpvzero); cpBodySetAngVel(_cpBody, 0.0); } } } }
__declspec( dllexport ) void push( const void * _in, int in_size, void * _out, int out_sz ) { int index; Variable *var; cpBody *body; cpShape *shape; index = PEEKINT(INPUT_MEMBLOCK,0); var = vhGetVariable(&mVariableHandler,index); switch (var->mType) { case VarTypeBody: body = (cpBody*)var->mPtr; cpBodySetAngle(body,degToRad(PEEKFLOAT(INPUT_MEMBLOCK,4))); cpBodySetPos(body,PEEKVECT(INPUT_MEMBLOCK,8)); cpBodySetAngVel(body,degToRad(PEEKFLOAT(INPUT_MEMBLOCK,16))); cpBodySetVel(body,PEEKVECT(INPUT_MEMBLOCK,20)); break; case VarTypeShape: shape = (cpShape*)var->mPtr; cpShapeSetFriction(shape,PEEKFLOAT(INPUT_MEMBLOCK,4)); cpShapeSetElasticity(shape,PEEKFLOAT(INPUT_MEMBLOCK,8)); cpShapeSetLayers(shape,PEEKUINT(INPUT_MEMBLOCK,12)); cpShapeSetGroup(shape,PEEKUINT(INPUT_MEMBLOCK,16)); break; } }
static void _update_kinematics() { PhysicsInfo *info; cpVect pos; cpFloat ang; Scalar invdt; Entity ent; if (timing_dt <= FLT_EPSILON) return; invdt = 1 / timing_dt; entitypool_foreach(info, pool) if (info->type == PB_KINEMATIC) { ent = info->pool_elem.ent; /* move to transform */ pos = cpv_of_vec2(transform_get_position(ent)); ang = transform_get_rotation(ent); cpBodySetPos(info->body, pos); cpBodySetAngle(info->body, ang); info->last_dirty_count = transform_get_dirty_count(ent); /* update linear, angular velocities based on delta */ cpBodySetVel(info->body, cpvmult(cpvsub(pos, info->last_pos), invdt)); cpBodySetAngVel(info->body, (ang - info->last_ang) * invdt); cpSpaceReindexShapesForBody(space, info->body); /* save current state for next computation */ info->last_pos = pos; info->last_ang = ang; } }
void NaiveRotationAlgorithm::stepSystem(SystemInfo *individual) { MachineSystem *oldSystem = individual->system; individual->system = new MachineSystem(*oldSystem); // copy it to stop all the damn bouncing about delete oldSystem; cpBody *inputBody = individual->system->partAtPosition(individual->system->inputMachinePosition)->body; cpBody *outputBody = individual->system->partAtPosition(individual->system->outputMachinePosition)->body; cpSpace *systemSpace = individual->system->getSpace(); cpConstraint *motor = cpSimpleMotorNew(cpSpaceGetStaticBody(systemSpace), inputBody, M_PI); cpSpaceAddConstraint(systemSpace, motor); cpConstraintSetMaxForce(motor, 50000); for (int i=0; i<simSteps; i++) { individual->inputValues[i] = (cpBodyGetAngle(inputBody)); cpSpaceStep(systemSpace, 0.1); individual->outputValues[i] = (cpBodyGetAngle(outputBody)); } cpSpaceRemoveConstraint(systemSpace, motor); cpBodySetAngVel(outputBody, 0); cpBodySetAngle(inputBody, 0); }
static cpSpace * init(void) { space = cpSpaceNew(); cpSpaceSetGravity(space, cpv(0, -600)); cpBody *body; cpShape *shape; // We create an infinite mass rogue body to attach the line segments too // This way we can control the rotation however we want. rogueBoxBody = cpBodyNew(INFINITY, INFINITY); cpBodySetAngVel(rogueBoxBody, 0.4f); // Set up the static box. cpVect a = cpv(-200, -200); cpVect b = cpv(-200, 200); cpVect c = cpv( 200, 200); cpVect d = cpv( 200, -200); shape = cpSpaceAddShape(space, cpSegmentShapeNew(rogueBoxBody, a, b, 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(rogueBoxBody, b, c, 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(rogueBoxBody, c, d, 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(rogueBoxBody, d, a, 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); cpFloat mass = 1; cpFloat width = 60; cpFloat height = 30; // Add the bricks. for(int i=0; i<3; i++){ for(int j=0; j<7; j++){ body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForBox(mass, width, height))); cpBodySetPos(body, cpv(i*60 - 150, j*30 - 150)); shape = cpSpaceAddShape(space, cpBoxShapeNew(body, width, height)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 0.7f); } } return space; }
void PhysicsBody::setAngularVelocity(float velocity) { if (!_dynamic) { CCLOG("physics warning: your can't set angular velocity for a static body."); return; } cpBodySetAngVel(_cpBody, velocity); }
void PhysicsBody::setAngularVelocity(float velocity) { if (!_dynamic) { CCLOG("physics warning: your can't set angular velocity for a static body."); return; } cpBodySetAngVel(_info->getBody(), PhysicsHelper::float2cpfloat(velocity)); }
void physics_set_freeze_rotation(Entity ent, bool freeze) { PhysicsInfo *info = entitypool_get(pool, ent); error_assert(info); if (freeze) { cpBodySetAngVel(info->body, 0); cpBodySetMoment(info->body, SCALAR_INFINITY); } else _recalculate_moment(info); }
void cpSpaceConvertBodyToStatic(cpSpace *space, cpBody *body) { cpAssertHard(!cpBodyIsStatic(body), "Body is already static."); cpAssertHard(cpBodyIsRogue(body), "Remove the body from the space before calling this function."); cpAssertSpaceUnlocked(space); cpBodySetMass(body, INFINITY); cpBodySetMoment(body, INFINITY); cpBodySetVel(body, cpvzero); cpBodySetAngVel(body, 0.0f); body->node.idleTime = INFINITY; CP_BODY_FOREACH_SHAPE(body, shape){ cpSpatialIndexRemove(space->activeShapes, shape, shape->hashid); cpSpatialIndexInsert(space->staticShapes, shape, shape->hashid); }
static void ClipPoly(cpSpace *space, cpShape *shape, cpVect n, cpFloat dist) { cpBody *body = cpShapeGetBody(shape); int count = cpPolyShapeGetNumVerts(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 = cpBodyLocal2World(body, cpPolyShapeGetVert(shape, j)); cpFloat a_dist = cpvdot(a, n) - dist; if(a_dist < 0.0){ clipped[clippedCount] = a; clippedCount++; } cpVect b = cpBodyLocal2World(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)*DENSITY; cpFloat moment = cpMomentForPoly(mass, clippedCount, clipped, cpvneg(centroid)); cpBody *new_body = cpSpaceAddBody(space, cpBodyNew(mass, moment)); cpBodySetPos(new_body, centroid); cpBodySetVel(new_body, cpBodyGetVelAtWorldPoint(body, centroid)); cpBodySetAngVel(new_body, cpBodyGetAngVel(body)); cpShape *new_shape = cpSpaceAddShape(space, cpPolyShapeNew(new_body, clippedCount, clipped, cpvneg(centroid))); // Copy whatever properties you have set on the original shape that are important cpShapeSetFriction(new_shape, cpShapeGetFriction(shape)); }
static JSBool body_setAngVel(JSContext* cx, uintN argc, jsval* vp) { jsdouble angVel; if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "d", &angVel)) { /* Throw a JavaScript exception. */ JS_ReportError(cx, "body_setAngVel: couldn't parse out angVel"); return JS_FALSE; } JSObject* bodyObj = JS_THIS_OBJECT(cx, vp); cpBody* body = (cpBody*)JS_GetPrivate(cx, bodyObj); cpBodySetAngVel(body, angVel); jsval rVal = JSVAL_VOID; JS_SET_RVAL(cx, vp, rVal); return JS_TRUE; }
static cpSpace * init(void) { // Create a rouge body to control the planet manually. planetBody = cpBodyNew(INFINITY, INFINITY); cpBodySetAngVel(planetBody, 0.2f); cpSpace *space = cpSpaceNew(); cpSpaceSetIterations(space, 20); for(int i=0; i<30; i++) add_box(space); cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(planetBody, 70.0f, cpvzero)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); return space; }
void PhysicsBody::setDynamic(bool dynamic) { if (dynamic != _dynamic) { _dynamic = dynamic; if (dynamic) { cpBodySetMass(_info->getBody(), _mass); cpBodySetMoment(_info->getBody(), _moment); if (_world != nullptr) { // reset the gravity enable if (isGravityEnabled()) { _gravityEnabled = false; setGravityEnable(true); } cpSpaceAddBody(_world->_info->getSpace(), _info->getBody()); } } else { if (_world != nullptr) { cpSpaceRemoveBody(_world->_info->getSpace(), _info->getBody()); } // avoid incorrect collion simulation. cpBodySetMass(_info->getBody(), PHYSICS_INFINITY); cpBodySetMoment(_info->getBody(), PHYSICS_INFINITY); cpBodySetVel(_info->getBody(), cpvzero); cpBodySetAngVel(_info->getBody(), 0.0f); resetForces(); } } }
void physics_update_all() { PhysicsInfo *info; Entity ent; entitypool_remove_destroyed(pool, physics_remove); entitymap_clear(debug_draw_map); /* simulate */ if (!timing_get_paused()) { _update_kinematics(); _step(); } /* synchronize transform <-> physics */ entitypool_foreach(info, pool) { ent = info->pool_elem.ent; /* if transform is dirtier, move to it, else overwrite it */ if (transform_get_dirty_count(ent) != info->last_dirty_count) { cpBodySetVel(info->body, cpvzero); cpBodySetAngVel(info->body, 0.0f); cpBodySetPos(info->body, cpv_of_vec2(transform_get_position(ent))); cpBodySetAngle(info->body, transform_get_rotation(ent)); cpSpaceReindexShapesForBody(space, info->body); } else if (info->type == PB_DYNAMIC) { transform_set_position(ent, vec2_of_cpv(cpBodyGetPos(info->body))); transform_set_rotation(ent, cpBodyGetAngle(info->body)); } info->last_dirty_count = transform_get_dirty_count(ent); }
void cBody::AngVel( const cpFloat& rotVel ) { cpBodySetAngVel( mBody, rotVel ); }
void Body::setAngVel(cpFloat value) { cpBodySetAngVel(body,value); }
void PhysicsBody::setAngularVelocity(float velocity) { cpBodySetAngVel(_info->body, PhysicsHelper::float2cpfloat(velocity)); }
void physics_set_angular_velocity(Entity ent, Scalar ang_vel) { PhysicsInfo *info = entitypool_get(pool, ent); error_assert(info); cpBodySetAngVel(info->body, ang_vel); }