瀏覽代碼

Add debug drawing of skeletons

Panagiotis Christopoulos Charitos 5 年之前
父節點
當前提交
646f493e0f
共有 25 個文件被更改,包括 281 次插入14 次删除
  1. 1 1
      samples/skeletal_animation/Main.cpp
  2. 0 0
      samples/skeletal_animation/assets/Armature.002_Take_001_BaseLayer.ankianim
  3. 二進制
      samples/skeletal_animation/assets/room.001.ankimesh
  4. 8 0
      samples/skeletal_animation/assets/room.001_room_blue.ankimdl
  5. 二進制
      samples/skeletal_animation/assets/room.002.ankimesh
  6. 8 0
      samples/skeletal_animation/assets/room.002_room_green.ankimdl
  7. 二進制
      samples/skeletal_animation/assets/room.003.ankimesh
  8. 8 0
      samples/skeletal_animation/assets/room.003_room_blue.ankimdl
  9. 二進制
      samples/skeletal_animation/assets/room.004.ankimesh
  10. 8 0
      samples/skeletal_animation/assets/room.004_room_green.ankimdl
  11. 二進制
      samples/skeletal_animation/assets/room.005.ankimesh
  12. 8 0
      samples/skeletal_animation/assets/room.005_room_red.ankimdl
  13. 二進制
      samples/skeletal_animation/assets/room.ankimesh
  14. 1 1
      samples/skeletal_animation/assets/room.ankimtl
  15. 26 0
      samples/skeletal_animation/assets/room_blue.ankimtl
  16. 26 0
      samples/skeletal_animation/assets/room_green.ankimtl
  17. 26 0
      samples/skeletal_animation/assets/room_red.ankimtl
  18. 45 0
      samples/skeletal_animation/assets/scene.lua
  19. 6 12
      shaders/SceneDebug.ankiprog
  20. 1 0
      src/anki/importer/GltfImporter.h
  21. 5 0
      src/anki/resource/SkeletonResource.h
  22. 44 0
      src/anki/scene/DebugDrawer.cpp
  23. 21 0
      src/anki/scene/DebugDrawer.h
  24. 34 0
      src/anki/scene/ModelNode.cpp
  25. 5 0
      src/anki/scene/components/SkinComponent.h

+ 1 - 1
samples/skeletal_animation/Main.cpp

@@ -19,7 +19,7 @@ public:
 		ANKI_CHECK(getResourceManager().loadResource("assets/scene.lua", script));
 		ANKI_CHECK(getScriptManager().evalString(script->getSource()));
 
-		ANKI_CHECK(getResourceManager().loadResource("assets/Armature.002_Take 001_BaseLayer.ankianim", m_anim));
+		ANKI_CHECK(getResourceManager().loadResource("assets/Armature.002_Take_001_BaseLayer.ankianim", m_anim));
 		getSceneGraph().findSceneNode("droid.001").getComponent<SkinComponent>().playAnimation(0, m_anim, 0.0, true);
 
 		getMainRenderer().getOffscreenRenderer().getVolumetricFog().setFogParticleColor(Vec3(1.0f, 0.9f, 0.9f));

+ 0 - 0
samples/skeletal_animation/assets/Armature.002_Take 001_BaseLayer.ankianim → samples/skeletal_animation/assets/Armature.002_Take_001_BaseLayer.ankianim


二進制
samples/skeletal_animation/assets/room.001.ankimesh


+ 8 - 0
samples/skeletal_animation/assets/room.001_room_blue.ankimdl

@@ -0,0 +1,8 @@
+<model>
+	<modelPatches>
+		<modelPatch>
+			<mesh>assets/room.001.ankimesh</mesh>
+			<material>assets/room_blue.ankimtl</material>
+		</modelPatch>
+	</modelPatches>
+</model>

二進制
samples/skeletal_animation/assets/room.002.ankimesh


+ 8 - 0
samples/skeletal_animation/assets/room.002_room_green.ankimdl

@@ -0,0 +1,8 @@
+<model>
+	<modelPatches>
+		<modelPatch>
+			<mesh>assets/room.002.ankimesh</mesh>
+			<material>assets/room_green.ankimtl</material>
+		</modelPatch>
+	</modelPatches>
+</model>

二進制
samples/skeletal_animation/assets/room.003.ankimesh


+ 8 - 0
samples/skeletal_animation/assets/room.003_room_blue.ankimdl

@@ -0,0 +1,8 @@
+<model>
+	<modelPatches>
+		<modelPatch>
+			<mesh>assets/room.003.ankimesh</mesh>
+			<material>assets/room_blue.ankimtl</material>
+		</modelPatch>
+	</modelPatches>
+</model>

二進制
samples/skeletal_animation/assets/room.004.ankimesh


+ 8 - 0
samples/skeletal_animation/assets/room.004_room_green.ankimdl

@@ -0,0 +1,8 @@
+<model>
+	<modelPatches>
+		<modelPatch>
+			<mesh>assets/room.004.ankimesh</mesh>
+			<material>assets/room_green.ankimtl</material>
+		</modelPatch>
+	</modelPatches>
+</model>

二進制
samples/skeletal_animation/assets/room.005.ankimesh


+ 8 - 0
samples/skeletal_animation/assets/room.005_room_red.ankimdl

@@ -0,0 +1,8 @@
+<model>
+	<modelPatches>
+		<modelPatch>
+			<mesh>assets/room.005.ankimesh</mesh>
+			<material>assets/room_red.ankimtl</material>
+		</modelPatch>
+	</modelPatches>
+</model>

二進制
samples/skeletal_animation/assets/room.ankimesh


+ 1 - 1
samples/skeletal_animation/assets/room.ankimtl

@@ -14,7 +14,7 @@
 	<inputs>
 		
 
-		<input shaderVar="m_diffColor" value="0.034270 0.490025 0.800000"/>
+		<input shaderVar="m_diffColor" value="1.000000 1.000000 1.000000"/>
 		<input shaderVar="m_specColor" value="0.040000 0.040000 0.040000"/>
 		<input shaderVar="m_roughness" value="0.500000"/>
 		<input shaderVar="m_metallic" value="0.000000"/>

+ 26 - 0
samples/skeletal_animation/assets/room_blue.ankimtl

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- This file is auto generated by ImporterMaterial.cpp -->
+<material shaderProgram="shaders/GBufferGeneric.ankiprog">
+	<mutation>
+		<mutator name="DIFFUSE_TEX" value="0"/>
+		<mutator name="SPECULAR_TEX" value="0"/>
+		<mutator name="ROUGHNESS_TEX" value="0"/>
+		<mutator name="METAL_TEX" value="0"/>
+		<mutator name="NORMAL_TEX" value="0"/>
+		<mutator name="PARALLAX" value="0"/>
+		<mutator name="EMISSIVE_TEX" value="0"/>
+	</mutation>
+
+	<inputs>
+		
+
+		<input shaderVar="m_diffColor" value="0.000000 0.000000 1.000000"/>
+		<input shaderVar="m_specColor" value="0.040000 0.040000 0.040000"/>
+		<input shaderVar="m_roughness" value="0.500000"/>
+		<input shaderVar="m_metallic" value="0.000000"/>
+		
+		<input shaderVar="m_emission" value="0.000000 0.000000 0.000000"/>
+		<input shaderVar="m_subsurface" value="0.000000"/>
+		
+	</inputs>
+</material>

+ 26 - 0
samples/skeletal_animation/assets/room_green.ankimtl

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- This file is auto generated by ImporterMaterial.cpp -->
+<material shaderProgram="shaders/GBufferGeneric.ankiprog">
+	<mutation>
+		<mutator name="DIFFUSE_TEX" value="0"/>
+		<mutator name="SPECULAR_TEX" value="0"/>
+		<mutator name="ROUGHNESS_TEX" value="0"/>
+		<mutator name="METAL_TEX" value="0"/>
+		<mutator name="NORMAL_TEX" value="0"/>
+		<mutator name="PARALLAX" value="0"/>
+		<mutator name="EMISSIVE_TEX" value="0"/>
+	</mutation>
+
+	<inputs>
+		
+
+		<input shaderVar="m_diffColor" value="0.000000 1.000000 0.000000"/>
+		<input shaderVar="m_specColor" value="0.040000 0.040000 0.040000"/>
+		<input shaderVar="m_roughness" value="0.500000"/>
+		<input shaderVar="m_metallic" value="0.000000"/>
+		
+		<input shaderVar="m_emission" value="0.000000 0.000000 0.000000"/>
+		<input shaderVar="m_subsurface" value="0.000000"/>
+		
+	</inputs>
+</material>

+ 26 - 0
samples/skeletal_animation/assets/room_red.ankimtl

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- This file is auto generated by ImporterMaterial.cpp -->
+<material shaderProgram="shaders/GBufferGeneric.ankiprog">
+	<mutation>
+		<mutator name="DIFFUSE_TEX" value="0"/>
+		<mutator name="SPECULAR_TEX" value="0"/>
+		<mutator name="ROUGHNESS_TEX" value="0"/>
+		<mutator name="METAL_TEX" value="0"/>
+		<mutator name="NORMAL_TEX" value="0"/>
+		<mutator name="PARALLAX" value="0"/>
+		<mutator name="EMISSIVE_TEX" value="0"/>
+	</mutation>
+
+	<inputs>
+		
+
+		<input shaderVar="m_diffColor" value="1.000000 0.000859 0.000000"/>
+		<input shaderVar="m_specColor" value="0.040000 0.040000 0.040000"/>
+		<input shaderVar="m_roughness" value="0.500000"/>
+		<input shaderVar="m_metallic" value="0.000000"/>
+		
+		<input shaderVar="m_emission" value="0.000000 0.000000 0.000000"/>
+		<input shaderVar="m_subsurface" value="0.000000"/>
+		
+	</inputs>
+</material>

+ 45 - 0
samples/skeletal_animation/assets/scene.lua

@@ -44,3 +44,48 @@ rot:setAll(-0.712312, -0.312519, 0.628445, 0.000000, 0.000000, 0.895396, 0.44527
 trf:setRotation(rot)
 trf:setScale(1.000000)
 node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
+
+node = scene:newModelNode("room.001", "assets/room.001_room_blue.ankimdl")
+trf = Transform.new()
+trf:setOrigin(Vec4.new(0.000000, 11.142166, 0.000000, 0))
+rot = Mat3x4.new()
+rot:setAll(1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000)
+trf:setRotation(rot)
+trf:setScale(11.360806)
+node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
+
+node = scene:newModelNode("room.002", "assets/room.002_room_green.ankimdl")
+trf = Transform.new()
+trf:setOrigin(Vec4.new(0.000000, 11.142166, 0.000000, 0))
+rot = Mat3x4.new()
+rot:setAll(1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000)
+trf:setRotation(rot)
+trf:setScale(11.360806)
+node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
+
+node = scene:newModelNode("room.003", "assets/room.003_room_blue.ankimdl")
+trf = Transform.new()
+trf:setOrigin(Vec4.new(0.000000, 11.142166, 0.000000, 0))
+rot = Mat3x4.new()
+rot:setAll(1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000)
+trf:setRotation(rot)
+trf:setScale(11.360806)
+node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
+
+node = scene:newModelNode("room.004", "assets/room.004_room_green.ankimdl")
+trf = Transform.new()
+trf:setOrigin(Vec4.new(0.000000, 11.142166, 0.000000, 0))
+rot = Mat3x4.new()
+rot:setAll(1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000)
+trf:setRotation(rot)
+trf:setScale(11.360806)
+node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
+
+node = scene:newModelNode("room.005", "assets/room.005_room_red.ankimdl")
+trf = Transform.new()
+trf:setOrigin(Vec4.new(0.000000, 11.142166, 0.000000, 0))
+rot = Mat3x4.new()
+rot:setAll(1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000)
+trf:setRotation(rot)
+trf:setScale(11.360806)
+node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)

+ 6 - 12
shaders/SceneDebug.ankiprog

@@ -8,6 +8,12 @@
 
 ANKI_SPECIALIZATION_CONSTANT_U32(INSTANCE_COUNT, 0, 1);
 
+layout(set = 1, binding = 0, row_major) uniform u0_
+{
+	Mat4 u_mvp[INSTANCE_COUNT];
+	Vec4 u_color;
+};
+
 #pragma anki start vert
 #include <shaders/Common.glsl>
 
@@ -17,12 +23,6 @@ layout(location = 1) in Vec2 in_uv;
 layout(location = 0) out Vec2 out_uv;
 #endif
 
-layout(set = 1, binding = 0, row_major) uniform u0_
-{
-	Mat4 u_mvp[INSTANCE_COUNT];
-	Vec4 u_color;
-};
-
 out gl_PerVertex
 {
 	Vec4 gl_Position;
@@ -46,12 +46,6 @@ layout(set = 1, binding = 1) uniform sampler u_trilinearRepeatSampler;
 layout(set = 1, binding = 2) uniform texture2D u_tex;
 #endif
 
-layout(set = 1, binding = 0, row_major) uniform u0_
-{
-	Mat4 u_mvp[INSTANCE_COUNT];
-	Vec4 u_color;
-};
-
 // NOTE: Don't eliminate the binding because it confuses the descriptor set creation
 #if DITHERED_DEPTH_TEST == 1
 layout(set = 0, binding = 0) uniform sampler u_nearestAnyClampSampler;

+ 1 - 0
src/anki/importer/GltfImporter.h

@@ -102,6 +102,7 @@ private:
 	{
 		StringAuto out(m_alloc, in);
 		out.replaceAll("|", "_");
+		out.replaceAll(" ", "_");
 		return out;
 	}
 

+ 5 - 0
src/anki/resource/SkeletonResource.h

@@ -52,6 +52,11 @@ public:
 		return ConstWeakArray<Bone*>((m_childrenCount) ? &m_children[0] : nullptr, m_childrenCount);
 	}
 
+	const Bone* getParent() const
+	{
+		return m_parent;
+	}
+
 private:
 	String m_name; ///< The name of the bone
 

+ 44 - 0
src/anki/scene/DebugDrawer.cpp

@@ -382,6 +382,50 @@ void DebugDrawer2::drawCubes(ConstWeakArray<Mat4> mvps,
 	cmdb->drawElements(PrimitiveTopology::LINES, indexCount, mvps.getSize());
 }
 
+void DebugDrawer2::drawLines(ConstWeakArray<Mat4> mvps,
+	const Vec4& color,
+	F32 lineSize,
+	Bool ditherFailedDepth,
+	ConstWeakArray<Vec3> lines,
+	StagingGpuMemoryManager& stagingGpuAllocator,
+	CommandBufferPtr& cmdb) const
+{
+	ANKI_ASSERT(mvps.getSize() > 0);
+	ANKI_ASSERT(lines.getSize() > 0 && (lines.getSize() % 2) == 0);
+
+	// Verts
+	StagingGpuMemoryToken vertsToken;
+	Vec3* verts = static_cast<Vec3*>(
+		stagingGpuAllocator.allocateFrame(sizeof(Vec3) * lines.getSize(), StagingGpuMemoryType::VERTEX, vertsToken));
+	memcpy(verts, lines.getBegin(), lines.getSizeInBytes());
+
+	// Set the uniforms
+	StagingGpuMemoryToken unisToken;
+	Mat4* pmvps = static_cast<Mat4*>(stagingGpuAllocator.allocateFrame(
+		sizeof(Mat4) * mvps.getSize() + sizeof(Vec4), StagingGpuMemoryType::UNIFORM, unisToken));
+
+	memcpy(pmvps, &mvps[0], mvps.getSizeInBytes());
+	Vec4* pcolor = reinterpret_cast<Vec4*>(pmvps + mvps.getSize());
+	*pcolor = color;
+
+	// Setup state
+	ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
+	variantInitInfo.addMutation("COLOR_TEXTURE", 0);
+	variantInitInfo.addMutation("DITHERED_DEPTH_TEST", U32(ditherFailedDepth != 0));
+	variantInitInfo.addConstant("INSTANCE_COUNT", mvps.getSize());
+	const ShaderProgramResourceVariant* variant;
+	m_prog->getOrCreateVariant(variantInitInfo, variant);
+	cmdb->bindShaderProgram(variant->getProgram());
+
+	cmdb->setVertexAttribute(0, 0, Format::R32G32B32_SFLOAT, 0);
+	cmdb->bindVertexBuffer(0, vertsToken.m_buffer, vertsToken.m_offset, sizeof(Vec3));
+
+	cmdb->bindUniformBuffer(1, 0, unisToken.m_buffer, unisToken.m_offset, unisToken.m_range);
+
+	cmdb->setLineWidth(lineSize);
+	cmdb->drawArrays(PrimitiveTopology::LINES, lines.getSize(), mvps.getSize());
+}
+
 void DebugDrawer2::drawBillboardTextures(const Mat4& projMat,
 	const Mat4& viewMat,
 	ConstWeakArray<Vec3> positions,

+ 21 - 0
src/anki/scene/DebugDrawer.h

@@ -153,6 +153,27 @@ public:
 			ConstWeakArray<Mat4>(&mvp, 1), color, lineSize, ditherFailedDepth, cubeSideSize, stagingGpuAllocator, cmdb);
 	}
 
+	void drawLines(ConstWeakArray<Mat4> mvps,
+		const Vec4& color,
+		F32 lineSize,
+		Bool ditherFailedDepth,
+		ConstWeakArray<Vec3> lines,
+		StagingGpuMemoryManager& stagingGpuAllocator,
+		CommandBufferPtr& cmdb) const;
+
+	void drawLine(const Mat4& mvp,
+		const Vec4& color,
+		F32 lineSize,
+		Bool ditherFailedDepth,
+		const Vec3& a,
+		const Vec3& b,
+		StagingGpuMemoryManager& stagingGpuAllocator,
+		CommandBufferPtr& cmdb) const
+	{
+		Array<Vec3, 2> points = {{a, b}};
+		drawLines(ConstWeakArray<Mat4>(&mvp, 1), color, lineSize, ditherFailedDepth, points, stagingGpuAllocator, cmdb);
+	}
+
 	void drawBillboardTextures(const Mat4& projMat,
 		const Mat4& viewMat,
 		ConstWeakArray<Vec3> positions,

+ 34 - 0
src/anki/scene/ModelNode.cpp

@@ -247,6 +247,40 @@ void ModelNode::draw(RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData
 
 		ctx.m_frameAllocator.deleteArray(mvps, userData.getSize());
 
+		// Bones
+		if(m_model->getSkeleton())
+		{
+			const SkinComponent& skinc = getComponentAt<SkinComponent>(0);
+			SkeletonResourcePtr skeleton = skinc.getSkeleronResource();
+			const U32 boneCount = skinc.getBoneTransforms().getSize();
+
+			Vec3* lines = ctx.m_frameAllocator.newArray<Vec3>(boneCount * 2);
+			for(U32 i = 0; i < boneCount; ++i)
+			{
+				const Bone& bone = skeleton->getBones()[i];
+				ANKI_ASSERT(bone.getIndex() == i);
+				const Vec4 point(0.0f, 0.0f, 0.0f, 1.0f);
+				const Bone* parent = bone.getParent();
+				Mat4 m = (parent)
+							 ? skinc.getBoneTransforms()[parent->getIndex()] * parent->getVertexTransform().getInverse()
+							 : Mat4::getIdentity();
+				lines[i * 2] = (m * point).xyz();
+				m = skinc.getBoneTransforms()[i] * bone.getVertexTransform().getInverse();
+				lines[i * 2 + 1] = (m * point).xyz();
+			}
+
+			const Mat4 mvp = ctx.m_viewProjectionMatrix * Mat4(getComponent<MoveComponent>().getWorldTransform());
+			m_dbgDrawer.drawLines(ConstWeakArray<Mat4>(&mvp, 1),
+				Vec4(1, 1, 1, 1),
+				10.0f,
+				ctx.m_debugDrawFlags.get(RenderQueueDebugDrawFlag::DITHERED_DEPTH_TEST_ON),
+				ConstWeakArray<Vec3>(lines, boneCount * 2),
+				*ctx.m_stagingGpuAllocator,
+				cmdb);
+
+			ctx.m_frameAllocator.deleteArray(lines, boneCount * 2);
+		}
+
 		// Restore state
 		if(!enableDepthTest)
 		{

+ 5 - 0
src/anki/scene/components/SkinComponent.h

@@ -36,6 +36,11 @@ public:
 		return m_boneTrfs;
 	}
 
+	const SkeletonResourcePtr& getSkeleronResource() const
+	{
+		return m_skeleton;
+	}
+
 private:
 	class Track
 	{