Shell(cpVect pos, cpVect vel, float angle) { cpVect vl[4] = {cpv(0, 0), cpv(0.1, 0), cpv(0.07, 0.3), cpv(0.03, 0.3)}; int vn = sizeof(vl)/sizeof(cpVect); float mass = cpAreaForPoly(vn, vl, 0) * shell_density; float moi = cpMomentForPoly(mass, vn, vl, cpv(0, 0), 0); body = cpBodyNew(mass, moi); cpshape = cpPolyShapeNew(body, vn, vl, cpTransformIdentity, 0); cpShapeSetFriction(cpshape, 0.9); cpVect centroid = cpCentroidForPoly(vn, vl); shape.setPointCount(vn); for (int i = 0; i < vn; i++) { shape.setPoint(i, sf::Vector2f(vl[i].x, vl[i].y)); } cpBodySetCenterOfGravity(body, centroid); cpBodySetPosition(body, pos-centroid); cpBodySetVelocity(body, vel); cpBodySetAngle(body, angle); cpShapeSetCollisionType(cpshape, 2); cpShapeSetUserData(cpshape, this); }
float PhysicsShapePolygon::calculateArea(const Vec2* points, int count) { cpVect* vecs = new (std::nothrow) cpVect[count]; PhysicsHelper::points2cpvs(points, vecs, count); float area = PhysicsHelper::cpfloat2float(cpAreaForPoly(count, vecs, 0.0f)); CC_SAFE_DELETE_ARRAY(vecs); return area; }
float PhysicsShapePolygon::calculateArea(Point* points, int count) { cpVect* vecs = new cpVect[count]; PhysicsHelper::points2cpvs(points, vecs, count); float area = PhysicsHelper::cpfloat2float(cpAreaForPoly(count, vecs)); CC_SAFE_DELETE(vecs); return area; }
float PhysicsShapeBox::calculateArea(const Size& size) { cpVect wh = PhysicsHelper::size2cpv(size); cpVect vec[4] = { {-wh.x/2.0f, -wh.y/2.0f}, {-wh.x/2.0f, wh.y/2.0f}, {wh.x/2.0f, wh.y/2.0f}, {wh.x/2.0f, -wh.y/2.0f} }; return PhysicsHelper::cpfloat2float(cpAreaForPoly(4, vec)); }
cpPolylineSet * cpPolylineConvexDecomposition_BETA(cpPolyline *line, cpFloat tol) { cpAssertSoft(cpPolylineIsClosed(line), "Cannot decompose an open polygon."); cpAssertSoft(cpAreaForPoly(line->count, line->verts, 0.0) >= 0.0, "Winding is backwards. (Are you passing a hole?)"); cpPolylineSet *set = cpPolylineSetNew(); ApproximateConcaveDecomposition(line->verts, line->count - 1, tol, set); return set; }
float PhysicsShapePolygon::calculateArea() { auto shape = _cpShapes.front(); int count = cpPolyShapeGetCount(shape); cpVect* vecs = new cpVect[count]; for(int i=0;i<count;++i) vecs[i] = cpPolyShapeGetVert(shape, i); float area = PhysicsHelper::cpfloat2float(cpAreaForPoly(count, vecs, cpPolyShapeGetRadius(shape))); CC_SAFE_DELETE_ARRAY(vecs); return area; }
__declspec( dllexport ) void areaforpolygon( const void * _in, int in_size, void * _out, int out_sz ) { int i; int size = PEEKINT(INPUT_MEMBLOCK,0); cpVect *vertices = (cpVect*)malloc(size*sizeof(cpVect)); for (i = 0;i != size;i++) { vertices[i] = PEEKVECT(INPUT_MEMBLOCK,4+i*8); } POKEFLOAT(OUTPUT_MEMBLOCK,0,cpAreaForPoly(size,vertices)); free(vertices); }
static VALUE rb_cpAreaForPoly(VALUE self, VALUE arr) { Check_Type(arr, T_ARRAY); long numVerts = RARRAY_LEN(arr); VALUE *ary_ptr = RARRAY_PTR(arr); cpVect verts[numVerts]; for(long i = 0; i < numVerts; i++) verts[i] = *VGET(ary_ptr[i]); cpFloat area = cpAreaForPoly(numVerts, verts); return rb_float_new(area); }
static struct cpShapeMassInfo cpPolyShapeMassInfo(cpFloat mass, int count, const cpVect *verts, cpFloat radius) { // TODO moment is approximate due to radius. cpVect centroid = cpCentroidForPoly(count, verts); struct cpShapeMassInfo info = { mass, cpMomentForPoly(1.0f, count, verts, cpvneg(centroid), radius), centroid, cpAreaForPoly(count, verts, radius), }; return info; }
/** @name areaForCircle @text Returns the area for a polygon. @in table vertices Array containg vertex coordinate components ( t[1] = x0, t[2] = y0, t[3] = x1, t[4] = y1... ) @out number area */ int MOAICpShape::_areaForPolygon ( lua_State* L ) { USLuaState state ( L ); if ( !state.CheckParams ( 1, "T" )) return 0; cpVect verts [ MAX_POLY_VERTS ]; int numVerts = MOAICpShape::LoadVerts ( state, 1, verts, MAX_POLY_VERTS ); if ( numVerts && cpPolyValidate ( verts, numVerts )) { cpFloat area = cpAreaForPoly ( numVerts, verts ); area = area < 0 ? -area : area; lua_pushnumber ( L, area ); return 1; } return 0; }
Ship(int vn, cpVect* vl, cpVect pos, Genome* ng = 0) { float mass = cpAreaForPoly(vn, vl, 0) * ship_density; float moi = cpMomentForPoly(mass, vn, vl, cpv(0, 0), 0); body = cpBodyNew(mass, moi); cpshape = cpPolyShapeNew(body, vn, vl, cpTransformIdentity, 0); cpShapeSetFriction(cpshape, 0.9); cpVect centroid = cpCentroidForPoly(vn, vl); shape.setPointCount(vn); for (int i = 0; i < vn; i++) { shape.setPoint(i, sf::Vector2f(vl[i].x, vl[i].y)); } cpBodySetCenterOfGravity(body, centroid); cpBodySetPosition(body, pos-centroid); cpBodySetVelocity(body, cpv(0, 0)); cpShapeSetCollisionType(cpshape, 1); cpShapeSetUserData(cpshape, this); last_fired = 0; nose_angle = PI/2; player = false; target = 0; score = 0; if (ng == 0) { Genome* braingenome = mutate(readgenome("shipmind.mind")); brain = braingenome->makenetwork(); delete braingenome; } else { brain = ng->makenetwork(); } score = 0; }
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 Slice::ClipPoly(cpSpace *space, cpShape *shape, cpVect n, cpFloat dist) { cpBody *body = cpShapeGetBody(shape); int count = cpPolyShapeGetCount(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 = cpBodyLocalToWorld(body, cpPolyShapeGetVert(shape, j)); cpFloat a_dist = cpvdot(a, n) - dist; if(a_dist < 0.0){ clipped[clippedCount] = a; clippedCount++; } cpVect b = cpBodyLocalToWorld(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, 0.0f)*DENSITY; cpFloat moment = cpMomentForPoly(mass, clippedCount, clipped, cpvneg(centroid), 0.0f); cpBody *new_body = cpSpaceAddBody(space, cpBodyNew(mass, moment)); cpBodySetPosition(new_body, centroid); cpBodySetVelocity(new_body, cpBodyGetVelocityAtWorldPoint(body, centroid)); cpBodySetAngularVelocity(new_body, cpBodyGetAngularVelocity(body)); cpTransform transform = cpTransformTranslate(cpvneg(centroid)); cpShape *new_shape = cpSpaceAddShape(space, cpPolyShapeNew(new_body, clippedCount, clipped, transform, 0.0)); // Copy whatever properties you have set on the original shape that are important cpShapeSetFriction(new_shape, cpShapeGetFriction(shape)); }
cpBool Buoyancy::WaterPreSolve(cpArbiter *arb, cpSpace *space, void *ptr) { CP_ARBITER_GET_SHAPES(arb, water, poly); cpBody *body = cpShapeGetBody(poly); // Get the top of the water sensor bounding box to use as the water level. cpFloat level = cpShapeGetBB(water).t; // Clip the polygon against the water level int count = cpPolyShapeGetCount(poly); int clippedCount = 0; #ifdef _MSC_VER // MSVC is pretty much the only compiler in existence that doesn't support variable sized arrays. cpVect clipped[10]; #else cpVect clipped[count + 1]; #endif for(int i=0, j=count-1; i<count; j=i, i++){ cpVect a = cpBodyLocalToWorld(body, cpPolyShapeGetVert(poly, j)); cpVect b = cpBodyLocalToWorld(body, cpPolyShapeGetVert(poly, i)); if(a.y < level){ clipped[clippedCount] = a; clippedCount++; } cpFloat a_level = a.y - level; cpFloat b_level = b.y - level; if(a_level*b_level < 0.0f){ cpFloat t = cpfabs(a_level)/(cpfabs(a_level) + cpfabs(b_level)); clipped[clippedCount] = cpvlerp(a, b, t); clippedCount++; } } // Calculate buoyancy from the clipped polygon area cpFloat clippedArea = cpAreaForPoly(clippedCount, clipped, 0.0f); cpFloat displacedMass = clippedArea*FLUID_DENSITY; cpVect centroid = cpCentroidForPoly(clippedCount, clipped); cpDataPointer data = ptr; DrawPolygon(clippedCount, clipped, 0.0f, RGBAColor(0, 0, 1, 1), RGBAColor(0, 0, 1, 0.1f), data); DrawDot(5, centroid, RGBAColor(0, 0, 1, 1), data); cpFloat dt = cpSpaceGetCurrentTimeStep(space); cpVect g = cpSpaceGetGravity(space); // Apply the buoyancy force as an impulse. cpBodyApplyImpulseAtWorldPoint(body, cpvmult(g, -displacedMass*dt), centroid); // Apply linear damping for the fluid drag. cpVect v_centroid = cpBodyGetVelocityAtWorldPoint(body, centroid); cpFloat k = k_scalar_body(body, centroid, cpvnormalize(v_centroid)); cpFloat damping = clippedArea*FLUID_DRAG*FLUID_DENSITY; cpFloat v_coef = cpfexp(-damping*dt*k); // linear drag // cpFloat v_coef = 1.0/(1.0 + damping*dt*cpvlength(v_centroid)*k); // quadratic drag cpBodyApplyImpulseAtWorldPoint(body, cpvmult(cpvsub(cpvmult(v_centroid, v_coef), v_centroid), 1.0/k), centroid); // Apply angular damping for the fluid drag. cpVect cog = cpBodyLocalToWorld(body, cpBodyGetCenterOfGravity(body)); cpFloat w_damping = cpMomentForPoly(FLUID_DRAG*FLUID_DENSITY*clippedArea, clippedCount, clipped, cpvneg(cog), 0.0f); cpBodySetAngularVelocity(body, cpBodyGetAngularVelocity(body)*cpfexp(-w_damping*dt/cpBodyGetMoment(body))); return cpTrue; }
float PhysicsShapePolygon::calculateDefaultArea() { cpShape* shape = _info->shapes.front(); return PhysicsHelper::cpfloat2float(cpAreaForPoly(((cpPolyShape*)shape)->numVerts, ((cpPolyShape*)shape)->verts)); }
float PhysicsShapePolygon::calculateArea() { auto shape = _cpShapes.front(); return PhysicsHelper::cpfloat2float(cpAreaForPoly(((cpPolyShape*)shape)->numVerts, ((cpPolyShape*)shape)->verts)); }
cpFloat Area::ForPoly( const int numVerts, const cVect * verts ) { return cpAreaForPoly( numVerts, constcasttocpv( verts ) ); }
float PhysicsShapeBox::calculateArea() { cpShape* shape = _info->getShapes().front(); return PhysicsHelper::cpfloat2float(cpAreaForPoly(((cpPolyShape*)shape)->numVerts, ((cpPolyShape*)shape)->verts)); }