# HG changeset patch # User sam # Date 1722000842 -25200 # Node ID 3f98ad20a9d38d229041a1b642c5c9d0f2902f70 # Parent 9ceb509af5ea7f89b3e8b62c2fc15b57b5430059 add: render by-node instead of by-mesh diff -r 9ceb509af5ea -r 3f98ad20a9d3 semiconginev2/gltf.nim --- 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, diff -r 9ceb509af5ea -r 3f98ad20a9d3 tests/test_gltf.nim --- 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)