Util: Remove unused JS functions, add min/max(vec), improve remove, add docs.
This commit is contained in:
parent
40b70003ec
commit
29e4735626
|
@ -342,16 +342,18 @@ proc clear_vertices*(self: Mesh) =
|
|||
self.data.num_indices[0] = 0
|
||||
|
||||
proc remove_vertex*(self: Mesh, index: int) =
|
||||
# TODO: This is only valid for points mode
|
||||
if not (index >= 0):
|
||||
return
|
||||
# -1 or undefined
|
||||
let num_indices = self.data.num_indices
|
||||
return # ignore -1
|
||||
assert self.data.num_indices[0] > index, "Invalid index"
|
||||
let stride = self.data.stride
|
||||
# move the last vertex to the one in index
|
||||
let pos0 = num_indices[0] * stride
|
||||
let pos0 = self.data.num_indices[0] * stride
|
||||
let pos1 = index * stride
|
||||
var bytes = self.data.varrays[0].to(int8)
|
||||
bytes.copyWithin(pos1, pos0, pos0 + stride)
|
||||
for i in 0 ..< stride:
|
||||
bytes[pos1+i] = bytes[pos0+i]
|
||||
self.data.num_indices[0] -= 1
|
||||
|
||||
proc ensure_capacity*(self: Mesh, extra_elements: int) =
|
||||
if self.data == nil:
|
||||
|
@ -371,7 +373,7 @@ proc ensure_capacity*(self: Mesh, extra_elements: int) =
|
|||
while fpos >= cap:
|
||||
cap *= 2
|
||||
var va = newArrRef[float32](cap)
|
||||
varray.copy_bytes_to va
|
||||
copyMem(va.toPointer, varray.toPointer, bytelen)
|
||||
self.load_from_va_ia @[va]
|
||||
self.data.num_indices[0] = current_index
|
||||
|
||||
|
@ -381,8 +383,8 @@ proc ensure_capacity*(self: Mesh, extra_elements: int) =
|
|||
# let ilen = self.offsets[self.offsets.len - 1]
|
||||
# let offset = (self.pack_offset or 0) + buffer_offset
|
||||
# try:
|
||||
# let va = makeSeq[float32](data, offset, vlen)
|
||||
# let ia = makeSeq[uint16](data, offset + vlen * 4, ilen)
|
||||
# let va = newSeq[float32](data, offset, vlen)
|
||||
# let ia = newSeq[uint16](data, offset + vlen * 4, ilen)
|
||||
# except Exception as e:
|
||||
# let e = Error(&"Mesh {self.name} is corrupt")
|
||||
# raise e
|
||||
|
@ -518,7 +520,7 @@ proc generate_tangents*(self: MeshData, uv_layer_name, tangent_layer_name: strin
|
|||
for idx in ia.to int32:
|
||||
maxi = max(maxi, idx)
|
||||
# dump (max_len, maxi)
|
||||
var tangents = makeSeq[Vec3](max_len div stride_f.int)
|
||||
var tangents = newSeq[Vec3](max_len div stride_f.int)
|
||||
# for va, ia in zip(self.varrays, self.iarrays):
|
||||
for i in 0 ..< self.varrays.len:
|
||||
let va = self.varrays[i]
|
||||
|
@ -627,7 +629,7 @@ proc debug_print_vertices*(self: Mesh, starts: int = 0, ends: int = 10) =
|
|||
of Short:
|
||||
($cast[ptr array[16, uint16]](varray[offset].addr)[]).split(',')[0 ..< attr.count].join(",") & "]"
|
||||
# of HalfFloat:
|
||||
# let a = makeSeq[uint16](varray.buffer, offset, attr.count)
|
||||
# let a = newSeq[uint16](varray.buffer, offset, attr.count)
|
||||
# @[read_f16(a[0]), read_f16(a[1]), read_f16(a[2])]
|
||||
else: ""
|
||||
echo &"{attr.name} {data}"
|
||||
|
|
110
src/util.nim
110
src/util.nim
|
@ -75,96 +75,55 @@ func remove_scale_skew*[T](m: GMat4[T]): GMat4[T] =
|
|||
result[3,1] = m[3,1]
|
||||
result[3,2] = m[3,2]
|
||||
|
||||
proc remove*[T](s: var seq[T], element: T) =
|
||||
proc remove*[T](s: var seq[T], element: T): bool {.raises:[],discardable.} =
|
||||
## Removes a value from a seq if it exists. Returns whether an item was
|
||||
## removed. Preserves the order of the other elements. If the element is
|
||||
## repeated, only one instance is removed.
|
||||
let index = s.find element
|
||||
if index != -1:
|
||||
s.delete index
|
||||
# TODO: option to warn or break when not present
|
||||
# and a version or an argument to not warn
|
||||
# Since we only remove an existing element, it should never raise,
|
||||
# but we have to use try/except to satisfy raises:[]
|
||||
try: s.delete index
|
||||
except: discard
|
||||
return true
|
||||
|
||||
proc remove_unordered*[T](s: seq[T], element: T) =
|
||||
proc remove_unordered*[T](s: seq[T], element: T): bool {.raises:[],discardable.} =
|
||||
## Removes a value from a seq if it exists. Returns whether an item was
|
||||
## removed. It's quicker than `remove` by moving the last element to the slot
|
||||
## of the removed one. If the element is repeated, only one instance is
|
||||
## removed.
|
||||
let index = s.find element
|
||||
if index != -1:
|
||||
s.del index
|
||||
# Since we only remove an existing element, it should never raise,
|
||||
# but we have to use try/except to satisfy raises:[]
|
||||
try: s.del index
|
||||
except: discard
|
||||
return true
|
||||
|
||||
func align4*[T: SomeInteger](n: T): T = n + ((4-(n and 3)) and 3)
|
||||
func align4*[T: SomeInteger](n: T): T =
|
||||
# Increments the number to the nearest multiplier of 4 if it's not already
|
||||
# aligned.
|
||||
n + ((4-(n and 3)) and 3)
|
||||
|
||||
func align*[T: SomeInteger](n, align: T): T =
|
||||
## Increments the number to the nearest multiplier of the `align` parameter,
|
||||
## if it's not already aligned. `align` must be a power of two.
|
||||
let mask = align - 1
|
||||
assert((align and mask) == 0, "align must be a power of two")
|
||||
return n + ((align-(n and mask)) and mask)
|
||||
|
||||
func bytelen*[T](s: seq[T]): int = s.len * sizeof(T)
|
||||
func bytelen*[T](s: seq[T]): int =
|
||||
## Provides the size of the seq in bytes.
|
||||
s.len * sizeof(T)
|
||||
|
||||
func get_or_default*[T](s: seq[T], i: int, default: T = T.default): T =
|
||||
func getOrDefault*[T](s: seq[T], i: int, default: T = T.default): T =
|
||||
## Returns an element of the seq if the index is within bounds, otherwise it
|
||||
## returns a default value, optionally given as argument.
|
||||
if i >= s.low and i <= s.high:
|
||||
return s[i]
|
||||
return default
|
||||
|
||||
|
||||
when defined(js):
|
||||
import jsffi
|
||||
proc newArrayBufferView(size: uint8): seq[uint8] {.importjs: "(new Uint8Array(#))".}
|
||||
proc newArrayBufferView(size: uint16): seq[uint16] {.importjs: "(new Uint16Array(#))".}
|
||||
proc newArrayBufferView(size: uint32): seq[uint32] {.importjs: "(new Uint32Array(#))".}
|
||||
proc newArrayBufferView(size: int8): seq[int8] {.importjs: "(new Int8Array(#))".}
|
||||
proc newArrayBufferView(size: int16): seq[int16] {.importjs: "(new Int16Array(#))".}
|
||||
proc newArrayBufferView(size: int32): seq[int32] {.importjs: "(new Int32Array(#))".}
|
||||
proc newArrayBufferView(size: float32): seq[float32] {.importjs: "(new Float32Array(#))".}
|
||||
proc newArrayBufferView(size: float64): seq[float64] {.importjs: "(new Float64Array(#))".}
|
||||
template makeSeq*[T](size: int): seq[T] =
|
||||
# incredibly cursed hack, but it works
|
||||
newArrayBufferView(size.tojs.to(typeof T))
|
||||
|
||||
proc as_byte_array*[T](arr: seq[T]): seq[int8] {.importjs: "(new Int8Array((#).buffer))".}
|
||||
proc as_ubyte_array*[T](arr: seq[T]): seq[uint8] {.importjs: "(new Uint8Array((#).buffer))".}
|
||||
proc set*[T](arr, arr2: seq[T]) {.importjs: "((#).set(#))"}
|
||||
template copy_bytes_to*[T](arr, arr2: seq[T]) =
|
||||
arr2.as_byte_array.set arr.as_byte_array
|
||||
proc copyWithin*[T](arr: seq[T], target, start, ends: int) {.importjs: "#.copyWithin(#,#,#)".}
|
||||
|
||||
else:
|
||||
template makeSeq*[T](size: int): seq[T] = newSeq[T](size)
|
||||
template as_byte_array*[T](arr: openArray[T]): ptr UncheckedArray[int8] =
|
||||
cast[ptr UncheckedArray[int8]](addr arr[0])
|
||||
template as_ubyte_array*[T](arr: openArray[T]): ptr UncheckedArray[uint8] =
|
||||
cast[ptr UncheckedArray[uint8]](addr arr[0])
|
||||
template as_byte_array*[T](arr: ArrRef[T]): ArrRef[int8] =
|
||||
arr.to(int8)
|
||||
template as_ubyte_array*[T](arr: ArrRef[T]): ArrRef[uint8] =
|
||||
arr.to(uint8)
|
||||
|
||||
template set*[T](arr, arr2: seq[T]) =
|
||||
for i,v in arr2:
|
||||
arr[i] = v
|
||||
|
||||
template copy_bytes_to*[T](arr, arr2: seq[T]|ArrRef[T]) =
|
||||
let src = arr.as_byte_array
|
||||
let dst = arr2.as_byte_array
|
||||
for i in 0 .. min(arr.byte_len, arr2.byte_len):
|
||||
dst[i] = src[i]
|
||||
|
||||
# TODO: version of arrays with len, that clamps bounds and can use negative indices
|
||||
proc copyWithin*[T](arr: ptr UncheckedArray[T], target, start, ends: int) =
|
||||
let len = ends-start
|
||||
let target_end = target + len
|
||||
if start < target and target < ends:
|
||||
# reverse (#TODO: only the overlapping section?)
|
||||
var i = ends - 1
|
||||
var o = target_end - 1
|
||||
while i != start:
|
||||
arr[o] = arr[i]
|
||||
i -= 1; o -= 1
|
||||
else:
|
||||
var i = start
|
||||
var o = target
|
||||
while i != ends:
|
||||
arr[o] = arr[i]
|
||||
i += 1; o += 1
|
||||
|
||||
template copyWithin*[T](arr: ArrRef[T], target, start, ends: int) =
|
||||
copyWithin(cast[ptr UncheckedArray[T]](arr[0].addr), target, start, ends)
|
||||
|
||||
template rotate_cw*[T](v: GVec3[T]): GVec3[T] = gvec3[T](v.y, -v.x, v.z)
|
||||
|
||||
template rotate_ccw*[T](v: GVec3[T]): GVec3[T] = gvec3[T](-v.y, v.x, v.z)
|
||||
|
@ -243,6 +202,13 @@ template high*[T](x: typedesc[GVec2[T]]): GVec2[T] = gvec2[T](T.high,T.high)
|
|||
template high*[T](x: typedesc[GVec3[T]]): GVec3[T] = gvec3[T](T.high,T.high,T.high)
|
||||
template high*[T](x: typedesc[GVec4[T]]): GVec4[T] = gvec4[T](T.high,T.high,T.high,T.high)
|
||||
|
||||
proc min*[T](v: GVec2[T]): T {.inline.} = min(v.x, v.y)
|
||||
proc min*[T](v: GVec3[T]): T {.inline.} = min(min(v.x, v.y), v.z)
|
||||
proc min*[T](v: GVec4[T]): T {.inline.} = min(min(min(v.x, v.y), v.z), v.w)
|
||||
proc max*[T](v: GVec2[T]): T {.inline.} = max(v.x, v.y)
|
||||
proc max*[T](v: GVec3[T]): T {.inline.} = max(max(v.x, v.y), v.z)
|
||||
proc max*[T](v: GVec4[T]): T {.inline.} = max(max(max(v.x, v.y), v.z), v.w)
|
||||
|
||||
# bounding box operations
|
||||
|
||||
template `&`*[T](a, b: (GVec3[T], GVec3[T])): (GVec3[T], GVec3[T]) =
|
||||
|
|
Loading…
Reference in a new issue