Browse Source

Fixing bugs

Panagiotis Christopoulos Charitos 11 years ago
parent
commit
28d22ea78d

+ 10 - 0
include/anki/collision/Frustum.h

@@ -142,6 +142,11 @@ private:
 class PerspectiveFrustum: public Frustum
 {
 public:
+	static Bool classof(const Frustum& c)
+	{
+		return c.getType() == Type::PERSPECTIVE;
+	}
+
 	/// Default
 	PerspectiveFrustum();
 
@@ -236,6 +241,11 @@ private:
 class OrthographicFrustum: public Frustum
 {
 public:
+	static Bool classof(const Frustum& c)
+	{
+		return c.getType() == Type::ORTHOGRAPHIC;
+	}
+
 	/// Default
 	OrthographicFrustum();
 

+ 6 - 0
include/anki/math/Vec4.h

@@ -107,6 +107,12 @@ public:
 		ANKI_ASSERT(isZero<T>(b.w()));
 		return TVec4(Base::xyz().cross(b.xyz()), static_cast<T>(0));
 	}
+
+	TVec4 getProjection(const TVec4& toThis) const
+	{
+		ANKI_ASSERT(w() == T(0));
+		return (toThis * ((*this).dot(toThis) / (toThis.dot(toThis)))).xyz0();
+	}
 	/// @{
 
 	/// @name Operators with other

+ 0 - 2
include/anki/renderer/Renderer.h

@@ -330,8 +330,6 @@ private:
 
 	String m_shadersPrependedSource; ///< String to append in user shaders
 
-	void computeProjectionParams(const Mat4& projMat);
-
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
 };
 

+ 2 - 2
include/anki/renderer/Tiler.h

@@ -121,10 +121,10 @@ private:
 		Camera& cam, Bool frustumChanged);
 
 	/// Calculate and set a top looking plane
-	void calcPlaneY(U i, const F32 o6, const F32 near);
+	void calcPlaneY(U i, const F32 o6, const F32 near, const Vec4& projParams);
 
 	/// Calculate and set a right looking plane
-	void calcPlaneX(U j, const F32 l6, const F32 near);
+	void calcPlaneX(U j, const F32 l6, const F32 near, const Vec4& projParams);
 };
 /// @}
 

+ 16 - 0
include/anki/scene/FrustumComponent.h

@@ -67,6 +67,18 @@ public:
 		return m_vpm;
 	}
 
+	/// Parameters used to get the view space position using the depth value 
+	/// and the NDC xy coordinates.
+	/// @code
+	/// vec3 fragPos;
+	/// fragPos.z = projectionParams.z / (projectionParams.w + depth);
+	/// fragPos.xy = projectionParams * NDC * fragPos.z;
+	/// @endcode
+	const Vec4& getProjectionParameters() const
+	{
+		return m_projParams;
+	}
+
 	/// Get the origin for sorting and visibility tests
 	const Vec4& getFrustumOrigin() const
 	{
@@ -138,12 +150,16 @@ private:
 	Mat4 m_vm = Mat4::getIdentity(); ///< View matrix
 	Mat4 m_vpm = Mat4::getIdentity(); ///< View projection matrix
 
+	Vec4 m_projParams = Vec4(0.0);
+
 	/// Visibility stuff. It's per frame so the pointer is invalid on the next 
 	/// frame and before any visibility tests are run
 	VisibilityTestResults* m_visible = nullptr;
 	VisibilityStats m_stats;
 
 	U8 m_flags;
+
+	void computeProjectionParams();
 };
 /// @}
 

+ 7 - 0
shaders/IsLp.frag.glsl

@@ -350,5 +350,12 @@ void main()
 	{
 		out_color = vec3(0.5 / float(pointLightsCount));
 	}
+
+	/*uint x = in_instanceId % 60;
+	uint y = in_instanceId / 60;
+	if(x == 30 && y == 20)
+	{
+		out_color = vec3(1.0, 0.0, 0.0);
+	}*/
 #endif
 }

+ 1 - 1
src/renderer/Dbg.cpp

@@ -138,7 +138,7 @@ Error Dbg::run(GlCommandBufferHandle& cmdb)
 		phyd.drawWorld(scene._getPhysicsWorld());
 	}
 
-#if 0
+#if 1
 	{
 		SceneNode& sn = scene.findSceneNode("plight0");
 		SpatialComponent& sp = sn.getComponent<SpatialComponent>();

+ 3 - 21
src/renderer/Renderer.cpp

@@ -161,8 +161,9 @@ Error Renderer::render(SceneGraph& scene,
 		|| m_projectionParamsUpdateTimestamp < camUpdateTimestamp
 		|| m_projectionParamsUpdateTimestamp == 0)
 	{
-		ANKI_ASSERT(cam.getCameraType() == Camera::Type::PERSPECTIVE);
-		computeProjectionParams(fr.getProjectionMatrix());
+		const FrustumComponent& frc = cam.getComponent<FrustumComponent>();
+
+		m_projectionParams = frc.getProjectionParameters();
 		m_projectionParamsUpdateTimestamp = getGlobalTimestamp();
 	}
 
@@ -253,25 +254,6 @@ Vec3 Renderer::unproject(const Vec3& windowCoords, const Mat4& modelViewMat,
 	return out.xyz();
 }
 
-//==============================================================================
-void Renderer::computeProjectionParams(const Mat4& m)
-{
-	// First, z' = (m * Pv) / 2 + 0.5 where Pv is the view space position.
-	// Solving that for Pv.z we get
-	// Pv.z = A / (z' + B)
-	// where A = (-m23 / 2) and B = (m22/2 - 0.5)
-	// so we save the A and B in the projection params vector
-	m_projectionParams.z() = -m(2, 3) * 0.5;
-	m_projectionParams.w() = m(2, 2) * 0.5 - 0.5;
-
-	// Using the same logic the Pv.x = x' * w / m00
-	// so Pv.x = x' * Pv.z * (-1 / m00)
-	m_projectionParams.x() = -1.0 / m(0, 0);
-
-	// Same for y
-	m_projectionParams.y() = -1.0 / m(1, 1);
-}
-
 //==============================================================================
 Error Renderer::createRenderTarget(U32 w, U32 h, GLenum internalFormat, 
 	U32 samples, GlTextureHandle& rt)

+ 51 - 14
src/renderer/Tiler.cpp

@@ -42,6 +42,20 @@ public:
 	}
 };
 
+//==============================================================================
+static Vec4 unproject(const F32 depth, const Vec2& ndc, const Vec4& projParams)
+{
+	Vec4 view;
+
+	view.z() = projParams.z() / (projParams.w() + depth);
+	Vec2 viewxy = ndc * projParams.xy() * view.z();
+	view.x() = viewxy.x();
+	view.y() = viewxy.y();
+	view.w() = 0.0;
+
+	return view;
+}
+
 //==============================================================================
 // Tiler                                                                       =
 //==============================================================================
@@ -428,8 +442,9 @@ void Tiler::testFastSphere(
 	const Sphere& s, VisibleTiles* visible, U& count) const
 {
 	const Camera& cam = m_r->getSceneGraph().getActiveCamera();
-	const Mat4& vp = 
-		cam.getComponent<FrustumComponent>().getViewProjectionMatrix();
+	const FrustumComponent& frc = cam.getComponent<FrustumComponent>();
+	const Mat4& vp = frc.getViewProjectionMatrix();
+	const Mat4& v = frc.getViewMatrix();
 	const Transform& trf = 
 		cam.getComponent<MoveComponent>().getWorldTransform();
 
@@ -510,11 +525,13 @@ void Tiler::testFastSphere(
 	Vec2 c = a.xy() / a.w();
 	c = c * 0.5 + 0.5;
 
+	Vec4 sphereCenterVSpace = (v * scent.xyz1()).xyz0();
+	Vec4 eyeVSpace = v * trf.getOrigin();
+
 	for(I y = yFrom; y < yTo; ++y)
 	{
 		for(I x = xFrom; x < xTo; ++x)
 		{
-#if 1
 			// Do detailed tests
 
 			Vec2 tileMin = Vec2(x, y) * tileSize;
@@ -539,6 +556,7 @@ void Tiler::testFastSphere(
 				}
 			}
 
+			// Unproject the closest point to view space
 			const Vec4& projParams = m_r->getProjectionParameters();
 			Vec4 view;
 			const F32 depth = 1.0;
@@ -548,12 +566,13 @@ void Tiler::testFastSphere(
 			view.y() = viewxy.y();
 			view.w() = 0.0;
 
-			Vec3 world = trf.getRotation() * view;
-			LineSegment ls(trf.getOrigin(), world.xyz0());
-			Bool inside = testCollisionShapes(ls, s);
+			// Do a simple ray-sphere test
+			Vec4 dir = view;
+			Vec4 proj = sphereCenterVSpace.getProjection(dir);
+			F32 lenSq = (sphereCenterVSpace - proj).getLengthSquared();
+			Bool inside = lenSq <= (srad * srad);
 
 			if(inside)
-#endif
 			{
 				visible->pushBack(x, y);
 				++count;
@@ -568,12 +587,13 @@ void Tiler::update(U32 threadId, PtrSize threadsCount,
 {
 	PtrSize start, end;
 	const MoveComponent& move = cam.getComponent<MoveComponent>();
-	const FrustumComponent& fr = cam.getComponent<FrustumComponent>();
-	ANKI_ASSERT(fr.getFrustum().getType() == Frustum::Type::PERSPECTIVE);
+	const FrustumComponent& frc = cam.getComponent<FrustumComponent>();
+	ANKI_ASSERT(frc.getFrustum().getType() == Frustum::Type::PERSPECTIVE);
 	const PerspectiveFrustum& frustum = 
-		static_cast<const PerspectiveFrustum&>(fr.getFrustum());
+		static_cast<const PerspectiveFrustum&>(frc.getFrustum());
 
 	const Transform& trf = move.getWorldTransform();
+	const Vec4& projParams = frc.getProjectionParameters();
 
 	if(frustumChanged)
 	{
@@ -596,7 +616,7 @@ void Tiler::update(U32 threadId, PtrSize threadsCount,
 
 		for(U i = start; i < end; i++)
 		{
-			calcPlaneY(i, o6, n);
+			calcPlaneY(i, o6, n, projParams);
 
 			CHECK_PLANE_PTR(&m_planesYW[i]);
 			CHECK_PLANE_PTR(&m_planesY[i]);
@@ -610,7 +630,7 @@ void Tiler::update(U32 threadId, PtrSize threadsCount,
 
 		for(U j = start; j < end; j++)
 		{
-			calcPlaneX(j, l6, n);
+			calcPlaneX(j, l6, n, projParams);
 
 			CHECK_PLANE_PTR(&m_planesXW[j]);
 			CHECK_PLANE_PTR(&m_planesX[j]);
@@ -686,8 +706,10 @@ void Tiler::update(U32 threadId, PtrSize threadsCount,
 }
 
 //==============================================================================
-void Tiler::calcPlaneY(U i, const F32 o6, const F32 near)
+void Tiler::calcPlaneY(
+	U i, const F32 o6, const F32 near, const Vec4& projParams)
 {
+#if 1
 	Vec4 a, b;
 	Plane& plane = m_planesY[i];
 	ANKI_ASSERT(i < m_allPlanes.getSize());
@@ -701,10 +723,25 @@ void Tiler::calcPlaneY(U i, const F32 o6, const F32 near)
 	b.normalize();
 
 	plane = Plane(b, 0.0);
+#else
+	Vec4 viewA = unproject(
+		1.0, Vec2(0.0, F32(i) / m_r->getTilesCount().y()) * 2.0 - 1.0,
+		projParams);
+
+	Vec4 viewB = unproject(
+		1.0, Vec2(1.0, F32(i) / m_r->getTilesCount().y()) * 2.0 - 1.0,
+		projParams);
+
+	Vec4 n = viewB.cross(viewA);
+	n.normalize();
+
+	plane = Plane(b, 0.0);
+#endif
 }
 
 //==============================================================================
-void Tiler::calcPlaneX(U j, const F32 l6, const F32 near)
+void Tiler::calcPlaneX(
+	U j, const F32 l6, const F32 near, const Vec4& projParams)
 {
 	Vec4 a, b;
 	Plane& plane = m_planesX[j];

+ 30 - 0
src/scene/FrustumComponent.cpp

@@ -5,6 +5,7 @@
 
 #include "anki/scene/FrustumComponent.h"
 #include "anki/scene/Visibility.h"
+#include "anki/util/Rtti.h"
 
 namespace anki {
 
@@ -27,6 +28,7 @@ Error FrustumComponent::update(SceneNode& node, F32, F32, Bool& updated)
 	{
 		updated = true;
 		m_pm = m_frustum->calculateProjectionMatrix();
+		computeProjectionParams();
 	}
 
 	if(m_flags & TRANSFORM_MARKED_FOR_UPDATE)
@@ -44,4 +46,32 @@ Error FrustumComponent::update(SceneNode& node, F32, F32, Bool& updated)
 	return ErrorCode::NONE;
 }
 
+//==============================================================================
+void FrustumComponent::computeProjectionParams()
+{
+	const Mat4& m = m_pm;
+
+	if(isa<PerspectiveFrustum>(m_frustum))
+	{
+		// First, z' = (m * Pv) / 2 + 0.5 where Pv is the view space position.
+		// Solving that for Pv.z we get
+		// Pv.z = A / (z' + B)
+		// where A = (-m23 / 2) and B = (m22/2 - 0.5)
+		// so we save the A and B in the projection params vector
+		m_projParams.z() = -m(2, 3) * 0.5;
+		m_projParams.w() = m(2, 2) * 0.5 - 0.5;
+
+		// Using the same logic the Pv.x = x' * w / m00
+		// so Pv.x = x' * Pv.z * (-1 / m00)
+		m_projParams.x() = -1.0 / m(0, 0);
+
+		// Same for y
+		m_projParams.y() = -1.0 / m(1, 1);
+	}
+	else
+	{
+		ANKI_ASSERT(0 && "TODO");
+	}
+}
+
 } // end namespace anki

+ 4 - 4
testapp/Main.cpp

@@ -245,15 +245,15 @@ Error init()
 
 	if(0)
 	{
-		err = scene.newSceneNode<SpotLight>("horse", spot);
+		err = scene.newSceneNode<PointLight>("plight0", point);
 		if(err) return err;
 
-		lightc = spot->tryGetComponent<LightComponent>();
+		lightc = point->tryGetComponent<LightComponent>();
 		lightc->setDistance(10.2);
 		lightc->setDiffuseColor(Vec4(1.0));
 		lightc->setSpecularColor(Vec4(0.6, 0.6, 0.3, 1.0));
 
-		move = spot->tryGetComponent<MoveComponent>();
+		move = point->tryGetComponent<MoveComponent>();
 		move->setLocalOrigin(Vec4(1.0, 2.0, 0.2, 0.0));
 		move->setLocalRotation(Mat3x4(Axisang(toRad(90.0), Vec3(0, 1, 0))));
 	}
@@ -500,7 +500,7 @@ Error initSubsystems(int argc, char* argv[])
 	config.set("is.sm.enabled", true);
 	config.set("is.sm.poissonEnabled", false);
 	config.set("is.sm.resolution", 1024);
-	config.set("pps.enabled", true);
+	config.set("pps.enabled", false);
 	config.set("pps.hdr.enabled", true);
 	config.set("pps.hdr.renderingQuality", 0.5);
 	config.set("pps.hdr.blurringDist", 1.0);