poppygl 0.0.5 → 0.0.7
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.d.ts +1 -0
- package/dist/index.js +41 -15
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -10,13 +10,7 @@ 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(
|
|
14
|
-
tmp,
|
|
15
|
-
positions[i],
|
|
16
|
-
positions[i + 1],
|
|
17
|
-
positions[i + 2],
|
|
18
|
-
1
|
|
19
|
-
);
|
|
13
|
+
vec4.set(tmp, positions[i], positions[i + 1], positions[i + 2], 1);
|
|
20
14
|
vec4.transformMat4(tmp, tmp, model);
|
|
21
15
|
const x = tmp[0];
|
|
22
16
|
const y = tmp[1];
|
|
@@ -250,7 +244,7 @@ var SoftwareRenderer = class {
|
|
|
250
244
|
return out;
|
|
251
245
|
}
|
|
252
246
|
drawMesh(mesh, camera, light, material, cullBackFaces = true, gammaOut = true) {
|
|
253
|
-
const { positions, normals, uvs, indices, model } = mesh;
|
|
247
|
+
const { positions, normals, uvs, indices, model, colors } = mesh;
|
|
254
248
|
const view = camera.view;
|
|
255
249
|
const proj = camera.proj;
|
|
256
250
|
const mvp = mat42.create();
|
|
@@ -271,6 +265,7 @@ var SoftwareRenderer = class {
|
|
|
271
265
|
const vInvW = new Float32Array(vertexCount);
|
|
272
266
|
const vNDCz = new Float32Array(vertexCount);
|
|
273
267
|
const vWorldN = new Array(vertexCount);
|
|
268
|
+
const vColor = new Array(vertexCount);
|
|
274
269
|
for (let i = 0; i < vertexCount; i++) {
|
|
275
270
|
const p = vec42.fromValues(
|
|
276
271
|
positions[i * 3 + 0],
|
|
@@ -297,6 +292,11 @@ var SoftwareRenderer = class {
|
|
|
297
292
|
const nw = vec32.create();
|
|
298
293
|
vec32.transformMat3(nw, n, normalMat);
|
|
299
294
|
vWorldN[i] = [nw[0], nw[1], nw[2]];
|
|
295
|
+
if (colors && colors.length >= (i + 1) * 3) {
|
|
296
|
+
vColor[i] = [colors[i * 3 + 0], colors[i * 3 + 1], colors[i * 3 + 2]];
|
|
297
|
+
} else {
|
|
298
|
+
vColor[i] = [1, 1, 1];
|
|
299
|
+
}
|
|
300
300
|
}
|
|
301
301
|
for (let i = 0; i < idx.length; i += 3) {
|
|
302
302
|
const i0 = idx[i + 0];
|
|
@@ -334,6 +334,11 @@ var SoftwareRenderer = class {
|
|
|
334
334
|
[uvs[i1 * 2 + 0], uvs[i1 * 2 + 1]],
|
|
335
335
|
[uvs[i2 * 2 + 0], uvs[i2 * 2 + 1]]
|
|
336
336
|
] : null;
|
|
337
|
+
const cs = [
|
|
338
|
+
vColor[i0],
|
|
339
|
+
vColor[i1],
|
|
340
|
+
vColor[i2]
|
|
341
|
+
];
|
|
337
342
|
for (let y = minY; y <= maxY; y++) {
|
|
338
343
|
for (let x = minX; x <= maxX; x++) {
|
|
339
344
|
const p = [x + 0.5, y + 0.5];
|
|
@@ -366,6 +371,13 @@ var SoftwareRenderer = class {
|
|
|
366
371
|
);
|
|
367
372
|
baseColor = mulColor(baseColor, texel);
|
|
368
373
|
}
|
|
374
|
+
const [cr, cg, cb] = this.perspInterp(cs, invW, [l0, l1, l2]);
|
|
375
|
+
baseColor = [
|
|
376
|
+
baseColor[0] * cr,
|
|
377
|
+
baseColor[1] * cg,
|
|
378
|
+
baseColor[2] * cb,
|
|
379
|
+
baseColor[3]
|
|
380
|
+
];
|
|
369
381
|
const [np0, np1, np2] = this.perspInterp(nws, invW, [l0, l1, l2]);
|
|
370
382
|
const nlen = Math.hypot(np0, np1, np2) || 1;
|
|
371
383
|
const nrm = [
|
|
@@ -713,6 +725,8 @@ function createSceneFromGLTF(gltf, resources) {
|
|
|
713
725
|
const normals = normalsAcc != null ? readAccessorAsFloat32(ctx, normalsAcc) : null;
|
|
714
726
|
const uvs = uvAcc != null ? readAccessorAsFloat32(ctx, uvAcc) : null;
|
|
715
727
|
const indices = primitive.indices != null ? readIndices(ctx, primitive.indices) : null;
|
|
728
|
+
const colorAcc = primitive.attributes?.COLOR_0;
|
|
729
|
+
const colors = colorAcc != null ? readAccessorAsFloat32(ctx, colorAcc) : null;
|
|
716
730
|
const material = getMaterial(
|
|
717
731
|
gltf,
|
|
718
732
|
textures,
|
|
@@ -725,7 +739,8 @@ function createSceneFromGLTF(gltf, resources) {
|
|
|
725
739
|
uvs,
|
|
726
740
|
indices,
|
|
727
741
|
model: world,
|
|
728
|
-
material
|
|
742
|
+
material,
|
|
743
|
+
colors
|
|
729
744
|
});
|
|
730
745
|
}
|
|
731
746
|
}
|
|
@@ -799,7 +814,8 @@ function parseGLB(arrayBuffer) {
|
|
|
799
814
|
const chunkLength = view.getUint32(offset, true);
|
|
800
815
|
const chunkType = view.getUint32(offset + 4, true);
|
|
801
816
|
offset += 8;
|
|
802
|
-
if (offset + chunkLength > length)
|
|
817
|
+
if (offset + chunkLength > length)
|
|
818
|
+
throw new Error("Truncated GLB chunk data.");
|
|
803
819
|
const chunkData = new Uint8Array(arrayBuffer, offset, chunkLength);
|
|
804
820
|
offset += chunkLength;
|
|
805
821
|
if (chunkType === JSON_CHUNK_TYPE) {
|
|
@@ -817,7 +833,8 @@ function parseGLB(arrayBuffer) {
|
|
|
817
833
|
// lib/gltf/loadGLTFWithResourcesFromURL.ts
|
|
818
834
|
function ensureFetch(fetchImpl) {
|
|
819
835
|
const impl = fetchImpl ?? globalThis.fetch;
|
|
820
|
-
if (!impl)
|
|
836
|
+
if (!impl)
|
|
837
|
+
throw new Error("Global fetch API is not available; provide fetchImpl.");
|
|
821
838
|
return impl;
|
|
822
839
|
}
|
|
823
840
|
async function fetchBinary(fetchImpl, url) {
|
|
@@ -832,7 +849,9 @@ async function loadGLTFWithResourcesFromURL(url, options = {}) {
|
|
|
832
849
|
const fetchImpl = ensureFetch(options.fetchImpl);
|
|
833
850
|
const response = await fetchImpl(url);
|
|
834
851
|
if (!response.ok)
|
|
835
|
-
throw new Error(
|
|
852
|
+
throw new Error(
|
|
853
|
+
`Failed to fetch ${url}: ${response.status} ${response.statusText}`
|
|
854
|
+
);
|
|
836
855
|
const resolvedURL = new URL(response.url || url);
|
|
837
856
|
const baseURL = resolvedURL;
|
|
838
857
|
const sourceBuffer = await response.arrayBuffer();
|
|
@@ -867,7 +886,9 @@ async function loadGLTFWithResourcesFromURL(url, options = {}) {
|
|
|
867
886
|
buffers[index] = buf;
|
|
868
887
|
return buf;
|
|
869
888
|
}
|
|
870
|
-
throw new Error(
|
|
889
|
+
throw new Error(
|
|
890
|
+
`Buffer ${index} is missing a uri and no GLB chunk was provided.`
|
|
891
|
+
);
|
|
871
892
|
}
|
|
872
893
|
await Promise.all(
|
|
873
894
|
(gltf.buffers || []).map(async (entry, idx) => {
|
|
@@ -892,7 +913,10 @@ async function loadGLTFWithResourcesFromURL(url, options = {}) {
|
|
|
892
913
|
const bufferView = gltf.bufferViews?.[img.bufferView];
|
|
893
914
|
if (!bufferView)
|
|
894
915
|
throw new Error(`Invalid image bufferView index ${img.bufferView}`);
|
|
895
|
-
const buffer = await resolveBuffer(
|
|
916
|
+
const buffer = await resolveBuffer(
|
|
917
|
+
bufferView.buffer,
|
|
918
|
+
gltf.buffers?.[bufferView.buffer]
|
|
919
|
+
);
|
|
896
920
|
if (!buffer)
|
|
897
921
|
throw new Error(`Missing buffer for image bufferView ${img.bufferView}`);
|
|
898
922
|
const byteOffset = bufferView.byteOffset ?? 0;
|
|
@@ -981,7 +1005,9 @@ async function renderGLTFToPNGBufferFromGLBBuffer(glb, options = {}) {
|
|
|
981
1005
|
continue;
|
|
982
1006
|
}
|
|
983
1007
|
if (!binaryChunk) {
|
|
984
|
-
throw new Error(
|
|
1008
|
+
throw new Error(
|
|
1009
|
+
`GLB is missing the binary chunk required for buffer ${index}.`
|
|
1010
|
+
);
|
|
985
1011
|
}
|
|
986
1012
|
buffers[index] = binaryChunk;
|
|
987
1013
|
}
|