@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.
- package/CHANGELOG.md +7 -2
- package/bundle.js +9 -9
- package/examples/07-sdl/main.js +0 -1
- package/examples/07-sdl/package.json +2 -2
- package/examples/09-sdl-polar-meters/package.json +3 -3
- package/package.json +8 -3
- package/packages/box-intersect/index.js +138 -0
- package/packages/box-intersect/lib/brute.js +144 -0
- package/packages/box-intersect/lib/intersect.js +494 -0
- package/packages/box-intersect/lib/median.js +142 -0
- package/packages/box-intersect/lib/partition.js +20 -0
- package/packages/box-intersect/lib/sort.js +236 -0
- package/packages/box-intersect/lib/sweep.js +434 -0
- package/packages/box-intersect/package.json +24 -0
- package/packages/clean-pslg/clean-pslg.js +381 -0
- package/packages/clean-pslg/lib/rat-seg-intersect.js +42 -0
- package/packages/clean-pslg/package.json +29 -0
- package/packages/poly-to-pslg/package.json +15 -0
- package/packages/poly-to-pslg/poly-to-pslg.js +51 -0
- package/packages/typedarray-pool/package.json +17 -0
- package/packages/typedarray-pool/pool.js +225 -0
- package/src/primitives/primitives.js +13 -3
- package/src/primitives/public-api.js +44 -0
|
@@ -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
|
-
|
|
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.
|
|
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) {
|