浏览代码

Same as before

Panagiotis Christopoulos Charitos 14 年之前
父节点
当前提交
86ed382269
共有 2 个文件被更改,包括 192 次插入8 次删除
  1. 113 0
      anki/collision/Frustum.cpp
  2. 79 8
      anki/collision/Frustum.h

+ 113 - 0
anki/collision/Frustum.cpp

@@ -143,4 +143,117 @@ void PerspectiveFrustum::recalculate()
 }
 
 
+//==============================================================================
+Mat4 PerspectiveFrustum::calculateProjectionMatrix() const
+{
+	Mat4 projectionMat;
+
+	float f = 1.0 / tan(fovY * 0.5); // f = cot(fovY/2)
+
+	projectionMat(0, 0) = f * fovY / fovX; // = f/aspectRatio;
+	projectionMat(0, 1) = 0.0;
+	projectionMat(0, 2) = 0.0;
+	projectionMat(0, 3) = 0.0;
+	projectionMat(1, 0) = 0.0;
+	projectionMat(1, 1) = f;
+	projectionMat(1, 2) = 0.0;
+	projectionMat(1, 3) = 0.0;
+	projectionMat(2, 0) = 0.0;
+	projectionMat(2, 1) = 0.0;
+	projectionMat(2, 2) = (zFar + zNear) / ( zNear - zFar);
+	projectionMat(2, 3) = (2.0 * zFar * zNear) / (zNear - zFar);
+	projectionMat(3, 0) = 0.0;
+	projectionMat(3, 1) = 0.0;
+	projectionMat(3, 2) = -1.0;
+	projectionMat(3, 3) = 0.0;
+
+	return projectionMat;
+}
+
+
+//==============================================================================
+// OrthographicFrustum                                                         =
+//==============================================================================
+
+//==============================================================================
+OrthographicFrustum& OrthographicFrustum::operator=(
+	const OrthographicFrustum& b)
+{
+	Frustum::operator=(b);
+	obb = b.obb;
+	left = b.left;
+	right = b.right;
+	top = b.top;
+	bottom = b.bottom;
+	return *this;
+}
+
+
+//==============================================================================
+float OrthographicFrustum::testPlane(const Plane& p) const
+{
+	return obb.testPlane(p);
+}
+
+
+//==============================================================================
+void OrthographicFrustum::transform(const Transform& trf)
+{
+	Frustum::transform(trf);
+	obb.transform(trf);
+}
+
+
+//==============================================================================
+Mat4 OrthographicFrustum::calculateProjectionMatrix() const
+{
+	float difx = right - left;
+	float dify = top - bottom;
+	float difz = zFar - zNear;
+	float tx = -(right + left) / difx;
+	float ty = -(top + bottom) / dify;
+	float tz = -(zFar + zNear) / difz;
+	Mat4 m;
+
+	m(0, 0) = 2.0 / difx;
+	m(0, 1) = 0.0;
+	m(0, 2) = 0.0;
+	m(0, 3) = tx;
+	m(1, 0) = 0.0;
+	m(1, 1) = 2.0 / dify;
+	m(1, 2) = 0.0;
+	m(1, 3) = ty;
+	m(2, 0) = 0.0;
+	m(2, 1) = 0.0;
+	m(2, 2) = -2.0 / difz;
+	m(2, 3) = tz;
+	m(3, 0) = 0.0;
+	m(3, 1) = 0.0;
+	m(3, 2) = 0.0;
+	m(3, 3) = 1.0;
+
+	return m;
+}
+
+
+//==============================================================================
+void OrthographicFrustum::recalculate()
+{
+	// Planes
+	//
+	planes[FP_LEFT] = Plane(Vec3(1.0, 0.0, 0.0), left);
+	planes[FP_RIGHT] = Plane(Vec3(-1.0, 0.0, 0.0), -right);
+	planes[FP_NEAR] = Plane(Vec3(0.0, 0.0, -1.0), zNear);
+	planes[FP_FAR] = Plane(Vec3(0.0, 0.0, 1.0), -zFar);
+	planes[FP_TOP] = Plane(Vec3(0.0, -1.0, 0.0), -top);
+	planes[FP_BOTTOM] = Plane(Vec3(0.0, 1.0, 0.0), bottom);
+
+	// OBB
+	//
+	Vec3 c((right + left) * 0.5, (top + bottom) * 0.5, - (zFar + zNear) * 0.5);
+	Vec3 e = Vec3(right, top, -zFar) - c;
+	obb = Obb(c, Mat3::getIdentity(), e);
+}
+
+
 } // end namespace

+ 79 - 8
anki/collision/Frustum.h

@@ -37,7 +37,7 @@ public:
 		FP_RIGHT,
 		FP_TOP,
 		FP_BOTTOM,
-		FP_COUNT
+		FP_COUNT ///< Number of planes
 	};
 
 	Frustum(FrustumType type_)
@@ -47,7 +47,7 @@ public:
 	/// Copy
 	Frustum& operator=(const Frustum& b);
 
-	/// Implements CollisionShape::transform
+	/// Implements CollisionShape::transform. Ignores scale
 	void transform(const Transform& trf);
 
 	/// Implements CollisionShape::accept
@@ -64,9 +64,16 @@ public:
 	/// Check if a collision shape is inside the frustum
 	bool insideFrustum(const CollisionShape& b) const;
 
+	/// Calculate the projection matrix
+	virtual Mat4 calculateProjectionMatrix() const = 0;
+
 protected:
-	boost::array<Plane, FP_COUNT> planes;
-	float zNear, zFar;
+	boost::array<Plane, FP_COUNT> planes; ///< Used to check frustum
+	/// @name Viewing variables
+	/// @{
+	float zNear;
+	float zFar;
+	/// @}
 
 	/// Called when a viewing variable changes. It recalculates the planes and
 	/// the other variables
@@ -77,14 +84,33 @@ private:
 };
 
 
-/// XXX
+/// Frustum shape for perspective cameras
 class PerspectiveFrustum: public Frustum
 {
 public:
+	/// @name Constructors
+	/// @{
+
+	/// Default
 	PerspectiveFrustum()
 		: Frustum(FT_PERSPECTIVE)
 	{}
 
+	/// Copy
+	PerspectiveFrustum(const PerspectiveFrustum& b)
+		: Frustum(FT_PERSPECTIVE)
+	{
+		*this = b;
+	}
+
+	/// Set all
+	PerspectiveFrustum(float fovX_, float fovY_, float zNear_, float zFar_)
+		: Frustum(FT_PERSPECTIVE)
+	{
+		setAll(fovX_, fovY_, zNear_, zFar_);
+	}
+	/// @}
+
 	/// @name Accessors
 	/// @{
 	float getFovX() const
@@ -107,6 +133,7 @@ public:
 		recalculate();
 	}
 
+	/// Set all the parameters and recalculate the planes and shape
 	void setAll(float fovX_, float fovY_, float zNear_, float zFar_)
 	{
 		fovX = fovX_;
@@ -126,21 +153,48 @@ public:
 	/// Re-implements Frustum::transform
 	void transform(const Transform& trf);
 
+	/// Implements Frustum::calculateProjectionMatrix
+	Mat4 calculateProjectionMatrix() const;
+
 private:
 	Vec3 eye; ///< The eye point
 	boost::array<Vec3, 4> dirs; ///< Directions
 	float fovX;
 	float fovY;
 
-	/// Implements CollisionShape::recalculate
+	/// Implements CollisionShape::recalculate. Recalculate @a planes, @a eye
+	/// and @a dirs
 	void recalculate();
 };
 
 
-/// XXX
+/// Frustum shape for orthographic cameras
 class OrthographicFrustum: public Frustum
 {
 public:
+	/// @name Constructors
+	/// @{
+
+	/// Default
+	OrthographicFrustum()
+		: Frustum(FT_ORTHOGRAPHIC)
+	{}
+
+	/// Copy
+	OrthographicFrustum(const OrthographicFrustum& b)
+		: Frustum(FT_ORTHOGRAPHIC)
+	{
+		*this = b;
+	}
+
+	/// Set all
+	OrthographicFrustum(float left_, float right_, float zNear_,
+		float zFar_, float top_, float bottom_)
+		: Frustum(FT_ORTHOGRAPHIC)
+	{
+		setAll(left_, right_, zNear_, zFar_, top_, bottom_);
+	}
+	/// @}
 
 	/// @name Accessors
 	/// @{
@@ -184,6 +238,7 @@ public:
 		recalculate();
 	}
 
+	/// Set all
 	void setAll(float left_, float right_, float zNear_,
 		float zFar_, float top_, float bottom_)
 	{
@@ -197,9 +252,25 @@ public:
 	}
 	/// @}
 
+	/// Copy
+	OrthographicFrustum& operator=(const OrthographicFrustum& b);
+
+	/// Implements CollisionShape::testPlane
+	float testPlane(const Plane& p) const;
+
+	/// Re-implements Frustum::transform
+	void transform(const Transform& trf);
+
+	/// Implements Frustum::calculateProjectionMatrix
+	Mat4 calculateProjectionMatrix() const;
+
 private:
-	Obb obb;
+	Obb obb; ///< Incluring shape
 	float left, right, top, bottom;
+
+	/// Implements CollisionShape::recalculate. Recalculate @a planes and
+	/// @a obb
+	void recalculate();
 };
 /// @}