Просмотр исходного кода

Collision work:
- Removing PerspectiveCameraShape
- Finalizing Frustum

Panagiotis Christopoulos Charitos 14 лет назад
Родитель
Сommit
45955bbd84

+ 1 - 1
anki/collision/Collision.h

@@ -6,7 +6,7 @@
 #include "anki/collision/Obb.h"
 #include "anki/collision/Ray.h"
 #include "anki/collision/LineSegment.h"
-#include "anki/collision/PerspectiveCameraShape.h"
+#include "anki/collision/Frustum.h"
 #include "anki/collision/Aabb.h"
 
 

+ 18 - 25
anki/collision/CollisionAlgorithmsMatrix.cpp

@@ -30,8 +30,8 @@ bool CollisionAlgorithmsMatrix::tcollide(const CollisionShape& a,
 			out = collide(t, static_cast<const Aabb&>(b));
 		case CollisionShape::CST_OBB:
 			out = collide(t, static_cast<const Obb&>(b));
-		case CollisionShape::CST_PERSPECTIVE_CAMERA_FRUSTRUM:
-			out = collide(t, static_cast<const PerspectiveCameraShape&>(b));
+		case CollisionShape::CST_FRUSTUM:
+			out = collide(t, static_cast<const Frustum&>(b));
 		default:
 			ANKI_ASSERT(0 && "Forgot something");
 	}
@@ -59,8 +59,8 @@ bool CollisionAlgorithmsMatrix::collide(const CollisionShape& a,
 			out = tcollide<Aabb>(a, b);
 		case CollisionShape::CST_OBB:
 			out = tcollide<Obb>(a, b);
-		case CollisionShape::CST_PERSPECTIVE_CAMERA_FRUSTRUM:
-			out = tcollide<PerspectiveCameraShape>(a, b);
+		case CollisionShape::CST_FRUSTUM:
+			out = tcollide<Frustum>(a, b);
 		default:
 			ANKI_ASSERT(0 && "Forgot something");
 	}
@@ -145,10 +145,9 @@ bool CollisionAlgorithmsMatrix::collide(const Ls& ls, const Obb& obb)
 
 
 //==============================================================================
-bool CollisionAlgorithmsMatrix::collide(const Ls& /*a*/, const Pcs& /*b*/)
+bool CollisionAlgorithmsMatrix::collide(const Ls& a, const Frustum& b)
 {
-	ANKI_ASSERT(0 && "Not implemented yet");
-	return false;
+	return b.insideFrustum(a);
 }
 
 
@@ -435,10 +434,9 @@ bool CollisionAlgorithmsMatrix::collide(const Obb& o0, const Obb& o1)
 
 
 //==============================================================================
-bool CollisionAlgorithmsMatrix::collide(const Obb& a, const Pcs& b)
+bool CollisionAlgorithmsMatrix::collide(const Obb& a, const Frustum& b)
 {
-	ANKI_ASSERT(0 && "Not impelented yet");
-	return false;
+	return b.insideFrustum(a);
 }
 
 
@@ -491,42 +489,37 @@ bool CollisionAlgorithmsMatrix::collide(const Obb& obb, const Aabb& aabb)
 //==============================================================================
 
 //==============================================================================
-bool CollisionAlgorithmsMatrix::collide(const Pcs& a, const Pcs& b)
+bool CollisionAlgorithmsMatrix::collide(const Frustum& a, const Frustum& b)
 {
-	ANKI_ASSERT(0 && "Not implemented yet");
-	return false;
+	return b.insideFrustum(a);
 }
 
 
 //==============================================================================
-bool CollisionAlgorithmsMatrix::collide(const Pcs& a, const Plane& b)
+bool CollisionAlgorithmsMatrix::collide(const Frustum& a, const Plane& b)
 {
-	ANKI_ASSERT(0 && "Not implemented yet");
-	return false;
+	return a.insideFrustum(b);
 }
 
 
 //==============================================================================
-bool CollisionAlgorithmsMatrix::collide(const Pcs& a, const Ray& b)
+bool CollisionAlgorithmsMatrix::collide(const Frustum& a, const Ray& b)
 {
-	ANKI_ASSERT(0 && "Not implemented yet");
-	return false;
+	return a.insideFrustum(b);
 }
 
 
 //==============================================================================
-bool CollisionAlgorithmsMatrix::collide(const Pcs& a, const Sphere& b)
+bool CollisionAlgorithmsMatrix::collide(const Frustum& a, const Sphere& b)
 {
-	ANKI_ASSERT(0 && "Not implemented yet");
-	return false;
+	return a.insideFrustum(b);
 }
 
 
 //==============================================================================
-bool CollisionAlgorithmsMatrix::collide(const Pcs& a, const Aabb& b)
+bool CollisionAlgorithmsMatrix::collide(const Frustum& a, const Aabb& b)
 {
-	ANKI_ASSERT(0 && "Not implemented yet");
-	return false;
+	return a.insideFrustum(b);
 }
 
 

+ 16 - 17
anki/collision/CollisionAlgorithmsMatrix.h

@@ -15,13 +15,13 @@ namespace anki {
 ///
 /// @code
 /// +------+------+------+------+------+------+------+------+
-/// |      | LS   | OBB  | PCC  | P    | R    | S    | AABB |
+/// |      | LS   | OBB  | FRU  | P    | R    | S    | AABB |
 /// +------+------+------+------+------+------+------+------+
 /// | LS   | N/A  | OK   | N/I  | OK   | N/A  | OK   | OK   |
 /// +------+------+------+------+------+------+------+------+
 /// | OBB  |      | OK   | N/I  | OK   | OK   | OK   | OK   |
 /// +------+------+------+------+------+------+------+------+
-/// | PCS  |      |      | N/I  | N/I  | N/I  | N/I  | N/I  |
+/// | FRU  |      |      | N/I  | N/I  | N/I  | N/I  | N/I  |
 /// +------+------+------+------+------+------+------+------+
 /// | P    |      |      |      | OK   | OK   | OK   | OK   |
 /// +------+------+------+------+------+------+------+------+
@@ -35,7 +35,6 @@ namespace anki {
 class CollisionAlgorithmsMatrix
 {
 public:
-	typedef PerspectiveCameraShape Pcs;
 	typedef LineSegment Ls;
 
 	/// Generic collide function. It doesn't uses visitor pattern for
@@ -45,7 +44,7 @@ public:
 	// 1st line (LS)
 	static bool collide(const Ls& a, const Ls& b);
 	static bool collide(const Ls& a, const Obb& b);
-	static bool collide(const Ls& a, const Pcs& b);
+	static bool collide(const Ls& a, const Frustum& b);
 	static bool collide(const Ls& a, const Plane& b);
 	static bool collide(const Ls& a, const Ray& b);
 	static bool collide(const Ls& a, const Sphere& b);
@@ -57,26 +56,26 @@ public:
 		return collide(b, a);
 	}
 	static bool collide(const Obb& a, const Obb& b);
-	static bool collide(const Obb& a, const Pcs& b);
+	static bool collide(const Obb& a, const Frustum& b);
 	static bool collide(const Obb& a, const Plane& b);
 	static bool collide(const Obb& a, const Ray& b);
 	static bool collide(const Obb& a, const Sphere& b);
 	static bool collide(const Obb& a, const Aabb& b);
 
-	// 3rd line (PCS)
-	static bool collide(const Pcs& a, const Ls& b)
+	// 3rd line (FRU)
+	static bool collide(const Frustum& a, const Ls& b)
 	{
 		return collide(b, a);
 	}
-	static bool collide(const Pcs& a, const Obb& b)
+	static bool collide(const Frustum& a, const Obb& b)
 	{
 		return collide(b, a);
 	}
-	static bool collide(const Pcs& a, const Pcs& b);
-	static bool collide(const Pcs& a, const Plane& b);
-	static bool collide(const Pcs& a, const Ray& b);
-	static bool collide(const Pcs& a, const Sphere& b);
-	static bool collide(const Pcs& a, const Aabb& b);
+	static bool collide(const Frustum& a, const Frustum& b);
+	static bool collide(const Frustum& a, const Plane& b);
+	static bool collide(const Frustum& a, const Ray& b);
+	static bool collide(const Frustum& a, const Sphere& b);
+	static bool collide(const Frustum& a, const Aabb& b);
 
 	// 4th line (P)
 	static bool collide(const Plane& a, const Ls& b)
@@ -87,7 +86,7 @@ public:
 	{
 		return collide(b, a);
 	}
-	static bool collide(const Plane& a,const Pcs& b)
+	static bool collide(const Plane& a,const Frustum& b)
 	{
 		return collide(b, a);
 	}
@@ -105,7 +104,7 @@ public:
 	{
 		return collide(b, a);
 	}
-	static bool collide(const Ray& a, const Pcs& b)
+	static bool collide(const Ray& a, const Frustum& b)
 	{
 		return collide(b, a);
 	}
@@ -126,7 +125,7 @@ public:
 	{
 		return collide(b, a);
 	}
-	static bool collide(const Sphere& a, const Pcs& b)
+	static bool collide(const Sphere& a, const Frustum& b)
 	{
 		return collide(b, a);
 	}
@@ -150,7 +149,7 @@ public:
 	{
 		return collide(b, a);
 	}
-	static bool collide(const Aabb& a, const Pcs& b)
+	static bool collide(const Aabb& a, const Frustum& b)
 	{
 		return collide(b, a);
 	}

+ 3 - 3
anki/collision/CollisionShape.h

@@ -24,7 +24,7 @@ public:
 		CST_SPHERE,
 		CST_AABB,
 		CST_OBB,
-		CST_PERSPECTIVE_CAMERA_FRUSTRUM
+		CST_FRUSTUM
 	};
 
 	/// Generic mutable visitor
@@ -33,7 +33,7 @@ public:
 	public:
 		virtual void visit(LineSegment&) = 0;
 		virtual void visit(Obb&) = 0;
-		virtual void visit(PerspectiveCameraShape&) = 0;
+		virtual void visit(Frustum&) = 0;
 		virtual void visit(Plane&) = 0;
 		virtual void visit(Ray&) = 0;
 		virtual void visit(Sphere&) = 0;
@@ -46,7 +46,7 @@ public:
 	public:
 		virtual void visit(const LineSegment&) = 0;
 		virtual void visit(const Obb&) = 0;
-		virtual void visit(const PerspectiveCameraShape&) = 0;
+		virtual void visit(const Frustum&) = 0;
 		virtual void visit(const Plane&) = 0;
 		virtual void visit(const Ray&) = 0;
 		virtual void visit(const Sphere&) = 0;

+ 1 - 1
anki/collision/Forward.h

@@ -9,7 +9,7 @@ class CollisionShape;
 
 class LineSegment;
 class Obb;
-class PerspectiveCameraShape;
+class Frustum;
 class Plane;
 class Ray;
 class Sphere;

+ 89 - 21
anki/collision/Frustum.cpp

@@ -1,5 +1,6 @@
 #include "anki/collision/Frustum.h"
 #include "anki/collision/LineSegment.h"
+#include <boost/foreach.hpp>
 
 
 namespace anki {
@@ -8,46 +9,113 @@ namespace anki {
 //==============================================================================
 Frustum& Frustum::operator=(const Frustum& b)
 {
-	for(int i = 0; i < planes.size(); ++i)
+	memcpy(this, &b, sizeof(Frustum));
+	return *this;
+}
+
+
+//==============================================================================
+float Frustum::testPlane(const Plane& p) const
+{
+	if(type == FT_ORTHOGRAPHIC)
 	{
-		planes[i] = b.planes[i];
+		return obb.testPlane(p);
 	}
+	else
+	{
+		float o = 0.0;
 
-	eye = b.eye;
+		for(uint i = 0; i < dirs.size(); i++)
+		{
+			LineSegment ls(eye, dirs[i]);
+			float t = ls.testPlane(p);
 
-	for(int i = 0; i < dirs.size(); ++i)
-	{
-		dirs[i] = b.dirs[i];
+			if(t == 0)
+			{
+				return 0.0;
+			}
+			else if(t < 0.0)
+			{
+				o = std::max(o, t);
+			}
+			else
+			{
+				o = std::min(o, t);
+			}
+		}
+
+		return o;
 	}
 }
 
 
 //==============================================================================
-float Frustum::testPlane(const Plane& p) const
+Frustum Frustum::getTransformed(const Transform& trf) const
 {
-	const Frustum& f = *this;
-	float o = 0.0;
+	Frustum o;
 
-	for(uint i = 0; i < 4; i++)
+	// Planes
+	for(uint i = 0; i < planes.size(); ++i)
 	{
-		LineSegment ls(f.getEye(), f.getDirections()[i]);
-		float t = ls.testPlane(p);
+		o.planes[i] = planes[i].getTransformed(trf);
+	}
 
-		if(t == 0)
-		{
-			return 0.0;
-		}
-		else if(t < 0.0)
+	// Other
+	if(type == FT_ORTHOGRAPHIC)
+	{
+		o.obb = obb.getTransformed(trf);
+	}
+	else
+	{
+		o.eye = eye.getTransformed(trf);
+
+		for(uint i = 0; i < dirs.size(); i++)
 		{
-			o = std::max(o, t);
+			o.dirs[i] = trf.getRotation() * dirs[i];
 		}
-		else
+	}
+
+	return o;
+}
+
+
+//==============================================================================
+void Frustum::setPerspective(float fovX, float fovY,
+	float zNear, float zFar, const Transform& trf)
+{
+	type = FT_PERSPECTIVE;
+
+	eye = Vec3(0.0, 0.0, -zNear);
+
+	float x = zFar / tan((Math::PI - fovX) / 2.0);
+	float y = tan(fovY / 2.0) * zFar;
+	float z = -zFar;
+
+	dirs[0] = Vec3(x, y, z - zNear); // top right
+	dirs[1] = Vec3(-x, y, z - zNear); // top left
+	dirs[2] = Vec3(-x, -y, z - zNear); // bottom left
+	dirs[3] = Vec3(x, -y, z - zNear); // bottom right
+
+	eye.transform(trf);
+	for(uint i = 0; i < 4; i++)
+	{
+		dirs[i] = trf.getRotation() * dirs[i];
+	}
+}
+
+
+//==============================================================================
+bool Frustum::insideFrustum(const CollisionShape& b) const
+{
+	BOOST_FOREACH(const Plane& plane, planes)
+	{
+		if(b.testPlane(plane) < 0.0)
 		{
-			o = std::min(o, t);
+			return false;
 		}
 	}
 
-	return o;
+	return true;
 }
 
 

+ 60 - 4
anki/collision/Frustum.h

@@ -2,6 +2,8 @@
 #define ANKI_COLLISION_FRUSTUM_H
 
 #include "anki/collision/CollisionShape.h"
+#include "anki/collision/Plane.h"
+#include "anki/collision/Obb.h"
 #include "anki/math/Math.h"
 #include <boost/array.hpp>
 
@@ -19,8 +21,29 @@ namespace anki {
 class Frustum: public CollisionShape
 {
 public:
+	/// Frustum type
+	enum FrustumType
+	{
+		FT_PERSPECTIVE,
+		FT_ORTHOGRAPHIC
+	};
+
+	/// The 6 planes
+	enum FrustrumPlane
+	{
+		FP_NEAR,
+		FP_FAR,
+		FP_LEFT,
+		FP_RIGHT,
+		FP_TOP,
+		FP_BOTTOM,
+		FP_COUNT
+	};
+
+	/// @name Constructors
+	/// @{
 	Frustum()
-		: CollisionShape(CST_FRUSTUM)
+		: CollisionShape(CST_FRUSTUM), type(FT_ORTHOGRAPHIC)
 	{}
 
 	Frustum(const Frustum& b)
@@ -33,9 +56,17 @@ public:
 		float zFar, const Transform& trf)
 		: CollisionShape(CST_FRUSTUM)
 	{
-		// XXX
+		setPerspective(fovX, fovY, zNear, zFar, trf);
 	}
 
+	Frustum(float left, float right, float near,
+		float far, float top, float buttom, const Transform& trf)
+		: CollisionShape(CST_FRUSTUM)
+	{
+		setOrthographic(left, right, near, far, top, buttom, trf);
+	}
+	/// @}
+
 	/// Copy
 	Frustum& operator=(const Frustum& b);
 
@@ -61,16 +92,41 @@ public:
 		v.visit(*this);
 	}
 
-	/// Set all
-	void setAll(float fovX, float fovY, float zNear,
+	/// Set all for perspective camera
+	void setPerspective(float fovX, float fovY, float zNear,
 		float zFar, const Transform& trf);
 
+	/// Set all for orthographic camera
+	void setOrthographic(float left, float right, float near,
+		float far, float top, float buttom, const Transform& trf)
+	{
+		type = FT_ORTHOGRAPHIC;
+		/// XXX
+	}
+
+	/// Check if a collision shape is inside the frustum
+	bool insideFrustum(const CollisionShape& b) const;
+
 private:
+	FrustumType type;
+
 	boost::array<Plane, 6> planes;
+
+	/// @name Including shape for perspective cameras
+	/// @{
 	Vec3 eye; ///< The eye point
 	boost::array<Vec3, 4> dirs; ///< Directions
+	/// @}
+
+	/// @name Including shape for orthographic cameras
+	/// @{
+	Obb obb;
+	/// @}
 };
 /// @}
 
 
 } // end namespace
+
+
+#endif

+ 0 - 76
anki/collision/PerspectiveCameraShape.cpp

@@ -1,76 +0,0 @@
-#include "anki/collision/PerspectiveCameraShape.h"
-#include "anki/collision/LineSegment.h"
-
-
-namespace anki {
-
-
-//==============================================================================
-float PerspectiveCameraShape::testPlane(const Plane& p) const
-{
-	const PerspectiveCameraShape& pcs = *this;
-	float o = 0.0;
-
-	for(uint i = 0; i < 4; i++)
-	{
-		LineSegment ls(pcs.getEye(), pcs.getDirections()[i]);
-		float t = ls.testPlane(p);
-
-		if(t == 0)
-		{
-			return 0.0;
-		}
-		else if(t < 0.0)
-		{
-			o = std::max(o, t);
-		}
-		else
-		{
-			o = std::min(o, t);
-		}
-	}
-
-	return o;
-}
-
-
-//==============================================================================
-void PerspectiveCameraShape::setAll(float fovX, float fovY,
-	float zNear, float zFar, const Transform& trf)
-{
-	eye = Vec3(0.0, 0.0, -zNear);
-
-	float x = zFar / tan((Math::PI - fovX) / 2.0);
-	float y = tan(fovY / 2.0) * zFar;
-	float z = -zFar;
-
-	dirs[0] = Vec3(x, y, z - zNear); // top right
-	dirs[1] = Vec3(-x, y, z - zNear); // top left
-	dirs[2] = Vec3(-x, -y, z - zNear); // bottom left
-	dirs[3] = Vec3(x, -y, z - zNear); // bottom right
-
-	eye.transform(trf);
-	for(uint i = 0; i < 4; i++)
-	{
-		dirs[i] = trf.getRotation() * dirs[i];
-	}
-}
-
-
-//==============================================================================
-PerspectiveCameraShape PerspectiveCameraShape::getTransformed(
-	const Transform& trf) const
-{
-	PerspectiveCameraShape o;
-	o.eye = eye.getTransformed(trf);
-
-	for(uint i = 0; i < 4; i++)
-	{
-		o.dirs[i] = trf.getRotation() * dirs[i];
-	}
-
-	return o;
-}
-
-
-} // end namespace

+ 0 - 79
anki/collision/PerspectiveCameraShape.h

@@ -1,79 +0,0 @@
-#ifndef ANKI_PERSPECTIVE_CAMERA_SHAPE_H
-#define ANKI_PERSPECTIVE_CAMERA_SHAPE_H
-
-#include "anki/collision/CollisionShape.h"
-#include "anki/math/Math.h"
-
-
-namespace anki {
-
-
-/// @addtogroup Collision
-/// @{
-
-/// Collision shape for the projection cameras
-class PerspectiveCameraShape: public CollisionShape
-{
-public:
-	/// Default constructor
-	PerspectiveCameraShape()
-		: CollisionShape(CST_PERSPECTIVE_CAMERA_FRUSTRUM)
-	{}
-
-	PerspectiveCameraShape(float fovX, float fovY, float zNear,
-		float zFar, const Transform& trf)
-		: CollisionShape(CST_PERSPECTIVE_CAMERA_FRUSTRUM)
-	{
-		setAll(fovX, fovY, zNear, zFar, trf);
-	}
-
-	/// @name Accessors
-	/// @{
-	const Vec3& getEye() const
-	{
-		return eye;
-	}
-
-	const boost::array<Vec3, 4>& getDirections() const
-	{
-		return dirs;
-	}
-	/// @{
-
-	/// Implements CollisionShape::accept
-	void accept(MutableVisitor& v)
-	{
-		v.visit(*this);
-	}
-	/// Implements CollisionShape::accept
-	void accept(ConstVisitor& v) const
-	{
-		v.visit(*this);
-	}
-
-	/// Implements CollisionShape::testPlane
-	float testPlane(const Plane& p) const;
-
-	/// Implements CollisionShape::transform
-	void transform(const Transform& trf)
-	{
-		*this = getTransformed(trf);
-	}
-
-	PerspectiveCameraShape getTransformed(const Transform& trf) const;
-
-	/// Set all
-	void setAll(float fovX, float fovY, float zNear,
-		float zFar, const Transform& trf);
-
-private:
-	Vec3 eye; ///< The eye point
-	boost::array<Vec3, 4> dirs; ///< Directions
-};
-///@}
-
-
-} // end namespace
-
-
-#endif

+ 2 - 2
anki/math/Vec3.h

@@ -77,8 +77,8 @@ public:
 
 	/// @name Other
 	/// @{
-	float dot(const Vec3& b) const;
-	Vec3 cross(const Vec3& b) const;
+	float dot(const Vec3& b) const; ///< 3 muls, 2 adds
+	Vec3 cross(const Vec3& b) const; ///< 6 muls, 3 adds
 	float getLength() const;
 	float getLengthSquared() const;
 	float getDistanceSquared(const Vec3& b) const;