changeset 408:848a6845a588

did: overhaul dynamic array-api in a few places
author Sam <sam@basx.dev>
date Thu, 04 Jan 2024 21:13:11 +0700
parents ffc265916415
children a430b5febe22
files semicongine/core/dynamic_arrays.nim semicongine/material.nim semicongine/mesh.nim semicongine/renderer.nim semicongine/resources/mesh.nim semicongine/scene.nim
diffstat 6 files changed, 28 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/semicongine/core/dynamic_arrays.nim	Wed Jan 03 11:19:55 2024 +0700
+++ b/semicongine/core/dynamic_arrays.nim	Thu Jan 04 21:13:11 2024 +0700
@@ -309,7 +309,7 @@
   result = initDataList(getDataType[T]())
   result.setValues(@data)
 
-func getValues*[T: GPUType|int|uint|float](value: DataList): ref seq[T] =
+func getValues[T: GPUType|int|uint|float](value: DataList): ref seq[T] =
   when T is float32: value.float32
   elif T is float64: value.float64
   elif T is int8: value.int8
@@ -361,7 +361,7 @@
   elif T is Texture: value.texture
   else: {. error: "Virtual datatype has no values" .}
 
-func getValue*[T: GPUType|int|uint|float](value: DataList, i: int): T =
+func getValue[T: GPUType|int|uint|float](value: DataList, i: int): T =
   when T is float32: value.float32[i]
   elif T is float64: value.float64[i]
   elif T is int8: value.int8[i]
@@ -413,6 +413,11 @@
   elif T is Texture: value.texture[i]
   else: {. error: "Virtual datatype has no values" .}
 
+template `[]`*(list: DataList, t: typedesc): ref seq[t] =
+  getValues[t](list)
+template `[]`*(list: DataList, i: int, t: typedesc): untyped =
+  getValue[t](list, i)
+
 func getRawData*(value: var DataList): (pointer, int) =
   if value.len == 0:
     return (nil, 0)
--- a/semicongine/material.nim	Wed Jan 03 11:19:55 2024 +0700
+++ b/semicongine/material.nim	Thu Jan 04 21:13:11 2024 +0700
@@ -35,14 +35,14 @@
 proc `==`*(a, b: MaterialData): bool =
   return a.name == b.name
 
-proc get*[T](material: MaterialData, attributeName: string): seq[T] =
-  getValues[T](material.attributes[attributeName])[]
-
-proc getDataList*(material: MaterialData, attributeName: string): DataList =
+template `[]`*(material: MaterialData, attributeName: string): DataList =
   material.attributes[attributeName]
 
-proc getSingle*[T](material: MaterialData, attributeName: string): T =
-  getValues[T](material.attributes[attributeName])[][0]
+template `[]`*(material: MaterialData, attributeName: string, t: typedesc): ref seq[t] =
+  material.attributes[attributeName][t]
+
+template `[]`*(material: MaterialData, attributeName: string, i: int, t: typedesc): untyped =
+  material.attributes[attributeName][i, t]
 
 let EMPTY_MATERIAL* = MaterialType(
   name: "empty material",
--- a/semicongine/mesh.nim	Wed Jan 03 11:19:55 2024 +0700
+++ b/semicongine/mesh.nim	Thu Jan 04 21:13:11 2024 +0700
@@ -247,17 +247,17 @@
 
 proc getAttribute[T: GPUType|int|uint|float](mesh: MeshObject, attribute: string): ref seq[T] =
   if mesh.vertexData.contains(attribute):
-    getValues[T](mesh.vertexData[attribute])
+    mesh.vertexData[attribute][T]
   elif mesh.instanceData.contains(attribute):
-    getValues[T](mesh.instanceData[attribute])
+    mesh.instanceData[attribute][T]
   else:
     raise newException(Exception, &"Attribute {attribute} is not defined for mesh {mesh}")
 
 proc getAttribute[T: GPUType|int|uint|float](mesh: MeshObject, attribute: string, i: int): T =
   if mesh.vertexData.contains(attribute):
-    getValue[T](mesh.vertexData[attribute], i)
+    mesh.vertexData[attribute][i, T]
   elif mesh.instanceData.contains(attribute):
-    getValue[T](mesh.instanceData[attribute], i)
+    mesh.instanceData[attribute][i, T]
   else:
     raise newException(Exception, &"Attribute {attribute} is not defined for mesh {mesh}")
 
@@ -372,16 +372,16 @@
 proc transform*[T: GPUType](mesh: var MeshObject, attribute: string, transform: Mat4) =
   if mesh.vertexData.contains(attribute):
     for i in 0 ..< mesh.vertexData[attribute].len:
-      setValue(mesh.vertexData[attribute], i, transform * getValue[T](mesh.vertexData[attribute], i))
+      setValue(mesh.vertexData[attribute], i, transform * mesh.vertexData[attribute][i, T])
   elif mesh.instanceData.contains(attribute):
     for i in 0 ..< mesh.instanceData[attribute].len:
-      setValue(mesh.instanceData[attribute], i, transform * getValue[T](mesh.vertexData[attribute], i))
+      setValue(mesh.instanceData[attribute], i, transform * mesh.vertexData[attribute][i, T])
   else:
     raise newException(Exception, &"Attribute {attribute} is not defined for mesh {mesh}")
 
 proc applyTransformToVertices*(mesh: var MeshObject, positionAttribute=DEFAULT_POSITION_ATTRIBUTE) =
   for i in 0 ..< mesh.vertexData[positionAttribute].len:
-    setValue(mesh.vertexData[positionAttribute], i, mesh.transform * getValue[Vec3f](mesh.vertexData[positionAttribute], i))
+    setValue(mesh.vertexData[positionAttribute], i, mesh.transform * mesh.vertexData[positionAttribute][i, Vec3f])
   mesh.transform = Unit4
 
 
--- a/semicongine/renderer.nim	Wed Jan 03 11:19:55 2024 +0700
+++ b/semicongine/renderer.nim	Thu Jan 04 21:13:11 2024 +0700
@@ -262,7 +262,7 @@
         for texture in shaderPipeline.samplers:
           scenedata.textures[shaderPipeline.vk][texture.name] = newSeq[VulkanTexture]()
           if scene.shaderGlobals.contains(texture.name):
-            for textureValue in getValues[Texture](scene.shaderGlobals[texture.name])[]:
+            for textureValue in scene.shaderGlobals[texture.name][Texture][]:
               if not uploadedTextures.contains(textureValue):
                 uploadedTextures[textureValue] = renderer.device.uploadTexture(textureValue)
               scenedata.textures[shaderPipeline.vk][texture.name].add uploadedTextures[textureValue]
@@ -271,7 +271,7 @@
             for material in scene.getMaterials(materialType):
               if material.hasMatchingAttribute(texture):
                 foundTexture = true
-                let value = get[Texture](material, texture.name)
+                let value = material[texture.name, Texture][]
                 assert value.len == 1, &"Mesh material attribute '{texture.name}' has texture-array, but only single textures are allowed"
                 if not uploadedTextures.contains(value[0]):
                   uploadedTextures[value[0]] = renderer.device.uploadTexture(value[0])
@@ -378,7 +378,7 @@
               var foundValue = false
               for material in renderer.scenedata[scene].materials[materialType]:
                 if material.hasMatchingAttribute(uniform):
-                  value.appendValues(material.getDataList(uniform.name))
+                  value.appendValues(material[uniform.name])
                   foundValue = true
               assert foundValue, &"Uniform '{uniform.name}' not found in scene shaderGlobals or materials"
             assert (uniform.arrayCount == 0 and value.len == 1) or value.len == uniform.arrayCount, &"Uniform '{uniform.name}' found has wrong length (shader declares {uniform.arrayCount} but shaderGlobals and materials provide {value.len})"
--- a/semicongine/resources/mesh.nim	Wed Jan 03 11:19:55 2024 +0700
+++ b/semicongine/resources/mesh.nim	Thu Jan 04 21:13:11 2024 +0700
@@ -266,14 +266,14 @@
     var tri: seq[int]
     case data.thetype
       of UInt16:
-        for entry in getValues[uint16](data)[]:
+        for entry in data[uint16][]:
           tri.add int(entry)
           if tri.len == 3:
             # FYI gltf uses counter-clockwise indexing
             result[].appendIndicesData(tri[0], tri[1], tri[2])
             tri.setLen(0)
       of UInt32:
-        for entry in getValues[uint32](data)[]:
+        for entry in data[uint32][]:
           tri.add int(entry)
           if tri.len == 3:
             # FYI gltf uses counter-clockwise indexing
--- a/semicongine/scene.nim	Wed Jan 03 11:19:55 2024 +0700
+++ b/semicongine/scene.nim	Thu Jan 04 21:13:11 2024 +0700
@@ -55,10 +55,10 @@
   scene.dirtyShaderGlobals.add name
 
 func getShaderGlobal*[T](scene: Scene, name: string): T =
-  getValues[T](scene.shaderGlobals[name])[0]
+  scene.shaderGlobals[name][T, 0]
 
-func getShaderGlobalArray*[T](scene: Scene, name: string): seq[T] =
-  getValues[T](scene.shaderGlobals[name])
+func getShaderGlobalArray*[T](scene: Scene, name: string): ref seq[T] =
+  scene.shaderGlobals[name][T]
 
 proc setShaderGlobal*[T](scene: var Scene, name: string, value: T) =
   setValues[T](scene.shaderGlobals[name], @[value])