PhysicsShape* PhysicsBody::addShape(PhysicsShape* shape, bool addMassAndMoment/* = true*/) { if (shape == nullptr) return nullptr; // add shape to body if (_shapes.getIndex(shape) == -1) { shape->setBody(this); // calculate the area, mass, and density // area must update before mass, because the density changes depend on it. if (addMassAndMoment) { _area += shape->getArea(); addMass(shape->getMass()); addMoment(shape->getMoment()); } if (_world && cpBodyGetSpace(_cpBody)) { _world->addShape(shape); } _shapes.pushBack(shape); } return shape; }
NS_CC_EXT_BEGIN #if CC_ENABLE_CHIPMUNK_INTEGRATION /* IMPORTANT - READ ME! This file sets pokes around in the private API a lot to provide efficient debug rendering given nothing more than reference to a Chipmunk space. It is not recommended to write rendering code like this in your own games as the private API may change with little or no warning. */ static Color4F ColorForBody(cpBody *body) { if (CP_BODY_TYPE_STATIC == cpBodyGetType(body) || cpBodyIsSleeping(body)) { return Color4F(0.5f, 0.5f, 0.5f ,0.5f); } else if (body->sleeping.idleTime > cpBodyGetSpace(body)->sleepTimeThreshold) { return Color4F(0.33f, 0.33f, 0.33f, 0.5f); } else { return Color4F(1.0f, 0.0f, 0.0f, 0.5f); } }
Line::Line(ShapeLine *src, float mass){ cpFloat moment = cpMomentForSegment(mass, toChipmunk(src->getA()), toChipmunk(src->getB()), src->getRadius()); DynamicBody::setup(cpShapeGetSpace(src->shape), mass, moment); ShapeLine::setup(src); cpSpaceRemoveShape(cpShapeGetSpace(shape), shape); cpSpaceAddShape(cpBodyGetSpace(body), shape); cpShapeSetBody(shape, body); }
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); }
//destroy bodies out of bound static void core_destroy_out_bodies ( cpBody *body, void *data ) { cpVect pos = cpBodyGetPos ( body ); if ( pos.y < -50 || pos.y > (CORE_MAX_HEIGHT + 50) || pos.x < - 50 || pos.x > 200) { cpSpaceAddPostStepCallback( cpBodyGetSpace(body), (cpPostStepFunc)postStepRemoveBody, body, NULL ); } else return; }
Polygon::Polygon(ShapePolygon *src, float mass){ std::vector<glm::vec2> ofVerts = src->getPoints(); std::vector<cpVect> verts = toChipmunk(ofVerts); cpFloat moment = cpMomentForPoly(mass, verts.size(), verts.data(), cpvzero, cpPolyShapeGetRadius(src->shape)); DynamicBody::setup(cpShapeGetSpace(src->shape), mass, moment); cpSpaceRemoveShape(cpShapeGetSpace(src->shape), src->shape); ShapePolygon::setup(src); cpShapeSetBody(shape, body); cpSpaceAddShape(cpBodyGetSpace(body), shape); }
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 handle_shape(cpShape *shape, void *data) { cpBody *body = cpShapeGetBody(shape); // get the static body that comes with the space cpSpace *space = cpBodyGetSpace(body); cpBody *static_body = cpSpaceGetStaticBody(space); // ignore the static body if (static_body == body) return; element *el = (element *) malloc(sizeof(element)); el->body = body; element **l = (element **) data; LL_APPEND(*l, el); }
Body::~Body(){ if(body){ //clean up all constraints constraintsToRemove.clear(); cpBodyEachConstraint(body, &constraintRemoveQuery, (void*)this); for(auto c: constraintsToRemove){ ((Constraint*)cpConstraintGetUserData(c))->constraint = nullptr; cpSpaceRemoveConstraint(cpConstraintGetSpace(c), c); cpConstraintDestroy(c); } //remove body cpSpaceRemoveBody(cpBodyGetSpace(body), body); cpBodyFree(body); body = nullptr; } }
static void free_shape(cpBody *body, cpShape *shape, void *data) { cpSpace *space = cpBodyGetSpace(body); cpSpaceRemoveShape(space, shape); cpShapeDestroy(shape); cpShapeFree(shape); }
cp::Space* Body::getSpace(void) { cpSpace *temp = cpBodyGetSpace(body); return static_cast<cp::Space*>(temp ? temp->data : 0); }