poppygl 0.0.2 → 0.0.4
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/dist/index.js +92 -41
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -10,14 +10,23 @@ function computeWorldAABB(drawCalls) {
|
|
|
10
10
|
for (const dc of drawCalls) {
|
|
11
11
|
const { positions, model } = dc;
|
|
12
12
|
for (let i = 0; i < positions.length; i += 3) {
|
|
13
|
-
vec4.set(
|
|
13
|
+
vec4.set(
|
|
14
|
+
tmp,
|
|
15
|
+
positions[i],
|
|
16
|
+
positions[i + 1],
|
|
17
|
+
positions[i + 2],
|
|
18
|
+
1
|
|
19
|
+
);
|
|
14
20
|
vec4.transformMat4(tmp, tmp, model);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
const x = tmp[0];
|
|
22
|
+
const y = tmp[1];
|
|
23
|
+
const z = tmp[2];
|
|
24
|
+
min[0] = Math.min(min[0], x);
|
|
25
|
+
min[1] = Math.min(min[1], y);
|
|
26
|
+
min[2] = Math.min(min[2], z);
|
|
27
|
+
max[0] = Math.max(max[0], x);
|
|
28
|
+
max[1] = Math.max(max[1], y);
|
|
29
|
+
max[2] = Math.max(max[2], z);
|
|
21
30
|
}
|
|
22
31
|
}
|
|
23
32
|
return { min, max };
|
|
@@ -128,20 +137,31 @@ function computeSmoothNormals(positions, indices) {
|
|
|
128
137
|
positions[i2 * 3 + 1],
|
|
129
138
|
positions[i2 * 3 + 2]
|
|
130
139
|
];
|
|
131
|
-
const v10 = [
|
|
132
|
-
|
|
140
|
+
const v10 = [
|
|
141
|
+
p1[0] - p0[0],
|
|
142
|
+
p1[1] - p0[1],
|
|
143
|
+
p1[2] - p0[2]
|
|
144
|
+
];
|
|
145
|
+
const v20 = [
|
|
146
|
+
p2[0] - p0[0],
|
|
147
|
+
p2[1] - p0[1],
|
|
148
|
+
p2[2] - p0[2]
|
|
149
|
+
];
|
|
133
150
|
const nx = v10[1] * v20[2] - v10[2] * v20[1];
|
|
134
151
|
const ny = v10[2] * v20[0] - v10[0] * v20[2];
|
|
135
152
|
const nz = v10[0] * v20[1] - v10[1] * v20[0];
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
normals[
|
|
140
|
-
normals[
|
|
141
|
-
normals[
|
|
142
|
-
normals[
|
|
143
|
-
normals[
|
|
144
|
-
normals[
|
|
153
|
+
const base0 = i0 * 3;
|
|
154
|
+
const base1 = i1 * 3;
|
|
155
|
+
const base2 = i2 * 3;
|
|
156
|
+
normals[base0 + 0] = normals[base0 + 0] + nx;
|
|
157
|
+
normals[base0 + 1] = normals[base0 + 1] + ny;
|
|
158
|
+
normals[base0 + 2] = normals[base0 + 2] + nz;
|
|
159
|
+
normals[base1 + 0] = normals[base1 + 0] + nx;
|
|
160
|
+
normals[base1 + 1] = normals[base1 + 1] + ny;
|
|
161
|
+
normals[base1 + 2] = normals[base1 + 2] + nz;
|
|
162
|
+
normals[base2 + 0] = normals[base2 + 0] + nx;
|
|
163
|
+
normals[base2 + 1] = normals[base2 + 1] + ny;
|
|
164
|
+
normals[base2 + 2] = normals[base2 + 2] + nz;
|
|
145
165
|
}
|
|
146
166
|
for (let i = 0; i < vertexCount; i++) {
|
|
147
167
|
const nx = normals[i * 3 + 0];
|
|
@@ -218,11 +238,14 @@ var SoftwareRenderer = class {
|
|
|
218
238
|
];
|
|
219
239
|
}
|
|
220
240
|
perspInterp(attrs, invWs, lambdas) {
|
|
221
|
-
const
|
|
222
|
-
const
|
|
241
|
+
const [lambda0, lambda1, lambda2] = lambdas;
|
|
242
|
+
const [invW0, invW1, invW2] = invWs;
|
|
243
|
+
const [attr0, attr1, attr2] = attrs;
|
|
244
|
+
const denom = lambda0 * invW0 + lambda1 * invW1 + lambda2 * invW2;
|
|
245
|
+
const n = attr0.length;
|
|
223
246
|
const out = new Array(n).fill(0);
|
|
224
247
|
for (let j = 0; j < n; j++) {
|
|
225
|
-
out[j] = (
|
|
248
|
+
out[j] = (lambda0 * attr0[j] * invW0 + lambda1 * attr1[j] * invW1 + lambda2 * attr2[j] * invW2) / denom;
|
|
226
249
|
}
|
|
227
250
|
return out;
|
|
228
251
|
}
|
|
@@ -276,9 +299,9 @@ var SoftwareRenderer = class {
|
|
|
276
299
|
vWorldN[i] = [nw[0], nw[1], nw[2]];
|
|
277
300
|
}
|
|
278
301
|
for (let i = 0; i < idx.length; i += 3) {
|
|
279
|
-
const i0 = idx[i + 0]
|
|
280
|
-
const i1 = idx[i + 1]
|
|
281
|
-
const i2 = idx[i + 2]
|
|
302
|
+
const i0 = idx[i + 0];
|
|
303
|
+
const i1 = idx[i + 1];
|
|
304
|
+
const i2 = idx[i + 2];
|
|
282
305
|
if (!(isFinite(vInvW[i0]) && isFinite(vInvW[i1]) && isFinite(vInvW[i2])))
|
|
283
306
|
continue;
|
|
284
307
|
const v0 = vScreen[i0];
|
|
@@ -291,9 +314,21 @@ var SoftwareRenderer = class {
|
|
|
291
314
|
let maxX = Math.min(this.width - 1, Math.max(v0[0], v1[0], v2[0]) | 0);
|
|
292
315
|
let minY = Math.max(0, Math.min(v0[1], v1[1], v2[1]) | 0);
|
|
293
316
|
let maxY = Math.min(this.height - 1, Math.max(v0[1], v1[1], v2[1]) | 0);
|
|
294
|
-
const invW = [
|
|
295
|
-
|
|
296
|
-
|
|
317
|
+
const invW = [
|
|
318
|
+
vInvW[i0],
|
|
319
|
+
vInvW[i1],
|
|
320
|
+
vInvW[i2]
|
|
321
|
+
];
|
|
322
|
+
const ndcZ = [
|
|
323
|
+
vNDCz[i0],
|
|
324
|
+
vNDCz[i1],
|
|
325
|
+
vNDCz[i2]
|
|
326
|
+
];
|
|
327
|
+
const nws = [
|
|
328
|
+
vWorldN[i0],
|
|
329
|
+
vWorldN[i1],
|
|
330
|
+
vWorldN[i2]
|
|
331
|
+
];
|
|
297
332
|
const uv = uvs ? [
|
|
298
333
|
[uvs[i0 * 2 + 0], uvs[i0 * 2 + 1]],
|
|
299
334
|
[uvs[i1 * 2 + 0], uvs[i1 * 2 + 1]],
|
|
@@ -313,8 +348,9 @@ var SoftwareRenderer = class {
|
|
|
313
348
|
const zndc = l0 * ndcZ[0] + l1 * ndcZ[1] + l2 * ndcZ[2];
|
|
314
349
|
const z01 = zndc * 0.5 + 0.5;
|
|
315
350
|
const di = y * this.width + x;
|
|
316
|
-
|
|
317
|
-
|
|
351
|
+
const depth = this.depth;
|
|
352
|
+
if (z01 >= depth[di]) continue;
|
|
353
|
+
depth[di] = z01;
|
|
318
354
|
let baseColor = [
|
|
319
355
|
material.baseColorFactor[0],
|
|
320
356
|
material.baseColorFactor[1],
|
|
@@ -330,9 +366,13 @@ var SoftwareRenderer = class {
|
|
|
330
366
|
);
|
|
331
367
|
baseColor = mulColor(baseColor, texel);
|
|
332
368
|
}
|
|
333
|
-
const
|
|
334
|
-
const nlen = Math.hypot(
|
|
335
|
-
const nrm = [
|
|
369
|
+
const [np0, np1, np2] = this.perspInterp(nws, invW, [l0, l1, l2]);
|
|
370
|
+
const nlen = Math.hypot(np0, np1, np2) || 1;
|
|
371
|
+
const nrm = [
|
|
372
|
+
np0 / nlen,
|
|
373
|
+
np1 / nlen,
|
|
374
|
+
np2 / nlen
|
|
375
|
+
];
|
|
336
376
|
const lightDir = light.dir ?? DEFAULT_LIGHT_DIR;
|
|
337
377
|
const ambient = clamp(
|
|
338
378
|
light.ambient ?? DEFAULT_RENDER_OPTIONS.ambient,
|
|
@@ -467,6 +507,8 @@ function getBufferViewSlice(ctx, bufferViewIndex, byteOffset) {
|
|
|
467
507
|
const bufferView = gltf.bufferViews?.[bufferViewIndex];
|
|
468
508
|
if (!bufferView)
|
|
469
509
|
throw new Error(`Invalid bufferView index ${bufferViewIndex}`);
|
|
510
|
+
if (typeof bufferView.buffer !== "number")
|
|
511
|
+
throw new Error(`bufferView ${bufferViewIndex} missing buffer reference`);
|
|
470
512
|
const bufferIndex = bufferView.buffer;
|
|
471
513
|
const buffer = buffers[bufferIndex];
|
|
472
514
|
if (!buffer) throw new Error(`Missing buffer at index ${bufferIndex}`);
|
|
@@ -500,6 +542,8 @@ function readAccessorAsFloat32(ctx, accessorIndex) {
|
|
|
500
542
|
`Unsupported accessor componentType ${accessor.componentType}`
|
|
501
543
|
);
|
|
502
544
|
const byteOffset = accessor.byteOffset ?? 0;
|
|
545
|
+
if (typeof accessor.bufferView !== "number")
|
|
546
|
+
throw new Error(`Accessor ${accessorIndex} missing bufferView`);
|
|
503
547
|
const {
|
|
504
548
|
array: src,
|
|
505
549
|
stride: bufferViewStride,
|
|
@@ -574,6 +618,8 @@ function readIndices(ctx, accessorIndex) {
|
|
|
574
618
|
throw new Error("Index componentType must be UNSIGNED_BYTE/SHORT/INT");
|
|
575
619
|
}
|
|
576
620
|
const byteOffset = accessor.byteOffset ?? 0;
|
|
621
|
+
if (typeof accessor.bufferView !== "number")
|
|
622
|
+
throw new Error(`Index accessor ${accessorIndex} missing bufferView`);
|
|
577
623
|
const {
|
|
578
624
|
array: src,
|
|
579
625
|
stride: bufferViewStride,
|
|
@@ -630,9 +676,11 @@ function getMaterial(gltf, textures, images, materialIndex) {
|
|
|
630
676
|
const factor = pbr.baseColorFactor || [1, 1, 1, 1];
|
|
631
677
|
let texImg = null;
|
|
632
678
|
if (pbr.baseColorTexture && Number.isInteger(pbr.baseColorTexture.index)) {
|
|
633
|
-
const
|
|
679
|
+
const texIndex = pbr.baseColorTexture.index;
|
|
680
|
+
const tex = textures[texIndex];
|
|
634
681
|
if (tex && Number.isInteger(tex.source)) {
|
|
635
|
-
|
|
682
|
+
const imageIndex = tex.source;
|
|
683
|
+
texImg = images[imageIndex] || null;
|
|
636
684
|
}
|
|
637
685
|
}
|
|
638
686
|
return { baseColorFactor: factor, baseColorTexture: texImg };
|
|
@@ -694,8 +742,8 @@ function createSceneFromGLTF(gltf, resources) {
|
|
|
694
742
|
}
|
|
695
743
|
|
|
696
744
|
// lib/gltf/resourceUtils.ts
|
|
697
|
-
import { PassThrough } from "stream";
|
|
698
|
-
import PImage from "pureimage";
|
|
745
|
+
import { PassThrough } from "readable-stream";
|
|
746
|
+
import * as PImage from "pureimage";
|
|
699
747
|
function bufferFromDataURI(uri) {
|
|
700
748
|
const match = uri.match(/^data:.*?;base64,(.*)$/);
|
|
701
749
|
if (!match) throw new Error(`Unsupported data URI: ${uri.slice(0, 64)}...`);
|
|
@@ -725,7 +773,9 @@ async function decodeImageFromBuffer(buf, mimeType) {
|
|
|
725
773
|
return PImage.decodePNGFromStream(bufferToStream(buf));
|
|
726
774
|
if (type === "image/jpeg" || type === "image/jpg")
|
|
727
775
|
return PImage.decodeJPEGFromStream(bufferToStream(buf));
|
|
728
|
-
throw new Error(
|
|
776
|
+
throw new Error(
|
|
777
|
+
`Unsupported embedded image mimeType: ${mimeType ?? "unknown"}`
|
|
778
|
+
);
|
|
729
779
|
}
|
|
730
780
|
|
|
731
781
|
// lib/gltf/parseGLB.ts
|
|
@@ -872,12 +922,12 @@ async function loadGLTFWithResourcesFromURL(url, options = {}) {
|
|
|
872
922
|
}
|
|
873
923
|
|
|
874
924
|
// lib/image/pureImageFactory.ts
|
|
875
|
-
import PImage2 from "pureimage";
|
|
925
|
+
import * as PImage2 from "pureimage";
|
|
876
926
|
var pureImageFactory = (width, height) => PImage2.make(width, height);
|
|
877
927
|
|
|
878
928
|
// lib/image/encodePNGToBuffer.ts
|
|
879
|
-
import { PassThrough as PassThrough2 } from "stream";
|
|
880
|
-
import PImage3 from "pureimage";
|
|
929
|
+
import { PassThrough as PassThrough2 } from "readable-stream";
|
|
930
|
+
import * as PImage3 from "pureimage";
|
|
881
931
|
async function encodePNGToBuffer(image) {
|
|
882
932
|
const passThrough = new PassThrough2();
|
|
883
933
|
const chunks = [];
|
|
@@ -911,7 +961,8 @@ async function renderGLTFToPNGBufferFromURL(url, options = {}) {
|
|
|
911
961
|
function normalizeToArrayBuffer(source) {
|
|
912
962
|
if (source instanceof ArrayBuffer) return source;
|
|
913
963
|
const { buffer, byteOffset, byteLength } = source;
|
|
914
|
-
|
|
964
|
+
const viewBuffer = buffer;
|
|
965
|
+
return viewBuffer.slice(byteOffset, byteOffset + byteLength);
|
|
915
966
|
}
|
|
916
967
|
async function renderGLTFToPNGBufferFromGLBBuffer(glb, options = {}) {
|
|
917
968
|
const arrayBuffer = normalizeToArrayBuffer(glb);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "poppygl",
|
|
3
3
|
"main": "dist/index.js",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.4",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/tscircuit/poppygl.git"
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"gl-matrix": "^3.4.4",
|
|
37
|
-
"pureimage": "^0.4.18"
|
|
37
|
+
"pureimage": "^0.4.18",
|
|
38
|
+
"readable-stream": "^4.7.0"
|
|
38
39
|
}
|
|
39
40
|
}
|