Ejemplo n.º 1
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);
	}
}
Ejemplo n.º 2
0
void wrPolyShapeSetVerts(cpShape *shape, int numVerts, cpVect *verts, cpVect *offset) {
    cpPolyShapeSetVerts(shape, numVerts, verts, *offset);
}
Ejemplo n.º 3
0
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);
}