changeset 1251:3f98ad20a9d3

add: render by-node instead of by-mesh
author sam <sam@basx.dev>
date Fri, 26 Jul 2024 20:34:02 +0700
parents 9ceb509af5ea
children 01e9f41d35b1
files semiconginev2/gltf.nim tests/test_gltf.nim
diffstat 2 files changed, 20 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/semiconginev2/gltf.nim	Thu Jul 25 23:15:05 2024 +0700
+++ b/semiconginev2/gltf.nim	Fri Jul 26 20:34:02 2024 +0700
@@ -1,9 +1,9 @@
 type
   GltfNode* = object
-    children: seq[int]
-    mesh: int
-    transform: Mat4
-  GltfMesh*[TMesh, TMaterial] = object
+    children*: seq[int]
+    mesh*: int = -1
+    transform*: Mat4 = Unit4
+  GltfData*[TMesh, TMaterial] = object
     scenes*: seq[seq[int]] # each scene has a seq of node indices
     nodes*: seq[GltfNode]  # each node has a seq of mesh indices
     meshes*: seq[seq[(TMesh, VkPrimitiveTopology)]]
@@ -224,7 +224,7 @@
           inc i
 
 proc loadNode(node: JsonNode): GltfNode =
-  result.transform = Unit4
+  result = GltfNode()
   if "mesh" in node:
     result.mesh = node["mesh"].getInt()
   if "children" in node:
@@ -263,7 +263,7 @@
   stream: Stream,
   meshAttributesMapping: static MeshAttributeNames,
   materialAttributesMapping: static MaterialAttributeNames,
-): GltfMesh[TMesh, TMaterial] =
+): GltfData[TMesh, TMaterial] =
   var
     header: glTFHeader
     data: glTFData
@@ -324,7 +324,7 @@
   meshAttributesMapping: static MeshAttributeNames,
   materialAttributesMapping: static MaterialAttributeNames,
   package = DEFAULT_PACKAGE
-): GltfMesh[TMesh, TMaterial] =
+): GltfData[TMesh, TMaterial] =
   ReadglTF[TMesh, TMaterial](
     stream = loadResource_intern(path, package = package),
     meshAttributesMapping = meshAttributesMapping,
--- a/tests/test_gltf.nim	Thu Jul 25 23:15:05 2024 +0700
+++ b/tests/test_gltf.nim	Fri Jul 26 20:34:02 2024 +0700
@@ -43,7 +43,7 @@
       position: GPUArray[Vec3f, VertexBuffer]
       uv: GPUArray[Vec2f, VertexBuffer]
 
-  var gltfMesh = LoadMeshes[Mesh, Material](
+  var gltfData = LoadMeshes[Mesh, Material](
     "town.glb",
     MeshAttributeNames(
       POSITION: "position",
@@ -61,13 +61,22 @@
       emissiveFactor: "emissive",
     )
   )
-  for mesh in mitems(gltfMesh.meshes):
+  for mesh in mitems(gltfData.meshes):
     for primitive in mitems(mesh):
       renderdata.AssignBuffers(primitive[0])
   renderdata.FlushAllMemory()
 
   var pipeline = CreatePipeline[Shader](renderPass = vulkan.swapchain.renderPass)
 
+  proc drawNode(commandbuffer: VkCommandBuffer, pipeline: Pipeline, nodeId: int, transform: Mat4 = Unit4) =
+    let nodeTransform = gltfData.nodes[nodeId].transform * transform
+    if gltfData.nodes[nodeId].mesh >= 0:
+      for primitive in gltfData.meshes[gltfData.nodes[nodeId].mesh]:
+        Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = primitive[0])
+    for childNode in gltfData.nodes[nodeId].children:
+      drawNode(commandbuffer = commandbuffer, pipeline = pipeline, nodeId = childNode, transform = nodeTransform)
+
+
   var start = getMonoTime()
   while ((getMonoTime() - start).inMilliseconds().int / 1000) < time:
 
@@ -76,10 +85,8 @@
       WithRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, NewVec4f(0, 0, 0, 0)):
 
         WithPipeline(commandbuffer, pipeline):
-
-          for mesh in gltfMesh.meshes:
-            for primitive in mesh:
-              Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = primitive[0])
+          for nodeId in gltfData.scenes[0]:
+            drawNode(commandbuffer = commandbuffer, pipeline = pipeline, nodeId = nodeId)
 
   # cleanup
   checkVkResult vkDeviceWaitIdle(vulkan.device)