cpBody* cpBodyInit(cpBody *body, cpFloat m, cpFloat i) { body->velocity_func = cpBodyUpdateVelocity; body->position_func = cpBodyUpdatePosition; cpBodySetMass(body, m); cpBodySetMoment(body, i); body->p = cpvzero; body->v = cpvzero; body->f = cpvzero; cpBodySetAngle(body, 0.0f); body->w = 0.0f; body->t = 0.0f; body->v_bias = cpvzero; body->w_bias = 0.0f; body->data = NULL; // body->active = 1; return body; }
void PhysicsBody::setMass(float mass) { if (mass <= 0) { return; } _mass = mass; _massDefault = false; // update density if (_mass == PHYSICS_INFINITY) { _density = PHYSICS_INFINITY; } else { if (_area > 0) { _density = _mass / _area; }else { _density = 0; } } // the static body's mass and moment is always infinity if (_dynamic) { cpBodySetMass(_info->getBody(), PhysicsHelper::float2cpfloat(_mass)); } }
cpBody* cpBodyInit(cpBody *body, cpFloat m, cpFloat i) { body->velocity_func = cpBodyUpdateVelocityDefault; body->position_func = cpBodyUpdatePositionDefault; cpBodySetMass(body, m); cpBodySetMoment(body, i); body->p = cpvzero; body->v = cpvzero; body->f = cpvzero; cpBodySetAngle(body, 0.0f); body->w = 0.0f; body->t = 0.0f; body->v_bias = cpvzero; body->w_bias = 0.0f; body->data = NULL; body->v_limit = (cpFloat)INFINITY; body->w_limit = (cpFloat)INFINITY; body->space = NULL; body->shapesList = NULL; cpComponentNode node = {NULL, NULL, 0, 0.0f}; body->node = node; return body; }
static int l_physics_setBodyMass(lua_State* state) { l_tools_checkUserDataPlusErrMsg(state, 1, "You must provide a body"); l_physics_Body* body = (l_physics_Body*)lua_touserdata(state, 1); float value = l_tools_toNumberOrError(state, 2); cpBodySetMass(body->body, value); return 0; }
void physics_set_mass(Entity ent, Scalar mass) { PhysicsInfo *info = entitypool_get(pool, ent); error_assert(info); if (mass <= SCALAR_EPSILON) return; cpBodySetMass(info->body, info->mass = mass); _recalculate_moment(info); }
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(); } } }
static cpBody *utils_update_drawing(cpBody *drawing) { cpFloat mass = cpBodyGetMass(drawing); cpFloat moment = cpBodyGetMoment(drawing); Body_data *pa = cpBodyGetUserData(drawing); //cpFloat x = g_array_index(pa->x_values, cpFloat, 0); //cpFloat y = g_array_index(pa->y_values, cpFloat, 0); cpVect pos_a, pos_b; cpVect origin = cpBodyGetPos(drawing); cpFloat mi, micx = 0, micy = 0; int length = pa->x_values->len; for (int index = 1; index < length; index++) { pos_a = cpv(g_array_index(pa->x_values, cpFloat, index - 1), g_array_index(pa->y_values, cpFloat, index - 1)); pos_b = cpv(g_array_index(pa->x_values, cpFloat, index), g_array_index(pa->y_values, cpFloat, index)); //fprintf(stdout, "Pos_a = (%5.2f, %5.2f)\n", pos_a.x, pos_a.y); mi = (CRAYON_MASS * cpAreaForSegment( pos_a, pos_b, CRAYON_RADIUS )); micx += mi * ((pos_a.x + pos_b.x) / 2); micy += mi * ((pos_a.y + pos_b.y) / 2); mass += mi; moment += cpMomentForSegment(mass, pos_a, pos_b); // not actually sum, but maybe it is } cpBodySetMass(drawing, mass); cpBodySetMoment(drawing, moment); // center of mass is the average of all vertices NOT //cpVect new_origin = cpv(x / length, y / length); cpVect new_origin = cpv(micx / mass, micy / mass); new_origin = cpBodyLocal2World(drawing, new_origin); cpBodySetPos( drawing, new_origin ); //fprintf(stdout, "Position set at (%5.2f, %5.2f)\n", new_origin.x, new_origin.y); cpSpace * space = cpBodyGetSpace(drawing); cpSpaceReindexShapesForBody(space, drawing); //cpBodySetPos(drawing, cpv(pos.x + (second.x / length), pos.y + (second.y / length))); //pa->offset = cpvsub(new_origin, origin); pa = shift_origin(drawing, origin, new_origin); cpBodySetUserData(drawing, pa); if (space) post_step_body_replace_shapes(space, drawing, NULL); else fprintf(stderr, "WTF\n"); //if (!(cpSpaceAddPostStepCallback(space, (cpPostStepFunc) post_step_body_replace_shapes, drawing, NULL))) //fprintf(stderr, "FAILED POST-STEP CALLBACK\n\n"); return drawing; }
void PhysicsBody::updateMass(float oldMass, float newMass) { if (_dynamic && !_gravityEnabled && _world != nullptr && oldMass != PHYSICS_INFINITY) { applyForce(_world->getGravity() * oldMass); } cpBodySetMass(_info->getBody(), newMass); if (_dynamic && !_gravityEnabled && _world != nullptr && newMass != PHYSICS_INFINITY) { applyForce(-_world->getGravity() * newMass); } }
void weapon_init(Entity *ent) { if (!weapon_sprite) { ALLEGRO_PATH *path = game_asset_path("sword.png"); weapon_sprite = al_load_bitmap(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP)); al_destroy_path(path); } cpBody *body = entity_body(ent); cpShape *shape = cpBoxShapeNew(body, WEAPON_WIDTH, WEAPON_HEIGHT, 0); cpSpaceAddShape(game.space, shape); cpShapeSetFriction(shape, 1); cpShapeSetElasticity(shape, 0); cpBodySetMass(body, 1); cpBodySetMoment(body, cpMomentForBox(1, WEAPON_WIDTH, WEAPON_HEIGHT)); }
void PhysicsBody::addMass(float mass) { if (mass == PHYSICS_INFINITY) { _mass = PHYSICS_INFINITY; _massDefault = false; _density = PHYSICS_INFINITY; } else if (mass == -PHYSICS_INFINITY) { return; } else { if (_massDefault) { _mass = 0; _massDefault = false; } if (_mass + mass > 0) { _mass += mass; } else { _mass = MASS_DEFAULT; _massDefault = true; } if (_area > 0) { _density = _mass / _area; } else { _density = 0; } } // the static body's mass and moment is always infinity if (_dynamic) { cpBodySetMass(_cpBody, _mass); } }
void Unit::updatePhysics( ) { cpBodySetMass( physBody, phys.mass ); cpFloat moment; switch(phys.type){ case potCircle: if( physShape ) cpCircleShapeSetRadius( physShape, phys.radius ); moment = cpMomentForCircle( phys.mass, 0, phys.radius, cpvzero ); break; default: moment = 1.0; break; } cpBodySetMoment( physBody, moment ); if( cpBodyIsStatic(physBody) && phys.type != potNone ) cpSpaceReindexShape( Phys::space, physShape ); }
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 cpBody *utils_update_drawing(cpBody *drawing) { cpFloat mass = cpBodyGetMass(drawing); cpFloat moment = cpBodyGetMoment(drawing); Point_array *pa = cpBodyGetUserData(drawing); cpFloat x = g_array_index(pa->x_values, cpFloat, 0); cpFloat y = g_array_index(pa->y_values, cpFloat, 0); cpVect pos_a, pos_b; cpVect origin = cpBodyGetPos(drawing); cpFloat mi, micx = 0, micy = 0; int length = pa->x_values->len; for (int index = 1; index < length; index++) { pos_a = cpv(g_array_index(pa->x_values, cpFloat, index - 1), g_array_index(pa->y_values, cpFloat, index - 1)); pos_b = cpv(g_array_index(pa->x_values, cpFloat, index), g_array_index(pa->y_values, cpFloat, index)); cpvadd(pos_a, origin); cpvadd(pos_b, origin); x += pos_b.x; y += pos_b.y; mi = (CRAYON_MASS * cpAreaForSegment( pos_a, pos_b, CRAYON_RADIUS )); micx += mi * ((pos_a.x + pos_b.x) / 2); micy += mi * ((pos_a.y + pos_b.y) / 2); mass += mi; moment += cpMomentForSegment(mass, pos_a, pos_b); // not actually sum } cpBodySetMass(drawing, mass); cpBodySetMoment(drawing, moment); // center of mass is the average of all vertices NOT //cpVect new_origin = cpv(x / length, y / length); cpVect new_origin = cpv(micx / mass, micy / mass); cpBodySetPos( drawing, new_origin ); //cpBodySetPos(drawing, cpv(pos.x + (second.x / length), pos.y + (second.y / length))); pa = shift_origin(pa, origin, new_origin); cpBodySetUserData(drawing, pa); return drawing; }
static void update(cpSpace *space) { cpFloat tolerance = 2.0; if(ChipmunkDemoRightClick && cpShapeNearestPointQuery(shape, ChipmunkDemoMouse, NULL) > tolerance){ cpBody *body = cpShapeGetBody(shape); int count = cpPolyShapeGetNumVerts(shape); // Allocate the space for the new vertexes on the stack. cpVect *verts = (cpVect *)alloca((count + 1)*sizeof(cpVect)); for(int i=0; i<count; i++){ verts[i] = cpPolyShapeGetVert(shape, i); } verts[count] = cpBodyWorld2Local(body, ChipmunkDemoMouse); // This function builds a convex hull for the vertexes. // Because the result array is NULL, it will reduce the input array instead. int hullCount = cpConvexHull(count + 1, verts, NULL, NULL, tolerance); // Figure out how much to shift the body by. cpVect centroid = cpCentroidForPoly(hullCount, verts); // Recalculate the body properties to match the updated shape. cpFloat mass = cpAreaForPoly(hullCount, verts)*DENSITY; cpBodySetMass(body, mass); cpBodySetMoment(body, cpMomentForPoly(mass, hullCount, verts, cpvneg(centroid))); cpBodySetPos(body, cpBodyLocal2World(body, centroid)); // Use the setter function from chipmunk_unsafe.h. // You could also remove and recreate the shape if you wanted. cpPolyShapeSetVerts(shape, hullCount, verts, cpvneg(centroid)); } int steps = 1; cpFloat dt = 1.0f/60.0f/(cpFloat)steps; for(int i=0; i<steps; i++){ cpSpaceStep(space, dt); } }
void PhysicsBody::addMass(float mass) { if (mass == PHYSICS_INFINITY) { _mass = PHYSICS_INFINITY; _massDefault = false; _density = PHYSICS_INFINITY; } else if (mass == -PHYSICS_INFINITY) { return; } else if (_mass != PHYSICS_INFINITY) { if (_massDefault) { _mass = 0; _massDefault = false; } if (_mass + mass > 0) { _mass += mass; }else { _mass = MASS_DEFAULT; _massDefault = true; } if (_area > 0) { _density = _mass / _area; } else { _density = 0; } } cpBodySetMass(_info->body, PhysicsHelper::float2cpfloat(_mass)); }
cpBody * cpBodyInit(cpBody *body, cpFloat m, cpFloat i) { //body->space = NULL; //body->shapeList = NULL; //body->arbiterList = NULL; //body->constraintList = NULL; //body->velocity_func = cpBodyUpdateVelocity; //body->position_func = cpBodyUpdatePosition; //cpComponentNode node = {NULL, NULL, 0.0f}; //body->node = node; body->p = cpvzero; body->v = cpvzero; body->f = cpvzero; body->w = 0.0f; body->t = 0.0f; // body->v_bias = cpvzero; // body->w_bias = 0.0f; body->v_limit = (cpFloat)INFINITY; body->w_limit = (cpFloat)INFINITY; body->data = NULL; // Setters must be called after full initialization so the sanity checks don't assert on garbage data. cpBodySetMass(body, m); cpBodySetMoment(body, i); //cpBodySetAngle(body, 0.0f); return body; }
static void pullControlPoint(cpShape *shape) { int i; float origArea, newArea, newMass; control_point_t *cp; cpPolyShape *ps; cpCircleShape *circle; cpVect lp; cpVect verts[4]; cpConstraint *mouseJoint; mouseJoint = atlMouseJoint(); if (!mouseJoint) { lp = cpBodyWorld2Local(shape->body, atlMouseClickPos()); } else { /* update joint position */ lp = cpBodyWorld2Local(shape->body, atlMousePos()); atlRemoveMouseJoint(g_Space); } atlCreateMouseJoint(g_Space, shape->body, lp); cp = (control_point_t *)shape->data; ps = (cpPolyShape *)cp->dom->shape; control_point_t *circlePoint; for (i = 0; i < 4; ++i) { verts[i] = cpPolyShapeGetVert((cpShape *)ps, i); if (lp.x > 0) { if (verts[i].x > 0) verts[i].x = lp.x; else verts[i].x = -lp.x; } else if (lp.x < 0) { if (verts[i].x < 0) verts[i].x = lp.x; else verts[i].x = -lp.x; } if (lp.y > 0) { if (verts[i].y > 0) verts[i].y = lp.y; else verts[i].y = -lp.y; } else if (lp.y < 0) { if (verts[i].y < 0) verts[i].y = lp.y; else verts[i].y = -lp.y; } circlePoint = (control_point_t *)cp->dom->pControlPoints[i]; circle = (cpCircleShape *)circlePoint->shape; cpCircleShapeSetOffset((cpShape *)circle, verts[i]); } origArea = (fabs(dominoVerts[0].x)+dominoVerts[3].x) * (fabs(dominoVerts[0].y)+dominoVerts[1].y); newArea = (fabs(verts[0].x)+verts[3].x) * (fabs(verts[0].y)+verts[1].y); if (newArea > origArea) newMass = newArea/origArea * 0.05f; else newMass = 1.0f; cpBodySetMass(cp->dom->body, newMass); cpPolyShapeSetVerts((cpShape *)ps, ps->numVerts, verts, cpvzero); }
void cBody::Mass( const cpFloat& mass ) { cpBodySetMass( mBody, mass ); }
void Body::setMass(cpFloat m) { cpBodySetMass(body,m); }
static VALUE rb_cpBodySetMass(VALUE self, VALUE val) { cpBodySetMass(BODY(self), NUM2DBL(val)); return val; }
/* * The moment is like the rotational mass of a body * Note: !This function may also set the mass of the object! */ static int l_physics_setBodyMoment(lua_State* state) { l_tools_checkUserDataPlusErrMsg(state, 1, "You must provide a body"); l_physics_Body* body = (l_physics_Body*)lua_touserdata(state, 1); /* * You can provide a custom moment * for this body *or* you can choose what * type of body this is and let chipmunk * calculate the value based on some attributes */ int index = 2; cpFloat _mass = 0; cpFloat moment = 0; if (lua_type(state, 2) == LUA_TNUMBER) { moment = l_tools_toNumberOrError(state, 2); } else if (lua_type(state, 2) == LUA_TSTRING) { const char* whatFor = lua_tostring(state, 2); if (strcmp(whatFor, "box") == 0) { cpFloat mass = l_tools_toNumberOrError(state, 3); cpFloat width = l_tools_toNumberOrError(state, 4); cpFloat height = l_tools_toNumberOrError(state, 5); _mass = mass; moment = cpMomentForBox(mass, width, height); } else if (strcmp(whatFor, "circle") == 0) { cpFloat mass = l_tools_toNumberOrError(state, index++); cpFloat inner_radius = l_tools_toNumberOrError(state, index++); cpFloat outer_radius = l_tools_toNumberOrError(state, index++); cpVect offset = cpvzero; offset.x = l_tools_toNumberOrError(state, index++); offset.y = l_tools_toNumberOrError(state, index++); _mass = mass; moment = cpMomentForCircle(mass, inner_radius, outer_radius, offset); } else if (strcmp(whatFor, "segment") == 0) { cpFloat mass = l_tools_toNumberOrError(state, index++); cpVect a = cpvzero; a.x = l_tools_toNumberOrError(state, index++); a.y = l_tools_toNumberOrError(state, index++); cpVect b = cpvzero; b.x = l_tools_toNumberOrError(state, index++); b.y = l_tools_toNumberOrError(state, index++); cpFloat radius = l_tools_toNumberOrError(state, index++); _mass = mass; moment = cpMomentForSegment(mass, a, b, radius); } } if (_mass > 0) cpBodySetMass(body->body, _mass); cpBodySetMoment(body->body, moment); return 0; }