Browse Source

Some collision work

Panagiotis Christopoulos Charitos 11 years ago
parent
commit
d4a1bcea08
4 changed files with 193 additions and 13 deletions
  1. 2 2
      shaders/IsLp.frag.glsl
  2. 181 10
      src/collision/Tests.cpp
  3. 9 0
      src/renderer/Dbg.cpp
  4. 1 1
      testapp/Main.cpp

+ 2 - 2
shaders/IsLp.frag.glsl

@@ -345,10 +345,10 @@ void main()
 		* vec3(0.01, 0.001, 0.001);
 		* vec3(0.01, 0.001, 0.001);
 #endif
 #endif
 
 
-#if 0
+#if 1
 	if(pointLightsCount != 0)
 	if(pointLightsCount != 0)
 	{
 	{
-		out_color = vec3(0.05 * float(pointLightsCount));
+		out_color += vec3(0.1);
 	}
 	}
 #endif
 #endif
 }
 }

+ 181 - 10
src/collision/Tests.cpp

@@ -9,6 +9,7 @@
 #include "anki/collision/CompoundShape.h"
 #include "anki/collision/CompoundShape.h"
 #include "anki/collision/LineSegment.h"
 #include "anki/collision/LineSegment.h"
 #include "anki/collision/Plane.h"
 #include "anki/collision/Plane.h"
+#include "anki/collision/Obb.h"
 #include "anki/collision/GjkEpa.h"
 #include "anki/collision/GjkEpa.h"
 #include "anki/util/Rtti.h"
 #include "anki/util/Rtti.h"
 
 
@@ -106,6 +107,135 @@ Bool test(const Aabb& aabb, const LineSegment& ls)
 	return true;
 	return true;
 }
 }
 
 
+//==============================================================================
+static Bool test(const Aabb& aabb, const Sphere& s)
+{
+	const Vec4& c = s.getCenter();
+
+	// find the box's closest point to the sphere
+	Vec4 cp(0.0); // Closest Point
+	for(U i = 0; i < 3; i++)
+	{
+		// if the center is greater than the max then the closest
+		// point is the max
+		if(c[i] > aabb.getMax()[i])
+		{
+			cp[i] = aabb.getMax()[i];
+		}
+		else if(c[i] < aabb.getMin()[i]) // relative to the above
+		{
+			cp[i] = aabb.getMin()[i];
+		}
+		else
+		{
+			// the c lies between min and max
+			cp[i] = c[i];
+		}
+	}
+
+	F32 rsq = s.getRadius() * s.getRadius();
+
+	// if the c lies totally inside the box then the sub is the zero,
+	// this means that the length is also zero and thus its always smaller
+	// than rsq
+	Vec4 sub = c - cp;
+
+	if(sub.getLengthSquared() <= rsq)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+//==============================================================================
+static Bool test(const LineSegment& ls, const Obb& obb)
+{
+	F32 maxS = MIN_F32;
+	F32 minT = MAX_F32;
+
+	// compute difference vector
+	Vec4 diff = obb.getCenter() - ls.getOrigin();
+
+	// for each axis do
+	for(U i = 0; i < 3; ++i)
+	{
+		// get axis i
+		Vec4 axis = obb.getRotation().getColumn(i).xyz0();
+
+		// project relative vector onto axis
+		F32 e = axis.dot(diff);
+		F32 f = ls.getDirection().dot(axis);
+
+		// ray is parallel to plane
+		if(isZero(f))
+		{
+			// ray passes by box
+			if(-e - obb.getExtend()[i] > 0.0 || -e + obb.getExtend()[i] > 0.0)
+			{
+				return false;
+			}
+			continue;
+		}
+
+		F32 s = (e - obb.getExtend()[i]) / f;
+		F32 t = (e + obb.getExtend()[i]) / f;
+
+		// fix order
+		if(s > t)
+		{
+			F32 temp = s;
+			s = t;
+			t = temp;
+		}
+
+		// adjust min and max values
+		if(s > maxS)
+		{
+			maxS = s;
+		}
+		if(t < minT)
+		{
+			minT = t;
+		}
+
+		// check for intersection failure
+		if(minT < 0.0 || maxS > 1.0 || maxS > minT)
+		{
+			return false;
+		}
+	}
+
+	// done, have intersection
+	return true;
+}
+
+//==============================================================================
+Bool test(const LineSegment& ls, const Sphere& s)
+{
+	const Vec4& v = ls.getDirection();
+	Vec4 w0 = s.getCenter() - ls.getOrigin();
+	F32 w0dv = w0.dot(v);
+	F32 rsq = s.getRadius() * s.getRadius();
+
+	if(w0dv < 0.0) // if the ang is >90
+	{
+		return w0.getLengthSquared() <= rsq;
+	}
+
+	Vec4 w1 = w0 - v; // aka center - P1, where P1 = seg.origin + seg.dir
+	F32 w1dv = w1.dot(v);
+
+	if(w1dv > 0.0) // if the ang is <90
+	{
+		return w1.getLengthSquared() <= rsq;
+	}
+
+	// the big parenthesis is the projection of w0 to v
+	Vec4 tmp = w0 - (v * (w0.dot(v) / v.getLengthSquared()));
+	return tmp.getLengthSquared() <= rsq;
+}
+
 //==============================================================================
 //==============================================================================
 static Bool test(const Sphere& a, const Sphere& b)
 static Bool test(const Sphere& a, const Sphere& b)
 {
 {
@@ -118,16 +248,57 @@ static Bool test(const Sphere& a, const Sphere& b)
 //==============================================================================
 //==============================================================================
 
 
 template<typename A, typename B>
 template<typename A, typename B>
-Bool t(const CollisionShape& a, const CollisionShape& b)
+static Bool t(const CollisionShape& a, const CollisionShape& b)
 {
 {
 	return test(dcast<const A&>(a), dcast<const B&>(b));
 	return test(dcast<const A&>(a), dcast<const B&>(b));
 }
 }
 
 
+template<typename A, typename B>
+static Bool tr(const CollisionShape& a, const CollisionShape& b)
+{
+	return test(dcast<const B&>(b), dcast<const A&>(a));
+}
+
 /// Test plane.
 /// Test plane.
 template<typename A>
 template<typename A>
-Bool tp(const CollisionShape& a, const CollisionShape& p)
+static Bool txp(const CollisionShape& a, const CollisionShape& b)
+{
+	return dcast<const A&>(a).testPlane(dcast<const Plane&>(b));
+}
+
+/// Test plane.
+template<typename A>
+static Bool tpx(const CollisionShape& a, const CollisionShape& b)
+{
+	return txp<A>(b, a);
+}
+
+/// Compound shape.
+Bool tcx(const CollisionShape& a, const CollisionShape& b)
+{
+	Bool inside = true;
+	const CompoundShape& c = dcast<const CompoundShape&>(a);
+
+	// Use the error to stop the loop
+	Error err = c.iterateShapes([&](const CollisionShape& cs)
+	{
+		if(!testCollisionShapes(cs, b))
+		{
+			inside = false;
+			return ErrorCode::FUNCTION_FAILED;
+		}
+
+		return ErrorCode::NONE;
+	});
+	(void)err;
+
+	return inside;
+}
+
+/// Compound shape.
+Bool txc(const CollisionShape& a, const CollisionShape& b)
 {
 {
-	return dcast<const A&>(a).testPlane(dcast<const Plane&>(p));
+	return tcx(b, a);
 }
 }
 
 
 using Callback = Bool(*)(const CollisionShape& a, const CollisionShape& b);
 using Callback = Bool(*)(const CollisionShape& a, const CollisionShape& b);
@@ -135,13 +306,13 @@ using Callback = Bool(*)(const CollisionShape& a, const CollisionShape& b);
 static const U COUNT = U(CollisionShape::Type::COUNT);
 static const U COUNT = U(CollisionShape::Type::COUNT);
 
 
 static const Callback matrix[COUNT][COUNT] = {
 static const Callback matrix[COUNT][COUNT] = {
-/*          AABB                  Comp     LS                    OBB      PL       S               */
-/* AABB */ {t<Aabb, Aabb>,        nullptr, t<Aabb, LineSegment>, gjk,     nullptr, nullptr          },  
-/* Comp */ {nullptr,              nullptr, nullptr,              nullptr, nullptr, nullptr          },  
-/* LS   */ {t<Aabb, LineSegment>, nullptr, nullptr,              nullptr, nullptr, nullptr          },
-/* OBB  */ {gjk,                  nullptr, nullptr,              gjk,     nullptr, nullptr          },
-/* PL   */ {tp<Aabb>,             nullptr, nullptr,              nullptr, nullptr, nullptr          },
-/* S    */ {nullptr,              nullptr, nullptr,              gjk,     nullptr, t<Sphere, Sphere>}};
+/*          AABB                  Comp  LS                      OBB                   PL                  S               */
+/* AABB */ {t<Aabb, Aabb>,        tcx,  tr<LineSegment, Aabb>,  gjk,                  tpx<Aabb>,          tr<Sphere, Aabb>       },  
+/* Comp */ {txc,                  tcx,  txc,                    txc,                  tpx<CompoundShape>, txc                    },  
+/* LS   */ {t<Aabb, LineSegment>, tcx,  nullptr,                tr<Obb, LineSegment>, tpx<LineSegment>,   tr<Sphere, LineSegment>},
+/* OBB  */ {gjk,                  tcx,  t<LineSegment, Obb>,    gjk,                  tpx<Obb>,           gjk                    },
+/* PL   */ {txp<Aabb>,            tcx,  txp<LineSegment>,       txp<Obb>,             nullptr,            txp<Sphere>            },
+/* S    */ {t<Aabb, Sphere>,      tcx,  t<LineSegment, Sphere>, gjk,                  tpx<Sphere>,        t<Sphere, Sphere>      }};
 
 
 } // end namespace anki
 } // end namespace anki
 
 

+ 9 - 0
src/renderer/Dbg.cpp

@@ -138,6 +138,15 @@ Error Dbg::run(GlCommandBufferHandle& cmdb)
 	}
 	}
 
 
 #if 1
 #if 1
+	{
+		m_drawer->setModelMatrix(Mat4::getIdentity());
+		Sphere s(Vec4(2.0, 1.4, 0.6, 0.0), 6.0);
+		CollisionDebugDrawer cd(m_drawer);
+		cd.visit(s);
+	}
+#endif
+
+#if 0
 	{
 	{
 		ConvexHullShape hull;
 		ConvexHullShape hull;
 		Vec4 storage[] = {
 		Vec4 storage[] = {

+ 1 - 1
testapp/Main.cpp

@@ -246,7 +246,7 @@ Error init()
 		if(err) return err;
 		if(err) return err;
 
 
 		lightc = point->tryGetComponent<LightComponent>();
 		lightc = point->tryGetComponent<LightComponent>();
-		lightc->setRadius(6.01);
+		lightc->setRadius(6.0);
 		lightc->setDiffuseColor(Vec4(1.0));
 		lightc->setDiffuseColor(Vec4(1.0));
 		lightc->setSpecularColor(Vec4(0.6, 0.6, 0.3, 1.0));
 		lightc->setSpecularColor(Vec4(0.6, 0.6, 0.3, 1.0));