changeset 231:3a9ab4a367ca

add: first try to load material colors
author Sam <sam@basx.dev>
date Thu, 18 May 2023 00:57:49 +0700
parents 027f6ff06585
children 408d68fbcbee
files src/semicongine/core/gpu_data.nim src/semicongine/resources/audio.nim src/semicongine/resources/mesh.nim
diffstat 3 files changed, 29 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/semicongine/core/gpu_data.nim	Tue May 16 16:08:06 2023 +0700
+++ b/src/semicongine/core/gpu_data.nim	Thu May 18 00:57:49 2023 +0700
@@ -1,4 +1,3 @@
-import std/typetraits
 import std/strformat
 import std/tables
 
@@ -708,7 +707,7 @@
   else: {.error: "Virtual datatype has no value" .}
 
 func appendValues*[T: GPUType|int|uint|float](value: var DataList, data: seq[T]) =
-  value.len += data.len
+  value.len += uint32(data.len)
   when T is float32: value.float32[].add data
   elif T is float64: value.float64[].add data
   elif T is int8: value.int8[].add data
--- a/src/semicongine/resources/audio.nim	Tue May 16 16:08:06 2023 +0700
+++ b/src/semicongine/resources/audio.nim	Thu May 18 00:57:49 2023 +0700
@@ -1,6 +1,5 @@
 import std/streams
 import std/endians
-import std/math
 
 import ../core/audiotypes
 
@@ -23,12 +22,6 @@
     sampleRate: uint32
     channels: uint32
 
-func changeEndian(value: int16): int16 =
-
-  var bytes: array[2, uint8] = cast[array[2, uint8]](value)
-  swap(bytes[0], bytes[1])
-  result = cast[int16](bytes)
-
 proc readSample(stream: Stream, encoding: Encoding, channels: int): Sample =
   result[0] = stream.readint16()
   swapEndian16(addr result[0], addr result[0])
--- a/src/semicongine/resources/mesh.nim	Tue May 16 16:08:06 2023 +0700
+++ b/src/semicongine/resources/mesh.nim	Thu May 18 00:57:49 2023 +0700
@@ -1,7 +1,6 @@
 import std/json
 import std/tables
 import std/sequtils
-import std/strutils
 import std/strformat
 import std/streams
 
@@ -95,16 +94,20 @@
     copyMem(dstPointer, addr mainBuffer[bufferOffset], length)
 
 proc addPrimitive(mesh: var Mesh, root: JsonNode, primitiveNode: JsonNode, mainBuffer: var seq[uint8]) =
-  # TODO: material
   if primitiveNode.hasKey("mode") and primitiveNode["mode"].getInt() != 4:
     raise newException(Exception, "Currently only TRIANGLE mode is supported for geometry mode")
 
+  var vertexCount = 0'u32
   for attribute, accessor in primitiveNode["attributes"].pairs:
     let data = root.getAccessorData(root["accessors"][accessor.getInt()], mainBuffer)
     mesh.appendMeshData(attribute, data)
+    vertexCount = data.len
     if attribute == "POSITION":
       transform[Vec3f](mesh, "POSITION", scale3d(1'f32, -1'f32, 1'f32))
 
+  let materialId = uint8(primitiveNode["material"].getInt())
+  mesh.appendMeshData("material", newSeqWith[uint8](int(vertexCount), materialId))
+
   if primitiveNode.hasKey("indices"):
     assert mesh.indexType != None
     let data = root.getAccessorData(root["accessors"][primitiveNode["indices"].getInt()], mainBuffer)
@@ -150,6 +153,7 @@
   # prepare mesh attributes
   for attribute, accessor in meshNode["primitives"][0]["attributes"].pairs:
     result.setMeshData(attribute, newDataList(thetype=root["accessors"][accessor.getInt()].getGPUType()))
+  result.setMeshData("material", newDataList(thetype=getDataType[uint8]()))
 
   # add all mesh data
   for primitive in meshNode["primitives"]:
@@ -206,6 +210,24 @@
 
   newScene(scenenode["name"].getStr(), rootEntity)
 
+proc getMaterialsData(root: JsonNode): seq[Vec4f] =
+  for materialNode in root["materials"]:
+    let pbr = materialNode["pbrMetallicRoughness"]
+    var baseColor = newVec4f(0, 0, 0, 1)
+    baseColor[0] = pbr["baseColorFactor"][0].getFloat() * 255
+    baseColor[1] = pbr["baseColorFactor"][1].getFloat() * 255
+    baseColor[2] = pbr["baseColorFactor"][2].getFloat() * 255
+    baseColor[3] = pbr["baseColorFactor"][3].getFloat() * 255
+    result.add baseColor
+    # TODO: pbr["baseColorTexture"]
+    # TODO: pbr["metallicRoughnessTexture"]
+    # TODO: pbr["metallicFactor"]
+    # TODO: pbr["roughnessFactor"]
+    # TODO: materialNode["normalTexture"]
+    # TODO: materialNode["occlusionTexture"]
+    # TODO: materialNode["emissiveTexture"]
+    # TODO: materialNode["emissiveFactor"]
+
 proc readglTF*(stream: Stream): seq[Scene] =
   var
     header: glTFHeader
@@ -234,6 +256,8 @@
   assert 0 <= bufferLenDiff <= 3 # binary buffer may be aligned to 4 bytes
 
   for scene in data.structuredContent["scenes"]:
-    result.add data.structuredContent.loadScene(scene, data.binaryBufferData)
+    var scene = data.structuredContent.loadScene(scene, data.binaryBufferData)
+    echo getMaterialsData(data.structuredContent)
+    scene.addShaderGlobalArray("material_colors", getMaterialsData(data.structuredContent))
+    result.add scene
 
-  debugecho data.structuredContent.pretty()