Procházet zdrojové kódy

Reverting back to old frustum but with transformation. Too complex for nothing

Panagiotis Christopoulos Charitos před 13 roky
rodič
revize
1d27ef98f1

+ 68 - 91
include/anki/collision/Frustum.h

@@ -12,8 +12,10 @@ namespace anki {
 /// @addtogroup Collision
 /// @addtogroup Collision
 /// @{
 /// @{
 
 
-/// Frustum collision shape. This shape consists from 6 planes. The planes are
-/// being used to find shapes that are inside the frustum
+/// Frustum collision shape
+///
+/// This shape consists from 6 planes. The planes are being used to find shapes
+/// that are inside the frustum
 class Frustum: public CollisionShape
 class Frustum: public CollisionShape
 {
 {
 public:
 public:
@@ -55,33 +57,27 @@ public:
 
 
 	float getNear() const
 	float getNear() const
 	{
 	{
-		return zNear;
-	}
-	float& getNear()
-	{
-		return zNear;
+		return near;
 	}
 	}
 	void setNear(const float x)
 	void setNear(const float x)
 	{
 	{
-		zNear = x;
+		near = x;
+		recalculate();
 	}
 	}
 
 
 	float getFar() const
 	float getFar() const
 	{
 	{
-		return zFar;
-	}
-	float& getFar()
-	{
-		return zFar;
+		return far;
 	}
 	}
 	void setFar(const float x)
 	void setFar(const float x)
 	{
 	{
-		zFar = x;
+		far = x;
+		recalculate();
 	}
 	}
 	/// @}
 	/// @}
 
 
-	/// Copy
-	Frustum& operator=(const Frustum& b);
+	/// Implements CollisionShape::transform. Ignores scale
+	void transform(const Transform& trf);
 
 
 	/// Implements CollisionShape::accept
 	/// Implements CollisionShape::accept
 	void accept(MutableVisitor& v)
 	void accept(MutableVisitor& v)
@@ -101,28 +97,23 @@ public:
 	virtual Mat4 calculateProjectionMatrix() const = 0;
 	virtual Mat4 calculateProjectionMatrix() const = 0;
 
 
 protected:
 protected:
+	/// Used to check against the frustum
+	std::array<Plane, FP_COUNT> planes;
+
 	/// @name Viewing variables
 	/// @name Viewing variables
 	/// @{
 	/// @{
-	float zNear;
-	float zFar;
+	float near;
+	float far;
 	/// @}
 	/// @}
 
 
-	Transform trf;
-
-	/// Used to check against the frustum
-	mutable std::array<Plane, FP_COUNT> planes;
+	Transform trf; ///< Retain the tranformation
 
 
-	/// It recalculates the planes in local space
-	virtual void recalculatePlanes() const = 0;
+	/// Called when a viewing variable changes. It recalculates the planes and
+	/// the other variables
+	virtual void recalculate() = 0;
 
 
-	/// Self explanatory
-	void transformPlanes() const
-	{
-		for(Plane& p : planes)
-		{
-			p.transform(trf);
-		}
-	}
+	/// Copy
+	Frustum& operator=(const Frustum& b);
 
 
 private:
 private:
 	FrustumType type;
 	FrustumType type;
@@ -148,10 +139,10 @@ public:
 	}
 	}
 
 
 	/// Set all
 	/// Set all
-	PerspectiveFrustum(float fovX_, float fovY_, float zNear_, float zFar_)
+	PerspectiveFrustum(float fovX_, float fovY_, float near_, float far_)
 		: Frustum(FT_PERSPECTIVE)
 		: Frustum(FT_PERSPECTIVE)
 	{
 	{
-		setAll(fovX_, fovY_, zNear_, zFar_);
+		setAll(fovX_, fovY_, near_, far_);
 	}
 	}
 	/// @}
 	/// @}
 
 
@@ -161,35 +152,30 @@ public:
 	{
 	{
 		return fovX;
 		return fovX;
 	}
 	}
-	float& getFovX()
-	{
-		return fovX;
-	}
 	void setFovX(float ang)
 	void setFovX(float ang)
 	{
 	{
 		fovX = ang;
 		fovX = ang;
+		recalculate();
 	}
 	}
 
 
 	float getFovY() const
 	float getFovY() const
 	{
 	{
 		return fovY;
 		return fovY;
 	}
 	}
-	float& getFovY()
-	{
-		return fovY;
-	}
 	void setFovY(float ang)
 	void setFovY(float ang)
 	{
 	{
 		fovY = ang;
 		fovY = ang;
+		recalculate();
 	}
 	}
 
 
 	/// Set all the parameters and recalculate the planes and shape
 	/// Set all the parameters and recalculate the planes and shape
-	void setAll(float fovX_, float fovY_, float zNear_, float zFar_)
+	void setAll(float fovX_, float fovY_, float near_, float far_)
 	{
 	{
 		fovX = fovX_;
 		fovX = fovX_;
 		fovY = fovY_,
 		fovY = fovY_,
-		zNear = zNear_;
-		zFar = zFar_;
+		near = near_;
+		far = far_;
+		recalculate();
 	}
 	}
 	/// @}
 	/// @}
 
 
@@ -199,9 +185,6 @@ public:
 	/// Implements CollisionShape::testPlane
 	/// Implements CollisionShape::testPlane
 	float testPlane(const Plane& p) const;
 	float testPlane(const Plane& p) const;
 
 
-	/// Implements CollisionShape::transform
-	virtual void transform(const Transform& trf);
-
 	/// Calculate and get transformed
 	/// Calculate and get transformed
 	PerspectiveFrustum getTransformed(const Transform& trf) const
 	PerspectiveFrustum getTransformed(const Transform& trf) const
 	{
 	{
@@ -210,6 +193,9 @@ public:
 		return o;
 		return o;
 	}
 	}
 
 
+	/// Re-implements Frustum::transform
+	void transform(const Transform& trf);
+
 	/// Implements Frustum::calculateProjectionMatrix
 	/// Implements Frustum::calculateProjectionMatrix
 	Mat4 calculateProjectionMatrix() const;
 	Mat4 calculateProjectionMatrix() const;
 
 
@@ -219,8 +205,8 @@ public:
 private:
 private:
 	/// @name Shape
 	/// @name Shape
 	/// @{
 	/// @{
-	mutable Vec3 eye; ///< The eye point
-	mutable std::array<Vec3, 4> dirs; ///< Directions
+	Vec3 eye; ///< The eye point
+	std::array<Vec3, 4> dirs; ///< Directions
 	/// @}
 	/// @}
 
 
 	/// @name Viewing variables
 	/// @name Viewing variables
@@ -229,14 +215,9 @@ private:
 	float fovY;
 	float fovY;
 	/// @}
 	/// @}
 
 
-	/// Implements CollisionShape::recalculatePlanes
-	void recalculatePlanes() const;
-
-	/// Recalculate @a eye and @a dirs
-	void recalculateShape() const;
-
-	/// Transform @a eye and @a dirs
-	void transformShape() const;
+	/// Implements CollisionShape::recalculate. Recalculate @a planes, @a eye
+	/// and @a dirs
+	void recalculate();
 };
 };
 
 
 /// Frustum shape for orthographic cameras
 /// Frustum shape for orthographic cameras
@@ -259,11 +240,11 @@ public:
 	}
 	}
 
 
 	/// Set all
 	/// Set all
-	OrthographicFrustum(float left_, float right_, float zNear_,
-		float zFar_, float top_, float bottom_)
+	OrthographicFrustum(float left_, float right_, float near_,
+		float far_, float top_, float bottom_)
 		: Frustum(FT_ORTHOGRAPHIC)
 		: Frustum(FT_ORTHOGRAPHIC)
 	{
 	{
-		setAll(left_, right_, zNear_, zFar_, top_, bottom_);
+		setAll(left_, right_, near_, far_, top_, bottom_);
 	}
 	}
 	/// @}
 	/// @}
 
 
@@ -273,64 +254,58 @@ public:
 	{
 	{
 		return left;
 		return left;
 	}
 	}
-	float& getLeft()
-	{
-		return left;
-	}
 	void setLeft(float f)
 	void setLeft(float f)
 	{
 	{
 		left = f;
 		left = f;
+		recalculate();
 	}
 	}
 
 
 	float getRight() const
 	float getRight() const
 	{
 	{
 		return right;
 		return right;
 	}
 	}
-	float& getRight()
-	{
-		return right;
-	}
 	void setRight(float f)
 	void setRight(float f)
 	{
 	{
 		right = f;
 		right = f;
+		recalculate();
 	}
 	}
 
 
 	float getTop() const
 	float getTop() const
 	{
 	{
 		return top;
 		return top;
 	}
 	}
-	float& getTop()
-	{
-		return top;
-	}
 	void setTop(float f)
 	void setTop(float f)
 	{
 	{
 		top = f;
 		top = f;
+		recalculate();
 	}
 	}
 
 
 	float getBottom() const
 	float getBottom() const
 	{
 	{
 		return bottom;
 		return bottom;
 	}
 	}
-	float& getBottom()
-	{
-		return bottom;
-	}
 	void setBottom(float f)
 	void setBottom(float f)
 	{
 	{
 		bottom = f;
 		bottom = f;
+		recalculate();
 	}
 	}
 
 
 	/// Set all
 	/// Set all
-	void setAll(float left_, float right_, float zNear_,
-		float zFar_, float top_, float bottom_)
+	void setAll(float left_, float right_, float near_,
+		float far_, float top_, float bottom_)
 	{
 	{
 		left = left_;
 		left = left_;
 		right = right_;
 		right = right_;
-		zNear = zNear_;
-		zFar = zFar_;
+		near = near_;
+		far = far_;
 		top = top_;
 		top = top_;
 		bottom = bottom_;
 		bottom = bottom_;
+		recalculate();
+	}
+
+	const Obb& getObb() const
+	{
+		return obb;
 	}
 	}
 	/// @}
 	/// @}
 
 
@@ -349,10 +324,18 @@ public:
 	/// Implements Frustum::calculateProjectionMatrix
 	/// Implements Frustum::calculateProjectionMatrix
 	Mat4 calculateProjectionMatrix() const;
 	Mat4 calculateProjectionMatrix() const;
 
 
+	/// Calculate and get transformed
+	OrthographicFrustum getTransformed(const Transform& trf) const
+	{
+		OrthographicFrustum o = *this;
+		o.transform(trf);
+		return o;
+	}
+
 private:
 private:
 	/// @name Shape
 	/// @name Shape
 	/// @{
 	/// @{
-	mutable Obb obb; ///< Including shape
+	Obb obb; ///< Including shape
 	/// @}
 	/// @}
 
 
 	/// @name Viewing variables
 	/// @name Viewing variables
@@ -360,15 +343,9 @@ private:
 	float left, right, top, bottom;
 	float left, right, top, bottom;
 	/// @}
 	/// @}
 
 
-	/// Implements Frustum::recalculatePlanes
-	void recalculatePlanes() const;
-
-	void recalculateShape() const;
-
-	void transformShape() const
-	{
-		obb.transform(trf);
-	}
+	/// Implements CollisionShape::recalculate. Recalculate @a planes and
+	/// @a obb
+	void recalculate();
 };
 };
 /// @}
 /// @}
 
 

+ 3 - 1
include/anki/math/Mat3.h

@@ -64,7 +64,9 @@ public:
 
 
 	/// @name Operators with others
 	/// @name Operators with others
 	/// @{
 	/// @{
-	Vec3 operator*(const Vec3& b) const;  ///< 9 muls, 6 adds
+
+	/// Vec3(dot(row0 * b), dot(row1 * b), dot(row2 * b)). 9 muls, 6 adds
+	Vec3 operator*(const Vec3& b) const;
 	/// @}
 	/// @}
 
 
 	/// @name Other
 	/// @name Other

+ 54 - 38
include/anki/scene/Camera.h

@@ -109,20 +109,6 @@ public:
 	}
 	}
 	/// @}
 	/// @}
 
 
-	/// @name Movable virtuals
-	/// @{
-
-	/// Overrides Movable::moveUpdate(). This does:
-	/// - Update view matrix
-	/// - Update frustum
-	void movableUpdate()
-	{
-		Movable::movableUpdate();
-		updateViewMatrix();
-		getFrustum().transform(getWorldTransform());
-	}
-	/// @}
-
 	/// @name Frustumable virtuals
 	/// @name Frustumable virtuals
 	/// @{
 	/// @{
 
 
@@ -137,6 +123,14 @@ public:
 
 
 	void lookAtPoint(const Vec3& point);
 	void lookAtPoint(const Vec3& point);
 
 
+protected:
+	/// Calculate the @a viewMat. The view matrix is the inverse world 
+	/// transformation
+	void updateViewMatrix()
+	{
+		viewMat = Mat4(getWorldTransform().getInverse());
+	}
+
 private:
 private:
 	/// @name Matrices
 	/// @name Matrices
 	/// @{
 	/// @{
@@ -153,14 +147,6 @@ private:
 	/// @}
 	/// @}
 
 
 	CameraType type;
 	CameraType type;
-
-	/// Calculate the @a viewMat
-	///
-	/// The view matrix is the inverse world transformation
-	void updateViewMatrix()
-	{
-		viewMat = Mat4(getWorldTransform().getInverse());
-	}
 };
 };
 
 
 /// Perspective camera
 /// Perspective camera
@@ -179,33 +165,48 @@ public:
 	/// @{
 	/// @{
 	float getFovX() const
 	float getFovX() const
 	{
 	{
-		return frustum.getFovX();
+		return frustumLocal.getFovX();
 	}
 	}
 	void setFovX(float ang)
 	void setFovX(float ang)
 	{
 	{
-		frustum.setFovX(ang);
+		frustumLocal.setFovX(ang);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
 	float getFovY() const
 	float getFovY() const
 	{
 	{
-		return frustum.getFovY();
+		return frustumLocal.getFovY();
 	}
 	}
 	void setFovY(float ang)
 	void setFovY(float ang)
 	{
 	{
-		frustum.setFovX(ang);
+		frustumLocal.setFovX(ang);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
 	void setAll(float fovX_, float fovY_, float zNear_, float zFar_)
 	void setAll(float fovX_, float fovY_, float zNear_, float zFar_)
 	{
 	{
-		frustum.setAll(fovX_, fovY_, zNear_, zFar_);
+		frustumLocal.setAll(fovX_, fovY_, zNear_, zFar_);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 	/// @}
 	/// @}
 
 
+	/// @name Movable virtuals
+	/// @{
+
+	/// Overrides Movable::moveUpdate(). This does:
+	/// - Update view matrix
+	/// - Update frustum
+	void movableUpdate()
+	{
+		Movable::movableUpdate();
+		updateViewMatrix();
+		frustumWorld = frustumLocal.getTransformed(getWorldTransform());
+	}
+	/// @}
+
 private:
 private:
-	PerspectiveFrustum frustum;
+	PerspectiveFrustum frustumLocal;
+	PerspectiveFrustum frustumWorld;
 
 
 	/// Called when the property changes
 	/// Called when the property changes
 	void updateFrustumSlot(const PerspectiveFrustum&)
 	void updateFrustumSlot(const PerspectiveFrustum&)
@@ -231,41 +232,41 @@ public:
 	/// @{
 	/// @{
 	float getLeft() const
 	float getLeft() const
 	{
 	{
-		return frustum.getLeft();
+		return frustumLocal.getLeft();
 	}
 	}
 	void setLeft(float f)
 	void setLeft(float f)
 	{
 	{
-		frustum.setLeft(f);
+		frustumLocal.setLeft(f);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
 	float getRight() const
 	float getRight() const
 	{
 	{
-		return frustum.getRight();
+		return frustumLocal.getRight();
 	}
 	}
 	void setRight(float f)
 	void setRight(float f)
 	{
 	{
-		frustum.setRight(f);
+		frustumLocal.setRight(f);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
 	float getTop() const
 	float getTop() const
 	{
 	{
-		return frustum.getTop();
+		return frustumLocal.getTop();
 	}
 	}
 	void setTop(float f)
 	void setTop(float f)
 	{
 	{
-		frustum.setTop(f);
+		frustumLocal.setTop(f);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
 	float getBottom() const
 	float getBottom() const
 	{
 	{
-		return frustum.getBottom();
+		return frustumLocal.getBottom();
 	}
 	}
 	void setBottom(float f)
 	void setBottom(float f)
 	{
 	{
-		frustum.setBottom(f);
+		frustumLocal.setBottom(f);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
@@ -273,13 +274,28 @@ public:
 	void setAll(float left_, float right_, float zNear_,
 	void setAll(float left_, float right_, float zNear_,
 		float zFar_, float top_, float bottom_)
 		float zFar_, float top_, float bottom_)
 	{
 	{
-		frustum.setAll(left_, right_, zNear_, zFar_, top_, bottom_);
+		frustumLocal.setAll(left_, right_, zNear_, zFar_, top_, bottom_);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 	/// @}
 	/// @}
 
 
+	/// @name Movable virtuals
+	/// @{
+
+	/// Overrides Movable::moveUpdate(). This does:
+	/// - Update view matrix
+	/// - Update frustum
+	void movableUpdate()
+	{
+		Movable::movableUpdate();
+		updateViewMatrix();
+		frustumWorld = frustumLocal.getTransformed(getWorldTransform());
+	}
+	/// @}
+
 private:
 private:
-	OrthographicFrustum frustum;
+	OrthographicFrustum frustumLocal;
+	OrthographicFrustum frustumWorld;
 
 
 	void updateFrustumSlot(const OrthographicFrustum&)
 	void updateFrustumSlot(const OrthographicFrustum&)
 	{
 	{

+ 63 - 60
src/collision/Frustum.cpp

@@ -11,20 +11,16 @@ namespace anki {
 //==============================================================================
 //==============================================================================
 Frustum& Frustum::operator=(const Frustum& b)
 Frustum& Frustum::operator=(const Frustum& b)
 {
 {
-	ANKI_ASSERT(type == b.type);
-	zNear = b.zNear;
-	zFar = b.zFar;
-	trf = b.trf;
 	planes = b.planes;
 	planes = b.planes;
+	near = b.near;
+	far = b.far;
+	trf = b.trf;
 	return *this;
 	return *this;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
 bool Frustum::insideFrustum(const CollisionShape& b) const
 bool Frustum::insideFrustum(const CollisionShape& b) const
 {
 {
-	recalculatePlanes();
-	transformPlanes();
-
 	for(const Plane& plane : planes)
 	for(const Plane& plane : planes)
 	{
 	{
 		if(b.testPlane(plane) < 0.0)
 		if(b.testPlane(plane) < 0.0)
@@ -36,6 +32,18 @@ bool Frustum::insideFrustum(const CollisionShape& b) const
 	return true;
 	return true;
 }
 }
 
 
+//==============================================================================
+void Frustum::transform(const Transform& trf_)
+{
+	trf.transform(trf_);
+
+	// Planes
+	for(Plane& p : planes)
+	{
+		p.transform(trf);
+	}
+}
+
 //==============================================================================
 //==============================================================================
 // PerspectiveFrustum                                                          =
 // PerspectiveFrustum                                                          =
 //==============================================================================
 //==============================================================================
@@ -54,9 +62,6 @@ PerspectiveFrustum& PerspectiveFrustum::operator=(const PerspectiveFrustum& b)
 //==============================================================================
 //==============================================================================
 float PerspectiveFrustum::testPlane(const Plane& p) const
 float PerspectiveFrustum::testPlane(const Plane& p) const
 {
 {
-	recalculateShape();
-	transformShape();
-
 	float o = 0.0;
 	float o = 0.0;
 
 
 	for(const Vec3& dir : dirs)
 	for(const Vec3& dir : dirs)
@@ -64,7 +69,7 @@ float PerspectiveFrustum::testPlane(const Plane& p) const
 		LineSegment ls(eye, dir);
 		LineSegment ls(eye, dir);
 		float t = ls.testPlane(p);
 		float t = ls.testPlane(p);
 
 
-		if(t == 0.0)
+		if(t == 0)
 		{
 		{
 			return 0.0;
 			return 0.0;
 		}
 		}
@@ -84,14 +89,8 @@ float PerspectiveFrustum::testPlane(const Plane& p) const
 //==============================================================================
 //==============================================================================
 void PerspectiveFrustum::transform(const Transform& trf_)
 void PerspectiveFrustum::transform(const Transform& trf_)
 {
 {
-	trf.transform(trf_);
-	transformPlanes();
-	transformShape();
-}
+	Frustum::transform(trf_);
 
 
-//==============================================================================
-void PerspectiveFrustum::transformShape() const
-{
 	eye.transform(trf);
 	eye.transform(trf);
 
 
 	for(Vec3& dir : dirs)
 	for(Vec3& dir : dirs)
@@ -103,17 +102,16 @@ void PerspectiveFrustum::transformShape() const
 //==============================================================================
 //==============================================================================
 void PerspectiveFrustum::getAabb(Aabb& aabb) const
 void PerspectiveFrustum::getAabb(Aabb& aabb) const
 {
 {
-	recalculateShape();
-	transformShape();
-
 	aabb.set(dirs);
 	aabb.set(dirs);
 	aabb.getMin() += eye;
 	aabb.getMin() += eye;
 	aabb.getMax() += eye;
 	aabb.getMax() += eye;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void PerspectiveFrustum::recalculatePlanes() const
+void PerspectiveFrustum::recalculate()
 {
 {
+	// Planes
+	//
 	float c, s; // cos & sine
 	float c, s; // cos & sine
 
 
 	Math::sinCos(Math::PI + fovX / 2, s, c);
 	Math::sinCos(Math::PI + fovX / 2, s, c);
@@ -129,24 +127,28 @@ void PerspectiveFrustum::recalculatePlanes() const
 	planes[FP_BOTTOM] = Plane(Vec3(0.0, -s, c), 0.0);
 	planes[FP_BOTTOM] = Plane(Vec3(0.0, -s, c), 0.0);
 
 
 	// near
 	// near
-	planes[FP_NEAR] = Plane(Vec3(0.0, 0.0, -1.0), zNear);
+	planes[FP_NEAR] = Plane(Vec3(0.0, 0.0, -1.0), near);
 	// far
 	// far
-	planes[FP_FAR] = Plane(Vec3(0.0, 0.0, 1.0), -zFar);
-}
-
-//==============================================================================
-void PerspectiveFrustum::recalculateShape() const
-{
-	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
+	planes[FP_FAR] = Plane(Vec3(0.0, 0.0, 1.0), -far);
+
+	// Rest
+	//
+	eye = Vec3(0.0, 0.0, -near);
+
+	float x = far / tan((Math::PI - fovX) / 2.0);
+	float y = tan(fovY / 2.0) * far;
+	float z = -far;
+
+	dirs[0] = Vec3(x, y, z - near); // top right
+	dirs[1] = Vec3(-x, y, z - near); // top left
+	dirs[2] = Vec3(-x, -y, z - near); // bottom left
+	dirs[3] = Vec3(x, -y, z - near); // bottom right
+
+	// Transform
+	//
+	Transform tmptrf = trf;
+	trf.setIdentity();
+	transform(tmptrf);
 }
 }
 
 
 //==============================================================================
 //==============================================================================
@@ -166,8 +168,8 @@ Mat4 PerspectiveFrustum::calculateProjectionMatrix() const
 	projectionMat(1, 3) = 0.0;
 	projectionMat(1, 3) = 0.0;
 	projectionMat(2, 0) = 0.0;
 	projectionMat(2, 0) = 0.0;
 	projectionMat(2, 1) = 0.0;
 	projectionMat(2, 1) = 0.0;
-	projectionMat(2, 2) = (zFar + zNear) / (zNear - zFar);
-	projectionMat(2, 3) = (2.0 * zFar * zNear) / (zNear - zFar);
+	projectionMat(2, 2) = (far + near) / (near - far);
+	projectionMat(2, 3) = (2.0 * far * near) / (near - far);
 	projectionMat(3, 0) = 0.0;
 	projectionMat(3, 0) = 0.0;
 	projectionMat(3, 1) = 0.0;
 	projectionMat(3, 1) = 0.0;
 	projectionMat(3, 2) = -1.0;
 	projectionMat(3, 2) = -1.0;
@@ -197,24 +199,19 @@ OrthographicFrustum& OrthographicFrustum::operator=(
 //==============================================================================
 //==============================================================================
 float OrthographicFrustum::testPlane(const Plane& p) const
 float OrthographicFrustum::testPlane(const Plane& p) const
 {
 {
-	recalculateShape();
-	transformShape();
 	return obb.testPlane(p);
 	return obb.testPlane(p);
 }
 }
 
 
 //==============================================================================
 //==============================================================================
 void OrthographicFrustum::transform(const Transform& trf_)
 void OrthographicFrustum::transform(const Transform& trf_)
 {
 {
-	trf.transform(trf_);
-	transformPlanes();
-	transformShape();
+	Frustum::transform(trf_);
+	obb.transform(trf);
 }
 }
 
 
 //==============================================================================
 //==============================================================================
 void OrthographicFrustum::getAabb(Aabb& aabb) const
 void OrthographicFrustum::getAabb(Aabb& aabb) const
 {
 {
-	recalculateShape();
-	transformShape();
 	obb.getAabb(aabb);
 	obb.getAabb(aabb);
 }
 }
 
 
@@ -223,15 +220,15 @@ Mat4 OrthographicFrustum::calculateProjectionMatrix() const
 {
 {
 	float difx = right - left;
 	float difx = right - left;
 	float dify = top - bottom;
 	float dify = top - bottom;
-	float difz = zFar - zNear;
+	float difz = far - near;
 	float tx = -(right + left) / difx;
 	float tx = -(right + left) / difx;
 	float ty = -(top + bottom) / dify;
 	float ty = -(top + bottom) / dify;
-	float tz = -(zFar + zNear) / difz;
+	float tz = -(far + near) / difz;
 	Mat4 m;
 	Mat4 m;
 
 
 	m(0, 0) = 2.0 / difx;
 	m(0, 0) = 2.0 / difx;
 	m(0, 1) = 0.0;
 	m(0, 1) = 0.0;
-	m(0, 2) = 0.0;
+	m(0, 2) = 0.0:
 	m(0, 3) = tx;
 	m(0, 3) = tx;
 	m(1, 0) = 0.0;
 	m(1, 0) = 0.0;
 	m(1, 1) = 2.0 / dify;
 	m(1, 1) = 2.0 / dify;
@@ -250,22 +247,28 @@ Mat4 OrthographicFrustum::calculateProjectionMatrix() const
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void OrthographicFrustum::recalculatePlanes() const
+void OrthographicFrustum::recalculate()
 {
 {
+	// Planes
+	//
 	planes[FP_LEFT] = Plane(Vec3(1.0, 0.0, 0.0), left);
 	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_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_NEAR] = Plane(Vec3(0.0, 0.0, -1.0), near);
+	planes[FP_FAR] = Plane(Vec3(0.0, 0.0, 1.0), -far);
 	planes[FP_TOP] = Plane(Vec3(0.0, -1.0, 0.0), -top);
 	planes[FP_TOP] = Plane(Vec3(0.0, -1.0, 0.0), -top);
 	planes[FP_BOTTOM] = Plane(Vec3(0.0, 1.0, 0.0), bottom);
 	planes[FP_BOTTOM] = Plane(Vec3(0.0, 1.0, 0.0), bottom);
-}
 
 
-//==============================================================================
-void OrthographicFrustum::recalculateShape() const
-{
-	Vec3 c((right + left) * 0.5, (top + bottom) * 0.5, - (zFar + zNear) * 0.5);
-	Vec3 e = Vec3(right, top, -zFar) - c;
+	// OBB
+	//
+	Vec3 c((right + left) * 0.5, (top + bottom) * 0.5, - (far + near) * 0.5);
+	Vec3 e = Vec3(right, top, -far) - c;
 	obb = Obb(c, Mat3::getIdentity(), e);
 	obb = Obb(c, Mat3::getIdentity(), e);
+
+	// Transform
+	//
+	Transform tmptrf = trf;
+	trf.setIdentity();
+	transform(tmptrf);
 }
 }
 
 
 } // end namespace
 } // end namespace

+ 8 - 4
src/scene/Camera.cpp

@@ -30,10 +30,12 @@ void Camera::lookAtPoint(const Vec3& point)
 //==============================================================================
 //==============================================================================
 PerspectiveCamera::PerspectiveCamera(const char* name, Scene* scene,
 PerspectiveCamera::PerspectiveCamera(const char* name, Scene* scene,
 	uint movableFlags, Movable* movParent)
 	uint movableFlags, Movable* movParent)
-	: Camera(CT_PERSPECTIVE, name, scene, movableFlags, movParent, &frustum)
+	: Camera(CT_PERSPECTIVE, name, scene, movableFlags, movParent, 
+		&frustumWorld)
 {
 {
 	Property<PerspectiveFrustum>* prop =
 	Property<PerspectiveFrustum>* prop =
-		new ReadWritePointerProperty<PerspectiveFrustum>("frustum", &frustum);
+		new ReadWritePointerProperty<PerspectiveFrustum>("frustum", 
+		&frustumLocal);
 
 
 	addNewProperty(prop);
 	addNewProperty(prop);
 
 
@@ -47,10 +49,12 @@ PerspectiveCamera::PerspectiveCamera(const char* name, Scene* scene,
 //==============================================================================
 //==============================================================================
 OrthographicCamera::OrthographicCamera(const char* name, Scene* scene,
 OrthographicCamera::OrthographicCamera(const char* name, Scene* scene,
 	uint movableFlags, Movable* movParent)
 	uint movableFlags, Movable* movParent)
-	: Camera(CT_ORTHOGRAPHIC, name, scene, movableFlags, movParent, &frustum)
+	: Camera(CT_ORTHOGRAPHIC, name, scene, movableFlags, movParent, 
+		&frustumWorld)
 {
 {
 	Property<OrthographicFrustum>* prop =
 	Property<OrthographicFrustum>* prop =
-		new ReadWritePointerProperty<OrthographicFrustum>("frustum", &frustum);
+		new ReadWritePointerProperty<OrthographicFrustum>("frustum", 
+		&frustumLocal);
 
 
 	addNewProperty(prop);
 	addNewProperty(prop);