Bläddra i källkod

Collision and scene changes

Panagiotis Christopoulos Charitos 11 år sedan
förälder
incheckning
2e29b23f50

+ 15 - 50
include/anki/collision/CollisionAlgorithms.h

@@ -13,23 +13,21 @@ namespace detail {
 /// Provides the collision algorithms that detect collision between various
 /// Provides the collision algorithms that detect collision between various
 /// shapes
 /// shapes
 /// @code
 /// @code
-/// +------+------+------+------+------+------+------+------+
-/// |      | 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   |
-/// +------+------+------+------+------+------+------+------+
-/// | FRU  |      |      | N/I  | N/I  | N/I  | N/I  | N/I  |
-/// +------+------+------+------+------+------+------+------+
-/// | P    |      |      |      | OK   | OK   | OK   | OK   |
-/// +------+------+------+------+------+------+------+------+
-/// | R    |      |      |      |      | N/A  | OK   | OK   |
-/// +------+------+------+------+------+------+------+------+
-/// | S    |      |      |      |      |      | OK   | OK   |
-/// +------+------+------+------+------+------+------+------+
-/// | AABB |      |      |      |      |      |      | OK   |
-/// +------+------+------+------+------+------+------+------+
+/// +------+------+------+------+------+------+------+
+/// |      | LS   | OBB  | P    | R    | S    | AABB |
+/// +------+------+------+------+------+------+------+
+/// | LS   | N/A  | OK   | OK   | N/A  | OK   | OK   |
+/// +------+------+------+------+------+------+------+
+/// | OBB  |      | OK   | OK   | OK   | OK   | OK   |
+/// +------+------+------+------+------+------+------+
+/// | P    |      |      | OK   | OK   | OK   | OK   |
+/// +------+------+------+------+------+------+------+
+/// | R    |      |      |      | N/A  | OK   | OK   |
+/// +------+------+------+------+------+------+------+
+/// | S    |      |      |      |      | OK   | OK   |
+/// +------+------+------+------+------+------+------+
+/// | AABB |      |      |      |      |      | OK   |
+/// +------+------+------+------+------+------+------+
 /// @endcode
 /// @endcode
 /// @{
 /// @{
 
 
@@ -40,7 +38,6 @@ extern Bool collide(const CollisionShape& a, const CollisionShape& b);
 // 1st line (LS)
 // 1st line (LS)
 extern Bool collide(const LineSegment& a, const LineSegment& b);
 extern Bool collide(const LineSegment& a, const LineSegment& b);
 extern Bool collide(const LineSegment& a, const Obb& b);
 extern Bool collide(const LineSegment& a, const Obb& b);
-extern Bool collide(const LineSegment& a, const Frustum& b);
 extern Bool collide(const LineSegment& a, const Plane& b);
 extern Bool collide(const LineSegment& a, const Plane& b);
 extern Bool collide(const LineSegment& a, const Ray& b);
 extern Bool collide(const LineSegment& a, const Ray& b);
 extern Bool collide(const LineSegment& a, const Sphere& b);
 extern Bool collide(const LineSegment& a, const Sphere& b);
@@ -52,27 +49,11 @@ inline Bool collide(const Obb& a, const LineSegment& b)
 	return collide(b, a);
 	return collide(b, a);
 }
 }
 extern Bool collide(const Obb& a, const Obb& b);
 extern Bool collide(const Obb& a, const Obb& b);
-extern Bool collide(const Obb& a, const Frustum& b);
 extern Bool collide(const Obb& a, const Plane& b);
 extern Bool collide(const Obb& a, const Plane& b);
 extern Bool collide(const Obb& a, const Ray& b);
 extern Bool collide(const Obb& a, const Ray& b);
 extern Bool collide(const Obb& a, const Sphere& b);
 extern Bool collide(const Obb& a, const Sphere& b);
 extern Bool collide(const Obb& a, const Aabb& b);
 extern Bool collide(const Obb& a, const Aabb& b);
 
 
-// 3rd line (FRU)
-inline Bool collide(const Frustum& a, const LineSegment& b)
-{
-	return collide(b, a);
-}
-inline Bool collide(const Frustum& a, const Obb& b)
-{
-	return collide(b, a);
-}
-extern Bool collide(const Frustum& a, const Frustum& b);
-extern Bool collide(const Frustum& a, const Plane& b);
-extern Bool collide(const Frustum& a, const Ray& b);
-extern Bool collide(const Frustum& a, const Sphere& b);
-extern Bool collide(const Frustum& a, const Aabb& b);
-
 // 4th line (P)
 // 4th line (P)
 inline Bool collide(const Plane& a, const LineSegment& b)
 inline Bool collide(const Plane& a, const LineSegment& b)
 {
 {
@@ -82,10 +63,6 @@ inline Bool collide(const Plane& a, const Obb& b)
 {
 {
 	return collide(b, a);
 	return collide(b, a);
 }
 }
-inline Bool collide(const Plane& a,const Frustum& b)
-{
-	return collide(b, a);
-}
 extern Bool collide(const Plane& a, const Plane& b);
 extern Bool collide(const Plane& a, const Plane& b);
 extern Bool collide(const Plane& a, const Ray& b);
 extern Bool collide(const Plane& a, const Ray& b);
 extern Bool collide(const Plane& a, const Sphere& b);
 extern Bool collide(const Plane& a, const Sphere& b);
@@ -100,10 +77,6 @@ inline Bool collide(const Ray& a, const Obb& b)
 {
 {
 	return collide(b, a);
 	return collide(b, a);
 }
 }
-inline Bool collide(const Ray& a, const Frustum& b)
-{
-	return collide(b, a);
-}
 inline Bool collide(const Ray& a, const Plane& b)
 inline Bool collide(const Ray& a, const Plane& b)
 {
 {
 	return collide(b, a);
 	return collide(b, a);
@@ -121,10 +94,6 @@ inline Bool collide(const Sphere& a, const Obb& b)
 {
 {
 	return collide(b, a);
 	return collide(b, a);
 }
 }
-inline Bool collide(const Sphere& a, const Frustum& b)
-{
-	return collide(b, a);
-}
 inline Bool collide(const Sphere& a, const Plane& b)
 inline Bool collide(const Sphere& a, const Plane& b)
 {
 {
 	return collide(b, a);
 	return collide(b, a);
@@ -145,10 +114,6 @@ inline Bool collide(const Aabb& a, const Obb& b)
 {
 {
 	return collide(b, a);
 	return collide(b, a);
 }
 }
-inline Bool collide(const Aabb& a, const Frustum& b)
-{
-	return collide(b, a);
-}
 inline Bool collide(const Aabb& a, const Plane& b)
 inline Bool collide(const Aabb& a, const Plane& b)
 {
 {
 	return collide(b, a);
 	return collide(b, a);

+ 0 - 3
include/anki/collision/CollisionShape.h

@@ -26,7 +26,6 @@ public:
 		SPHERE,
 		SPHERE,
 		AABB,
 		AABB,
 		OBB,
 		OBB,
-		FRUSTUM,
 		COMPOUND
 		COMPOUND
 	};
 	};
 
 
@@ -39,7 +38,6 @@ public:
 
 
 		virtual void visit(LineSegment&) = 0;
 		virtual void visit(LineSegment&) = 0;
 		virtual void visit(Obb&) = 0;
 		virtual void visit(Obb&) = 0;
-		virtual void visit(Frustum&) = 0;
 		virtual void visit(Plane&) = 0;
 		virtual void visit(Plane&) = 0;
 		virtual void visit(Ray&) = 0;
 		virtual void visit(Ray&) = 0;
 		virtual void visit(Sphere&) = 0;
 		virtual void visit(Sphere&) = 0;
@@ -56,7 +54,6 @@ public:
 
 
 		virtual void visit(const LineSegment&) = 0;
 		virtual void visit(const LineSegment&) = 0;
 		virtual void visit(const Obb&) = 0;
 		virtual void visit(const Obb&) = 0;
-		virtual void visit(const Frustum&) = 0;
 		virtual void visit(const Plane&) = 0;
 		virtual void visit(const Plane&) = 0;
 		virtual void visit(const Ray&) = 0;
 		virtual void visit(const Ray&) = 0;
 		virtual void visit(const Sphere&) = 0;
 		virtual void visit(const Sphere&) = 0;

+ 10 - 2
include/anki/collision/CompoundShape.h

@@ -47,7 +47,11 @@ private:
 		U idx = 0;
 		U idx = 0;
 		while(m_dflt[idx])
 		while(m_dflt[idx])
 		{
 		{
-			f(*m_dflt[idx]);
+			if(m_dflt[idx])
+			{
+				f(*m_dflt[idx]);
+			}
+			++idx;
 		}
 		}
 		ANKI_ASSERT(idx > 0 && "Empty CompoundShape");
 		ANKI_ASSERT(idx > 0 && "Empty CompoundShape");
 	}
 	}
@@ -58,7 +62,11 @@ private:
 		U idx = 0;
 		U idx = 0;
 		while(m_dflt[idx])
 		while(m_dflt[idx])
 		{
 		{
-			f(*m_dflt[idx]);
+			if(m_dflt[idx])
+			{
+				f(*m_dflt[idx]);
+			}
+			++idx;
 		}
 		}
 		ANKI_ASSERT(idx > 0 && "Empty CompoundShape");
 		ANKI_ASSERT(idx > 0 && "Empty CompoundShape");
 	}
 	}

+ 63 - 126
include/anki/collision/Frustum.h

@@ -1,9 +1,10 @@
 #ifndef ANKI_COLLISION_FRUSTUM_H
 #ifndef ANKI_COLLISION_FRUSTUM_H
 #define ANKI_COLLISION_FRUSTUM_H
 #define ANKI_COLLISION_FRUSTUM_H
 
 
-#include "anki/collision/CollisionShape.h"
+#include "anki/collision/CompoundShape.h"
 #include "anki/collision/Plane.h"
 #include "anki/collision/Plane.h"
 #include "anki/collision/Obb.h"
 #include "anki/collision/Obb.h"
+#include "anki/collision/LineSegment.h"
 #include "anki/Math.h"
 #include "anki/Math.h"
 #include "anki/util/Array.h"
 #include "anki/util/Array.h"
 
 
@@ -12,34 +13,34 @@ namespace anki {
 /// @addtogroup Collision
 /// @addtogroup Collision
 /// @{
 /// @{
 
 
-/// Frustum type
-enum class FrustumType: U8
-{
-	PERSPECTIVE,
-	ORTHOGRAPHIC
-};
-
-/// The 6 frustum planes
-enum class FrustumPlane: U8
-{
-	NEAR,
-	FAR,
-	LEFT,
-	RIGHT,
-	TOP,
-	BOTTOM,
-	COUNT ///< Number of planes
-};
-
 /// Frustum collision shape. This shape consists from 6 planes. The planes are
 /// Frustum collision shape. This shape consists from 6 planes. The planes are
 /// being used to find shapes that are inside the frustum
 /// being used to find shapes that are inside the frustum
-class Frustum: public CollisionShape
+class Frustum: public CompoundShape
 {
 {
 public:
 public:
+	/// Frustum type
+	enum class Type: U8
+	{
+		PERSPECTIVE,
+		ORTHOGRAPHIC
+	};
+
+	/// The 6 frustum planes
+	enum class PlaneType: U8
+	{
+		NEAR,
+		FAR,
+		LEFT,
+		RIGHT,
+		TOP,
+		BOTTOM,
+		COUNT ///< Number of planes
+	};
+
 	/// @name Constructors
 	/// @name Constructors
 	/// @{
 	/// @{
-	Frustum(FrustumType type)
-		: CollisionShape(Type::FRUSTUM), m_type(type)
+	Frustum(Type type)
+		: m_type(type)
 	{}
 	{}
 
 
 	virtual ~Frustum()
 	virtual ~Frustum()
@@ -48,7 +49,7 @@ public:
 
 
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
-	FrustumType getFrustumType() const
+	Type getType() const
 	{
 	{
 		return m_type;
 		return m_type;
 	}
 	}
@@ -60,7 +61,7 @@ public:
 	void setNear(const F32 x)
 	void setNear(const F32 x)
 	{
 	{
 		m_near = x;
 		m_near = x;
-		recalculate();
+		m_frustumDirty = true;
 	}
 	}
 
 
 	F32 getFar() const
 	F32 getFar() const
@@ -70,41 +71,27 @@ public:
 	void setFar(const F32 x)
 	void setFar(const F32 x)
 	{
 	{
 		m_far = x;
 		m_far = x;
-		recalculate();
+		m_frustumDirty = true;
 	}
 	}
-	/// @}
 
 
-	/// Check for collision
-	template<typename T>
-	Bool collide(const T& x) const
+	const Transform& getTransform() const
 	{
 	{
-		return detail::collide(*this, x);
+		return m_trf;
 	}
 	}
+	/// @}
 
 
-	/// Implements CollisionShape::accept
-	void accept(MutableVisitor& v)
-	{
-		v.visit(*this);
-	}
-	/// Implements CollisionShape::accept
-	void accept(ConstVisitor& v) const
-	{
-		v.visit(*this);
-	}
+	/// Override CompoundShape::transform
+	void transform(const Transform& trf) override;
+
+	/// Convenient method to reset the transformation
+	void resetTransform();
 
 
 	/// Check if a collision shape @a b is inside the frustum
 	/// Check if a collision shape @a b is inside the frustum
-	Bool insideFrustum(const CollisionShape& b) const;
+	Bool insideFrustum(const CollisionShape& b);
 
 
 	/// Calculate the projection matrix
 	/// Calculate the projection matrix
 	virtual Mat4 calculateProjectionMatrix() const = 0;
 	virtual Mat4 calculateProjectionMatrix() const = 0;
 
 
-	/// Its like transform() but but with a difference. It doesn't transform
-	/// the @a trf, it just replaces it
-	virtual void setTransform(const Transform& trf) = 0;
-
-	/// Implements CollisionShape::toAbb
-	void computeAabb(Aabb& aabb) const;
-
 protected:
 protected:
 	/// @name Viewing variables
 	/// @name Viewing variables
 	/// @{
 	/// @{
@@ -113,9 +100,12 @@ protected:
 	/// @}
 	/// @}
 
 
 	/// Used to check against the frustum
 	/// Used to check against the frustum
-	Array<Plane, (U)FrustumPlane::COUNT> m_planes;
+	Array<Plane, (U)PlaneType::COUNT> m_planes;
 
 
-	Transform m_trf = Transform::getIdentity(); ///< Retain the transformation
+	Transform m_trf = Transform::getIdentity(); ///< Keep the transformation
+
+	/// It's true when the frustum changed
+	Bool8 m_frustumDirty = true;
 
 
 	/// Called when a viewing variable changes. It recalculates the planes and
 	/// Called when a viewing variable changes. It recalculates the planes and
 	/// the other variables
 	/// the other variables
@@ -124,16 +114,8 @@ protected:
 	/// Copy
 	/// Copy
 	Frustum& operator=(const Frustum& b);
 	Frustum& operator=(const Frustum& b);
 
 
-	void transformPlanes()
-	{
-		for(Plane& p : m_planes)
-		{
-			p.transform(m_trf);
-		}
-	}
-
 private:
 private:
-	FrustumType m_type;
+	Type m_type;
 };
 };
 
 
 /// Frustum shape for perspective cameras
 /// Frustum shape for perspective cameras
@@ -144,20 +126,18 @@ public:
 	/// @{
 	/// @{
 
 
 	/// Default
 	/// Default
-	PerspectiveFrustum()
-		: Frustum(FrustumType::PERSPECTIVE)
-	{}
+	PerspectiveFrustum();
 
 
 	/// Copy
 	/// Copy
 	PerspectiveFrustum(const PerspectiveFrustum& b)
 	PerspectiveFrustum(const PerspectiveFrustum& b)
-		: Frustum(FrustumType::PERSPECTIVE)
+		: PerspectiveFrustum()
 	{
 	{
 		*this = b;
 		*this = b;
 	}
 	}
 
 
 	/// Set all
 	/// Set all
 	PerspectiveFrustum(F32 fovX, F32 fovY, F32 near, F32 far)
 	PerspectiveFrustum(F32 fovX, F32 fovY, F32 near, F32 far)
-		: Frustum(FrustumType::PERSPECTIVE)
+		: PerspectiveFrustum()
 	{
 	{
 		setAll(fovX, fovY, near, far);
 		setAll(fovX, fovY, near, far);
 	}
 	}
@@ -172,7 +152,7 @@ public:
 	void setFovX(F32 ang)
 	void setFovX(F32 ang)
 	{
 	{
 		m_fovX = ang;
 		m_fovX = ang;
-		recalculate();
+		m_frustumDirty = true;
 	}
 	}
 
 
 	F32 getFovY() const
 	F32 getFovY() const
@@ -182,7 +162,7 @@ public:
 	void setFovY(F32 ang)
 	void setFovY(F32 ang)
 	{
 	{
 		m_fovY = ang;
 		m_fovY = ang;
-		recalculate();
+		m_frustumDirty = true;
 	}
 	}
 
 
 	/// Set all the parameters and recalculate the planes and shape
 	/// Set all the parameters and recalculate the planes and shape
@@ -192,21 +172,18 @@ public:
 		m_fovY = fovY,
 		m_fovY = fovY,
 		m_near = near;
 		m_near = near;
 		m_far = far;
 		m_far = far;
-		recalculate();
+		m_frustumDirty = true;
 	}
 	}
 
 
-	const Array<Vec3, 4>& getDirections() const
+	const Array<LineSegment, 4>& getLineSegments() const
 	{
 	{
-		return m_dirs;
+		return m_segments;
 	}
 	}
 	/// @}
 	/// @}
 
 
 	/// Copy
 	/// Copy
 	PerspectiveFrustum& operator=(const PerspectiveFrustum& b);
 	PerspectiveFrustum& operator=(const PerspectiveFrustum& b);
 
 
-	/// Implements CollisionShape::testPlane
-	F32 testPlane(const Plane& p) const;
-
 	/// Calculate and get transformed
 	/// Calculate and get transformed
 	PerspectiveFrustum getTransformed(const Transform& trf) const
 	PerspectiveFrustum getTransformed(const Transform& trf) const
 	{
 	{
@@ -215,18 +192,9 @@ public:
 		return o;
 		return o;
 	}
 	}
 
 
-	/// Re-implements Frustum::transform
-	void transform(const Transform& trf);
-
-	/// Implements Frustum::setTransform
-	void setTransform(const Transform& trf);
-
 	/// Implements Frustum::calculateProjectionMatrix
 	/// Implements Frustum::calculateProjectionMatrix
 	Mat4 calculateProjectionMatrix() const;
 	Mat4 calculateProjectionMatrix() const;
 
 
-	/// Implements CollisionShape::computeAabb
-	void computeAabb(Aabb& aabb) const;
-
 private:
 private:
 	/// @name Viewing variables
 	/// @name Viewing variables
 	/// @{
 	/// @{
@@ -236,18 +204,13 @@ private:
 
 
 	/// @name Shape
 	/// @name Shape
 	/// @{
 	/// @{
-	Vec3 m_eye; ///< The eye point
-	Array<Vec3, 4> m_dirs; ///< Directions
+	Array<LineSegment, 4> m_segments;
 	/// @}
 	/// @}
 
 
-	/// Implements CollisionShape::recalculate. Recalculate:
+	/// Implements Frustum::recalculate. Recalculates:
 	/// @li planes
 	/// @li planes
-	/// @li eye
-	/// @li dirs
+	/// @li line segments
 	void recalculate();
 	void recalculate();
-
-	/// Transform the @a eye and @a dirs using @a Frustrum::trf
-	void transformShape();
 };
 };
 
 
 /// Frustum shape for orthographic cameras
 /// Frustum shape for orthographic cameras
@@ -258,13 +221,11 @@ public:
 	/// @{
 	/// @{
 
 
 	/// Default
 	/// Default
-	OrthographicFrustum()
-		: Frustum(FrustumType::ORTHOGRAPHIC)
-	{}
+	OrthographicFrustum();
 
 
 	/// Copy
 	/// Copy
 	OrthographicFrustum(const OrthographicFrustum& b)
 	OrthographicFrustum(const OrthographicFrustum& b)
-		: Frustum(FrustumType::ORTHOGRAPHIC)
+		: OrthographicFrustum()
 	{
 	{
 		*this = b;
 		*this = b;
 	}
 	}
@@ -272,7 +233,7 @@ public:
 	/// Set all
 	/// Set all
 	OrthographicFrustum(F32 left, F32 right, F32 near,
 	OrthographicFrustum(F32 left, F32 right, F32 near,
 		F32 far, F32 top, F32 bottom)
 		F32 far, F32 top, F32 bottom)
-		: Frustum(FrustumType::ORTHOGRAPHIC)
+		: OrthographicFrustum()
 	{
 	{
 		setAll(left, right, near, far, top, bottom);
 		setAll(left, right, near, far, top, bottom);
 	}
 	}
@@ -287,7 +248,7 @@ public:
 	void setLeft(F32 f)
 	void setLeft(F32 f)
 	{
 	{
 		m_left = f;
 		m_left = f;
-		recalculate();
+		m_frustumDirty = true;
 	}
 	}
 
 
 	F32 getRight() const
 	F32 getRight() const
@@ -297,7 +258,7 @@ public:
 	void setRight(F32 f)
 	void setRight(F32 f)
 	{
 	{
 		m_right = f;
 		m_right = f;
-		recalculate();
+		m_frustumDirty = true;
 	}
 	}
 
 
 	F32 getTop() const
 	F32 getTop() const
@@ -307,7 +268,7 @@ public:
 	void setTop(F32 f)
 	void setTop(F32 f)
 	{
 	{
 		m_top = f;
 		m_top = f;
-		recalculate();
+		m_frustumDirty = true;
 	}
 	}
 
 
 	F32 getBottom() const
 	F32 getBottom() const
@@ -317,7 +278,7 @@ public:
 	void setBottom(F32 f)
 	void setBottom(F32 f)
 	{
 	{
 		m_bottom = f;
 		m_bottom = f;
-		recalculate();
+		m_frustumDirty = true;
 	}
 	}
 
 
 	/// Set all
 	/// Set all
@@ -330,7 +291,7 @@ public:
 		m_far = far;
 		m_far = far;
 		m_top = top;
 		m_top = top;
 		m_bottom = bottom;
 		m_bottom = bottom;
-		recalculate();
+		m_frustumDirty = true;
 	}
 	}
 
 
 	/// Needed for debug drawing
 	/// Needed for debug drawing
@@ -343,24 +304,6 @@ public:
 	/// Copy
 	/// Copy
 	OrthographicFrustum& operator=(const OrthographicFrustum& b);
 	OrthographicFrustum& operator=(const OrthographicFrustum& b);
 
 
-	/// Implements CollisionShape::testPlane
-	F32 testPlane(const Plane& p) const
-	{
-		return m_obb.testPlane(p);
-	}
-
-	/// Override Frustum::transform
-	void transform(const Transform& trf);
-
-	/// Implements Frustum::setTransform
-	void setTransform(const Transform& trf);
-
-	/// Implements CollisionShape::computeAabb
-	void computeAabb(Aabb& aabb) const
-	{
-		m_obb.computeAabb(aabb);
-	}
-
 	/// Implements Frustum::calculateProjectionMatrix
 	/// Implements Frustum::calculateProjectionMatrix
 	Mat4 calculateProjectionMatrix() const;
 	Mat4 calculateProjectionMatrix() const;
 
 
@@ -383,18 +326,12 @@ private:
 	Obb m_obb; ///< Including shape
 	Obb m_obb; ///< Including shape
 	/// @}
 	/// @}
 
 
-	/// Implements CollisionShape::recalculate. Recalculate @a planes and
+	/// Implements Frustum::recalculate. Recalculate @a planes and
 	/// @a obb
 	/// @a obb
 	void recalculate();
 	void recalculate();
-
-	/// Transform the @a obb using @a Frustrum::trf
-	void transformShape()
-	{
-		m_obb.transform(m_trf);
-	}
 };
 };
 /// @}
 /// @}
 
 
-} // end namespace
+} // end namespace anki
 
 
 #endif
 #endif

+ 2 - 2
include/anki/collision/Functions.h

@@ -6,7 +6,7 @@
 
 
 namespace anki {
 namespace anki {
 
 
-/// @addtogroup Collision
+/// @addtogroup collision
 /// @{
 /// @{
 
 
 /// Extract the clip planes using an MVP matrix
 /// Extract the clip planes using an MVP matrix
@@ -16,7 +16,7 @@ namespace anki {
 ///
 ///
 /// @note plane_count * 8 muls, plane_count sqrt
 /// @note plane_count * 8 muls, plane_count sqrt
 extern void extractClipPlanes(const Mat4& mvp, 
 extern void extractClipPlanes(const Mat4& mvp, 
-	Plane* planes[(U)FrustumPlane::COUNT]);
+	Plane* planes[(U)Frustum::PlaneType::COUNT]);
 
 
 /// @}
 /// @}
 
 

+ 1 - 1
include/anki/collision/Plane.h

@@ -6,7 +6,7 @@
 
 
 namespace anki {
 namespace anki {
 
 
-/// @addtogroup Collision
+/// @addtogroup collision
 /// @{
 /// @{
 
 
 /// Plane collision shape
 /// Plane collision shape

+ 6 - 0
include/anki/gl/GlJobChain.h

@@ -128,6 +128,12 @@ public:
 	/// Execute all jobs
 	/// Execute all jobs
 	void executeAllJobs();
 	void executeAllJobs();
 
 
+	/// Fake that it's been executed
+	void makeExecuted()
+	{
+		m_executed = true;
+	}
+
 	/// Make immutable
 	/// Make immutable
 	void makeImmutable()
 	void makeImmutable()
 	{
 	{

+ 33 - 60
include/anki/scene/Camera.h

@@ -17,33 +17,40 @@ class Camera: public SceneNode, public MoveComponent, public FrustumComponent,
 {
 {
 public:
 public:
 	/// @note Don't EVER change the order
 	/// @note Don't EVER change the order
-	enum CameraType
+	enum class Type: U8
 	{
 	{
-		CT_PERSPECTIVE,
-		CT_ORTHOGRAPHIC,
-		CT_COUNT
+		PERSPECTIVE,
+		ORTHOGRAPHIC,
+		COUNT
 	};
 	};
 
 
 	/// @name Constructors/Destructor
 	/// @name Constructors/Destructor
 	/// @{
 	/// @{
 	Camera(
 	Camera(
 		const char* name, SceneGraph* scene, // SceneNode
 		const char* name, SceneGraph* scene, // SceneNode
-		CameraType type); // Self
+		Type type, Frustum* frustum); // Self
 
 
 	virtual ~Camera();
 	virtual ~Camera();
 	/// @}
 	/// @}
 
 
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
-	CameraType getCameraType() const
+	Type getCameraType() const
 	{
 	{
-		return type;
+		return m_type;
 	}
 	}
 
 
 	/// Needed by the renderer
 	/// Needed by the renderer
-	virtual F32 getNear() const = 0;
+	F32 getNear() const
+	{
+		return getFrustum().getNear();
+	}
+
 	/// Needed by the renderer
 	/// Needed by the renderer
-	virtual F32 getFar() const = 0;
+	F32 getFar() const
+	{
+		return getFrustum().getFar();
+	}
 	/// @}
 	/// @}
 
 
 	/// @name SceneNode virtuals
 	/// @name SceneNode virtuals
@@ -66,14 +73,6 @@ public:
 	}
 	}
 	/// @}
 	/// @}
 
 
-	/// @name FrustumComponent virtuals
-	/// @{
-	Vec3 getFrustumOrigin()
-	{
-		return getWorldTransform().getOrigin();
-	}
-	/// @}
-
 	void lookAtPoint(const Vec3& point);
 	void lookAtPoint(const Vec3& point);
 
 
 protected:
 protected:
@@ -84,7 +83,7 @@ protected:
 	void moveUpdate(MoveComponent& move);
 	void moveUpdate(MoveComponent& move);
 
 
 private:
 private:
-	CameraType type;
+	Type m_type;
 };
 };
 
 
 /// Perspective camera
 /// Perspective camera
@@ -98,39 +97,29 @@ public:
 
 
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
-	F32 getNear() const
-	{
-		return frustum.getNear();
-	}
-
-	F32 getFar() const
-	{
-		return frustum.getFar();
-	}
-
 	F32 getFovX() const
 	F32 getFovX() const
 	{
 	{
-		return frustum.getFovX();
+		return m_frustum.getFovX();
 	}
 	}
 	void setFovX(F32 x)
 	void setFovX(F32 x)
 	{
 	{
-		frustum.setFovX(x);
+		m_frustum.setFovX(x);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
 	F32 getFovY() const
 	F32 getFovY() const
 	{
 	{
-		return frustum.getFovY();
+		return m_frustum.getFovY();
 	}
 	}
 	void setFovY(F32 x)
 	void setFovY(F32 x)
 	{
 	{
-		frustum.setFovY(x);
+		m_frustum.setFovY(x);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
 	void setAll(F32 fovX_, F32 fovY_, F32 near_, F32 far_)
 	void setAll(F32 fovX_, F32 fovY_, F32 near_, F32 far_)
 	{
 	{
-		frustum.setAll(fovX_, fovY_, near_, far_);
+		m_frustum.setAll(fovX_, fovY_, near_, far_);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 	/// @}
 	/// @}
@@ -139,20 +128,12 @@ public:
 	/// @{
 	/// @{
 	const CollisionShape& getSpatialCollisionShape()
 	const CollisionShape& getSpatialCollisionShape()
 	{
 	{
-		return frustum;
-	}
-	/// @}
-
-	/// @name FrustumComponent virtuals
-	/// @{
-	Frustum& getFrustum()
-	{
-		return frustum;
+		return m_frustum;
 	}
 	}
 	/// @}
 	/// @}
 
 
 private:
 private:
-	PerspectiveFrustum frustum;
+	PerspectiveFrustum m_frustum;
 };
 };
 
 
 /// Orthographic camera
 /// Orthographic camera
@@ -168,37 +149,37 @@ public:
 	/// @{
 	/// @{
 	F32 getNear() const
 	F32 getNear() const
 	{
 	{
-		return frustum.getNear();
+		return m_frustum.getNear();
 	}
 	}
 
 
 	F32 getFar() const
 	F32 getFar() const
 	{
 	{
-		return frustum.getFar();
+		return m_frustum.getFar();
 	}
 	}
 
 
 	F32 getLeft() const
 	F32 getLeft() const
 	{
 	{
-		return frustum.getLeft();
+		return m_frustum.getLeft();
 	}
 	}
 
 
 	F32 getRight() const
 	F32 getRight() const
 	{
 	{
-		return frustum.getRight();
+		return m_frustum.getRight();
 	}
 	}
 
 
 	F32 getBottom() const
 	F32 getBottom() const
 	{
 	{
-		return frustum.getBottom();
+		return m_frustum.getBottom();
 	}
 	}
 
 
 	F32 getTop() const
 	F32 getTop() const
 	{
 	{
-		return frustum.getTop();
+		return m_frustum.getTop();
 	}
 	}
 
 
 	void setAll(F32 left, F32 right, F32 near, F32 far, F32 top, F32 bottom)
 	void setAll(F32 left, F32 right, F32 near, F32 far, F32 top, F32 bottom)
 	{
 	{
-		frustum.setAll(left, right, near, far, top, bottom);
+		m_frustum.setAll(left, right, near, far, top, bottom);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 	/// @}
 	/// @}
@@ -207,20 +188,12 @@ public:
 	/// @{
 	/// @{
 	const CollisionShape& getSpatialCollisionShape()
 	const CollisionShape& getSpatialCollisionShape()
 	{
 	{
-		return frustum;
-	}
-	/// @}
-
-	/// @name FrustumComponent virtuals
-	/// @{
-	Frustum& getFrustum()
-	{
-		return frustum;
+		return m_frustum;
 	}
 	}
 	/// @}
 	/// @}
 
 
 private:
 private:
-	OrthographicFrustum frustum;
+	OrthographicFrustum m_frustum;
 };
 };
 /// @}
 /// @}
 
 

+ 37 - 24
include/anki/scene/FrustumComponent.h

@@ -23,63 +23,75 @@ public:
 	/// @{
 	/// @{
 
 
 	/// Pass the frustum here so we can avoid the virtuals
 	/// Pass the frustum here so we can avoid the virtuals
-	FrustumComponent(SceneNode* node)
-		: SceneComponent(FRUSTUM_COMPONENT, node)
+	FrustumComponent(SceneNode* node, Frustum* frustum)
+		: SceneComponent(FRUSTUM_COMPONENT, node), m_frustum(frustum)
 	{
 	{
+		// WARNING: Never touch m_frustum in constructor
+		ANKI_ASSERT(frustum);
 		markForUpdate();
 		markForUpdate();
 	}
 	}
 	/// @}
 	/// @}
 
 
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
-	virtual Frustum& getFrustum() = 0;
+	Frustum& getFrustum()
+	{
+		return *m_frustum;
+	}
+	const Frustum& getFrustum() const
+	{
+		return *m_frustum;
+	}
 
 
 	const Mat4& getProjectionMatrix() const
 	const Mat4& getProjectionMatrix() const
 	{
 	{
-		return projectionMat;
+		return m_pm;
 	}
 	}
 	void setProjectionMatrix(const Mat4& m)
 	void setProjectionMatrix(const Mat4& m)
 	{
 	{
-		projectionMat = m;
+		m_pm = m;
 	}
 	}
 
 
 	const Mat4& getViewMatrix() const
 	const Mat4& getViewMatrix() const
 	{
 	{
-		return viewMat;
+		return m_vm;
 	}
 	}
 	void setViewMatrix(const Mat4& m)
 	void setViewMatrix(const Mat4& m)
 	{
 	{
-		viewMat = m;
+		m_vm = m;
 	}
 	}
 
 
 	const Mat4& getViewProjectionMatrix() const
 	const Mat4& getViewProjectionMatrix() const
 	{
 	{
-		return viewProjectionMat;
+		return m_vpm;
 	}
 	}
 	void setViewProjectionMatrix(const Mat4& m)
 	void setViewProjectionMatrix(const Mat4& m)
 	{
 	{
-		viewProjectionMat = m;
+		m_vpm = m;
 	}
 	}
 
 
 	/// Get the origin for sorting and visibility tests
 	/// Get the origin for sorting and visibility tests
-	virtual Vec3 getFrustumOrigin() = 0;
+	const Vec3& getFrustumOrigin() const
+	{
+		return getFrustum().getTransform().getOrigin();
+	}
 
 
-	void setVisibilityTestResults(VisibilityTestResults* visible_)
+	void setVisibilityTestResults(VisibilityTestResults* visible)
 	{
 	{
-		ANKI_ASSERT(visible == nullptr);
-		visible = visible_;
+		ANKI_ASSERT(m_visible == nullptr);
+		m_visible = m_visible;
 	}
 	}
 	/// Call this after the tests. Before it will point to junk
 	/// Call this after the tests. Before it will point to junk
 	VisibilityTestResults& getVisibilityTestResults()
 	VisibilityTestResults& getVisibilityTestResults()
 	{
 	{
-		ANKI_ASSERT(visible != nullptr);
-		return *visible;
+		ANKI_ASSERT(m_visible != nullptr);
+		return *m_visible;
 	}
 	}
 	/// @}
 	/// @}
 
 
 	void markForUpdate()
 	void markForUpdate()
 	{
 	{
-		markedForUpdate = true;
+		m_markedForUpdate = true;
 	}
 	}
 
 
 	/// Is a spatial inside the frustum?
 	/// Is a spatial inside the frustum?
@@ -99,8 +111,8 @@ public:
 	{
 	{
 		if(updateType == ASYNC_UPDATE)
 		if(updateType == ASYNC_UPDATE)
 		{
 		{
-			Bool out = markedForUpdate;
-			markedForUpdate = false;
+			Bool out = m_markedForUpdate;
+			m_markedForUpdate = false;
 			return out;
 			return out;
 		}
 		}
 		else
 		else
@@ -112,7 +124,7 @@ public:
 	/// Override SceneComponent::reset
 	/// Override SceneComponent::reset
 	void reset() override
 	void reset() override
 	{
 	{
-		visible = nullptr;
+		m_visible = nullptr;
 	}
 	}
 
 
 	static constexpr Type getClassType()
 	static constexpr Type getClassType()
@@ -121,15 +133,16 @@ public:
 	}
 	}
 
 
 private:
 private:
-	Mat4 projectionMat = Mat4::getIdentity();
-	Mat4 viewMat = Mat4::getIdentity();
-	Mat4 viewProjectionMat = Mat4::getIdentity();
+	Frustum* m_frustum;
+	Mat4 m_pm = Mat4::getIdentity(); ///< Projection matrix
+	Mat4 m_vm = Mat4::getIdentity(); ///< View matrix
+	Mat4 m_vpm = Mat4::getIdentity(); ///< View projection matrix
 
 
 	/// Visibility stuff. It's per frame so the pointer is invalid on the next 
 	/// Visibility stuff. It's per frame so the pointer is invalid on the next 
 	/// frame and before any visibility tests are run
 	/// frame and before any visibility tests are run
-	VisibilityTestResults* visible = nullptr;
+	VisibilityTestResults* m_visible = nullptr;
 
 
-	Bool8 markedForUpdate;
+	Bool8 m_markedForUpdate;
 };
 };
 /// @}
 /// @}
 
 

+ 18 - 31
include/anki/scene/Light.h

@@ -267,52 +267,52 @@ public:
 	/// @{
 	/// @{
 	GlTextureHandle& getTexture()
 	GlTextureHandle& getTexture()
 	{
 	{
-		return tex->getGlTexture();
+		return m_tex->getGlTexture();
 	}
 	}
 	const GlTextureHandle& getTexture() const
 	const GlTextureHandle& getTexture() const
 	{
 	{
-		return tex->getGlTexture();
+		return m_tex->getGlTexture();
 	}
 	}
 
 
 	F32 getOuterAngle() const
 	F32 getOuterAngle() const
 	{
 	{
-		return frustum.getFovX();
+		return m_frustum.getFovX();
 	}
 	}
 	void setOuterAngle(F32 x)
 	void setOuterAngle(F32 x)
 	{
 	{
-		frustum.setFovX(x);
-		frustum.setFovY(x);
-		cosOuterAngle = cos(x / 2.0);
+		m_frustum.setFovX(x);
+		m_frustum.setFovY(x);
+		m_cosOuterAngle = cos(x / 2.0);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
 	F32 getOuterAngleCos() const
 	F32 getOuterAngleCos() const
 	{
 	{
-		return cosOuterAngle;
+		return m_cosOuterAngle;
 	}
 	}
 
 
 	void setInnerAngle(F32 ang)
 	void setInnerAngle(F32 ang)
 	{
 	{
-		cosInnerAngle = cos(ang / 2.0);
+		m_cosInnerAngle = cos(ang / 2.0);
 	}
 	}
 	F32 getInnerAngleCos() const
 	F32 getInnerAngleCos() const
 	{
 	{
-		return cosInnerAngle;
+		return m_cosInnerAngle;
 	}
 	}
 
 
 	F32 getDistance() const
 	F32 getDistance() const
 	{
 	{
-		return frustum.getFar();
+		return m_frustum.getFar();
 	}
 	}
 	void setDistance(F32 f)
 	void setDistance(F32 f)
 	{
 	{
-		frustum.setFar(f);
+		m_frustum.setFar(f);
 		frustumUpdate();
 		frustumUpdate();
 	}
 	}
 
 
 	const PerspectiveFrustum& getFrustum() const
 	const PerspectiveFrustum& getFrustum() const
 	{
 	{
-		return frustum;
+		return m_frustum;
 	}
 	}
 	/// @}
 	/// @}
 
 
@@ -326,33 +326,20 @@ public:
 	/// @{
 	/// @{
 	const CollisionShape& getSpatialCollisionShape()
 	const CollisionShape& getSpatialCollisionShape()
 	{
 	{
-		return frustum;
-	}
-	/// @}
-
-	/// @name FrustumVirtuals
-	/// @{
-	Vec3 getFrustumOrigin()
-	{
-		return getWorldTransform().getOrigin();
-	}
-
-	Frustum& getFrustum()
-	{
-		return frustum;
+		return m_frustum;
 	}
 	}
 	/// @}
 	/// @}
 
 
 	void loadTexture(const char* filename)
 	void loadTexture(const char* filename)
 	{
 	{
-		tex.load(filename);
+		m_tex.load(filename);
 	}
 	}
 
 
 private:
 private:
-	PerspectiveFrustum frustum;
-	TextureResourcePointer tex;
-	F32 cosOuterAngle;
-	F32 cosInnerAngle;
+	PerspectiveFrustum m_frustum;
+	TextureResourcePointer m_tex;
+	F32 m_cosOuterAngle;
+	F32 m_cosInnerAngle;
 };
 };
 
 
 } // end namespace anki
 } // end namespace anki

+ 1 - 1
src/collision/Aabb.cpp

@@ -114,4 +114,4 @@ void Aabb::setFromPointCloud(
 	}
 	}
 }
 }
 
 
-} // namespace anki
+} // end namespace anki

+ 0 - 52
src/collision/CollisionAlgorithms.cpp

@@ -34,9 +34,6 @@ static Bool tcollide(const CollisionShape& a, const CollisionShape& b)
 	case CollisionShape::Type::OBB:
 	case CollisionShape::Type::OBB:
 		out = collide(t, static_cast<const Obb&>(b));
 		out = collide(t, static_cast<const Obb&>(b));
 		break;
 		break;
-	case CollisionShape::Type::FRUSTUM:
-		out = collide(t, static_cast<const Frustum&>(b));
-		break;
 	default:
 	default:
 		ANKI_ASSERT(0 && "Forgot something");
 		ANKI_ASSERT(0 && "Forgot something");
 		break;
 		break;
@@ -70,9 +67,6 @@ Bool collide(const CollisionShape& a, const CollisionShape& b)
 	case CollisionShape::Type::OBB:
 	case CollisionShape::Type::OBB:
 		out = tcollide<Obb>(a, b);
 		out = tcollide<Obb>(a, b);
 		break;
 		break;
-	case CollisionShape::Type::FRUSTUM:
-		out = tcollide<Frustum>(a, b);
-		break;
 	default:
 	default:
 		ANKI_ASSERT(0 && "Forgot something");
 		ANKI_ASSERT(0 && "Forgot something");
 		break;
 		break;
@@ -154,12 +148,6 @@ Bool collide(const LineSegment& ls, const Obb& obb)
 	return true;
 	return true;
 }
 }
 
 
-//==============================================================================
-Bool collide(const LineSegment& a, const Frustum& b)
-{
-	return b.insideFrustum(a);
-}
-
 //==============================================================================
 //==============================================================================
 Bool collide(const LineSegment& ls, const Plane& p)
 Bool collide(const LineSegment& ls, const Plane& p)
 {
 {
@@ -437,12 +425,6 @@ Bool collide(const Obb& o0, const Obb& o1)
 	return true;
 	return true;
 }
 }
 
 
-//==============================================================================
-Bool collide(const Obb& a, const Frustum& b)
-{
-	return b.insideFrustum(a);
-}
-
 //==============================================================================
 //==============================================================================
 Bool collide(const Obb& a, const Plane& b)
 Bool collide(const Obb& a, const Plane& b)
 {
 {
@@ -483,40 +465,6 @@ Bool collide(const Obb& obb, const Aabb& aabb)
 	return collide(obb, obb_);
 	return collide(obb, obb_);
 }
 }
 
 
-//==============================================================================
-// 3rd line (PCS)                                                              =
-//==============================================================================
-
-//==============================================================================
-Bool collide(const Frustum& a, const Frustum& b)
-{
-	return b.insideFrustum(a);
-}
-
-//==============================================================================
-Bool collide(const Frustum& a, const Plane& b)
-{
-	return a.insideFrustum(b);
-}
-
-//==============================================================================
-Bool collide(const Frustum& a, const Ray& b)
-{
-	return a.insideFrustum(b);
-}
-
-//==============================================================================
-Bool collide(const Frustum& a, const Sphere& b)
-{
-	return a.insideFrustum(b);
-}
-
-//==============================================================================
-Bool collide(const Frustum& a, const Aabb& b)
-{
-	return a.insideFrustum(b);
-}
-
 //==============================================================================
 //==============================================================================
 // 4th line (P)                                                                =
 // 4th line (P)                                                                =
 //==============================================================================
 //==============================================================================

+ 12 - 0
src/collision/CompoundShape.cpp

@@ -84,5 +84,17 @@ void CompoundShape::computeAabb(Aabb& out) const
 	out.setMax(max);
 	out.setMax(max);
 }
 }
 
 
+//==============================================================================
+void CompoundShape::addShape(CollisionShape* shape)
+{
+	U idx = 0;
+	while(m_dflt[idx])
+	{
+		++idx;
+	}
+
+	m_dflt[idx] = shape;
+}
+
 } // end namespace anki
 } // end namespace anki
 
 

+ 67 - 115
src/collision/Frustum.cpp

@@ -17,12 +17,22 @@ Frustum& Frustum::operator=(const Frustum& b)
 	m_far = b.m_far;
 	m_far = b.m_far;
 	m_planes = b.m_planes;
 	m_planes = b.m_planes;
 	m_trf = b.m_trf;
 	m_trf = b.m_trf;
+	m_frustumDirty = b.m_frustumDirty;
 	return *this;
 	return *this;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-Bool Frustum::insideFrustum(const CollisionShape& b) const
+Bool Frustum::insideFrustum(const CollisionShape& b)
 {
 {
+	if(m_frustumDirty)
+	{
+		m_frustumDirty = false;
+		recalculate();
+
+		// recalculate() reset the tranformations so re-transform
+		transform(m_trf);
+	}
+
 	for(const Plane& plane : m_planes)
 	for(const Plane& plane : m_planes)
 	{
 	{
 		if(b.testPlane(plane) < 0.0)
 		if(b.testPlane(plane) < 0.0)
@@ -35,101 +45,56 @@ Bool Frustum::insideFrustum(const CollisionShape& b) const
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void Frustum::computeAabb(Aabb& aabb) const
+void Frustum::transform(const Transform& trf)
 {
 {
-	switch(m_type)
+	if(m_frustumDirty)
 	{
 	{
-	case FrustumType::PERSPECTIVE:
-		static_cast<const PerspectiveFrustum*>(this)->computeAabb(aabb);
-		break;
-	case FrustumType::ORTHOGRAPHIC:
-		static_cast<const OrthographicFrustum*>(this)->computeAabb(aabb);
-		break;
-	default:
-		ANKI_ASSERT(0);
+		m_frustumDirty = false;
+		recalculate();
 	}
 	}
-}
-
-//==============================================================================
-// PerspectiveFrustum                                                          =
-//==============================================================================
-
-//==============================================================================
-PerspectiveFrustum& PerspectiveFrustum::operator=(const PerspectiveFrustum& b)
-{
-	Frustum::operator=(b);
-	m_fovX = b.m_fovX;
-	m_fovY = b.m_fovY;
-	m_eye = b.m_eye;
-	m_dirs = b.m_dirs;
-	return *this;
-}
 
 
-//==============================================================================
-F32 PerspectiveFrustum::testPlane(const Plane& p) const
-{
-	// At this point all are in the front side of the plane, all the are 
-	// intersecting or all on the negative side
+	m_trf.transform(trf);
 
 
-	LineSegment ls(m_eye, m_dirs[0]);
-	F32 o = ls.testPlane(p);
+	// Transform the compound
+	CompoundShape::transform(trf);
 
 
-	for(U i = 1; i < m_dirs.getSize(); i++)
+	// Transform the planes
+	for(Plane& p : m_planes)
 	{
 	{
-		LineSegment ls(m_eye, m_dirs[i]);
-		F32 t = ls.testPlane(p);
-
-		if(t == 0.0)
-		{
-			return 0.0;
-		}
-		else if(t < 0.0)
-		{
-			o = std::max(o, t);
-		}
-		else
-		{
-			o = std::min(o, t);
-		}
+		p.transform(trf);
 	}
 	}
-
-	return o;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void PerspectiveFrustum::transformShape()
+void Frustum::resetTransform()
 {
 {
-	m_eye.transform(m_trf);
-
-	for(Vec3& dir : m_dirs)
-	{
-		dir = m_trf.getRotation() * dir;
-	}
+	recalculate();
+	m_frustumDirty = false;
+	m_trf.setIdentity();
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void PerspectiveFrustum::transform(const Transform& trf)
-{
-	m_trf.transform(trf);
-	recalculate();
-}
+// PerspectiveFrustum                                                          =
+//==============================================================================
 
 
 //==============================================================================
 //==============================================================================
-void PerspectiveFrustum::setTransform(const Transform& trf)
+PerspectiveFrustum::PerspectiveFrustum()
+	: Frustum(Type::PERSPECTIVE)
 {
 {
-	m_trf = trf;
-	recalculate();
+	for(LineSegment& ls : m_segments)
+	{
+		addShape(&ls);
+	}
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void PerspectiveFrustum::computeAabb(Aabb& aabb) const
+PerspectiveFrustum& PerspectiveFrustum::operator=(const PerspectiveFrustum& b)
 {
 {
-	Array<Vec3, 5> points = {{
-		m_dirs[0], m_dirs[1], m_dirs[2], m_dirs[3], Vec3(0.0)}};
-	aabb.setFromPointCloud(&points[0], points.size(), sizeof(Vec3), 
-		points.size() * sizeof(Vec3));
-	aabb.getMin() += m_eye;
-	aabb.getMax() += m_eye;
+	Frustum::operator=(b);
+	m_fovX = b.m_fovX;
+	m_fovY = b.m_fovY;
+	m_segments = b.m_segments;
+	return *this;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
@@ -141,38 +106,37 @@ void PerspectiveFrustum::recalculate()
 
 
 	sinCos(getPi<F32>() + m_fovX / 2.0, s, c);
 	sinCos(getPi<F32>() + m_fovX / 2.0, s, c);
 	// right
 	// right
-	m_planes[(U)FrustumPlane::RIGHT] = Plane(Vec3(c, 0.0, s), 0.0);
+	m_planes[(U)PlaneType::RIGHT] = Plane(Vec3(c, 0.0, s), 0.0);
 	// left
 	// left
-	m_planes[(U)FrustumPlane::LEFT] = Plane(Vec3(-c, 0.0, s), 0.0);
+	m_planes[(U)PlaneType::LEFT] = Plane(Vec3(-c, 0.0, s), 0.0);
 
 
 	sinCos((getPi<F32>() + m_fovY) * 0.5, s, c);
 	sinCos((getPi<F32>() + m_fovY) * 0.5, s, c);
 	// bottom
 	// bottom
-	m_planes[(U)FrustumPlane::BOTTOM] = Plane(Vec3(0.0, s, c), 0.0);
+	m_planes[(U)PlaneType::BOTTOM] = Plane(Vec3(0.0, s, c), 0.0);
 	// top
 	// top
-	m_planes[(U)FrustumPlane::TOP] = Plane(Vec3(0.0, -s, c), 0.0);
+	m_planes[(U)PlaneType::TOP] = Plane(Vec3(0.0, -s, c), 0.0);
 
 
 	// near
 	// near
-	m_planes[(U)FrustumPlane::NEAR] = Plane(Vec3(0.0, 0.0, -1.0), m_near);
+	m_planes[(U)PlaneType::NEAR] = Plane(Vec3(0.0, 0.0, -1.0), m_near);
 	// far
 	// far
-	m_planes[(U)FrustumPlane::FAR] = Plane(Vec3(0.0, 0.0, 1.0), -m_far);
+	m_planes[(U)PlaneType::FAR] = Plane(Vec3(0.0, 0.0, 1.0), -m_far);
 
 
 	// Rest
 	// Rest
 	//
 	//
-	m_eye = Vec3(0.0, 0.0, -m_near);
+	Vec3 eye = Vec3(0.0, 0.0, -m_near);
+	for(LineSegment& ls : m_segments)
+	{
+		ls.setOrigin(eye);
+	}
 
 
 	F32 x = m_far / tan((getPi<F32>() - m_fovX) / 2.0);
 	F32 x = m_far / tan((getPi<F32>() - m_fovX) / 2.0);
 	F32 y = tan(m_fovY / 2.0) * m_far;
 	F32 y = tan(m_fovY / 2.0) * m_far;
 	F32 z = -m_far;
 	F32 z = -m_far;
 
 
-	m_dirs[0] = Vec3(x, y, z - m_near); // top right
-	m_dirs[1] = Vec3(-x, y, z - m_near); // top left
-	m_dirs[2] = Vec3(-x, -y, z - m_near); // bottom left
-	m_dirs[3] = Vec3(x, -y, z - m_near); // bottom right
-
-	// Transform
-	//
-	transformPlanes();
-	transformShape();
+	m_segments[0].setDirection(Vec3(x, y, z - m_near)); // top right
+	m_segments[1].setDirection(Vec3(-x, y, z - m_near)); // top left
+	m_segments[2].setDirection(Vec3(-x, -y, z - m_near)); // bottom left
+	m_segments[3].setDirection(Vec3(x, -y, z - m_near)); // bottom right
 }
 }
 
 
 //==============================================================================
 //==============================================================================
@@ -220,7 +184,6 @@ Mat4 PerspectiveFrustum::calculateProjectionMatrix() const
 	projectionMat(3, 3) = 0.0;
 	projectionMat(3, 3) = 0.0;
 #endif
 #endif
 
 
-
 	return projectionMat;
 	return projectionMat;
 }
 }
 
 
@@ -228,6 +191,13 @@ Mat4 PerspectiveFrustum::calculateProjectionMatrix() const
 // OrthographicFrustum                                                         =
 // OrthographicFrustum                                                         =
 //==============================================================================
 //==============================================================================
 
 
+//==============================================================================
+OrthographicFrustum::OrthographicFrustum()
+	: Frustum(Type::ORTHOGRAPHIC)
+{
+	addShape(&m_obb);
+}
+
 //==============================================================================
 //==============================================================================
 OrthographicFrustum& OrthographicFrustum::operator=(
 OrthographicFrustum& OrthographicFrustum::operator=(
 	const OrthographicFrustum& b)
 	const OrthographicFrustum& b)
@@ -241,20 +211,6 @@ OrthographicFrustum& OrthographicFrustum::operator=(
 	return *this;
 	return *this;
 }
 }
 
 
-//==============================================================================
-void OrthographicFrustum::transform(const Transform& trf)
-{
-	m_trf.transform(trf);
-	recalculate();
-}
-
-//==============================================================================
-void OrthographicFrustum::setTransform(const Transform& trf)
-{
-	m_trf = trf;
-	recalculate();
-}
-
 //==============================================================================
 //==============================================================================
 Mat4 OrthographicFrustum::calculateProjectionMatrix() const
 Mat4 OrthographicFrustum::calculateProjectionMatrix() const
 {
 {
@@ -292,12 +248,12 @@ Mat4 OrthographicFrustum::calculateProjectionMatrix() const
 void OrthographicFrustum::recalculate()
 void OrthographicFrustum::recalculate()
 {
 {
 	// Planes
 	// Planes
-	m_planes[(U)FrustumPlane::LEFT] = Plane(Vec3(1.0, 0.0, 0.0), m_left);
-	m_planes[(U)FrustumPlane::RIGHT] = Plane(Vec3(-1.0, 0.0, 0.0), -m_right);
-	m_planes[(U)FrustumPlane::NEAR] = Plane(Vec3(0.0, 0.0, -1.0), m_near);
-	m_planes[(U)FrustumPlane::FAR] = Plane(Vec3(0.0, 0.0, 1.0), -m_far);
-	m_planes[(U)FrustumPlane::TOP] = Plane(Vec3(0.0, -1.0, 0.0), -m_top);
-	m_planes[(U)FrustumPlane::BOTTOM] = Plane(Vec3(0.0, 1.0, 0.0), m_bottom);
+	m_planes[(U)PlaneType::LEFT] = Plane(Vec3(1.0, 0.0, 0.0), m_left);
+	m_planes[(U)PlaneType::RIGHT] = Plane(Vec3(-1.0, 0.0, 0.0), -m_right);
+	m_planes[(U)PlaneType::NEAR] = Plane(Vec3(0.0, 0.0, -1.0), m_near);
+	m_planes[(U)PlaneType::FAR] = Plane(Vec3(0.0, 0.0, 1.0), -m_far);
+	m_planes[(U)PlaneType::TOP] = Plane(Vec3(0.0, -1.0, 0.0), -m_top);
+	m_planes[(U)PlaneType::BOTTOM] = Plane(Vec3(0.0, 1.0, 0.0), m_bottom);
 
 
 	// OBB
 	// OBB
 	Vec3 c((m_right + m_left) * 0.5, 
 	Vec3 c((m_right + m_left) * 0.5, 
@@ -305,10 +261,6 @@ void OrthographicFrustum::recalculate()
 		-(m_far + m_near) * 0.5);
 		-(m_far + m_near) * 0.5);
 	Vec3 e = Vec3(m_right, m_top, -m_far) - c;
 	Vec3 e = Vec3(m_right, m_top, -m_far) - c;
 	m_obb = Obb(c, Mat3::getIdentity(), e);
 	m_obb = Obb(c, Mat3::getIdentity(), e);
-
-	// Transform
-	transformPlanes();
-	transformShape();
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 14 - 13
src/collision/Functions.cpp

@@ -3,69 +3,70 @@
 namespace anki {
 namespace anki {
 
 
 //==============================================================================
 //==============================================================================
-void extractClipPlanes(const Mat4& mvp, Plane* planes[(U)FrustumPlane::COUNT])
+void extractClipPlanes(const Mat4& mvp, 
+	Plane* planes[(U)Frustum::PlaneType::COUNT])
 {
 {
 	// Plane equation coefficients
 	// Plane equation coefficients
 	F32 a, b, c, d;
 	F32 a, b, c, d;
 
 
-	if(planes[(U)FrustumPlane::NEAR])
+	if(planes[(U)Frustum::PlaneType::NEAR])
 	{
 	{
 		a = mvp(3, 0) + mvp(2, 0);
 		a = mvp(3, 0) + mvp(2, 0);
 		b = mvp(3, 1) + mvp(2, 1);
 		b = mvp(3, 1) + mvp(2, 1);
 		c = mvp(3, 2) + mvp(2, 2);
 		c = mvp(3, 2) + mvp(2, 2);
 		d = mvp(3, 3) + mvp(2, 3);
 		d = mvp(3, 3) + mvp(2, 3);
 
 
-		*planes[(U)FrustumPlane::NEAR] = Plane(a, b, c, d);
+		*planes[(U)Frustum::PlaneType::NEAR] = Plane(a, b, c, d);
 	}
 	}
 
 
-	if(planes[(U)FrustumPlane::FAR])
+	if(planes[(U)Frustum::PlaneType::FAR])
 	{
 	{
 		a = mvp(3, 0) - mvp(2, 0);
 		a = mvp(3, 0) - mvp(2, 0);
 		b = mvp(3, 1) - mvp(2, 1);
 		b = mvp(3, 1) - mvp(2, 1);
 		c = mvp(3, 2) - mvp(2, 2);
 		c = mvp(3, 2) - mvp(2, 2);
 		d = mvp(3, 3) - mvp(2, 3);
 		d = mvp(3, 3) - mvp(2, 3);
 
 
-		*planes[(U)FrustumPlane::FAR] = Plane(a, b, c, d);
+		*planes[(U)Frustum::PlaneType::FAR] = Plane(a, b, c, d);
 	}
 	}
 
 
-	if(planes[(U)FrustumPlane::LEFT])
+	if(planes[(U)Frustum::PlaneType::LEFT])
 	{
 	{
 		a = mvp(3, 0) + mvp(0, 0);
 		a = mvp(3, 0) + mvp(0, 0);
 		b = mvp(3, 1) + mvp(0, 1);
 		b = mvp(3, 1) + mvp(0, 1);
 		c = mvp(3, 2) + mvp(0, 2);
 		c = mvp(3, 2) + mvp(0, 2);
 		d = mvp(3, 3) + mvp(0, 3);
 		d = mvp(3, 3) + mvp(0, 3);
 
 
-		*planes[(U)FrustumPlane::LEFT] = Plane(a, b, c, d);
+		*planes[(U)Frustum::PlaneType::LEFT] = Plane(a, b, c, d);
 	}
 	}
 
 
-	if(planes[(U)FrustumPlane::RIGHT])
+	if(planes[(U)Frustum::PlaneType::RIGHT])
 	{
 	{
 		a = mvp(3, 0) - mvp(0, 0);
 		a = mvp(3, 0) - mvp(0, 0);
 		b = mvp(3, 1) - mvp(0, 1);
 		b = mvp(3, 1) - mvp(0, 1);
 		c = mvp(3, 2) - mvp(0, 2);
 		c = mvp(3, 2) - mvp(0, 2);
 		d = mvp(3, 3) - mvp(0, 3);
 		d = mvp(3, 3) - mvp(0, 3);
 
 
-		*planes[(U)FrustumPlane::RIGHT] = Plane(a, b, c, d);
+		*planes[(U)Frustum::PlaneType::RIGHT] = Plane(a, b, c, d);
 	}
 	}
 
 
-	if(planes[(U)FrustumPlane::TOP])
+	if(planes[(U)Frustum::PlaneType::TOP])
 	{
 	{
 		a = mvp(3, 0) - mvp(1, 0);
 		a = mvp(3, 0) - mvp(1, 0);
 		b = mvp(3, 1) - mvp(1, 1);
 		b = mvp(3, 1) - mvp(1, 1);
 		c = mvp(3, 2) - mvp(1, 2);
 		c = mvp(3, 2) - mvp(1, 2);
 		d = mvp(3, 3) - mvp(1, 3);
 		d = mvp(3, 3) - mvp(1, 3);
 
 
-		*planes[(U)FrustumPlane::TOP] = Plane(a, b, c, d);
+		*planes[(U)Frustum::PlaneType::TOP] = Plane(a, b, c, d);
 	}
 	}
 
 
-	if(planes[(U)FrustumPlane::BOTTOM])
+	if(planes[(U)Frustum::PlaneType::BOTTOM])
 	{
 	{
 		a = mvp(3, 0) + mvp(1, 0);
 		a = mvp(3, 0) + mvp(1, 0);
 		b = mvp(3, 1) + mvp(1, 1);
 		b = mvp(3, 1) + mvp(1, 1);
 		c = mvp(3, 2) + mvp(1, 2);
 		c = mvp(3, 2) + mvp(1, 2);
 		d = mvp(3, 3) + mvp(1, 3);
 		d = mvp(3, 3) + mvp(1, 3);
 
 
-		*planes[(U)FrustumPlane::BOTTOM] = Plane(a, b, c, d);
+		*planes[(U)Frustum::PlaneType::BOTTOM] = Plane(a, b, c, d);
 	}	
 	}	
 }
 }
 
 

+ 8 - 1
src/gl/GlJobManager.cpp

@@ -147,7 +147,14 @@ void GlJobManager::finish()
 	// Iterate the queue and release the refcounts
 	// Iterate the queue and release the refcounts
 	for(U i = 0; i < m_queue.size(); i++)
 	for(U i = 0; i < m_queue.size(); i++)
 	{
 	{
-		m_queue[i] = GlJobChainHandle();
+		if(m_queue[i].isCreated())
+		{
+			// Fake that it's executed to avoid warnings
+			m_queue[i]._get().makeExecuted();
+
+			// Release
+			m_queue[i] = GlJobChainHandle();
+		}
 	}
 	}
 
 
 	// Delete default VAO
 	// Delete default VAO

+ 3 - 3
src/renderer/DebugDrawer.cpp

@@ -354,12 +354,12 @@ void CollisionDebugDrawer::visit(const Aabb& aabb)
 //==============================================================================
 //==============================================================================
 void CollisionDebugDrawer::visit(const Frustum& f)
 void CollisionDebugDrawer::visit(const Frustum& f)
 {
 {
-	switch(f.getFrustumType())
+	switch(f.getType())
 	{
 	{
-	case FrustumType::ORTHOGRAPHIC:
+	case Frustum::Type::ORTHOGRAPHIC:
 		visit(static_cast<const OrthographicFrustum&>(f).getObb());
 		visit(static_cast<const OrthographicFrustum&>(f).getObb());
 		break;
 		break;
-	case FrustumType::PERSPECTIVE:
+	case Frustum::Type::PERSPECTIVE:
 		{
 		{
 			const PerspectiveFrustum& pf =
 			const PerspectiveFrustum& pf =
 				static_cast<const PerspectiveFrustum&>(f);
 				static_cast<const PerspectiveFrustum&>(f);

+ 1 - 1
src/renderer/Is.cpp

@@ -246,7 +246,7 @@ public:
 		for(U i = 0; i < 4; i++)
 		for(U i = 0; i < 4; i++)
 		{
 		{
 			Vec3 extendPoint = light.getWorldTransform().getOrigin() 
 			Vec3 extendPoint = light.getWorldTransform().getOrigin() 
-				+ frustum.getDirections()[i];
+				+ frustum.getLineSegments()[i].getDirection();
 
 
 			extendPoint.transform(cam->getViewMatrix());
 			extendPoint.transform(cam->getViewMatrix());
 			baseslight->m_extendPoints[i] = Vec4(extendPoint, 1.0);
 			baseslight->m_extendPoints[i] = Vec4(extendPoint, 1.0);

+ 1 - 1
src/renderer/Renderer.cpp

@@ -179,7 +179,7 @@ void Renderer::render(SceneGraph& scene,
 		|| m_projectionParamsUpdateTimestamp < camUpdateTimestamp
 		|| m_projectionParamsUpdateTimestamp < camUpdateTimestamp
 		|| m_projectionParamsUpdateTimestamp == 1)
 		|| m_projectionParamsUpdateTimestamp == 1)
 	{
 	{
-		ANKI_ASSERT(cam.getCameraType() == Camera::CT_PERSPECTIVE);
+		ANKI_ASSERT(cam.getCameraType() == Camera::Type::PERSPECTIVE);
 		computeProjectionParams(cam.getProjectionMatrix());
 		computeProjectionParams(cam.getProjectionMatrix());
 		m_projectionParamsUpdateTimestamp = getGlobTimestamp();
 		m_projectionParamsUpdateTimestamp = getGlobTimestamp();
 	}
 	}

+ 1 - 1
src/renderer/Tiler.cpp

@@ -324,7 +324,7 @@ void Tiler::updateTiles(Camera& cam)
 
 
 	switch(cam.getCameraType())
 	switch(cam.getCameraType())
 	{
 	{
-	case Camera::CT_PERSPECTIVE:
+	case Camera::Type::PERSPECTIVE:
 		for(U i = 0; i < threadPool.getThreadsCount(); i++)
 		for(U i = 0; i < threadPool.getThreadsCount(); i++)
 		{
 		{
 			jobs[i].m_tiler = this;
 			jobs[i].m_tiler = this;

+ 7 - 6
src/scene/Camera.cpp

@@ -9,12 +9,12 @@ namespace anki {
 //==============================================================================
 //==============================================================================
 Camera::Camera(
 Camera::Camera(
 	const char* name, SceneGraph* scene, // SceneNode
 	const char* name, SceneGraph* scene, // SceneNode
-	CameraType type_) 
+	Type type, Frustum* frustum) 
 	:	SceneNode(name, scene), 
 	:	SceneNode(name, scene), 
 		MoveComponent(this),
 		MoveComponent(this),
-		FrustumComponent(this),
+		FrustumComponent(this, frustum),
 		SpatialComponent(this),
 		SpatialComponent(this),
-		type(type_)
+		m_type(type)
 {
 {
 	// Init components
 	// Init components
 	addComponent(static_cast<MoveComponent*>(this));
 	addComponent(static_cast<MoveComponent*>(this));
@@ -63,7 +63,8 @@ void Camera::moveUpdate(MoveComponent& move)
 	fr.setViewMatrix(Mat4(move.getWorldTransform().getInverse()));
 	fr.setViewMatrix(Mat4(move.getWorldTransform().getInverse()));
 	fr.setViewProjectionMatrix(fr.getProjectionMatrix() * fr.getViewMatrix());
 	fr.setViewProjectionMatrix(fr.getProjectionMatrix() * fr.getViewMatrix());
 	fr.markForUpdate();
 	fr.markForUpdate();
-	fr.getFrustum().setTransform(move.getWorldTransform());
+	fr.getFrustum().resetTransform();
+	fr.getFrustum().transform(move.getWorldTransform());
 
 
 	// Spatial
 	// Spatial
 	SpatialComponent& sp = *this;
 	SpatialComponent& sp = *this;
@@ -76,7 +77,7 @@ void Camera::moveUpdate(MoveComponent& move)
 
 
 //==============================================================================
 //==============================================================================
 PerspectiveCamera::PerspectiveCamera(const char* name, SceneGraph* scene)
 PerspectiveCamera::PerspectiveCamera(const char* name, SceneGraph* scene)
-	: Camera(name, scene, CT_PERSPECTIVE)
+	: Camera(name, scene, Type::PERSPECTIVE, &m_frustum)
 {}
 {}
 
 
 //==============================================================================
 //==============================================================================
@@ -85,7 +86,7 @@ PerspectiveCamera::PerspectiveCamera(const char* name, SceneGraph* scene)
 
 
 //==============================================================================
 //==============================================================================
 OrthographicCamera::OrthographicCamera(const char* name, SceneGraph* scene)
 OrthographicCamera::OrthographicCamera(const char* name, SceneGraph* scene)
-	: Camera(name, scene, CT_ORTHOGRAPHIC)
+	: Camera(name, scene, Type::ORTHOGRAPHIC, &m_frustum)
 {}
 {}
 
 
 } // end namespace anki
 } // end namespace anki

+ 6 - 4
src/scene/Light.cpp

@@ -63,7 +63,8 @@ void Light::moveUpdate(MoveComponent& move)
 		fr.setViewProjectionMatrix(
 		fr.setViewProjectionMatrix(
 			fr.getProjectionMatrix() * fr.getViewMatrix());
 			fr.getProjectionMatrix() * fr.getViewMatrix());
 
 
-		fr.getFrustum().setTransform(move.getWorldTransform());
+		fr.getFrustum().resetTransform();
+		fr.getFrustum().transform(move.getWorldTransform());
 
 
 		fr.markForUpdate();
 		fr.markForUpdate();
 	});
 	});
@@ -101,7 +102,7 @@ void PointLight::componentUpdated(SceneComponent& comp,
 //==============================================================================
 //==============================================================================
 SpotLight::SpotLight(const char* name, SceneGraph* scene)
 SpotLight::SpotLight(const char* name, SceneGraph* scene)
 	:	Light(name, scene, LT_SPOT),
 	:	Light(name, scene, LT_SPOT),
-		FrustumComponent(this)
+		FrustumComponent(this, &m_frustum)
 {
 {
 	// Init components
 	// Init components
 	addComponent(static_cast<FrustumComponent*>(this));
 	addComponent(static_cast<FrustumComponent*>(this));
@@ -109,7 +110,7 @@ SpotLight::SpotLight(const char* name, SceneGraph* scene)
 	const F32 ang = toRad(45.0);
 	const F32 ang = toRad(45.0);
 	const F32 dist = 1.0;
 	const F32 dist = 1.0;
 
 
-	frustum.setAll(ang, ang, 0.1, dist);
+	m_frustum.setAll(ang, ang, 0.1, dist);
 }
 }
 
 
 //==============================================================================
 //==============================================================================
@@ -119,7 +120,8 @@ void SpotLight::componentUpdated(SceneComponent& comp,
 	if(comp.getType() == MoveComponent::getClassType())
 	if(comp.getType() == MoveComponent::getClassType())
 	{
 	{
 		MoveComponent& move = comp.downCast<MoveComponent>();
 		MoveComponent& move = comp.downCast<MoveComponent>();
-		frustum.setTransform(move.getWorldTransform());
+		m_frustum.resetTransform();
+		m_frustum.transform(move.getWorldTransform());
 		moveUpdate(move);
 		moveUpdate(move);
 	}
 	}
 }
 }