changeset 811:cc59b7650075

did: improve error output, allow import of meshes without materials
author Sam <sam@basx.dev>
date Tue, 19 Sep 2023 21:27:25 +0700
parents 528671dce35a
children 27346eb7dd37
files src/semicongine/core/dynamic_arrays.nim src/semicongine/resources/mesh.nim
diffstat 2 files changed, 63 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/semicongine/core/dynamic_arrays.nim	Sun Sep 17 22:44:16 2023 +0700
+++ b/src/semicongine/core/dynamic_arrays.nim	Tue Sep 19 21:27:25 2023 +0700
@@ -672,3 +672,49 @@
 proc copy*(datalist: DataList): DataList =
   result = newDataList(datalist.theType)
   result.appendValues(datalist)
+
+func `$`*(list: DataList): string =
+  case list.theType
+    of Float32: $list.float32[]
+    of Float64: $list.float64[]
+    of Int8: $list.int8[]
+    of Int16: $list.int16[]
+    of Int32: $list.int32[]
+    of Int64: $list.int64[]
+    of UInt8: $list.uint8[]
+    of UInt16: $list.uint16[]
+    of UInt32: $list.uint32[]
+    of UInt64: $list.uint64[]
+    of Vec2I32: $list.vec2i32[]
+    of Vec2I64: $list.vec2i64[]
+    of Vec3I32: $list.vec3i32[]
+    of Vec3I64: $list.vec3i64[]
+    of Vec4I32: $list.vec4i32[]
+    of Vec4I64: $list.vec4i64[]
+    of Vec2U32: $list.vec2u32[]
+    of Vec2U64: $list.vec2u64[]
+    of Vec3U32: $list.vec3u32[]
+    of Vec3U64: $list.vec3u64[]
+    of Vec4U32: $list.vec4u32[]
+    of Vec4U64: $list.vec4u64[]
+    of Vec2F32: $list.vec2f32[]
+    of Vec2F64: $list.vec2f64[]
+    of Vec3F32: $list.vec3f32[]
+    of Vec3F64: $list.vec3f64[]
+    of Vec4F32: $list.vec4f32[]
+    of Vec4F64: $list.vec4f64[]
+    of Mat2F32: $list.mat2f32[]
+    of Mat2F64: $list.mat2f64[]
+    of Mat23F32: $list.mat23f32[]
+    of Mat23F64: $list.mat23f64[]
+    of Mat32F32: $list.mat32f32[]
+    of Mat32F64: $list.mat32f64[]
+    of Mat3F32: $list.mat3f32[]
+    of Mat3F64: $list.mat3f64[]
+    of Mat34F32: $list.mat34f32[]
+    of Mat34F64: $list.mat34f64[]
+    of Mat43F32: $list.mat43f32[]
+    of Mat43F64: $list.mat43f64[]
+    of Mat4F32: $list.mat4f32[]
+    of Mat4F64: $list.mat4f64[]
+    of Sampler2D: $list.texture[]
--- a/src/semicongine/resources/mesh.nim	Sun Sep 17 22:44:16 2023 +0700
+++ b/src/semicongine/resources/mesh.nim	Tue Sep 19 21:27:25 2023 +0700
@@ -45,7 +45,7 @@
     10497: VK_SAMPLER_ADDRESS_MODE_REPEAT
   }.toTable
 
-proc getGPUType(accessor: JsonNode): DataType =
+proc getGPUType(accessor: JsonNode, attribute: string): DataType =
   # TODO: no full support for all datatypes that glTF may provide
   # semicongine/core/gpu_data should maybe generated with macros to allow for all combinations
   let componentType = ACCESSOR_TYPE_MAP[accessor["componentType"].getInt()]
@@ -57,29 +57,29 @@
     case componentType
     of UInt32: return Vec2U32
     of Float32: return Vec2F32
-    else: raise newException(Exception, &"Unsupported data type: {componentType} {theType}")
+    else: raise newException(Exception, &"Unsupported data type for attribute '{attribute}': {componentType} {theType}")
   of "VEC3":
     case componentType
     of UInt32: return Vec3U32
     of Float32: return Vec3F32
-    else: raise newException(Exception, &"Unsupported data type: {componentType} {theType}")
+    else: raise newException(Exception, &"Unsupported data type for attribute '{attribute}': {componentType} {theType}")
   of "VEC4":
     case componentType
     of UInt32: return Vec4U32
     of Float32: return Vec4F32
-    else: raise newException(Exception, &"Unsupported data type: {componentType} {theType}")
+    else: raise newException(Exception, &"Unsupported data type for attribute '{attribute}': {componentType} {theType}")
   of "MAT2":
     case componentType
     of Float32: return Vec4F32
-    else: raise newException(Exception, &"Unsupported data type: {componentType} {theType}")
+    else: raise newException(Exception, &"Unsupported data type for attribute '{attribute}': {componentType} {theType}")
   of "MAT3":
     case componentType
     of Float32: return Vec4F32
-    else: raise newException(Exception, &"Unsupported data type: {componentType} {theType}")
+    else: raise newException(Exception, &"Unsupported data type for attribute '{attribute}': {componentType} {theType}")
   of "MAT4":
     case componentType
     of Float32: return Vec4F32
-    else: raise newException(Exception, &"Unsupported data type: {componentType} {theType}")
+    else: raise newException(Exception, &"Unsupported data type for attribute '{attribute}': {componentType} {theType}")
 
 proc getBufferViewData(bufferView: JsonNode, mainBuffer: seq[uint8], baseBufferOffset=0): seq[uint8] =
   assert bufferView["buffer"].getInt() == 0, "Currently no external buffers supported"
@@ -93,7 +93,7 @@
   copyMem(dstPointer, addr mainBuffer[bufferOffset], result.len)
 
 proc getAccessorData(root: JsonNode, accessor: JsonNode, mainBuffer: seq[uint8]): DataList =
-  result = newDataList(thetype=accessor.getGPUType())
+  result = newDataList(thetype=accessor.getGPUType("??"))
   result.setLen(accessor["count"].getInt())
 
   let bufferView = root["bufferViews"][accessor["bufferView"].getInt()]
@@ -221,11 +221,14 @@
   if primitiveNode.hasKey("material"):
     materialId = uint16(primitiveNode["material"].getInt())
   mesh[].appendAttributeData("materialIndex", newSeqWith(vertexCount, materialId))
-  let material = loadMaterial(root, root["materials"][int(materialId)], mainBuffer, materialId)
-  # FIX: materialIndex is designed to support multiple different materials per mesh (as it is per vertex),
-  # but or current mesh/rendering implementation is only designed for a single material
-  # currently this is usually handled by adding the values as shader globals
-  mesh[].material = material
+  if "materials" in root and int(materialId) < root["materials"].len:
+    let material = loadMaterial(root, root["materials"][int(materialId)], mainBuffer, materialId)
+    # FIX: materialIndex is designed to support multiple different materials per mesh (as it is per vertex),
+    # but or current mesh/rendering implementation is only designed for a single material
+    # currently this is usually handled by adding the values as shader globals
+    mesh[].material = material
+  else:
+    mesh[].material = DEFAULT_MATERIAL
 
   if primitiveNode.hasKey("indices"):
     assert mesh[].indexType != None
@@ -274,7 +277,7 @@
 
   # prepare mesh attributes
   for attribute, accessor in meshNode["primitives"][0]["attributes"].pairs:
-    result[].initVertexAttribute(attribute.toLowerAscii, root["accessors"][accessor.getInt()].getGPUType())
+    result[].initVertexAttribute(attribute.toLowerAscii, root["accessors"][accessor.getInt()].getGPUType(attribute))
   result[].initVertexAttribute("materialIndex", UInt16)
 
   # add all mesh data