@footgun/cobalt 0.3.3 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,225 @@
1
+ 'use strict'
2
+
3
+ var bits = require('bit-twiddle')
4
+ var dup = require('dup')
5
+
6
+ //Legacy pool support
7
+ if(!globalThis.__TYPEDARRAY_POOL) {
8
+ globalThis.__TYPEDARRAY_POOL = {
9
+ UINT8 : dup([32, 0])
10
+ , UINT16 : dup([32, 0])
11
+ , UINT32 : dup([32, 0])
12
+ , BIGUINT64 : dup([32, 0])
13
+ , INT8 : dup([32, 0])
14
+ , INT16 : dup([32, 0])
15
+ , INT32 : dup([32, 0])
16
+ , BIGINT64 : dup([32, 0])
17
+ , FLOAT : dup([32, 0])
18
+ , DOUBLE : dup([32, 0])
19
+ , DATA : dup([32, 0])
20
+ , UINT8C : dup([32, 0])
21
+ }
22
+ }
23
+
24
+ var hasUint8C = (typeof Uint8ClampedArray) !== 'undefined'
25
+ var hasBigUint64 = (typeof BigUint64Array) !== 'undefined'
26
+ var hasBigInt64 = (typeof BigInt64Array) !== 'undefined'
27
+ var POOL = globalThis.__TYPEDARRAY_POOL
28
+
29
+ //Upgrade pool
30
+ if(!POOL.UINT8C) {
31
+ POOL.UINT8C = dup([32, 0])
32
+ }
33
+ if(!POOL.BIGUINT64) {
34
+ POOL.BIGUINT64 = dup([32, 0])
35
+ }
36
+ if(!POOL.BIGINT64) {
37
+ POOL.BIGINT64 = dup([32, 0])
38
+ }
39
+
40
+ //New technique: Only allocate from ArrayBufferView
41
+ var DATA = POOL.DATA
42
+
43
+ exports.free = function free(array) {
44
+
45
+ if(Object.prototype.toString.call(array) !== '[object ArrayBuffer]') {
46
+ array = array.buffer
47
+ }
48
+ if(!array) {
49
+ return
50
+ }
51
+ var n = array.length || array.byteLength
52
+ var log_n = bits.log2(n)|0
53
+ DATA[log_n].push(array)
54
+ }
55
+
56
+ function freeArrayBuffer(buffer) {
57
+ if(!buffer) {
58
+ return
59
+ }
60
+ var n = buffer.length || buffer.byteLength
61
+ var log_n = bits.log2(n)
62
+ DATA[log_n].push(buffer)
63
+ }
64
+
65
+ function freeTypedArray(array) {
66
+ freeArrayBuffer(array.buffer)
67
+ }
68
+
69
+ exports.freeUint8 =
70
+ exports.freeUint16 =
71
+ exports.freeUint32 =
72
+ exports.freeBigUint64 =
73
+ exports.freeInt8 =
74
+ exports.freeInt16 =
75
+ exports.freeInt32 =
76
+ exports.freeBigInt64 =
77
+ exports.freeFloat32 =
78
+ exports.freeFloat =
79
+ exports.freeFloat64 =
80
+ exports.freeDouble =
81
+ exports.freeUint8Clamped =
82
+ exports.freeDataView = freeTypedArray
83
+
84
+ exports.freeArrayBuffer = freeArrayBuffer
85
+
86
+ exports.malloc = function malloc(n, dtype) {
87
+ if(dtype === undefined || dtype === 'arraybuffer') {
88
+ return mallocArrayBuffer(n)
89
+ } else {
90
+ switch(dtype) {
91
+ case 'uint8':
92
+ return mallocUint8(n)
93
+ case 'uint16':
94
+ return mallocUint16(n)
95
+ case 'uint32':
96
+ return mallocUint32(n)
97
+ case 'int8':
98
+ return mallocInt8(n)
99
+ case 'int16':
100
+ return mallocInt16(n)
101
+ case 'int32':
102
+ return mallocInt32(n)
103
+ case 'float':
104
+ case 'float32':
105
+ return mallocFloat(n)
106
+ case 'double':
107
+ case 'float64':
108
+ return mallocDouble(n)
109
+ case 'uint8_clamped':
110
+ return mallocUint8Clamped(n)
111
+ case 'bigint64':
112
+ return mallocBigInt64(n)
113
+ case 'biguint64':
114
+ return mallocBigUint64(n)
115
+ case 'data':
116
+ case 'dataview':
117
+ return mallocDataView(n)
118
+
119
+ default:
120
+ return null
121
+ }
122
+ }
123
+ return null
124
+ }
125
+
126
+ function mallocArrayBuffer(n) {
127
+ var n = bits.nextPow2(n)
128
+ var log_n = bits.log2(n)
129
+ var d = DATA[log_n]
130
+ if(d.length > 0) {
131
+ return d.pop()
132
+ }
133
+ return new ArrayBuffer(n)
134
+ }
135
+ exports.mallocArrayBuffer = mallocArrayBuffer
136
+
137
+ function mallocUint8(n) {
138
+ return new Uint8Array(mallocArrayBuffer(n), 0, n)
139
+ }
140
+ exports.mallocUint8 = mallocUint8
141
+
142
+ function mallocUint16(n) {
143
+ return new Uint16Array(mallocArrayBuffer(2*n), 0, n)
144
+ }
145
+ exports.mallocUint16 = mallocUint16
146
+
147
+ function mallocUint32(n) {
148
+ return new Uint32Array(mallocArrayBuffer(4*n), 0, n)
149
+ }
150
+ exports.mallocUint32 = mallocUint32
151
+
152
+ function mallocInt8(n) {
153
+ return new Int8Array(mallocArrayBuffer(n), 0, n)
154
+ }
155
+ exports.mallocInt8 = mallocInt8
156
+
157
+ function mallocInt16(n) {
158
+ return new Int16Array(mallocArrayBuffer(2*n), 0, n)
159
+ }
160
+ exports.mallocInt16 = mallocInt16
161
+
162
+ function mallocInt32(n) {
163
+ return new Int32Array(mallocArrayBuffer(4*n), 0, n)
164
+ }
165
+ exports.mallocInt32 = mallocInt32
166
+
167
+ function mallocFloat(n) {
168
+ return new Float32Array(mallocArrayBuffer(4*n), 0, n)
169
+ }
170
+ exports.mallocFloat32 = exports.mallocFloat = mallocFloat
171
+
172
+ function mallocDouble(n) {
173
+ return new Float64Array(mallocArrayBuffer(8*n), 0, n)
174
+ }
175
+ exports.mallocFloat64 = exports.mallocDouble = mallocDouble
176
+
177
+ function mallocUint8Clamped(n) {
178
+ if(hasUint8C) {
179
+ return new Uint8ClampedArray(mallocArrayBuffer(n), 0, n)
180
+ } else {
181
+ return mallocUint8(n)
182
+ }
183
+ }
184
+ exports.mallocUint8Clamped = mallocUint8Clamped
185
+
186
+ function mallocBigUint64(n) {
187
+ if(hasBigUint64) {
188
+ return new BigUint64Array(mallocArrayBuffer(8*n), 0, n)
189
+ } else {
190
+ return null;
191
+ }
192
+ }
193
+ exports.mallocBigUint64 = mallocBigUint64
194
+
195
+ function mallocBigInt64(n) {
196
+ if (hasBigInt64) {
197
+ return new BigInt64Array(mallocArrayBuffer(8*n), 0, n)
198
+ } else {
199
+ return null;
200
+ }
201
+ }
202
+ exports.mallocBigInt64 = mallocBigInt64
203
+
204
+ function mallocDataView(n) {
205
+ return new DataView(mallocArrayBuffer(n), 0, n)
206
+ }
207
+ exports.mallocDataView = mallocDataView
208
+
209
+
210
+ exports.clearCache = function clearCache() {
211
+ for(var i=0; i<32; ++i) {
212
+ POOL.UINT8[i].length = 0
213
+ POOL.UINT16[i].length = 0
214
+ POOL.UINT32[i].length = 0
215
+ POOL.INT8[i].length = 0
216
+ POOL.INT16[i].length = 0
217
+ POOL.INT32[i].length = 0
218
+ POOL.FLOAT[i].length = 0
219
+ POOL.DOUBLE[i].length = 0
220
+ POOL.BIGUINT64[i].length = 0
221
+ POOL.BIGINT64[i].length = 0
222
+ POOL.UINT8C[i].length = 0
223
+ DATA[i].length = 0
224
+ }
225
+ }
@@ -57,7 +57,8 @@ async function init (cobalt, node) {
57
57
  // Define vertices and indices for your line represented as two triangles (a rectangle)
58
58
  // For example, this could represent a line segment from (10, 10) to (100, 10) with a thickness of 10 units
59
59
  // Updated vertices in normalized device coordinates (NDC)
60
- const vertices = new Float32Array(300000)
60
+
61
+ const vertices = new Float32Array(1024)
61
62
 
62
63
  const vertexBuffer = device.createBuffer({
63
64
  size: vertices.byteLength,
@@ -65,10 +66,10 @@ async function init (cobalt, node) {
65
66
  //mappedAtCreation: true,
66
67
  })
67
68
 
68
-
69
69
  //new Float32Array(vertexBuffer.getMappedRange()).set(vertices);
70
70
  //vertexBuffer.unmap()
71
71
 
72
+
72
73
  const uniformBuffer = device.createBuffer({
73
74
  size: 64 * 2, // 4x4 matrix with 4 bytes per float32, times 2 matrices (view, projection)
74
75
  usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
@@ -186,9 +187,18 @@ function draw (cobalt, node, commandEncoder) {
186
187
  node.data.dirty = false
187
188
  const stride = 6 * Float32Array.BYTES_PER_ELEMENT // 2 floats per vertex position + 4 floats per vertex color
188
189
 
190
+ // if node.data.vertices has been re-sized, re-create the buffer
191
+ if (node.data.vertices.buffer.byteLength > node.data.vertexBuffer.size) {
192
+ node.data.vertexBuffer.destroy()
193
+ node.data.vertexBuffer = device.createBuffer({
194
+ size: node.data.vertices.byteLength,
195
+ usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
196
+ })
197
+ }
198
+
189
199
  let byteCount = node.data.vertexCount * stride
190
200
  if (byteCount > node.data.vertexBuffer.size) {
191
- console.warn('too many primitives, bailing')
201
+ console.error('too many primitives, bailing')
192
202
  return
193
203
  }
194
204
 
@@ -47,6 +47,12 @@ export default {
47
47
 
48
48
  let i = node.data.vertexCount * 6 // 2 floats position + 4 floats color per vertex
49
49
 
50
+
51
+ const currentElementCount = node.data.vertexCount * 6
52
+ const floatsToAdd = triangles.length * 3 * 6
53
+ node.data.vertices = handleArrayResize(Float32Array, node.data.vertices, currentElementCount, floatsToAdd)
54
+
55
+
50
56
  const pos = vec2.create()
51
57
 
52
58
  for (const tri of triangles) {
@@ -123,6 +129,11 @@ export default {
123
129
  // angle between each segment
124
130
  const deltaAngle = 2 * Math.PI / numSegments
125
131
 
132
+ const currentElementCount = node.data.vertexCount * 6
133
+ const floatsToAdd = numSegments * 3 * 6
134
+ node.data.vertices = handleArrayResize(Float32Array, node.data.vertices, currentElementCount, floatsToAdd)
135
+
136
+
126
137
  const m = node.data.transforms.at(-1)
127
138
 
128
139
  // Generate points for the ellipsoid
@@ -218,6 +229,12 @@ export default {
218
229
  const bottomLeft = vec2.transformMat3([ x - halfWidth, y + halfHeight ], m)
219
230
  const bottomRight = vec2.transformMat3([ x + halfWidth, y + halfHeight ], m)
220
231
 
232
+
233
+ const currentElementCount = node.data.vertexCount * 6
234
+ const floatsToAdd = 6 * 6
235
+ node.data.vertices = handleArrayResize(Float32Array, node.data.vertices, currentElementCount, floatsToAdd)
236
+
237
+
221
238
  let i = node.data.vertexCount * 6 // 2 floats position + 4 floats color per vertex
222
239
 
223
240
 
@@ -314,6 +331,11 @@ function line (cobalt, node, start, end, color, lineWidth=1) {
314
331
 
315
332
  let i = node.data.vertexCount * 6 // 2 floats position + 4 floats color per vertex
316
333
 
334
+
335
+ const currentElementCount = node.data.vertexCount * 6
336
+ const floatsToAdd = 6 * 6
337
+ node.data.vertices = handleArrayResize(Float32Array, node.data.vertices, currentElementCount, floatsToAdd)
338
+
317
339
  // triangle 1
318
340
  // pt 1
319
341
  node.data.vertices[i + 0] = start[0] + perp[0] * halfLineWidth
@@ -383,6 +405,28 @@ function line (cobalt, node, start, end, color, lineWidth=1) {
383
405
  }
384
406
 
385
407
 
408
+ // if the new elements won't fit in the existing vertices array, resize it
409
+ // @param ArrayType ArrayType one of the TypedArray types (Float32Array, Uint8Array, etc.)
410
+ // @param TypedArray arr
411
+ function handleArrayResize (ArrayType, arr, currentElementCount, elementsToAdd) {
412
+ // if the new vertices fit in the existing vertices array bail
413
+ if ((currentElementCount + elementsToAdd) <= arr.length)
414
+ return arr
415
+
416
+ // attempt to double the existing array size when we need more capacity
417
+ const newSize = arr.length * 2
418
+
419
+ const MAX_LENGTH = 16 * 1024 * 1024 / arr.BYTES_PER_ELEMENT
420
+
421
+ if (newSize > MAX_LENGTH)
422
+ throw new Error('vertices exceed max array size')
423
+
424
+ const newArray = new ArrayType(newSize)
425
+ newArray.set(arr)
426
+ return newArray
427
+ }
428
+
429
+
386
430
  // return component of vector perpendicular to a unit basis vector
387
431
  // (IMPORTANT NOTE: assumes "basis" has unit magnitude (length==1))
388
432
  function perpendicularComponent (inp) {