static cpBool bulletPlaneBeginFunc(cpArbiter *arb, cpSpace *space, void*) { cpShape *a,*b; cpArbiterGetShapes(arb, &a,&b); cpBody *targetBody = cpShapeGetBody(b); if (((Bullet *)cpBodyGetUserData(cpShapeGetBody(a)))->player()->body() != targetBody) { printf("Hit plane\n"); Player * player = (Player *)(cpBodyGetUserData(targetBody)); player->hurt(200); cpSpaceAddPostStepCallback( space, (cpPostStepFunc)ammoFree, a, NULL); return true; } return false; }
ETERM *space_delete(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); // remove all subscribers for(erlmunk_subscriber *subscriber = s->subscribers; subscriber != NULL; subscriber = subscriber->hh.next) { space_remove_subscriber(s, subscriber); } // remove all bodies for(erlmunk_body *b = s->bodies; b != NULL; b = b->hh.next) { erlmunk_body_data *data = cpBodyGetUserData(b->body); if (data->term != NULL) erl_free_compound(data->term); free(data); cpSpaceRemoveBody(s->space, b->body); cpBodyDestroy(b->body); cpBodyFree(b->body); space_remove_body_hash(s, b); } return NULL; }
ETERM *space_remove_body(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b = NULL; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; // DEBUGF(("removing body #%d\n", body_id)); // remove the user data associated with the body erlmunk_body_data *data = cpBodyGetUserData(b->body); if (data->term != NULL) erl_free_compound(data->term); free(data); cpBodyEachShape(b->body, shapeRemove, NULL); cpSpaceRemoveBody(s->space, b->body); space_remove_body_hash(s, b); cpBodyDestroy(b->body); cpBodyFree(b->body); return NULL; }
void drawing_activate(cpSpace *space, cpBody *drawing) { drawing = utils_update_drawing(drawing); cpSpaceAddBody(space, drawing); Point_array * parray = cpBodyGetUserData(drawing); point_array_free_arrays(parray); }
cpBody* drawing_update(cpSpace *space, cpBody *drawing, cpFloat x, cpFloat y) { Body_data *pa = cpBodyGetUserData(drawing); int length = pa->x_values->len; cpVect old = cpvzero; old.x = g_array_index(pa->x_values, cpFloat, length - 1); old.y = g_array_index(pa->y_values, cpFloat, length - 1); old = cpBodyLocal2World(drawing, old); cpVect point = cpv(x, y); // if the difference between the new x and the previous x is greater than the threshold if (cpvdistsq(old, point) > THRESHOLD) { cpVect position = cpBodyGetPos(drawing); point = cpvsub(point, position); //cpBodyWorld2Local(drawing, point); fprintf(stdout, "Point= (%5.2f, %5.2f) while x= %5.2f, y=%5.2f\n", point.x, point.y, x, y); x = point.x; y = point.y; g_array_append_val(pa->x_values, x); g_array_append_val(pa->y_values, y); cpBodySetUserData(drawing, pa); drawing = add_segment_to_body(space, drawing); } cpBodySetVel(drawing, cpvzero); return drawing; }
static Body_data* shift_origin(cpBody *body, cpVect old_origin, cpVect new_origin) { Body_data *pa = cpBodyGetUserData(body); cpVect offset = cpvsub(new_origin, old_origin); cpFloat x_offset = offset.x; cpFloat y_offset = offset.y; int length = pa->x_values->len; cpFloat x, y; GArray *new_x = g_array_sized_new(FALSE, FALSE, sizeof(cpFloat), length); GArray *new_y = g_array_sized_new(FALSE, FALSE, sizeof(cpFloat), length); //fprintf(stdout, "There are %d indices:\n", length); for (int index = 0; index < length; index++) { x = g_array_index(pa->x_values, cpFloat, index) - x_offset; y = g_array_index(pa->y_values, cpFloat, index) - y_offset; g_array_append_val( new_x, x ); g_array_append_val( new_y, y ); //fprintf(stdout, "Index %d:\t(%5.2f, %5.2f)\n", index, x, y); } g_array_free(pa->x_values, TRUE); g_array_free(pa->y_values, TRUE); pa->x_values = new_x; pa->y_values = new_y; return pa; }
static void post_step_body_replace_shapes(cpSpace *space, cpBody *body, void *data) { Body_data *pa = cpBodyGetUserData(body); int length = pa->x_values->len; cpBodyEachShape(body, (cpBodyShapeIteratorFunc) free_shape, NULL); cpSpaceReindexShapesForBody(space, body); //fprintf(stderr, "0Made it this far.\n"); for (int index = 1; index < length; index++) { cpFloat x = g_array_index(pa->x_values, cpFloat, index); cpFloat y = g_array_index(pa->y_values, cpFloat, index); cpShape *seg = cpSegmentShapeNew(body, cpv(x,y), cpv(g_array_index(pa->x_values, cpFloat, index - 1), g_array_index(pa->y_values, cpFloat, index - 1)), CRAYON_RADIUS); //fprintf(stderr, "1Made it this far.\n"); cpShapeSetFriction(seg, CRAYON_FRICTION); //fprintf(stderr, "2Made it this far.\n"); //cpShapeSetElasticity(cpShape *shape, cpFloat value)? cpSpaceAddShape(space, seg); //fprintf(stderr, "3Made it this far.\n"); } cpSpaceReindexShapesForBody(space, body); }
ETERM *body_get_user_data(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; erlmunk_body_data *data = cpBodyGetUserData(b->body); ETERM *datap = erl_copy_term(data->term); ETERM *atom_ok = erl_mk_atom("ok"); ETERM **body_get_data_array = (ETERM **) malloc(sizeof(ETERM*) * 2); body_get_data_array[0] = atom_ok; body_get_data_array[1] = datap; ETERM *body_get_data_tuple = erl_mk_tuple(body_get_data_array, 2); free(body_get_data_array); ETERM *reply_tuple = erl_mk_reply(fromp, body_get_data_tuple); ETERM *gen_cast_tuple = erl_mk_gen_cast(reply_tuple); return gen_cast_tuple; }
void handle_subscriber(erlmunk_subscriber *subscriber, element *bodies) { element *el; int count = 0; LL_COUNT(bodies, el, count); // DEBUGF(("# bodies in subscriber bounding box: %d", count)); ETERM **l_array = (ETERM **) malloc(sizeof(ETERM) * count); int nth_body = 0; LL_FOREACH(bodies, el) { cpVect vect = cpBodyGetPosition(el->body); float angle = cpBodyGetAngle(el->body); // cpVect vel = cpBodyGetVelocity(el->body); erlmunk_body_data *data = (erlmunk_body_data *) cpBodyGetUserData(el->body); // DEBUGF(("id: %d, x: %f, y: %f, angle: %f, vel.x: %f, vel.y: %f, data: %p", // data->id, vect.x, vect.y, angle, vel.x, vel.y, data)); ETERM **t_array = (ETERM **) malloc(sizeof(ETERM) * 4); t_array[0] = erl_mk_float(vect.x); t_array[1] = erl_mk_float(vect.y); t_array[2] = erl_mk_float(angle); if (data->term == NULL) t_array[3] = erl_mk_undefined(); else t_array[3] = erl_copy_term(data->term); ETERM *tuple = erl_mk_tuple(t_array, 4); free(t_array); ETERM *prop_value = erl_mk_int_prop_value(data->id, tuple); l_array[nth_body++] = prop_value; }
static void _add_collision(cpBody *body, cpArbiter *arbiter, void *collisions) { cpBody *ba, *bb; Collision *col; /* get in right order */ cpArbiterGetBodies(arbiter, &ba, &bb); if (bb == body) { ba = body; bb = ba; } /* save collision */ col = array_add(collisions); col->a = cpBodyGetUserData(ba); col->b = cpBodyGetUserData(bb); }
void free_body_full(cpBody *body) { cpBodyEachShape(body, (cpBodyShapeIteratorFunc) free_shape, NULL); point_array_free( (Body_data *) cpBodyGetUserData(body) ); cpSpace *space = cpBodyGetSpace(body); cpSpaceRemoveBody(space, body); cpBodyDestroy(body); cpBodyFree(body); }
static void print_positions(cpBody* drawing) { cpVect pos = cpBodyGetPos(drawing); printf("Center of mass (%2.2f, %2.2f)\n", pos.x, pos.y); Body_data *pa = (Body_data *) cpBodyGetUserData(drawing); for (int i = 0; i < pa->x_values->len; i++) { printf("Segment %d starts at (%2.2f, %2.2f)\n", i, g_array_index(pa->x_values, cpFloat, i), g_array_index(pa->y_values, cpFloat, i)); } }
static cpBool handle_collision(cpArbiter *arbiter, cpSpace *space, cpDataPointer user_data) { CP_ARBITER_GET_BODIES(arbiter, b1, b2); erlmunk_subscriber *subscriber = (erlmunk_subscriber *) user_data; erlmunk_body_data *data1 = cpBodyGetUserData(b1); erlmunk_body_data *data2 = cpBodyGetUserData(b2); // DEBUGF(("collision detected between %d and %d\n", data1->id, data2->id)); ETERM **data1_array = (ETERM **) malloc(sizeof(ETERM) * 2); data1_array[0] = erl_mk_int(data1->id); data1_array[1] = data1->term; ETERM *data1_term = erl_mk_tuple(data1_array, 2); free(data1_array); ETERM **data2_array = (ETERM **) malloc(sizeof(ETERM) * 2); data2_array[0] = erl_mk_int(data2->id); data2_array[1] = data2->term; ETERM *data2_term = erl_mk_tuple(data2_array, 2); free(data2_array); ETERM *a = erl_mk_atom("erlmunk_collision"); ETERM **data_array = (ETERM **) malloc(sizeof(ETERM) * 3); data_array[0] = a; data_array[1] = data1_term; data_array[2] = data2_term; ETERM *data = erl_mk_tuple(data_array, 3); free(data_array); ETERM *gen_cast = erl_mk_gen_cast(data); if (erl_send(subscriber->client->fd, subscriber->from, gen_cast) != 1) { DEBUGF(("failed to send data to subscriber")); } return cpFalse; }
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; }
//Post-step: Ammo free static void ammoFree( cpSpace *space, cpShape *shape, void *unused) { cpBody *body = cpShapeGetBody(shape); Bullet *ammo = (Bullet*)cpBodyGetUserData(body); //cpVect pos = cpBodyGetPosition(Body); //printf("body->p: %f %f \n", Body->p.x, Body->p.y); //printf("Position: %f %f \n",pos.x,pos.y); //ammo->explosion(Body->p.x - 59, Body->p.y - 59); // for(int i=0; i < EXPLOSION_MAXIMUM_SPRITES; i++) // if( !explosionCheck[i] ) // explosionSet(i, Body->p.x - 59, Body->p.y - 59); Explosion(body->p.x - 59, body->p.y -59); printf("Post step free"); ammo->destroy(); }
/* * @return [Chipmunk2d::Body] * @private api */ static mrb_value constraint_get_mrb_cp_body(mrb_state *mrb, mrb_value self, cpBody *body) { mrb_cp_body_user_data *user_data; if (body) { user_data = cpBodyGetUserData(body); if (!user_data) { mrb_raise(mrb, E_RUNTIME_ERROR, "body does not have a valid user_data!"); } else { return user_data->body; } } return mrb_nil_value(); }
/* * @return [Array<Chipmunk2d::Body>] */ static mrb_value arbiter_bodies(mrb_state* mrb, mrb_value self) { cpArbiter* arbiter; cpBody* body1; cpBody* body2; mrb_value argv[2] = { mrb_nil_value(), mrb_nil_value() }; mrb_cp_body_user_data* user_data; arbiter = mrb_cp_get_arbiter_ptr(mrb, self); cpArbiterGetBodies(arbiter, &body1, &body2); user_data = (struct mrb_cp_body_user_data*)cpBodyGetUserData(body1); if (user_data) { argv[0] = user_data->body; } user_data = (struct mrb_cp_body_user_data*)cpBodyGetUserData(body2); if (user_data) { argv[1] = user_data->body; } return mrb_ary_new_from_values(mrb, 2, argv); }
void drawing_activate(cpSpace *space, cpBody *drawing, long in_color) { long seed = (long int) drawing; srand((unsigned int) seed); long color = rand(); cpSpaceAddBody(space, drawing); drawing = utils_update_drawing(drawing); Body_data * parray = cpBodyGetUserData(drawing); if (in_color = -1){ parray->color_rgb = color; }else{ parray->color = in_color; } point_array_free_arrays(parray); }
// once a new point has been added to the point_array, add the new segment to the body static cpBody *add_segment_to_body(cpSpace *space, cpBody *drawing) { Body_data *pa = cpBodyGetUserData(drawing); int length = pa->x_values->len; cpShape *seg = cpSegmentShapeNew(drawing, cpv(g_array_index(pa->x_values, cpFloat, length - 2), g_array_index(pa->y_values, cpFloat, length - 2)), cpv(g_array_index(pa->x_values, cpFloat, length - 1), g_array_index(pa->y_values, cpFloat, length - 1)), CRAYON_RADIUS); cpShapeSetFriction(seg, CRAYON_FRICTION); //cpShapeSetElasticity(cpShape *shape, cpFloat value)? cpSpaceAddShape(space, seg); return drawing; }
cpBody* drawing_update(cpSpace *space, cpBody *drawing, cpFloat x, cpFloat y) { Point_array *pa = cpBodyGetUserData(drawing); int length = pa->x_values->len; // if the difference between the new x and the previous x is greater than the threshold if (( abs((SCALE * x) - (SCALE * g_array_index(pa->x_values, cpFloat, length - 1))) >= (SCALE * THRESHOLD) ) || ( abs((SCALE * y) - (SCALE * g_array_index(pa->y_values, cpFloat, length - 1))) >= (SCALE * THRESHOLD) )) { g_array_append_val(pa->x_values, x); g_array_append_val(pa->y_values, y); cpBodySetUserData(drawing, pa); drawing = add_segment_to_body(space, drawing); } cpBodySetVel(drawing, cpvzero); return drawing; }
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; }
ETERM *body_update_user_data(ETERM *fromp, ETERM *argp) { // DEBUGF(("body_update_user_data\n")); // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); ETERM *keyp = erl_element(3, argp); ETERM *valuep = erl_element(4, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; erlmunk_body_data *data = cpBodyGetUserData(b->body); ETERM *new_data_term = erl_lists_keyreplace(data->term, keyp, valuep); erl_free_compound(data->term); data->term = new_data_term; ETERM *new_valuep = erl_proplists_get_value(keyp, new_data_term); // obtain updated key value and return that ETERM *atom_ok = erl_mk_atom("ok"); ETERM **body_update_data_array = (ETERM **) malloc(sizeof(ETERM*) * 2); body_update_data_array[0] = atom_ok; body_update_data_array[1] = new_valuep; ETERM *body_update_data_tuple = erl_mk_tuple(body_update_data_array, 2); free(body_update_data_array); ETERM *reply_tuple = erl_mk_reply(fromp, body_update_data_tuple); ETERM *gen_cast_tuple = erl_mk_gen_cast(reply_tuple); return gen_cast_tuple; }
void weapon_collide(Entity *ent, cpArbiter *arb) { cpBody *body = entity_body(ent); cpBody *other = physics_arbiter_get_other(body, arb); Entity *other_ent = cpBodyGetUserData(other); //only damage players if (!entity_valid(other_ent) || entity_type(other_ent) != &PlayerEntity) { return; } //only damage enemies if (entity_owner(ent) != connection_get_user_id() || entity_owner(other_ent) == connection_get_user_id()) { return; } float speed = cpvlength(cpBodyGetVelocity(body)); if (speed < WEAPON_HURT_THRESHOLD) { return; } player_hurt(entity_owner(other_ent), WEAPON_DAMAGE * speed, entity_owner(ent)); }
ETERM *body_set_user_data(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); ETERM *datap = erl_element(3, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; erlmunk_body_data *data = cpBodyGetUserData(b->body); data->term = erl_copy_term(datap); cpBodySetUserData(b->body, (cpDataPointer) data); return NULL; }
void planeCloud(cpShape * planeShape, int num) { Player *p1 = (Player*)cpBodyGetUserData(cpShapeGetBody(planeShape)); p1->setInCloud(num); }
void free_body_full(cpBody *body) { cpBodyEachShape(body, (cpBodyShapeIteratorFunc) free_shape, NULL); point_array_free( (Point_array *) cpBodyGetUserData(body) ); cpBodyFree(body); }
std::pair<Body*, Body*> Arbiter::getBodies() const { cpBody* a, * b; cpArbiterGetBodies(_arbiter, &a, &b); return std::make_pair((Body*)cpBodyGetUserData(a), (Body*)cpBodyGetUserData(b)); }