# HG changeset patch # User sam # Date 1721755617 -25200 # Node ID d594b1d07d49946679c9fbd814bf684ece3f44d5 # Parent 3ef5764504addffe974d667f38a5882d258d120c add: initial changes for glTF loader diff -r 3ef5764504ad -r d594b1d07d49 semiconginev2.nim --- a/semiconginev2.nim Tue Jul 23 21:31:44 2024 +0700 +++ b/semiconginev2.nim Wed Jul 24 00:26:57 2024 +0700 @@ -48,6 +48,8 @@ include ./semiconginev2/contrib/algorithms/texture_packing include ./semiconginev2/text +include ./semiconginev2/gltf + when not defined(WITHOUT_CONTRIB): include ./semiconginev2/contrib/steam include ./semiconginev2/contrib/settings diff -r 3ef5764504ad -r d594b1d07d49 semiconginev2/gltf.nim --- a/semiconginev2/gltf.nim Tue Jul 23 21:31:44 2024 +0700 +++ b/semiconginev2/gltf.nim Wed Jul 24 00:26:57 2024 +0700 @@ -1,4 +1,9 @@ type + GLTFMesh[TMesh, TMaterial] = object + scenes: seq[int] + nodes: seq[int] + meshes: seq[TMesh] + materials: seq[TMaterial] glTFHeader = object magic: uint32 version: uint32 @@ -7,7 +12,19 @@ structuredContent: JsonNode binaryBufferData: seq[uint8] + MaterialAttributeNames = object + baseColorFactor: string + emissiveFactor: string + metallicFactor: string + roughnessFactor: string + baseColorTexture: string + metallicRoughnessTexture: string + normalTexture: string + occlusionTexture: string + emissiveTexture: string + const + HEADER_MAGIC = 0x46546C67 JSON_CHUNK = 0x4E4F534A BINARY_CHUNK = 0x004E4942 ACCESSOR_TYPE_MAP = { @@ -150,9 +167,20 @@ result.sampler.wrapModeT = SAMPLER_WRAP_MODE_MAP[sampler["wrapS"].getInt()] -proc loadMaterial(root: JsonNode, materialNode: JsonNode, defaultMaterial: MaterialType, mainBuffer: seq[uint8]): MaterialData = +proc loadMaterial[TMaterial]( + root: JsonNode, + materialNode: JsonNode, + mainBuffer: seq[uint8], + mapping: MaterialAttributeNames +): TMaterial = let pbr = materialNode["pbrMetallicRoughness"] - var attributes: Table[string, DataList] + for glName, glValue in fieldPairs(mapping): + if glValue != "": + for name, value in fieldPairs(result): + when name == glName: + value = + + #[ # color if defaultMaterial.attributes.contains("color"): @@ -207,8 +235,8 @@ )] else: attributes["emissiveColor"] = @[NewVec3f(1'f32, 1'f32, 1'f32)] + ]# - result = InitMaterialData(theType = defaultMaterial, name = materialNode["name"].getStr(), attributes = attributes) proc loadMesh(meshname: string, root: JsonNode, primitiveNode: JsonNode, materials: seq[MaterialData], mainBuffer: seq[uint8]): Mesh = if primitiveNode.hasKey("mode") and primitiveNode["mode"].getInt() != 4: @@ -313,7 +341,7 @@ for childNode in node["children"]: result.children.add loadNode(root, root["nodes"][childNode.getInt()], materials, mainBuffer) -proc loadMeshTree(root: JsonNode, scenenode: JsonNode, materials: seq[MaterialData], mainBuffer: var seq[uint8]): MeshTree = +proc loadScene(root: JsonNode, scenenode: JsonNode, materials: seq[MaterialData], mainBuffer: var seq[uint8]): MeshTree = result = MeshTree() for nodeId in scenenode["nodes"]: result.children.add loadNode(root, root["nodes"][nodeId.getInt()], materials, mainBuffer) @@ -322,7 +350,30 @@ result.updateTransforms() -proc ReadglTF*(stream: Stream, defaultMaterial: MaterialType): seq[MeshTree] = +proc ReadglTF*[TMaterial, TMesh]( + stream: Stream, + attributeNames: MaterialAttributeNames, + baseColorFactor = "", + emissiveFactor = "", + metallicFactor = "", + roughnessFactor = "", + baseColorTexture = "", + metallicRoughnessTexture = "", + normalTexture = "", + occlusionTexture = "", + emissiveTexture = "", +): GLTFMesh[TMesh, TMaterial] = + let mapping = MaterialAttributeNames( + baseColorFactor: baseColorFactor + emissiveFactor: emissiveFactor + metallicFactor: metallicFactor + roughnessFactor: roughnessFactor + baseColorTexture: baseColorTexture + metallicRoughnessTexture: metallicRoughnessTexture + normalTexture: normalTexture + occlusionTexture: occlusionTexture + emissiveTexture: emissiveTexture + ) var header: glTFHeader data: glTFData @@ -330,7 +381,7 @@ for name, value in fieldPairs(header): stream.read(value) - assert header.magic == 0x46546C67 + assert header.magic == HEADER_MAGIC assert header.version == 2 var chunkLength = stream.readUint32() @@ -353,7 +404,7 @@ var materials: seq[MaterialData] for materialnode in data.structuredContent["materials"]: - materials.add data.structuredContent.loadMaterial(materialnode, defaultMaterial, data.binaryBufferData) + result.materials.add loadMaterial[TMaterial](data.structuredContent, materialnode, data.binaryBufferData, mapping) for scenedata in data.structuredContent["scenes"]: - result.add data.structuredContent.loadMeshTree(scenedata, materials, data.binaryBufferData) + result.add data.structuredContent.loadScene(scenedata, materials, data.binaryBufferData)