Example #1
0
// Calculate the closest points on two shapes given the closest edge on their minkowski difference to (0, 0)
static inline struct ClosestPoints
ClosestPointsNew(const struct MinkowskiPoint v0, const struct MinkowskiPoint v1)
{
    // Find the closest p(t) on the minkowski difference to (0, 0)
    cpFloat t = ClosestT(v0.ab, v1.ab);
    cpVect p = LerpT(v0.ab, v1.ab, t);

    // Interpolate the original support points using the same 't' value as above.
    // This gives you the closest surface points in absolute coordinates. NEAT!
    cpVect pa = LerpT(v0.a, v1.a, t);
    cpVect pb = LerpT(v0.b, v1.b, t);
    cpCollisionID id = (v0.id & 0xFFFF)<<16 | (v1.id & 0xFFFF);

    // First try calculating the MSA from the minkowski difference edge.
    // This gives us a nice, accurate MSA when the surfaces are close together.
    cpVect delta = cpvsub(v1.ab, v0.ab);
    cpVect n = cpvnormalize(cpvrperp(delta));
    cpFloat d = cpvdot(n, p);

    if(d <= 0.0f || (-1.0f < t && t < 1.0f)) {
        // If the shapes are overlapping, or we have a regular vertex/edge collision, we are done.
        struct ClosestPoints points = {pa, pb, n, d, id};
        return points;
    } else {
        // Vertex/vertex collisions need special treatment since the MSA won't be shared with an axis of the minkowski difference.
        cpFloat d2 = cpvlength(p);
        cpVect n2 = cpvmult(p, 1.0f/(d2 + CPFLOAT_MIN));

        struct ClosestPoints points = {pa, pb, n2, d2, id};
        return points;
    }
}
Example #2
0
static struct Notch
DeepestNotch(int count, cpVect *verts, int hullCount, cpVect *hullVerts, int first, cpFloat tol)
{
	struct Notch notch = {};
	int j = Next(first, count);
	
	for(int i=0; i<hullCount; i++){
		cpVect a = hullVerts[i];
		cpVect b = hullVerts[Next(i, hullCount)];
		
		// TODO use a cross check instead?
		cpVect n = cpvnormalize(cpvrperp(cpvsub(a, b)));
		cpFloat d = cpvdot(n, a);
		
		cpVect v = verts[j];
		while(!cpveql(v, b)){
			cpFloat depth = cpvdot(n, v) - d;
			
			if(depth > notch.d){
				notch.d = depth;
				notch.i = j;
				notch.v = v;
				notch.n = n;
			}
			
			j = Next(j, count);
			v = verts[j];
		}
		
		j = Next(j, count);
	}
	
	return notch;
}
Example #3
0
cpSegmentShape *
cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat r)
{
	seg->a = a;
	seg->b = b;
	seg->n = cpvrperp(cpvnormalize(cpvsub(b, a)));
	
	seg->r = r;
	
	seg->a_tangent = cpvzero;
	seg->b_tangent = cpvzero;
	
	cpShapeInit((cpShape *)seg, &cpSegmentShapeClass, body, cpSegmentShapeMassInfo(0.0f, a, b, r));
	
	return seg;
}
static void
SetVerts(cpPolyShape *poly, int count, const cpVect *verts)
{
	poly->count = count;
	if(count <= CP_POLY_SHAPE_INLINE_ALLOC){
		poly->planes = poly->_planes;
	} else {
		poly->planes = (struct cpSplittingPlane *)cpcalloc(2*count, sizeof(struct cpSplittingPlane));
	}
	
	for(int i=0; i<count; i++){
		cpVect a = verts[(i - 1 + count)%count];
		cpVect b = verts[i];
		cpVect n = cpvnormalize(cpvrperp(cpvsub(b, a)));
		
		poly->planes[i + count].v0 = b;
		poly->planes[i + count].n = n;
	}
}