void startTest() {
	TCHAR logFileName[1024];

	getLogFilename(logFileName);
	testLogFile = _tfopen(logFileName, _T("w"));
	if (!testLogFile)
		return;

	int pointTestErr = testPoint();
	logHLine();
	int vectorTestErr = testVector();
	logHLine();
	int lineTestErr = testLine();
	logHLine();
	int planeTestErr = testPlane();
	logHLine();
	int triangleTestErr = testTriangle();
	logHLine();
	int basisTestErr = testBasis();
	logHLine();
	int matrixTestErr = testMatrix();


	fclose(testLogFile);
	testLogFile = NULL;
}
Exemple #2
0
//Returns a vector of GameObjects which need to be drawn
std::vector<GameObject*> World::cull(int mountainSide)
{
   vector<GameObject*> objects;
   //Get mvp matrix
   glm::mat4 model, view, projection, mvp;
   float radius;
   glm::vec4 point;
   glm::vec4 platformCenter = glm::vec4(0, 0, 0, 1);
   //View and projection matrices are shared by all objects
   glGetUniformfv(handles->ShadeProg, handles->uViewMatrix, glm::value_ptr(view));
   glGetUniformfv(handles->ShadeProg, handles->uProjMatrix, glm::value_ptr(projection));
   
   for (int i = 0; i < platforms.size(); i++) {
      //This will cull any platforms on the opposite side of the mountain
      if (((mountainSide + platforms.at(i).mountainSide) % 4 != 0) || (mountainSide == platforms.at(i).mountainSide)) {
         //Not on the back side, check against each plane of view frustum
         //Get the model transform for this Object
         model = platforms.at(i).model.state.transform;
         radius = max(platforms.at(i).getScale().x, platforms.at(i).getScale().z);
         mvp = projection * view * model;
         //Negative Z
         if(testPlane(glm::row(mvp, 2), glm::row(mvp, 3), platformCenter, radius) > 0)
         {
            //Positive Z
            if(testPlane(-glm::row(mvp, 2), glm::row(mvp, 3), platformCenter, radius) > 0)
            {
               //Negative Y
               if(testPlane(glm::row(mvp, 1), glm::row(mvp, 3), platformCenter, radius) > 0)
               {
                  //Positive Y
                  if(testPlane(-glm::row(mvp, 1), glm::row(mvp, 3), platformCenter, radius) > 0)
                  {
                     //Negative X
                     if(testPlane(glm::row(mvp, 0), glm::row(mvp, 3), platformCenter, radius) > 0)
                     {
                        //Positive X
                        if(testPlane(-glm::row(mvp, 0), glm::row(mvp, 3), platformCenter, radius) > 0)
                        {
                           objects.push_back(&platforms.at(i));
                        }
                     }
                  }
               }
            }
         }
      }
   }
   return objects;
}
dgInt32 dgCollisionBox::CalculatePlaneIntersection (const dgVector& normal, const dgVector& point, dgVector* const contactsOut) const
{
	dgVector support[4];
	dgInt32 featureCount = 3;
	
	const dgConvexSimplexEdge** const vertToEdgeMapping = GetVertexToEdgeMapping();
	if (vertToEdgeMapping) {
		dgInt32 edgeIndex;
		//support[0] = SupportVertex (normal.Scale4(normalSign), &edgeIndex);
		support[0] = SupportVertex (normal, &edgeIndex);

		dgFloat32 dist = normal.DotProduct4(support[0] - point).GetScalar();
		if (dist <= DG_IMPULSIVE_CONTACT_PENETRATION) {
			dgVector normalAlgin (normal.Abs());
			if (!((normalAlgin.m_x > dgFloat32 (0.9999f)) || (normalAlgin.m_y > dgFloat32 (0.9999f)) || (normalAlgin.m_z > dgFloat32 (0.9999f)))) {
				// 0.25 degrees
				const dgFloat32 tiltAngle = dgFloat32 (0.005f);
				const dgFloat32 tiltAngle2 = tiltAngle * tiltAngle ;
				dgPlane testPlane (normal, - (normal.DotProduct4(support[0]).GetScalar()));

				featureCount = 1;
				const dgConvexSimplexEdge* const edge = vertToEdgeMapping[edgeIndex];
				const dgConvexSimplexEdge* ptr = edge;
				do {
					const dgVector& p = m_vertex[ptr->m_twin->m_vertex];
					dgFloat32 test1 = testPlane.Evalue(p);
					dgVector dist (p - support[0]);
					dgFloat32 angle2 = test1 * test1 / (dist.DotProduct4(dist).GetScalar());
					if (angle2 < tiltAngle2) {
						support[featureCount] = p;
						featureCount ++;
					}
					ptr = ptr->m_twin->m_next;
				} while ((ptr != edge) && (featureCount < 3));
			}
		}
	}

	dgInt32 count = 0;
	switch (featureCount)
	{
		case 1:
		{
			contactsOut[0] = support[0] - normal.CompProduct4(normal.DotProduct4(support[0] - point));
			count = 1;
			break;
		}

		case 2:
		{
			contactsOut[0] = support[0] - normal.CompProduct4(normal.DotProduct4(support[0] - point));
			contactsOut[1] = support[1] - normal.CompProduct4(normal.DotProduct4(support[1] - point));
			count = 2;
			break;
		}

		default:
		{
			dgFloat32 test[8];
			dgAssert(normal.m_w == dgFloat32(0.0f));
			dgPlane plane(normal, -(normal.DotProduct4(point).GetScalar()));
			for (dgInt32 i = 0; i < 8; i++) {
				dgAssert(m_vertex[i].m_w == dgFloat32(0.0f));
				test[i] = plane.DotProduct4(m_vertex[i] | dgVector::m_wOne).m_x;
			}

			dgConvexSimplexEdge* edge = NULL;
			for (dgInt32 i = 0; i < dgInt32 (sizeof (m_edgeEdgeMap) / sizeof (m_edgeEdgeMap[0])); i ++) {
				dgConvexSimplexEdge* const ptr = m_edgeEdgeMap[i];
				dgFloat32 side0 = test[ptr->m_vertex];
				dgFloat32 side1 = test[ptr->m_twin->m_vertex];
				if ((side0 * side1) < dgFloat32 (0.0f)) {
					edge = ptr;
					break;
				}
			}

			if (edge) {
				if (test[edge->m_vertex] < dgFloat32 (0.0f)) {
					edge = edge->m_twin;
				}
				dgAssert (test[edge->m_vertex] > dgFloat32 (0.0f));

				dgConvexSimplexEdge* ptr = edge;
				dgConvexSimplexEdge* firstEdge = NULL;
				dgFloat32 side0 = test[edge->m_vertex];
				do {
					dgAssert (m_vertex[ptr->m_twin->m_vertex].m_w == dgFloat32 (0.0f));
					dgFloat32 side1 = test[ptr->m_twin->m_vertex];
					if (side1 < side0) {
						if (side1 < dgFloat32 (0.0f)) {
							firstEdge = ptr;
							break;
						}

						side0 = side1;
						edge = ptr->m_twin;
						ptr = edge;
					}
					ptr = ptr->m_twin->m_next;
				} while (ptr != edge);

				if (firstEdge) {
					edge = firstEdge;
					ptr = edge;
					do {
						dgVector dp (m_vertex[ptr->m_twin->m_vertex] - m_vertex[ptr->m_vertex]);
						dgFloat32 t = plane.DotProduct4(dp).m_x;
						if (t >= dgFloat32 (-1.e-24f)) {
							t = dgFloat32 (0.0f);
						} else {
							t = test[ptr->m_vertex] / t;
							if (t > dgFloat32 (0.0f)) {
								t = dgFloat32 (0.0f);
							}
							if (t < dgFloat32 (-1.0f)) {
								t = dgFloat32 (-1.0f);
							}
						}

						dgAssert (t <= dgFloat32 (0.01f));
						dgAssert (t >= dgFloat32 (-1.05f));
						contactsOut[count] = m_vertex[ptr->m_vertex] - dp.Scale4 (t);
						count ++;

						dgConvexSimplexEdge* ptr1 = ptr->m_next;
						for (; ptr1 != ptr; ptr1 = ptr1->m_next) {
							dgInt32 index0 = ptr1->m_twin->m_vertex;
							if (test[index0] >= dgFloat32 (0.0f)) {
								dgAssert (test[ptr1->m_vertex] <= dgFloat32 (0.0f));
								break;
							}
						}
						dgAssert (ptr != ptr1);
						ptr = ptr1->m_twin;

					} while ((ptr != edge) && (count < 8));
				}
			}
		}
	}

	if (count > 2) {
		count = RectifyConvexSlice (count, normal, contactsOut);
	}
	return count;
}