Commits

Anonymous committed 69cbb76

solve ambiguity on collision test.

Comments (0)

Files changed (10)

 {
 	s_world = PG_WorldNew();
 	s_world->fStepTime = 0.03;
+
 	body = PG_BodyNew();
 	PG_Set_Vector2(body->vecPosition,0,0);
-	PG_Set_Vector2(body->vecLinearVelocity,0,30);
-	body->fAngleVelocity = -5.f;
+	PG_Set_Vector2(body->vecLinearVelocity, 0, -80.f);
+	body->fRotation = M_PI/4;
+	body->fAngleVelocity = 0.f;
 	PG_Bind_RectShape(body, 20, 20, 0);
 	PG_AddBodyToWorld(s_world, body);
+	
 	body1 = PG_BodyNew();
 	PG_Set_Vector2(body1->vecPosition,0, -100);
 	body1->bStatic = 1;
-	PG_Bind_RectShape(body1, 20, 20, 0);
+	PG_Bind_RectShape(body1, 300, 20, 0);
 	PG_AddBodyToWorld(s_world, body1);
+
 }
 
 void TestBasic3Init()

Test/pgPhysicsRenderer.c

 #include "pgPhysicsRenderer.h"
 #include "pgShapeObject.h"
 #include "pgAABBBox.h"
-#include <gl/glut.h>
+#include <GL/glut.h>
 
 int RENDER_AABB = 1;
 

Test/pgPhysicsRenderer.h

 
 extern int RENDER_AABB;
 
-#endif //_PYGAME_PHYSICS_RENDERER_
+#endif //_PYGAME_PHYSICS_RENDERER_
+
+

include/pgAABBBox.h

 
 #endif //_PYGAME_MATH_AABBBOX_
 
+

include/pgVector2.h

 double c_cross(pgVector2 a, pgVector2 b);
 void c_rotate(pgVector2* a, double seta);
 
-#endif //_PYGAME_COMPLEX_EXTENSIONS_
+#endif
+
+

src/pgBodyObject.c

 	return ans;
 }
 
+
 pgVector2 PG_GetRelativePos(pgBodyObject* bodyA, pgBodyObject* bodyB, pgVector2* p_in_B)
 {
 	pgVector2 trans, p_in_A;
 	double rotate;
 	
 	trans = c_diff(bodyB->vecPosition, bodyA->vecPosition);
+	c_rotate(&trans, -bodyA->fRotation);
 	rotate = bodyA->fRotation - bodyB->fRotation;
 	p_in_A = *p_in_B;
-	c_rotate(&p_in_A, rotate);
+	c_rotate(&p_in_A, -rotate);
 	p_in_A = c_sum(p_in_A, trans);
 	
 	return p_in_A;

src/pgCollision.c

 	moment = c_mul_complex_with_real(contact->normal, moment_len);
 	p = *(contact->ppAccMoment);
 	//TODO: test weight, temp codes
-	p->real += moment.real / 3;
-	p->imag += moment.imag / 3; 
+	p->real += moment.real / contact->weight;
+	p->imag += moment.imag / contact->weight; 
 }
 
 void PG_UpdateV(pgJointObject* joint, double step)
 	}
 }
 
-PG_ContactDestroy(pgJointObject* contact)
+void PG_ContactDestroy(pgJointObject* contact)
 {
 	pgVector2 **p = ((pgContact*)contact)->ppAccMoment;
 	if(p)

src/pgShapeObject.c

 //get the contact normal.
 //note: this method is not available in CCD(continue collision detection)
 //since the velocity is not small.
-static void _SAT_GetContactNormal(pgAABBBox* clipBox, PyObject* contactList,
+static double _SAT_GetContactNormal(pgAABBBox* clipBox, PyObject* contactList,
 								  int from, int to)
 {
 	int i;
         p->normal = normal;
     }
 
+	return min_dep;
 }
 
+#define _swap(a, b, t) {(t) = (a); (a) = (b); (b) = (t);}
 
 //TODO: now just detect Box-Box collision, later add Box-Circle
 int PG_RectShapeCollision(pgBodyObject* selfBody, pgBodyObject* incidBody, PyObject* contactList)
 {
-	int i, i1;
-	int from, to;
+	int i, i1, k;
+	int from, to, _from[2], _to[2];
 	int apart;
 	pgVector2 ip[4];
 	int has_ip[4]; //use it to prevent from duplication
 	pgVector2 pf, pt;
-	pgRectShape *self, *incid;
+	pgRectShape *self, *incid, *tmp;
+	pgBodyObject * tmpBody;
 	pgAABBBox clipBox;
 	pgContact* contact;
 	pgVector2* pAcc;
+	PyObject* list[2];
+	double dist[2];
+
+	list[0] = PyList_New(0);
+	list[1] = PyList_New(0);
 
 	self = (pgRectShape*)selfBody->shape;
 	incid = (pgRectShape*)incidBody->shape;
 
-	//transform incidBody's coordinate according to selfBody's coordinate
-	for(i = 0; i < 4; ++i)
-		ip[i] = PG_GetRelativePos(selfBody, incidBody, &(incid->point[i]));
+	apart = 1;	
+	for(k = 0; k < 2; ++k)
+	{
+		//transform incidBody's coordinate according to selfBody's coordinate
+		for(i = 0; i < 4; ++i)
+			ip[i] = PG_GetRelativePos(selfBody, incidBody, &(incid->point[i]));
+		//clip incidBody by selfBody
+		clipBox = PG_GenAABB(self->bottomLeft.real, self->topRight.real,
+			self->bottomLeft.imag, self->topRight.imag);
+		memset(has_ip, 0, sizeof(has_ip));
+		_from[k] = PyList_Size(list[k]);
+		
+		for(i = 0; i < 4; ++i)
+		{
+			i1 = (i+1)%4;
+			if(PG_LiangBarskey(&clipBox, &ip[i], &ip[i1], &pf, &pt))
+			{
+				apart = 0;
+				if(pf.real == ip[i].real && pf.imag == ip[i].imag)
+				{
+					has_ip[i] = 1;
+				}
+				else
+				{
+					contact = (pgContact*)PG_ContactNew(selfBody, incidBody);
+					contact->pos = pf;
+					PyList_Append(list[k], (PyObject*)contact);
+				}
+				
+				if(pt.real == ip[i1].real && pt.imag == ip[i1].imag)
+				{	
+					has_ip[i1] = 1;
+				}
+				else
+				{
+					contact = (pgContact*)PG_ContactNew(selfBody, incidBody);
+					contact->pos = pt;
+					PyList_Append(list[k], (PyObject*)contact);
+				}
 
-	//clip incidBody by selfBody
-	clipBox = PG_GenAABB(self->bottomLeft.real, self->topRight.real,
-		self->bottomLeft.imag, self->topRight.imag);
-	apart = 1;
-	memset(has_ip, 0, sizeof(has_ip));
+			}
+		}
+
+		if(apart)
+			goto END;
+
+		for(i = 0; i < 4; ++i)
+		{
+			if(has_ip[i])
+			{
+				contact = (pgContact*)PG_ContactNew(selfBody, incidBody);
+				contact->pos = ip[i];
+				PyList_Append(list[k], (PyObject*)contact);
+			}
+		}
+		//now all the contact points are added to list
+		_to[k] = PyList_Size(list[k]) - 1;
+		dist[k] = _SAT_GetContactNormal(&clipBox, list[k], _from[k], _to[k]);
+
+		//now swap refBody and incBody, and do it again
+		_swap(selfBody, incidBody, tmpBody);
+		_swap(self, incid, tmp);
+	}
 
 	from = PyList_Size(contactList);
-	for(i = 0; i < 4; ++i)
+	//here has some bugs
+	for(i = 0; i < 2; ++i)
 	{
-		i1 = (i+1)%4;
-		//if collision happens, clip incident object and append the 
-		//clipped points to contact points list
-		//note: clipped vertices of incident object will be appended later
-		//      to prevent from duplication
-		if(PG_LiangBarskey(&clipBox, &ip[i], &ip[i1], &pf, &pt))
+		i1 = (i+1)%2;
+		if(dist[i] <= dist[i1])
 		{
-			apart = 0;
-			if(pf.real == ip[i].real && pf.imag == ip[i].imag)
+			for(k = _from[i]; k <= _to[i]; ++k)
 			{
-				has_ip[i] = 1;
+				contact = (pgContact*)PyList_GetItem(list[i], k);
+				PyList_Append(contactList, (PyObject*)contact);
+				Py_XINCREF((PyObject*)contact);
 			}
-			else
-			{
-				contact = (pgContact*)PG_ContactNew(selfBody, incidBody);
-				contact->pos = pf;
-				PyList_Append(contactList, (PyObject*)contact);
-			}
-			
-			if(pt.real == ip[i1].real && pt.imag == ip[i1].imag)
-			{	
-				has_ip[i1] = 1;
-			}
-			else
-			{
-				contact = (pgContact*)PG_ContactNew(selfBody, incidBody);
-				contact->pos = pt;
-				PyList_Append(contactList, (PyObject*)contact);
-			}
-
+			break;
 		}
+		_swap(selfBody, incidBody, tmpBody);
 	}
-
-	if(apart)
-		return 0;
-
-	for(i = 0; i < 4; ++i)
-	{
-		if(has_ip[i])
-		{
-			contact = (pgContact*)PG_ContactNew(selfBody, incidBody);
-			contact->pos = ip[i];
-			PyList_Append(contactList, (PyObject*)contact);
-		}
-	}
-	//now all the contact points are added to list
 	to = PyList_Size(contactList) - 1;
-	_SAT_GetContactNormal(&clipBox, contactList, from, to);
 
 	pAcc = PyObject_Malloc(sizeof(pgVector2));
 	pAcc->real = pAcc->imag = 0;
 		contact->ppAccMoment = PyObject_Malloc(sizeof(pgVector2*));
 		*(contact->ppAccMoment) = pAcc;
 
-		contact->weight = (to-from)+1;
+		contact->weight = (to - from)+1;
 	}
 
+
+END:
+	Py_XDECREF(list[0]);
+	Py_XDECREF(list[1]);
 	return 1;
 }
 	a->real = x*cos(seta) - y*sin(seta);
 	a->imag = x*sin(seta) + y*cos(seta);
 }
+

src/pgWorldObject.c

 	for(i = 0; i < cnt; ++i)
 	{
 		contact = (pgJointObject*)(PyList_GetItem((PyObject*)(world->contactList), i));
-		PG_ApplyContact(contact);
+		PG_ApplyContact((PyObject*)contact);
 	}
 	//update V
 	for(i = 0; i < cnt; ++i)
 
 int PG_RemoveBodyFromWorld(pgWorldObject* world,pgBodyObject* body)
 {
-	
+	return 0;
 }
 
 int PG_AddJointToWorld(pgWorldObject* world,pgJointObject* joint)
 
 int PG_RemoveJointFromWorld(pgWorldObject* world,pgJointObject* joint)
 {
-
+    return 0;
 }
 
 void PG_WorldInit(pgWorldObject* world)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.