void weapon_update(Entity *ent) { cpBody *body = entity_body(ent); WeaponEntityData *data = entity_data(ent); if (data->owner && !data->player_joint) { cvar_setd_player(entity_owner(ent), "weapon_id", entity_id(ent)); data->player_joint = cpSpaceAddConstraint(game.space, cpPivotJointNew2( body, entity_body(data->owner), cpv(0, -WEAPON_HEIGHT / 2), cpv(1, 0) )); cpConstraintSetErrorBias(data->player_joint, 0); } int mult = 0; if (keymap_is_held("mouse1")) mult++; if (keymap_is_held("mouse2")) mult--; if (mult) { cpVect force_pos = cpv(0, WEAPON_HEIGHT); cpVect weapon_pos = cpBodyGetPosition(body); cpVect world_force_pos = cpvadd(weapon_pos, cpvrotate(cpBodyGetRotation(body), force_pos)); cpVect mouse_delta = cpvsub(keymap_mouse_world(), world_force_pos); cpVect force = cpvmult(cpvnormalize(mouse_delta), mult * WEAPON_SWING_FORCE); cpBodyApplyForceAtWorldPoint(body, force, world_force_pos); } }
/* * Chipmunk2d::Constraint#error_bias=(error_bias) * @param [Float] error_bias */ static mrb_value constraint_set_error_bias(mrb_state *mrb, mrb_value self) { cpConstraint *constraint; mrb_float error_bias; mrb_get_args(mrb, "f", &error_bias); constraint = mrb_data_get_ptr(mrb, self, &mrb_cp_constraint_type); cpConstraintSetErrorBias(constraint, (cpFloat)error_bias); return mrb_nil_value(); }
/* Mouse handling is a bit tricky. We want the user to move * tiles using the mouse but because tiles are dynamic bodies * managed by Chipmunk2D, we cannot directly control them. * This is resolved by creating a pivot joint between an * invisible mouse body that we can control and the tile body * that we cannot directly control. */ static void apply_mouse_motion(struct state* state) { struct mouse m; update_mouse(&m); int w, h; get_screen_size(&w, &h); int x = m.x_position * w; int y = m.y_position * h; cpVect mouse_pos = cpv(x, y); cpVect new_point = cpvlerp(cpBodyGetPosition(state->mouse_body), mouse_pos, 0.25f); cpBodySetVelocity( state->mouse_body, cpvmult(cpvsub(new_point, cpBodyGetPosition(state->mouse_body)), 60.0f)); cpBodySetPosition(state->mouse_body, new_point); if (m.left_click && state->mouse_joint == NULL) { cpFloat radius = 5.0; cpPointQueryInfo info = { 0 }; cpShape* shape = cpSpacePointQueryNearest(state->space, mouse_pos, radius, GRAB_FILTER, &info); if (shape && cpBodyGetMass(cpShapeGetBody(shape)) < INFINITY) { cpVect nearest = (info.distance > 0.0f ? info.point : mouse_pos); cpBody* body = cpShapeGetBody(shape); state->mouse_joint = cpPivotJointNew2(state->mouse_body, body, cpvzero, cpBodyWorldToLocal(body, nearest)); cpConstraintSetMaxForce(state->mouse_joint, 5000000.0f); cpConstraintSetErrorBias(state->mouse_joint, cpfpow(1.0f - 0.15f, 60.0f)); cpSpaceAddConstraint(state->space, state->mouse_joint); } } if (m.left_click == false && state->mouse_joint != NULL) { cpSpaceRemoveConstraint(state->space, state->mouse_joint); cpConstraintFree(state->mouse_joint); state->mouse_joint = NULL; } }
void physics_add_top_down_friction(cpBody *body, cpBody *control, float friction, cpConstraint **out_pivot, cpConstraint **out_gear) { //emulates linear friction cpConstraint *pivot = cpSpaceAddConstraint(game.space, cpPivotJointNew2( control, body, cpvzero, cpvzero )); cpConstraintSetErrorBias(pivot, cpBodyGetMass(body) * friction); cpConstraintSetMaxForce(pivot, cpBodyGetMass(body) * friction); //emulates angular friction cpConstraint *gear = cpSpaceAddConstraint(game.space, cpGearJointNew( control, body, 0, 1 )); cpConstraintSetMaxBias(gear, 0); cpConstraintSetMaxForce(gear, friction / cpBodyGetMass(body) / 10); if (out_pivot) *out_pivot = pivot; if (out_gear) *out_gear = gear; }
// float SG_CALL sgPhysicsConstraintGetMaxForce(SGPhysicsConstraint* constr); void SG_CALL sgPhysicsConstraintSetErrorBias(SGPhysicsConstraint* constr, float bias) { cpConstraintSetErrorBias(constr->handle, bias); }
void CCJoint::setErrorBias(cpFloat errorBias) { cpConstraintSetErrorBias(this->m_constraint, errorBias); }