Browse Source

Hookup the physics debug drawer

Panagiotis Christopoulos Charitos 7 years ago
parent
commit
a72e82cc11

BIN
samples/physics_playground/assets/physics_playground.blend


+ 0 - 1
src/anki/Renderer.h

@@ -6,7 +6,6 @@
 #pragma once
 
 #include <anki/renderer/GBuffer.h>
-#include <anki/renderer/DebugDrawer.h>
 #include <anki/renderer/Common.h>
 #include <anki/renderer/LightShading.h>
 #include <anki/renderer/Volumetric.h>

+ 2 - 0
src/anki/physics/Common.h

@@ -16,6 +16,8 @@
 #define BT_NO_PROFILE 1
 #include <btBulletCollisionCommon.h>
 #include <btBulletDynamicsCommon.h>
+#include <BulletCollision/CollisionDispatch/btGhostObject.h>
+#include <BulletDynamics/Character/btKinematicCharacterController.h>
 #pragma GCC diagnostic pop
 
 namespace anki

+ 2 - 3
src/anki/physics/PhysicsDrawer.h

@@ -23,7 +23,7 @@ public:
 	}
 
 	/// Draw a line.
-	virtual void drawLines(const Vec3* lines, const U32 linesCount, const Vec4& color) = 0;
+	virtual void drawLines(const Vec3* lines, const U32 vertCount, const Vec4& color) = 0;
 
 	void drawWorld(const PhysicsWorld& world);
 
@@ -70,8 +70,7 @@ private:
 
 		int getDebugMode() const override
 		{
-			// TODO
-			return 0;
+			return btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb;
 		}
 	};
 

+ 11 - 0
src/anki/physics/PhysicsPlayerController.cpp

@@ -9,8 +9,19 @@
 namespace anki
 {
 
+PhysicsPlayerController::PhysicsPlayerController(PhysicsWorld* world, const PhysicsPlayerControllerInitInfo& init)
+	: PhysicsObject(PhysicsObjectType::PLAYER_CONTROLLER, world)
+{
+	m_ghostObject = getAllocator().newInstance<btPairCachingGhostObject>();
+	m_convexShape = getAllocator().newInstance<btCapsuleShape>(init.m_outerRadius, init.m_height);
+
+	m_controller = getAllocator().newInstance<btKinematicCharacterController>(
+		m_ghostObject, m_convexShape, init.m_stepHeight, btVector3(0, 1, 0));
+}
+
 PhysicsPlayerController::~PhysicsPlayerController()
 {
+	// TODO
 }
 
 void PhysicsPlayerController::moveToPosition(const Vec4& position)

+ 4 - 5
src/anki/physics/PhysicsPlayerController.h

@@ -29,10 +29,7 @@ public:
 class PhysicsPlayerController final : public PhysicsObject
 {
 public:
-	PhysicsPlayerController(PhysicsWorld* world, const PhysicsPlayerControllerInitInfo& init)
-		: PhysicsObject(PhysicsObjectType::PLAYER_CONTROLLER, world)
-	{
-	}
+	PhysicsPlayerController(PhysicsWorld* world, const PhysicsPlayerControllerInitInfo& init);
 
 	~PhysicsPlayerController();
 
@@ -50,7 +47,9 @@ public:
 	}
 
 private:
-	// TODO
+	btPairCachingGhostObject* m_ghostObject = nullptr;
+	btCapsuleShape* m_convexShape = nullptr;
+	btKinematicCharacterController* m_controller = nullptr;
 };
 /// @}
 

+ 0 - 1
src/anki/renderer/Dbg.cpp

@@ -8,7 +8,6 @@
 #include <anki/renderer/GBuffer.h>
 #include <anki/renderer/LightShading.h>
 #include <anki/renderer/FinalComposite.h>
-#include <anki/renderer/DebugDrawer.h>
 #include <anki/renderer/RenderQueue.h>
 #include <anki/Scene.h>
 #include <anki/util/Logger.h>

+ 1 - 1
src/anki/renderer/RenderQueue.h

@@ -53,7 +53,7 @@ public:
 	RenderQueueDrawCallback m_callback;
 	const void* m_userData;
 	U64 m_mergeKey;
-	F32 m_distanceFromCamera;
+	F32 m_distanceFromCamera; ///< Don't set this
 };
 
 static_assert(

+ 63 - 35
src/anki/renderer/DebugDrawer.cpp → src/anki/scene/DebugDrawer.cpp

@@ -3,75 +3,103 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#include <anki/renderer/DebugDrawer.h>
-#include <anki/renderer/Renderer.h>
-#include <anki/resource/TextureResource.h>
-#include <anki/renderer/Renderer.h>
-#include <anki/renderer/FinalComposite.h>
-#include <anki/renderer/GBuffer.h>
-#include <anki/util/Logger.h>
+#include <anki/scene/DebugDrawer.h>
+#include <anki/resource/ResourceManager.h>
+#include <anki/renderer/RenderQueue.h>
+#include <anki/core/StagingGpuMemoryManager.h>
 #include <anki/physics/PhysicsWorld.h>
 #include <anki/Collision.h>
-#include <anki/Scene.h>
 
 namespace anki
 {
 
-Error DebugDrawer::init(Renderer* r)
+Error DebugDrawer::init(ResourceManager* rsrcManager)
 {
-	ANKI_ASSERT(r);
-	m_r = r;
+	ANKI_ASSERT(rsrcManager);
 
 	// Create the prog and shaders
-	ANKI_CHECK(r->getResourceManager().loadResource("shaders/SceneDebug.glslp", m_prog));
-	ShaderProgramResourceConstantValueInitList<1> consts(m_prog);
-	consts.add("INSTANCE_COUNT", 1u);
-	ShaderProgramResourceMutationInitList<2> mutations(m_prog);
-	mutations.add("COLOR_TEXTURE", 0).add("DITHERED_DEPTH_TEST", 0);
-
-	const ShaderProgramResourceVariant* variant;
-	m_prog->getOrCreateVariant(mutations.get(), consts.get(), variant);
-	m_grProg = variant->getProgram();
+	ANKI_CHECK(rsrcManager->loadResource("shaders/SceneDebug.glslp", m_prog));
 
 	return Error::NONE;
 }
 
+void DebugDrawer::prepareFrame(RenderQueueDrawContext* ctx)
+{
+	m_ctx = ctx;
+}
+
 void DebugDrawer::flush()
 {
-	if(m_cachedPositionCount > 0)
+	if(m_cachedPositionCount == 0)
 	{
-		m_cmdb->bindShaderProgram(m_grProg);
+		return;
+	}
+
+	CommandBufferPtr& cmdb = m_ctx->m_commandBuffer;
 
-		// Set vertex state
+	// Bind program
+	{
+		ShaderProgramResourceMutationInitList<2> mutators(m_prog);
+		mutators.add("COLOR_TEXTURE", 0);
+		mutators.add(
+			"DITHERED_DEPTH_TEST", m_ctx->m_debugDrawFlags.get(RenderQueueDebugDrawFlag::DITHERED_DEPTH_TEST_ON));
+		ShaderProgramResourceConstantValueInitList<1> consts(m_prog);
+		consts.add("INSTANCE_COUNT", 1u);
+		const ShaderProgramResourceVariant* variant;
+		m_prog->getOrCreateVariant(mutators.get(), consts.get(), variant);
+		cmdb->bindShaderProgram(variant->getProgram());
+	}
+
+	// Set vertex state
+	{
 		const U32 size = m_cachedPositionCount * sizeof(Vec3);
 
 		StagingGpuMemoryToken token;
-		void* mem = m_r->getStagingGpuMemoryManager().allocateFrame(size, StagingGpuMemoryType::VERTEX, token);
+		void* mem = m_ctx->m_stagingGpuAllocator->allocateFrame(size, StagingGpuMemoryType::VERTEX, token);
 		memcpy(mem, &m_cachedPositions[0], size);
 
-		m_cmdb->bindVertexBuffer(0, token.m_buffer, token.m_offset, sizeof(Vec3));
-		m_cmdb->setVertexAttribute(0, 0, Format::R32G32B32_SFLOAT, 0);
+		cmdb->bindVertexBuffer(0, token.m_buffer, token.m_offset, sizeof(Vec3));
+		cmdb->setVertexAttribute(0, 0, Format::R32G32B32_SFLOAT, 0);
+	}
 
-		// Set uniform state
+	// Set uniform state
+	{
 		struct Uniforms
 		{
 			Mat4 m_mvp;
 			Vec4 m_color;
 		};
 
+		StagingGpuMemoryToken token;
 		Uniforms* uniforms = static_cast<Uniforms*>(
-			m_r->getStagingGpuMemoryManager().allocateFrame(sizeof(Uniforms), StagingGpuMemoryType::UNIFORM, token));
+			m_ctx->m_stagingGpuAllocator->allocateFrame(sizeof(Uniforms), StagingGpuMemoryType::UNIFORM, token));
 		uniforms->m_mvp = m_mvpMat;
 		uniforms->m_color = m_crntCol;
 
-		m_cmdb->bindUniformBuffer(1, 0, token.m_buffer, token.m_offset, token.m_range);
+		cmdb->bindUniformBuffer(1, 0, token.m_buffer, token.m_offset, token.m_range);
+	}
+
+	const Bool enableDepthTest = m_ctx->m_debugDrawFlags.get(RenderQueueDebugDrawFlag::DEPTH_TEST_ON);
+	if(enableDepthTest)
+	{
+		cmdb->setDepthCompareOperation(CompareOperation::LESS);
+	}
+	else
+	{
+		cmdb->setDepthCompareOperation(CompareOperation::ALWAYS);
+	}
 
-		// Draw
-		m_cmdb->drawArrays(m_topology, m_cachedPositionCount);
+	// Draw
+	cmdb->drawArrays(m_topology, m_cachedPositionCount);
 
-		// Other
-		m_cachedPositionCount = 0;
+	// Restore state
+	if(!enableDepthTest)
+	{
+		cmdb->setDepthCompareOperation(CompareOperation::LESS);
 	}
+
+	// Other
+	m_cachedPositionCount = 0;
 }
 
 void DebugDrawer::drawLine(const Vec3& from, const Vec3& to, const Vec4& color)
@@ -318,11 +346,11 @@ void CollisionDebugDrawer::visit(const ConvexHullShape& hull)
 	}
 }
 
-void PhysicsDebugDrawer::drawLines(const Vec3* lines, const U32 linesCount, const Vec4& color)
+void PhysicsDebugDrawer::drawLines(const Vec3* lines, const U32 vertCount, const Vec4& color)
 {
 	m_dbg->setTopology(PrimitiveTopology::LINES);
 	m_dbg->setColor(color);
-	for(U i = 0; i < linesCount * 2; ++i)
+	for(U i = 0; i < vertCount; ++i)
 	{
 		m_dbg->pushBackVertex(lines[i]);
 	}

+ 9 - 11
src/anki/renderer/DebugDrawer.h → src/anki/scene/DebugDrawer.h

@@ -5,7 +5,7 @@
 
 #pragma once
 
-#include <anki/renderer/Common.h>
+#include <anki/scene/Common.h>
 #include <anki/Math.h>
 #include <anki/Gr.h>
 #include <anki/collision/CollisionShape.h>
@@ -16,6 +16,9 @@
 namespace anki
 {
 
+// Forward
+class RenderQueueDrawContext;
+
 /// @addtogroup renderer
 /// @{
 
@@ -23,17 +26,14 @@ namespace anki
 class DebugDrawer
 {
 public:
-	ANKI_USE_RESULT Error init(Renderer* r);
+	ANKI_USE_RESULT Error init(ResourceManager* rsrcManager);
 
-	void prepareFrame(CommandBufferPtr& cmdb)
-	{
-		m_cmdb = cmdb;
-	}
+	void prepareFrame(RenderQueueDrawContext* ctx);
 
 	void finishFrame()
 	{
 		flush();
-		m_cmdb.reset(nullptr);
+		m_ctx = nullptr;
 	}
 
 	void drawGrid();
@@ -85,11 +85,9 @@ public:
 	}
 
 private:
-	Renderer* m_r;
 	ShaderProgramResourcePtr m_prog;
-	ShaderProgramPtr m_grProg;
 
-	CommandBufferPtr m_cmdb;
+	RenderQueueDrawContext* m_ctx = nullptr;
 
 	// State
 	Mat4 m_mMat = Mat4::getIdentity();
@@ -146,7 +144,7 @@ public:
 	{
 	}
 
-	void drawLines(const Vec3* lines, const U32 linesCount, const Vec4& color) final;
+	void drawLines(const Vec3* lines, const U32 vertCount, const Vec4& color) final;
 
 private:
 	DebugDrawer* m_dbg; ///< The debug drawer

+ 37 - 3
src/anki/scene/PhysicsDebugNode.cpp

@@ -8,6 +8,7 @@
 #include <anki/scene/components/RenderComponent.h>
 #include <anki/scene/components/SpatialComponent.h>
 #include <anki/scene/SceneGraph.h>
+#include <anki/scene/DebugDrawer.h>
 
 namespace anki
 {
@@ -16,31 +17,64 @@ namespace anki
 class PhysicsDebugNode::MyRenderComponent : public RenderComponent
 {
 public:
-	ShaderProgramResourcePtr m_prog;
+	DebugDrawer m_dbgDrawer;
+	PhysicsDebugDrawer m_physDbgDrawer;
 
 	MyRenderComponent(SceneNode* node)
 		: RenderComponent(node)
+		, m_physDbgDrawer(&m_dbgDrawer)
 	{
 		m_castsShadow = false;
 		m_isForwardShading = false;
 	}
 
+	ANKI_USE_RESULT Error init()
+	{
+		return m_dbgDrawer.init(&getSceneGraph().getResourceManager());
+	}
+
 	void setupRenderableQueueElement(RenderableQueueElement& el) const override
 	{
-		// TODO
+		el.m_callback = drawCallback;
+		el.m_mergeKey = 1;
+		el.m_userData = this;
+	}
+
+	/// RenderableQueueElement draw callback.
+	static void drawCallback(RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData)
+	{
+		static_cast<MyRenderComponent*>(userData[0])->draw(ctx);
+	}
+
+	/// Draw the world.
+	void draw(RenderQueueDrawContext& ctx)
+	{
+		if(ctx.m_debugDraw)
+		{
+			m_dbgDrawer.prepareFrame(&ctx);
+			m_dbgDrawer.setViewProjectionMatrix(ctx.m_viewProjectionMatrix);
+			m_dbgDrawer.setModelMatrix(Mat4::getIdentity());
+			m_physDbgDrawer.drawWorld(getSceneGraph().getPhysicsWorld());
+			m_dbgDrawer.finishFrame();
+		}
 	}
 };
 
+PhysicsDebugNode::~PhysicsDebugNode()
+{
+}
+
 Error PhysicsDebugNode::init()
 {
 	MyRenderComponent* rcomp = newComponent<MyRenderComponent>(this);
-	ANKI_CHECK(getResourceManager().loadResource("shaders/SceneDebug.glslp", rcomp->m_prog));
+	ANKI_CHECK(rcomp->init());
 
 	ObbSpatialComponent* scomp = newComponent<ObbSpatialComponent>(this);
 	Vec3 center = (getSceneGraph().getSceneMax() + getSceneGraph().getSceneMin()) / 2.0f;
 	scomp->m_obb.setCenter(center.xyz0());
 	scomp->m_obb.setExtend((getSceneGraph().getSceneMax() - center).xyz0());
 	scomp->m_obb.setRotation(Mat3x4::getIdentity());
+	scomp->setSpatialOrigin(Vec4(0.0f));
 
 	return Error::NONE;
 }

+ 4 - 1
src/anki/scene/PhysicsDebugNode.h

@@ -14,7 +14,10 @@ namespace anki
 class PhysicsDebugNode : public SceneNode
 {
 public:
-	PhysicsDebugNode(SceneGraph* scene, CString name);
+	PhysicsDebugNode(SceneGraph* scene, CString name)
+		: SceneNode(scene, name)
+	{
+	}
 
 	~PhysicsDebugNode();
 

+ 5 - 0
src/anki/scene/SceneGraph.cpp

@@ -5,6 +5,7 @@
 
 #include <anki/scene/SceneGraph.h>
 #include <anki/scene/CameraNode.h>
+#include <anki/scene/PhysicsDebugNode.h>
 #include <anki/scene/ModelNode.h>
 #include <anki/scene/SectorNode.h>
 #include <anki/scene/Octree.h>
@@ -108,6 +109,10 @@ Error SceneGraph::init(AllocAlignedCallback allocCb,
 	m_defaultMainCam->setAll(toRad(60.0f), toRad(60.0f), 0.1f, 1000.0f);
 	m_mainCam = m_defaultMainCam;
 
+	// Create a special node for debugging the physics world
+	PhysicsDebugNode* pnode;
+	ANKI_CHECK(newSceneNode<PhysicsDebugNode>("_physicsDebugNode", pnode));
+
 	return Error::NONE;
 }