コード例 #1
0
ファイル: testwheel.c プロジェクト: andrenho/newhope
void draw_shape(cpBody* body, cpShape* shape, void* data)
{
	// get body info
	cpVect v = cpBodyGetPos(body);
	cpFloat angle = cpBodyGetAngle(body);
	cpVect rot = cpvforangle(angle);

	// get vectors
	int n = cpPolyShapeGetNumVerts(shape); 
	SDL_Point* pts = calloc(sizeof(SDL_Point), n+1);

	// rotate vectors
	int i;
	for(i=0; i<n; i++) {
		cpVect p = cpPolyShapeGetVert(shape, i);
		cpVect vr = cpvrotate(cpv(p.x,p.y), rot);
		pts[i] = (SDL_Point) { (vr.x+v.x)*10+50, (vr.y+v.y)*10+50 };
		if(i == 0)
			pts[n] = pts[i];
	}

	// draw
	SDL_RenderDrawLines(ren, pts, n+1);

	free(pts);
}
コード例 #2
0
void PhysicsShapePolygon::updateScale()
{
    cpFloat factorX = _newScaleX / _scaleX;
    cpFloat factorY = _newScaleY / _scaleY;

    auto shape = _cpShapes.front();
    int count = cpPolyShapeGetCount(shape);
    cpVect* vects = new cpVect[count];
    for(int i=0;i<count;++i)
        vects[i] = cpPolyShapeGetVert(shape, i);

    for (int i = 0; i < count; ++i)
    {
        vects[i].x *= factorX;
        vects[i].y *= factorY;
    }

    // convert hole to clockwise
    if (factorX * factorY < 0)
    {
        for (int i = 0; i < count / 2; ++i)
        {
            cpVect v = vects[i];
            vects[i] = vects[count - i - 1];
            vects[count - i - 1] = v;
        }
    }
    
    cpPolyShapeSetVertsRaw(shape, count, vects);
    CC_SAFE_DELETE_ARRAY(vects);
    
    PhysicsShape::updateScale();
}
コード例 #3
0
ファイル: debug_draw.c プロジェクト: hdgarrood/swinging-game
static void
draw_poly_shape(struct draw_options opts, cpShape *shape, cpBody *body)
{
    int num_verts = cpPolyShapeGetNumVerts(shape);
    cpVect first_vert = cpBodyLocal2World(body, cpPolyShapeGetVert(shape, 0));
    cpVect prev_vert = first_vert;
    cpVect pos = cpBodyGetPos(body);

    for (int i = 1; i < num_verts; i++)
    {
        cpVect vert = cpBodyLocal2World(body, cpPolyShapeGetVert(shape, i));
        draw_line(opts, prev_vert, vert);
        prev_vert = vert;
    }

    /* close up the polygon */
    draw_line(opts, prev_vert, first_vert);
}
コード例 #4
0
void PhysicsShapePolygon::getPoints(Vec2* outPoints) const
{
    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);
    PhysicsHelper::cpvs2points(vecs, outPoints, count);
    CC_SAFE_DELETE_ARRAY(vecs);
}
コード例 #5
0
ファイル: Slice.cpp プロジェクト: damucz/chipmunk2d
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));
}
コード例 #6
0
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;
}
コード例 #7
0
Vec2 PhysicsShapePolygon::getCenter()
{
    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);
    
    Vec2 center =  PhysicsHelper::cpv2point(cpCentroidForPoly(count, vecs));
    CC_SAFE_DELETE_ARRAY(vecs);
    
    return center;
}
コード例 #8
0
float PhysicsShapePolygon::calculateDefaultMoment()
{
    if(_mass == PHYSICS_INFINITY)
    {
        return PHYSICS_INFINITY;
    }
    else
    {
        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 moment = PhysicsHelper::cpfloat2float(cpMomentForPoly(_mass, count, vecs, cpvzero, cpPolyShapeGetRadius(shape)));
        CC_SAFE_DELETE_ARRAY(vecs);
        return moment;
    }
}
コード例 #9
0
ファイル: Convex.c プロジェクト: 1103785815/wizardwar
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);
	}
}
コード例 #10
0
Vec2 PhysicsShapePolygon::getPoint(int i) const
{
    return PhysicsHelper::cpv2point(cpPolyShapeGetVert(_cpShapes.front(), i));
}
コード例 #11
0
Size PhysicsShapeBox::getSize() const
{
    cpShape* shape = _cpShapes.front();
    return PhysicsHelper::cpv2size(cpv(cpvdist(cpPolyShapeGetVert(shape, 1), cpPolyShapeGetVert(shape, 2)),
                                       cpvdist(cpPolyShapeGetVert(shape, 0), cpPolyShapeGetVert(shape, 1))));
}
コード例 #12
0
Point PhysicsShapePolygon::getPoint(int i) const
{
    return PhysicsHelper::cpv2point(cpPolyShapeGetVert(_info->getShapes().front(), i));
}
コード例 #13
0
ファイル: cpPolyShape-lua.c プロジェクト: balijanos/rpi64
static int cpPolyShape_getVert (lua_State *L) {
  cpPolyShape *ps = check_cpPolyShape(L, 1);
  int i = luaL_checkint(L, 2);
  push_cpVect(L, cpPolyShapeGetVert((cpShape*)ps, i-1));
  return 2;
}
コード例 #14
0
ファイル: Buoyancy.cpp プロジェクト: damucz/chipmunk2d
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;
}
コード例 #15
0
ファイル: editor.c プロジェクト: davidreynolds/Atlas2D
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);
}