Mercurial > games > semicongine
comparison semiconginev2/gltf.nim @ 1249:d83726af7abb
did: first triangles getting loaded from gltf
author | sam <sam@basx.dev> |
---|---|
date | Thu, 25 Jul 2024 22:41:24 +0700 |
parents | 317bb5a73606 |
children | 9ceb509af5ea |
comparison
equal
deleted
inserted
replaced
1248:317bb5a73606 | 1249:d83726af7abb |
---|---|
139 | 139 |
140 if bufferView.hasKey("byteStride"): | 140 if bufferView.hasKey("byteStride"): |
141 raise newException(Exception, "Unsupported feature: byteStride in buffer view") | 141 raise newException(Exception, "Unsupported feature: byteStride in buffer view") |
142 copyMem(dstPointer, addr mainBuffer[bufferOffset], result.len) | 142 copyMem(dstPointer, addr mainBuffer[bufferOffset], result.len) |
143 | 143 |
144 proc componentTypeId(t: typedesc): int = | |
145 if t is int8: return 5120 | |
146 elif t is uint8: return 5121 | |
147 elif t is int16: return 5122 | |
148 elif t is uint16: return 5123 | |
149 elif t is uint32: return 5125 | |
150 elif t is float32: return 5126 | |
151 | |
144 proc getAccessorData[T](root: JsonNode, accessor: JsonNode, mainBuffer: seq[uint8]): seq[T] = | 152 proc getAccessorData[T](root: JsonNode, accessor: JsonNode, mainBuffer: seq[uint8]): seq[T] = |
153 let componentType = accessor["componentType"].getInt() | |
154 let itemType = accessor["type"].getStr() | |
155 | |
156 when T is TVec or T is TMat: | |
157 assert componentTypeId(elementType(default(T))) == componentType, name(T) & " != " & $componentType | |
158 else: | |
159 assert componentTypeId(T) == componentType, name(T) & " != " & $componentType | |
160 | |
161 when T is TVec: | |
162 when len(default(T)) == 2: assert itemType == "VEC2" | |
163 elif len(default(T)) == 3: assert itemType == "VEC3" | |
164 elif len(default(T)) == 4: assert itemType == "VEC4" | |
165 elif T is TMat: | |
166 when T is Mat2: assert itemType == "MAT2" | |
167 elif T is Mat3: assert itemType == "MAT3" | |
168 elif T is Mat4: assert itemType == "MAT4" | |
169 else: | |
170 assert itemType == "SCALAR" | |
171 | |
145 result.setLen(accessor["count"].getInt()) | 172 result.setLen(accessor["count"].getInt()) |
146 | 173 |
147 let bufferView = root["bufferViews"][accessor["bufferView"].getInt()] | 174 let bufferView = root["bufferViews"][accessor["bufferView"].getInt()] |
148 assert bufferView["buffer"].getInt() == 0, "Currently no external buffers supported" | 175 assert bufferView["buffer"].getInt() == 0, "Currently no external buffers supported" |
149 | 176 |
156 var dstPointer = result.ToCPointer() | 183 var dstPointer = result.ToCPointer() |
157 | 184 |
158 if bufferView.hasKey("byteStride"): | 185 if bufferView.hasKey("byteStride"): |
159 warn "Congratulations, you try to test a feature (loading buffer data with stride attributes) that we have no idea where it is used and how it can be tested (need a coresponding *.glb file)." | 186 warn "Congratulations, you try to test a feature (loading buffer data with stride attributes) that we have no idea where it is used and how it can be tested (need a coresponding *.glb file)." |
160 # we don't support stride, have to convert stuff here... does this even work? | 187 # we don't support stride, have to convert stuff here... does this even work? |
161 for i in 0 ..< int(result.len): | 188 for i in 0 ..< result.len: |
162 copyMem(dstPointer, addr mainBuffer[bufferOffset + i * bufferView["byteStride"].getInt()], result.len * sizeof(T)) | 189 copyMem(dstPointer, addr mainBuffer[bufferOffset + i * bufferView["byteStride"].getInt()], sizeof(T)) |
163 dstPointer = cast[typeof(dstPointer)](cast[uint](dstPointer) + (result.len * sizeof(T)).uint) | 190 dstPointer = cast[typeof(dstPointer)](cast[uint](dstPointer) + sizeof(T).uint) |
164 else: | 191 else: |
165 copyMem(dstPointer, addr mainBuffer[bufferOffset], length) | 192 copyMem(dstPointer, addr mainBuffer[bufferOffset], length) |
166 | 193 |
167 proc loadTexture(root: JsonNode, textureNode: JsonNode, mainBuffer: seq[uint8]): Image[BGRA] = | 194 proc loadTexture(root: JsonNode, textureNode: JsonNode, mainBuffer: seq[uint8]): Image[BGRA] = |
168 | 195 |
191 NewVec4f(node[0].getFloat(), node[1].getFloat(), node[2].getFloat(), node[3].getFloat()) | 218 NewVec4f(node[0].getFloat(), node[1].getFloat(), node[2].getFloat(), node[3].getFloat()) |
192 | 219 |
193 proc loadMaterial[TMaterial]( | 220 proc loadMaterial[TMaterial]( |
194 root: JsonNode, | 221 root: JsonNode, |
195 materialNode: JsonNode, | 222 materialNode: JsonNode, |
223 mapping: static MaterialAttributeNames, | |
196 mainBuffer: seq[uint8], | 224 mainBuffer: seq[uint8], |
197 mapping: static MaterialAttributeNames | |
198 ): TMaterial = | 225 ): TMaterial = |
199 result = TMaterial() | 226 result = TMaterial() |
200 | 227 |
201 let pbr = materialNode["pbrMetallicRoughness"] | 228 let pbr = materialNode["pbrMetallicRoughness"] |
202 for name, value in fieldPairs(result): | 229 for name, value in fieldPairs(result): |
212 elif gltfAttribute in ["metallicFactor", "roughnessFactor"]: | 239 elif gltfAttribute in ["metallicFactor", "roughnessFactor"]: |
213 value = pbr[gltfAttribute].getFloat() | 240 value = pbr[gltfAttribute].getFloat() |
214 else: | 241 else: |
215 {.error: "Unsupported gltf material attribute".} | 242 {.error: "Unsupported gltf material attribute".} |
216 | 243 |
217 proc loadPrimitive[TMesh](root: JsonNode, primitive: JsonNode, mapping: static MeshAttributeNames, mainBuffer: seq[uint8]): (TMesh, VkPrimitiveTopology) = | 244 proc loadPrimitive[TMesh]( |
245 root: JsonNode, | |
246 primitive: JsonNode, | |
247 mapping: static MeshAttributeNames, | |
248 mainBuffer: seq[uint8] | |
249 ): (TMesh, VkPrimitiveTopology) = | |
218 result[0] = TMesh() | 250 result[0] = TMesh() |
219 result[1] = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST | 251 result[1] = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST |
220 if primitive.hasKey("mode"): | 252 if primitive.hasKey("mode"): |
221 result[1] = PRIMITIVE_MODE_MAP[primitive["mode"].getInt()] | 253 result[1] = PRIMITIVE_MODE_MAP[primitive["mode"].getInt()] |
222 | 254 |
223 for name, value in fieldPairs(result[0]): | 255 for resultFieldName, resultValue in fieldPairs(result[0]): |
224 for gltfAttribute, mappedName in fieldPairs(mapping): | 256 for gltfAttribute, mappedName in fieldPairs(mapping): |
225 when gltfAttribute != "" and name == mappedName: | 257 when typeof(mappedName) is string: |
226 assert value is GPUData, "Attribute " & name & " must be of type GPUData" | 258 when gltfAttribute != "" and resultFieldName == mappedName: |
259 assert resultValue is GPUData, "Attribute " & resultFieldName & " must be of type GPUData" | |
260 when gltfAttribute == "indices": | |
261 if primitive.hasKey(gltfAttribute): | |
262 let accessor = primitive[gltfAttribute].getInt() | |
263 resultValue.data = getAccessorData[elementType(resultValue.data)](root, root["accessors"][accessor], mainBuffer) | |
264 elif gltfAttribute == "material": | |
265 if primitive.hasKey(gltfAttribute): | |
266 resultValue.data = typeof(resultValue.data)(primitive[gltfAttribute].getInt()) | |
267 else: | |
268 if primitive["attributes"].hasKey(gltfAttribute): | |
269 let accessor = primitive["attributes"][gltfAttribute].getInt() | |
270 resultValue.data = getAccessorData[elementType(resultValue.data)](root, root["accessors"][accessor], mainBuffer) | |
271 else: | |
272 var i = 0 | |
273 for mappedIndexName in mappedName: | |
274 if gltfAttribute != "" and resultFieldName == mappedIndexName: | |
275 assert resultValue is GPUData, "Attribute " & resultFieldName & " must be of type GPUData" | |
276 let gltfAttributeIndexed = gltfAttribute & "_" & $i | |
277 if primitive["attributes"].hasKey(gltfAttributeIndexed): | |
278 let accessor = primitive["attributes"][gltfAttributeIndexed].getInt() | |
279 resultValue.data = getAccessorData[elementType(resultValue.data)](root, root["accessors"][accessor], mainBuffer) | |
280 inc i | |
227 #[ | 281 #[ |
228 when gltfAttribute == "indices": | 282 when gltfAttribute == "indices": |
229 if primitive.hasKey(gltfAttribute): | 283 if primitive.hasKey(gltfAttribute): |
230 let accessor = primitive[gltfAttribute].getInt() | 284 let accessor = primitive[gltfAttribute].getInt() |
231 value.data = getAccessorData[elementType(value.data)](root, root["accessors"][accessor], mainBuffer) | 285 value.data = getAccessorData[elementType(value.data)](root, root["accessors"][accessor], mainBuffer) |
434 | 488 |
435 debug "Loading mesh: ", data.structuredContent.pretty | 489 debug "Loading mesh: ", data.structuredContent.pretty |
436 | 490 |
437 if "materials" in data.structuredContent: | 491 if "materials" in data.structuredContent: |
438 for materialnode in items(data.structuredContent["materials"]): | 492 for materialnode in items(data.structuredContent["materials"]): |
439 result.materials.add loadMaterial[TMaterial](data.structuredContent, materialnode, data.binaryBufferData, materialAttributesMapping) | 493 result.materials.add loadMaterial[TMaterial](data.structuredContent, materialnode, materialAttributesMapping, data.binaryBufferData) |
440 | 494 |
441 if "textures" in data.structuredContent: | 495 if "textures" in data.structuredContent: |
442 for texturenode in items(data.structuredContent["textures"]): | 496 for texturenode in items(data.structuredContent["textures"]): |
443 result.textures.add loadTexture(data.structuredContent, texturenode, data.binaryBufferData) | 497 result.textures.add loadTexture(data.structuredContent, texturenode, data.binaryBufferData) |
444 | 498 |
459 | 513 |
460 echo "Meshes:" | 514 echo "Meshes:" |
461 for m in result.meshes: | 515 for m in result.meshes: |
462 echo " Primitives:" | 516 echo " Primitives:" |
463 for p in m: | 517 for p in m: |
464 echo " ", p[1], ": ", p[0] | 518 for field, value in fieldPairs(p[0]): |
519 if typeof(value) is GPUData: | |
520 echo " ", field, ": ", value.data.len | |
465 | 521 |
466 proc LoadMeshes*[TMesh, TMaterial]( | 522 proc LoadMeshes*[TMesh, TMaterial]( |
467 path: string, | 523 path: string, |
468 meshAttributesMapping: static MeshAttributeNames, | 524 meshAttributesMapping: static MeshAttributeNames, |
469 materialAttributesMapping: static MaterialAttributeNames, | 525 materialAttributesMapping: static MaterialAttributeNames, |