Mesh: Allow creating meshes with any type of vertex array seq, not just float32.

This commit is contained in:
Alberto Torres 2025-03-18 18:37:48 +01:00
parent 2219f8c9ad
commit f45e1757f6
2 changed files with 84 additions and 50 deletions

View file

@ -252,53 +252,13 @@ proc clone*(self: MeshData): MeshData =
d.users = @[]
return d
proc initMesh(self: Mesh, engine: MyouEngine, name: string, scene: Scene = nil,
proc newMesh*[T](engine: MyouEngine, name: string="mesh", scene: Scene = nil,
draw_method: MeshDrawMethod = Triangles,
common_attributes: CommonMeshAttributes = {vertex, color},
layout: AttributeList = @[],
# stride: int32 = layout.stride,
skip_upload: bool = false,
vertex_count: int32 = 0,
vertex_array: seq[float32] = @[],
index_array: seq[uint16] = @[],
pass: int32 = 0,
): Mesh =
discard procCall(self.GameObject.initGameObject(engine, name))
self.otype = TMesh
self.passes = @[0'i32]
self.sort_sign = BackToFront
self.draw_method = draw_method
self.layout = layout
if layout.len == 0:
if vertex in common_attributes:
self.layout.add Attribute(name: "vertex", dtype: Float, count: 3)
if color in common_attributes:
self.layout.add Attribute(name: "vc_color", dtype: UByte, count: 4)
if normal in common_attributes:
self.layout.add Attribute(name: "normal", dtype: Byte, count: 4)
if uv in common_attributes:
self.layout.add Attribute(name: "uv_0", dtype: Float, count: 2)
let stride = self.layout.stride
if vertex_array.len != 0:
var va = newArrRef(vertex_array)
var ia = newArrRef(index_array)
self.skip_upload = skip_upload
self.load_from_va_ia(@[va], @[ia])
elif vertex_count != 0:
self.ensure_capacity(vertex_count)
if scene != nil:
scene.add_object(self, name=name)
return self
proc newMesh*(engine: MyouEngine, name: string="mesh", scene: Scene = nil,
draw_method: MeshDrawMethod = Triangles,
common_attributes: CommonMeshAttributes = {vertex, color},
layout: AttributeList = @[],
# stride: int32 = layout.stride,
skip_upload: bool = false,
vertex_count: int32 = 0,
vertex_array: seq[float32] = @[],
vertex_array: seq[T] = @[],
index_array: seq[uint16] = @[],
pass: int32 = 0,
): Mesh =
@ -320,13 +280,64 @@ proc newMesh*(engine: MyouEngine, name: string="mesh", scene: Scene = nil,
## If you give a vertex array and an index array, they will be used directly
## as GPU buffers. If you only supply the vertex array, indices will
## implicitely be sequential.
# TODO: document pass and skip_upload
new(result)
result.otype = TMesh
let self = new Mesh
self.otype = TMesh
return initMesh(result, engine, name, scene, draw_method, common_attributes, layout,
skip_upload, vertex_count, vertex_array, index_array, pass)
discard procCall(self.GameObject.initGameObject(engine, name))
self.otype = TMesh
self.passes = @[0'i32]
self.sort_sign = BackToFront
self.draw_method = draw_method
self.layout = layout
if layout.len == 0:
if vertex in common_attributes:
self.layout.add Attribute(name: "vertex", dtype: Float, count: 3)
if color in common_attributes:
self.layout.add Attribute(name: "vc_color", dtype: UByte, count: 4)
if normal in common_attributes:
self.layout.add Attribute(name: "normal", dtype: Byte, count: 4)
if uv in common_attributes:
self.layout.add Attribute(name: "uv_0", dtype: Float, count: 2)
let stride = self.layout.stride
if vertex_array.len != 0:
var va = newArrRef(vertex_array).to float32
var ia = newArrRef(index_array)
self.skip_upload = skip_upload
self.load_from_va_ia(@[va], @[ia])
elif vertex_count != 0:
self.ensure_capacity(vertex_count)
if scene != nil:
scene.add_object(self, name=name)
return self
proc newMesh*(engine: MyouEngine, name: string="mesh", scene: Scene = nil,
draw_method: MeshDrawMethod = Triangles,
common_attributes: CommonMeshAttributes = {vertex, color},
layout: AttributeList = @[],
skip_upload: bool = false,
vertex_count: int32 = 0,
pass: int32 = 0,
): Mesh =
## Create a new Mesh object. If you supply `scene` it will be added to that
## scene.
##
## The most common draw methods are `Triangles` (the default), `Points`,
## `Lines`, and `TriangleStrip` (for `add_polygonal_line()`).
##
## If you supply a layout, it will be used. Otherwise a layout will be
## created from `common_attributes`, which by default is `{vertex, color}`.
## The available common attributes are `{vertex, color, normal, uv}` and they
## will be added in that order.
##
## You can give a `vertex_count` to allocate a mesh with capacity for that
## amount of vertices, but you can always resize it later. Meant to be used
## with `add_vertex()` and `add_polygonal_line`
newMesh[float32](engine, name, scene, draw_method, common_attributes, layout,
skip_upload, vertex_count, @[], @[], pass)
proc add_vertex*(self: Mesh, x, y, z: float32, r, g, b, a: uint8): int {.discardable.} =
## Tries to add a vertex to the mesh with the specified position and color.

View file

@ -410,14 +410,13 @@ proc new_gameobject*(self: Scene, name: string): GameObject =
## Create a GameObject and add it to the scene.
return self.engine.new_gameobject(name=name, scene=self)
proc new_mesh*(self: Scene, name: string,
proc new_mesh*[T](self: Scene, name: string,
draw_method: MeshDrawMethod = Triangles,
common_attributes: CommonMeshAttributes = {vertex, color},
layout: AttributeList = @[],
# stride: int32 = layout.stride,
skip_upload: bool = false,
vertex_count: int32 = 0,
vertex_array: seq[float32] = @[],
vertex_array: seq[T] = @[],
index_array: seq[uint16] = @[],
pass: int32 = 0,
): Mesh =
@ -441,6 +440,30 @@ proc new_mesh*(self: Scene, name: string,
self.engine.new_mesh(name, self, draw_method, common_attributes, layout,
skip_upload, vertex_count, vertex_array, index_array, pass)
proc new_mesh*(self: Scene, name: string,
draw_method: MeshDrawMethod = Triangles,
common_attributes: CommonMeshAttributes = {vertex, color},
layout: AttributeList = @[],
skip_upload: bool = false,
vertex_count: int32 = 0,
pass: int32 = 0,
): Mesh =
## Create a new Mesh object and add it to this scene.
##
## The most common draw methods are `Triangles` (the default), `Points`,
## `Lines`, and `TriangleStrip` (for `add_polygonal_line()`).
##
## If you supply a layout, it will be used. Otherwise a layout will be
## created from `common_attributes`, which by default is `{vertex, color}`.
## The available common attributes are `{vertex, color, normal, uv}` and they
## will be added in that order.
##
## You can give a `vertex_count` to allocate a mesh with capacity for that
## amount of vertices, but you can always resize it later. Meant to be used
## with `add_vertex()` and `add_polygonal_line`
new_mesh[float32](self.engine, name, self, draw_method, common_attributes, layout,
skip_upload, vertex_count, @[], @[], pass)
proc newCamera*(self: Scene, name: string="camera",
near_plane: float32 = 0.1,
far_plane: float32 = 10000,