Esempio n. 1
0
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);
}
Esempio n. 2
0
int physics_poly_get_num_verts(Entity ent, unsigned int i)
{
    PhysicsInfo *info;
    info = entitypool_get(pool, ent);
    error_assert(info);
    return cpPolyShapeGetNumVerts(_get_shape(info, i)->shape);
}
Esempio n. 3
0
cpVect
cpPolyShapeGetVert(cpShape *shape, int idx)
{
	assert(shape->klass == &polyClass);
	assert(idx < cpPolyShapeGetNumVerts(shape));
	
	return ((cpPolyShape *)shape)->verts[idx];
}
Esempio n. 4
0
cpVect
cpPolyShapeGetVert(cpShape *shape, int idx)
{
	cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");
	cpAssert(0 <= idx && idx < cpPolyShapeGetNumVerts(shape), "Index out of range.");

	return ((cpPolyShape *)shape)->verts[idx];
}
Esempio n. 5
0
/* calculate moment for a single shape */
static Scalar _moment(cpBody *body, ShapeInfo *shapeInfo)
{
    Scalar mass = cpBodyGetMass(body);
    switch (shapeInfo->type)
    {
        case PS_CIRCLE:
            return cpMomentForCircle(mass, 0,
                                     cpCircleShapeGetRadius(shapeInfo->shape),
                                     cpCircleShapeGetOffset(shapeInfo->shape));

        case PS_POLYGON:
            return cpMomentForPoly(mass,
                                   cpPolyShapeGetNumVerts(shapeInfo->shape),
                                   ((cpPolyShape *) shapeInfo->shape)->verts,
                                   cpvzero);
    }
}
Esempio n. 6
0
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);
}
Esempio n. 7
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);
	}
}
Esempio n. 8
0
static void
ClipPoly(cpSpace *space, cpShape *shape, cpVect n, cpFloat dist)
{
	cpBody *body = cpShapeGetBody(shape);
	
	int count = cpPolyShapeGetNumVerts(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 = cpBodyLocal2World(body, cpPolyShapeGetVert(shape, j));
		cpFloat a_dist = cpvdot(a, n) - dist;
		
		if(a_dist < 0.0){
			clipped[clippedCount] = a;
			clippedCount++;
		}
		
		cpVect b = cpBodyLocal2World(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)*DENSITY;
	cpFloat moment = cpMomentForPoly(mass, clippedCount, clipped, cpvneg(centroid));
	
	cpBody *new_body = cpSpaceAddBody(space, cpBodyNew(mass, moment));
	cpBodySetPos(new_body, centroid);
	cpBodySetVel(new_body, cpBodyGetVelAtWorldPoint(body, centroid));
	cpBodySetAngVel(new_body, cpBodyGetAngVel(body));
	
	cpShape *new_shape = cpSpaceAddShape(space, cpPolyShapeNew(new_body, clippedCount, clipped, cpvneg(centroid)));
	// Copy whatever properties you have set on the original shape that are important
	cpShapeSetFriction(new_shape, cpShapeGetFriction(shape));
}
Esempio n. 9
0
void PhysicsShapePolygon::updateScale()
{
    cpFloat factorX = PhysicsHelper::float2cpfloat(_newScaleX / _scaleX);
    cpFloat factorY = PhysicsHelper::float2cpfloat(_newScaleY / _scaleY);

    auto shape = _cpShapes.front();
    int count = cpPolyShapeGetNumVerts(shape);
    cpVect* vects = ((cpPolyShape*)shape)->verts;
    cpSplittingPlane* planes = ((cpPolyShape*)shape)->planes;

    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;
        }
    }

    for (int i = 0; i < count; ++i)
    {
//        cpVect n = cpvnormalize(cpvperp(cpvsub(vects[i], vects[(i + 1) % count])));
//
//        planes[i].n = n;
//        planes[i].d = cpvdot(n, vects[i]);
        
        // FIXED ME: if update 'planes[i]' as the above codes, then can not query polygon shape by PhysicsWorld::getShapes().
        // But modified like this, then ray test can not work correctly on some cases.
        planes[i].d = cpvdot(planes[i].n, vects[i]);
    }
    
    PhysicsShape::updateScale();
}
Esempio n. 10
0
static int cpPolyShape_getNumVerts (lua_State *L) {
  cpPolyShape* ps = check_cpPolyShape(L, 1);
  lua_pushinteger(L, cpPolyShapeGetNumVerts((cpShape *)ps));
  return 1;
}