Esempio n. 1
0
static void
cpMarchCellHard(
	cpFloat t, cpFloat a, cpFloat b, cpFloat c, cpFloat d,
	cpFloat x0, cpFloat x1, cpFloat y0, cpFloat y1,
	cpMarchSegmentFunc segment, void *segment_data
){
	// midpoints
	cpFloat xm = cpflerp(x0, x1, 0.5f);
	cpFloat ym = cpflerp(y0, y1, 0.5f);

	switch((a>t)<<0 | (b>t)<<1 | (c>t)<<2 | (d>t)<<3){
		case 0x1: segs(cpv(x0, ym), cpv(xm, ym), cpv(xm, y0), segment, segment_data); break;
		case 0x2: segs(cpv(xm, y0), cpv(xm, ym), cpv(x1, ym), segment, segment_data); break;
		case 0x3: seg(cpv(x0, ym), cpv(x1, ym), segment, segment_data); break;
		case 0x4: segs(cpv(xm, y1), cpv(xm, ym), cpv(x0, ym), segment, segment_data); break;
		case 0x5: seg(cpv(xm, y1), cpv(xm, y0), segment, segment_data); break;
		case 0x6: segs(cpv(xm, y0), cpv(xm, ym), cpv(x0, ym), segment, segment_data);
		          segs(cpv(xm, y1), cpv(xm, ym), cpv(x1, ym), segment, segment_data); break;
		case 0x7: segs(cpv(xm, y1), cpv(xm, ym), cpv(x1, ym), segment, segment_data); break;
		case 0x8: segs(cpv(x1, ym), cpv(xm, ym), cpv(xm, y1), segment, segment_data); break;
		case 0x9: segs(cpv(x1, ym), cpv(xm, ym), cpv(xm, y0), segment, segment_data);
		          segs(cpv(x0, ym), cpv(xm, ym), cpv(xm, y1), segment, segment_data); break;
		case 0xA: seg(cpv(xm, y0), cpv(xm, y1), segment, segment_data); break;
		case 0xB: segs(cpv(x0, ym), cpv(xm, ym), cpv(xm, y1), segment, segment_data); break;
		case 0xC: seg(cpv(x1, ym), cpv(x0, ym), segment, segment_data); break;
		case 0xD: segs(cpv(x1, ym), cpv(xm, ym), cpv(xm, y0), segment, segment_data); break;
		case 0xE: segs(cpv(xm, y0), cpv(xm, ym), cpv(x0, ym), segment, segment_data); break;
		default: break; // 0x0 and 0xF
	}
}
Esempio n. 2
0
static cpSpace *
init(void)
{
	ChipmunkDemoMessageString = "Sticky collisions using the cpArbiter data pointer.";
	
	cpSpace *space = cpSpaceNew();
	cpSpaceSetIterations(space, 10);
	cpSpaceSetGravity(space, cpv(0, -1000));
	cpSpaceSetCollisionSlop(space, 2.0);

	cpBody *staticBody = cpSpaceGetStaticBody(space);
	cpShape *shape;

	// Create segments around the edge of the screen.
	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-340,-260), cpv(-340, 260), 20.0f));
	cpShapeSetElasticity(shape, 1.0f);
	cpShapeSetFriction(shape, 1.0f);
	cpShapeSetCollisionType(shape, COLLIDE_STICK_SENSOR);
	cpShapeSetLayers(shape, NOT_GRABABLE_MASK);

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv( 340,-260), cpv( 340, 260), 20.0f));
	cpShapeSetElasticity(shape, 1.0f);
	cpShapeSetFriction(shape, 1.0f);
	cpShapeSetCollisionType(shape, COLLIDE_STICK_SENSOR);
	cpShapeSetLayers(shape, NOT_GRABABLE_MASK);

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-340,-260), cpv( 340,-260), 20.0f));
	cpShapeSetElasticity(shape, 1.0f);
	cpShapeSetFriction(shape, 1.0f);
	cpShapeSetCollisionType(shape, COLLIDE_STICK_SENSOR);
	cpShapeSetLayers(shape, NOT_GRABABLE_MASK);
	
	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-340, 260), cpv( 340, 260), 20.0f));
	cpShapeSetElasticity(shape, 1.0f);
	cpShapeSetFriction(shape, 1.0f);
	cpShapeSetCollisionType(shape, COLLIDE_STICK_SENSOR);
	cpShapeSetLayers(shape, NOT_GRABABLE_MASK);
	
	for(int i=0; i<200; i++){
		cpFloat mass = 0.15f;
		cpFloat radius = 10.0f;
		
		cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero)));
		cpBodySetPos(body, cpv(cpflerp(-150.0f, 150.0f, frand()), cpflerp(-150.0f, 150.0f, frand())));

		cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius + STICK_SENSOR_THICKNESS, cpvzero));
		cpShapeSetFriction(shape, 0.9f);
		cpShapeSetCollisionType(shape, COLLIDE_STICK_SENSOR);
	}
	
	cpSpaceAddCollisionHandler(space, COLLIDE_STICK_SENSOR, COLLIDE_STICK_SENSOR, NULL, StickyPreSolve, NULL, StickySeparate, NULL);
	
	return space;
}
Esempio n. 3
0
// The looping and sample caching code is shared between cpMarchHard() and cpMarchSoft().
static void
cpMarchCells(
  cpBB bb, unsigned long x_samples, unsigned long y_samples, cpFloat t,
  cpMarchSegmentFunc segment, void *segment_data,
  cpMarchSampleFunc sample, void *sample_data,
	cpMarchCellFunc cell
){
	cpFloat x_denom = 1.0/(cpFloat)(x_samples - 1);
	cpFloat y_denom = 1.0/(cpFloat)(y_samples - 1);

	// TODO range assertions and short circuit for 0 sized windows.

	// Keep a copy of the previous row to avoid double lookups.
	cpFloat *buffer = (cpFloat *)cpcalloc(x_samples, sizeof(cpFloat));
	for(unsigned long i=0; i<x_samples; i++) buffer[i] = sample(cpv(cpflerp(bb.l, bb.r, i*x_denom), bb.b), sample_data);

	for(unsigned long j=0; j<y_samples-1; j++){
		cpFloat y0 = cpflerp(bb.b, bb.t, (j+0)*y_denom);
		cpFloat y1 = cpflerp(bb.b, bb.t, (j+1)*y_denom);

		cpFloat a, b = buffer[0];
		cpFloat c, d = sample(cpv(bb.l, y1), sample_data);
		buffer[0] = d;

		for(unsigned long i=0; i<x_samples-1; i++){
			cpFloat x0 = cpflerp(bb.l, bb.r, (i+0)*x_denom);
			cpFloat x1 = cpflerp(bb.l, bb.r, (i+1)*x_denom);

			a = b, b = buffer[i + 1];
			c = d, d = sample(cpv(x1, y1), sample_data);
			buffer[i + 1] = d;

			cell(t, a, b, c, d, x0, x1, y0, y1, segment, segment_data);
		}
	}

	cpfree(buffer);
}
Esempio n. 4
0
static void DrawShape(cpShape *shape, DrawNode *renderer)
{
    cpBody *body = cpShapeGetBody(shape);
    Color4F color = ColorForBody(body);
    
    switch (shape->CP_PRIVATE(klass)->type)
    {
        case CP_CIRCLE_SHAPE:
        {
            cpCircleShape *circle = (cpCircleShape *)shape;
            cpVect center = circle->tc;
            cpFloat radius = circle->r;
            renderer->drawDot(cpVert2Point(center), cpfmax(radius, 1.0), color);
            renderer->drawSegment(cpVert2Point(center), cpVert2Point(cpvadd(center, cpvmult(cpBodyGetRotation(body), radius))), 1.0, color);
        }
             break;
        case CP_SEGMENT_SHAPE:
        {
            cpSegmentShape *seg = (cpSegmentShape *)shape;
            renderer->drawSegment(cpVert2Point(seg->ta), cpVert2Point(seg->tb), cpfmax(seg->r, 2.0), color);
        }
            break;
        case CP_POLY_SHAPE:
        {
            cpPolyShape* poly = (cpPolyShape*)shape;
            Color4F line = color;
            line.a = cpflerp(color.a, 1.0, 0.5);
            int num = poly->count;
            Vec2* pPoints = new (std::nothrow) Vec2[num];
            for(int i=0;i<num;++i)
                pPoints[i] = cpVert2Point(poly->planes[i].v0);
            renderer->drawPolygon(pPoints, num, color, 1.0, line);
            CC_SAFE_DELETE_ARRAY(pPoints);
        }
            break;
        default:
            cpAssertHard(false, "Bad assertion in DrawShape()");
    }
}
static void DrawShape(cpShape *shape, DrawNode *renderer)
{
    cpBody *body = shape->body;
    Color4F color = ColorForBody(body);

    switch (shape->CP_PRIVATE(klass)->type)
    {
    case CP_CIRCLE_SHAPE:
    {
        cpCircleShape *circle = (cpCircleShape *)shape;
        cpVect center = circle->tc;
        cpFloat radius = circle->r;
        renderer->drawDot(cpVert2Point(center), cpfmax(radius, 1.0), color);
        renderer->drawSegment(cpVert2Point(center), cpVert2Point(cpvadd(center, cpvmult(body->rot, radius))), 1.0, color);
    }
    break;
    case CP_SEGMENT_SHAPE:
    {
        cpSegmentShape *seg = (cpSegmentShape *)shape;
        renderer->drawSegment(cpVert2Point(seg->ta), cpVert2Point(seg->tb), cpfmax(seg->r, 2.0), color);
    }
    break;
    case CP_POLY_SHAPE:
    {
        cpPolyShape *poly = (cpPolyShape *)shape;
        Color4F line = color;
        line.a = cpflerp(color.a, 1.0, 0.5);
        Vec2* pPoints = cpVertArray2ccpArrayN(poly->tVerts, poly->numVerts);
        renderer->drawPolygon(pPoints, poly->numVerts, color, 1.0, line);
        CC_SAFE_DELETE_ARRAY(pPoints);
    }
    break;
    default:
        cpAssertHard(false, "Bad assertion in DrawShape()");
    }
}
Esempio n. 6
0
// Lerps between two positions based on their sample values.
static inline cpFloat
midlerp(cpFloat x0, cpFloat x1, cpFloat s0, cpFloat s1, cpFloat t)
{
	return cpflerp(x0, x1, (t - s0)/(s1 - s0));
}
Esempio n. 7
0
static VALUE
rb_cpflerp(VALUE self, VALUE f1, VALUE f2, VALUE t) {
  cpFloat result = cpflerp(NUM2DBL(f1), NUM2DBL(f2), NUM2DBL(t));
  return rb_float_new(result);
}