Example #1
0
circle2circle(cpShape shape1, cpShape shape2, cpContact arr)
{
	cpCircleShape circ1 = (cpCircleShape )shape1; //TODO
	cpCircleShape circ2 = (cpCircleShape )shape2;
	
	return circle2circleQuery(circ1.tc, circ2.tc, circ1.r, circ2.r, arr);
}
Example #2
0
cpContactInit(cpContact con, cpVect p, cpVect n, double dist, cpHashValue hash)
{
	con.p = p;
	con.n = n;
	con.dist = dist;
	
	con.jnAcc = 0.0f;
	con.jtAcc = 0.0f;
	con.jBias = 0.0f;
	
	con.hash = hash;
		
	return con;
}
Example #3
0
circle2circleQuery(cpVect p1, cpVect p2, double r1, double r2, cpContact con)
{
	double mindist = r1 + r2;
	cpVect delta = cpVect.Sub(p2, p1);
	double distsq = cpVect.LengthSQ(delta);
	if(distsq >= mindist*mindist) return 0;
	
	double dist = System.Math.Sqrt(distsq);

	// Allocate and initialize the contact.
	cpContactInit(
		con,
		cpVect.Add(p1, cpVect.Multiply(delta, 0.5f + (r1 - 0.5f*mindist)/(dist ? dist : double.PositiveInfinity))),
		(dist ? cpVect.Multiply(delta, 1.0f/dist) : cpv(1.0f, 0.0f)),
		dist - mindist,
		0
	);
	
	return 1;
}
Example #4
0
circle2segment(cpCircleShape circleShape, cpSegmentShape segmentShape, cpContact con)
{
	cpVect seg_a = segmentShape.ta;
	cpVect seg_b = segmentShape.tb;
	cpVect center = circleShape.tc;
	
	cpVect seg_delta = cpVect.Sub(seg_b, seg_a);
	double closest_t = cpfclamp01(cpVect.Dot(seg_delta, cpVect.Sub(center, seg_a))/cpVect.LengthSQ(seg_delta));
	cpVect closest = cpVect.Add(seg_a, cpVect.Multiply(seg_delta, closest_t));
	
	if(circle2circleQuery(center, closest, circleShape.r, segmentShape.r, con)){
		cpVect n = con[0].n;
		
		// Reject endcap collisions if tangents are provided.
		if(
			(closest_t == 0.0f && cpVect.Dot(n, segmentShape.a_tangent) < 0.0) ||
			(closest_t == 1.0f && cpVect.Dot(n, segmentShape.b_tangent) < 0.0)
		) return 0;
		
		return 1;
	} else {
		return 0;
	}
}
Example #5
0
		public void Draw(cpContact contact)
		{
			DrawDot(contact.r1, 0.5f, cpColor.Red);
			DrawDot(contact.r2, 0.5f, cpColor.Red);
		}
Example #6
0
nextContactPoint(cpContact arr, int *numPtr)
{
	int index = *numPtr;
	
	if(index < CP_MAX_CONTACTS_PER_ARBITER){
		(*numPtr) = index + 1;
		return &arr[index];
	} else {
		return &arr[CP_MAX_CONTACTS_PER_ARBITER - 1];
	}
}
Example #7
0
seg2seg(cpShape shape1, cpShape shape2, cpContact* con)
{
	cpSegmentShape* seg1 = (cpSegmentShape )shape1;
	cpSegmentShape* seg2 = (cpSegmentShape )shape2;
	
	cpVect v1 = cpVect.Sub(seg1.tb, seg1.ta);
	cpVect v2 = cpVect.Sub(seg2.tb, seg2.ta);
	double v1lsq = cpVect.LengthSQ(v1);
	double v2lsq = cpVect.LengthSQ(v2);
	// project seg2 onto seg1
	cpVect p1a = cpvproject(cpVect.Sub(seg2.ta, seg1.ta), v1);
	cpVect p1b = cpvproject(cpVect.Sub(seg2.tb, seg1.ta), v1);
	// project seg1 onto seg2
	cpVect p2a = cpvproject(cpVect.Sub(seg1.ta, seg2.ta), v2);
	cpVect p2b = cpvproject(cpVect.Sub(seg1.tb, seg2.ta), v2);
	
	// clamp projections to segment endcaps
	if (cpVect.Dot(p1a, v1) < 0.0f)
	 p1a = cpvzero;
	else if (cpVect.Dot(p1a, v1) > 0.0f && cpVect.LengthSQ(p1a) > v1lsq)
	 p1a = v1;
	if (cpVect.Dot(p1b, v1) < 0.0f)
	 p1b = cpvzero;
	else if (cpVect.Dot(p1b, v1) > 0.0f && cpVect.LengthSQ(p1b) > v1lsq)
	 p1b = v1;
	if (cpVect.Dot(p2a, v2) < 0.0f)
	 p2a = cpvzero;
	else if (cpVect.Dot(p2a, v2) > 0.0f && cpVect.LengthSQ(p2a) > v2lsq)
	 p2a = v2;
	if (cpVect.Dot(p2b, v2) < 0.0f)
	 p2b = cpvzero;
	else if (cpVect.Dot(p2b, v2) > 0.0f && cpVect.LengthSQ(p2b) > v2lsq)
	 p2b = v2;
	
	p1a = cpVect.Add(p1a, seg1.ta);
	p1b = cpVect.Add(p1b, seg1.ta);
	p2a = cpVect.Add(p2a, seg2.ta);
	p2b = cpVect.Add(p2b, seg2.ta);
	
	int num = 0;
	
	if (!circle2circleQuery(p1a, p2a, seg1.r, seg2.r, nextContactPoint(con, &num)))
	 --num;
	
	if (!circle2circleQuery(p1b, p2b, seg1.r, seg2.r, nextContactPoint(con, &num)))
	 --num;
	
	if (!circle2circleQuery(p1a, p2b, seg1.r, seg2.r, nextContactPoint(con, &num)))
	 --num;
	
	if (!circle2circleQuery(p1b, p2a, seg1.r, seg2.r, nextContactPoint(con, &num)))
	 --num;
	
	return num;
}
Example #8
0
circle2poly(cpShape shape1, cpShape shape2, cpContact con)
{
	cpCircleShape circ = (cpCircleShape )shape1;
	cpPolyShape poly = (cpPolyShape )shape2;
	cpSplittingPlane planes = poly.tPlanes;
	
	int mini = 0;
	double min = cpSplittingPlaneCompare(planes[0], circ.tc) - circ.r;
	for(int i=0; i<poly.numVerts; i++){
		double dist = cpSplittingPlaneCompare(planes[i], circ.tc) - circ.r;
		if(dist > 0.0f){
			return 0;
		} else if(dist > min) {
			min = dist;
			mini = i;
		}
	}
	
	cpVect n = planes[mini].n;
	cpVect a = poly.tVerts[mini];
	cpVect b = poly.tVerts[(mini + 1)%poly.numVerts];
	double dta = cpVect.CrossProduct(n, a);
	double dtb = cpVect.CrossProduct(n, b);
	double dt = cpVect.CrossProduct(n, circ.tc);
		
	if(dt < dtb){
		return circle2circleQuery(circ.tc, b, circ.r, 0.0f, con);
	} else if(dt < dta) {
		cpContactInit(
			con,
			cpVect.Sub(circ.tc, cpVect.Multiply(n, circ.r + min/2.0f)),
			cpvneg(n),
			min,
			0				 
		);
	
		return 1;
	} else {
		return circle2circleQuery(circ.tc, a, circ.r, 0.0f, con);
	}
}
Example #9
0
seg2poly(cpShape shape1, cpShape shape2, cpContact arr)
{
	cpSegmentShape seg = (cpSegmentShape )shape1;
	cpPolyShape poly = (cpPolyShape )shape2;
	cpSplittingPlane planes = poly.tPlanes;
	
	double segD = cpVect.Dot(seg.tn, seg.ta);
	double minNorm = cpPolyShapeValueOnAxis(poly, seg.tn, segD) - seg.r;
	double minNeg = cpPolyShapeValueOnAxis(poly, cpvneg(seg.tn), -segD) - seg.r;
	if(minNeg > 0.0f || minNorm > 0.0f) return 0;
	
	int mini = 0;
	double poly_min = segValueOnAxis(seg, planes.n, planes.d);
	if(poly_min > 0.0f) return 0;
	for(int i=0; i<poly.numVerts; i++){
		double dist = segValueOnAxis(seg, planes[i].n, planes[i].d);
		if(dist > 0.0f){
			return 0;
		} else if(dist > poly_min){
			poly_min = dist;
			mini = i;
		}
	}
	
	int num = 0;
	
	cpVect poly_n = cpvneg(planes[mini].n);
	
	cpVect va = cpVect.Add(seg.ta, cpVect.Multiply(poly_n, seg.r));
	cpVect vb = cpVect.Add(seg.tb, cpVect.Multiply(poly_n, seg.r));
	if(cpPolyShapeContainsVert(poly, va))
		cpContactInit(nextContactPoint(arr, &num), va, poly_n, poly_min, CP_HASH_PAIR(seg.shape.hashid, 0));
	if(cpPolyShapeContainsVert(poly, vb))
		cpContactInit(nextContactPoint(arr, &num), vb, poly_n, poly_min, CP_HASH_PAIR(seg.shape.hashid, 1));
	
	// doubleing point precision problems here.
	// This will have to do for now.
//	poly_min -= cp_collision_slop; // TODO is this needed anymore?
	
	if(minNorm >= poly_min || minNeg >= poly_min) {
		if(minNorm > minNeg)
			findPointsBehindSeg(arr, &num, seg, poly, minNorm, 1.0f);
		else
			findPointsBehindSeg(arr, &num, seg, poly, minNeg, -1.0f);
	}
	
	// If no other collision points are found, try colliding endpoints.
	if(num == 0){
		cpVect poly_a = poly.tVerts[mini];
		cpVect poly_b = poly.tVerts[(mini + 1)%poly.numVerts];
		
		if(circle2circleQuery(seg.ta, poly_a, seg.r, 0.0f, arr)) return 1;
		if(circle2circleQuery(seg.tb, poly_a, seg.r, 0.0f, arr)) return 1;
		if(circle2circleQuery(seg.ta, poly_b, seg.r, 0.0f, arr)) return 1;
		if(circle2circleQuery(seg.tb, poly_b, seg.r, 0.0f, arr)) return 1;
	}

	return num;
}
Example #10
0
findPointsBehindSeg(cpContact arr, int *num, cpSegmentShape seg, cpPolyShape poly, double pDist, double coef) 
{
	double dta = cpVect.CrossProduct(seg.tn, seg.ta);
	double dtb = cpVect.CrossProduct(seg.tn, seg.tb);
	cpVect n = cpVect.Multiply(seg.tn, coef);
	
	for(int i=0; i<poly.numVerts; i++){
		cpVect v = poly.tVerts[i];
		if(cpVect.Dot(v, n) < cpVect.Dot(seg.tn, seg.ta)*coef + seg.r){
			double dt = cpVect.CrossProduct(seg.tn, v);
			if(dta >= dt && dt >= dtb){
				cpContactInit(nextContactPoint(arr, num), v, n, pDist, CP_HASH_PAIR(poly.shape.hashid, i));
			}
		}
	}
}
Example #11
0
poly2poly(cpShape shape1, cpShape shape2, cpContact arr)
{
	cpPolyShape poly1 = (cpPolyShape )shape1;
	cpPolyShape poly2 = (cpPolyShape )shape2;
	
	double min1;
	int mini1 = findMSA(poly2, poly1.tPlanes, poly1.numVerts, &min1);
	if(mini1 == -1) return 0;
	
	double min2;
	int mini2 = findMSA(poly1, poly2.tPlanes, poly2.numVerts, &min2);
	if(mini2 == -1) return 0;
	
	// There is overlap, find the penetrating verts
	if(min1 > min2)
		return findVerts(arr, poly1, poly2, poly1.tPlanes[mini1].n, min1);
	else
		return findVerts(arr, poly1, poly2, cpvneg(poly2.tPlanes[mini2].n), min2);
}
Example #12
0
findVerts(cpContact arr, cpPolyShape poly1, cpPolyShape poly2, cpVect n, double dist)
{
	int num = 0;
	
	for(int i=0; i<poly1.numVerts; i++){
		cpVect v = poly1.tVerts[i];
		if(cpPolyShapeContainsVert(poly2, v))
			cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly1.shape.hashid, i));
	}
	
	for(int i=0; i<poly2.numVerts; i++){
		cpVect v = poly2.tVerts[i];
		if(cpPolyShapeContainsVert(poly1, v))
			cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly2.shape.hashid, i));
	}
	
	return (num ? num : findVertsFallback(arr, poly1, poly2, n, dist));
}
Example #13
0
 public void Draw(cpContact contact)
 {
     DrawDot(contact.r1, 0.5f, cpColor.Red);
     DrawDot(contact.r2, 0.5f, cpColor.Red);
 }