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, |
