poppygl 0.0.24 → 0.0.25
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/README.md +13 -13
- package/dist/index.d.ts +1 -16
- package/dist/index.js +5 -261
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,10 +9,10 @@ Render GLTF files to PNG images in completely native JavaScript without WebGL/Op
|
|
|
9
9
|
Give poppygl a `.gltf` or `.glb` URL and it will fetch every referenced buffer/texture, rasterize the scene, and hand back a PNG buffer.
|
|
10
10
|
|
|
11
11
|
```ts
|
|
12
|
-
import {
|
|
12
|
+
import { renderGLTFToPNGFromURL } from "poppygl"
|
|
13
13
|
import { writeFile } from "node:fs/promises"
|
|
14
14
|
|
|
15
|
-
const png = await
|
|
15
|
+
const png = await renderGLTFToPNGFromURL(
|
|
16
16
|
"https://models.babylonjs.com/DamagedHelmet.glb",
|
|
17
17
|
{
|
|
18
18
|
width: 800,
|
|
@@ -28,14 +28,14 @@ await writeFile("DamagedHelmet.png", png)
|
|
|
28
28
|
|
|
29
29
|
## Render from an in-memory GLB buffer
|
|
30
30
|
|
|
31
|
-
Already have the `.glb` bytes (for example, uploaded by a user or read from disk)? Send the buffer straight to `
|
|
31
|
+
Already have the `.glb` bytes (for example, uploaded by a user or read from disk)? Send the buffer straight to `renderGLTFToPNGFromGLB` and receive the PNG output.
|
|
32
32
|
|
|
33
33
|
```ts
|
|
34
34
|
import { readFile } from "node:fs/promises"
|
|
35
|
-
import {
|
|
35
|
+
import { renderGLTFToPNGFromGLB } from "poppygl"
|
|
36
36
|
|
|
37
37
|
const glb = await readFile("DamagedHelmet.glb")
|
|
38
|
-
const png = await
|
|
38
|
+
const png = await renderGLTFToPNGFromGLB(glb, {
|
|
39
39
|
width: 1024,
|
|
40
40
|
height: 768,
|
|
41
41
|
})
|
|
@@ -43,11 +43,11 @@ const png = await renderGLTFToPNGBufferFromGLBBuffer(glb, {
|
|
|
43
43
|
// write or return the PNG buffer
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
> This helper expects every referenced buffer/image to be embedded in the GLB (the usual single-file package). If the asset links out to external resources, load it with `
|
|
46
|
+
> This helper expects every referenced buffer/image to be embedded in the GLB (the usual single-file package). If the asset links out to external resources, load it with `renderGLTFToPNGFromURL` instead so poppygl can fetch the extras.
|
|
47
47
|
|
|
48
48
|
## Render options
|
|
49
49
|
|
|
50
|
-
`
|
|
50
|
+
`renderGLTFToPNGFromURL` accepts the same render options as the lower-level APIs:
|
|
51
51
|
|
|
52
52
|
- `width`/`height` (default `512`): output resolution in pixels.
|
|
53
53
|
- `supersampling`: render at `width * supersampling` / `height * supersampling`, then downsample (default `1`).
|
|
@@ -76,8 +76,8 @@ import {
|
|
|
76
76
|
bufferFromDataURI,
|
|
77
77
|
createSceneFromGLTF,
|
|
78
78
|
decodeImageFromBuffer,
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
encodePNG,
|
|
80
|
+
createUint8Bitmap,
|
|
81
81
|
renderSceneFromGLTF,
|
|
82
82
|
} from "poppygl"
|
|
83
83
|
import gltfJson from "./CesiumMan.gltf.json" assert { type: "json" }
|
|
@@ -105,8 +105,8 @@ const images = await Promise.all(
|
|
|
105
105
|
)
|
|
106
106
|
|
|
107
107
|
const scene = createSceneFromGLTF(gltfJson, { buffers, images })
|
|
108
|
-
const { bitmap } = renderSceneFromGLTF(scene, { width: 512, height: 512 },
|
|
109
|
-
const png = await
|
|
108
|
+
const { bitmap } = renderSceneFromGLTF(scene, { width: 512, height: 512 }, createUint8Bitmap)
|
|
109
|
+
const png = await encodePNG(bitmap)
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
The only contract is that `buffers` is an array of `Uint8Array` instances and `images` is an array of `BitmapLike` textures (PNG and JPEG are supported out of the box via `decodeImageFromBuffer`).
|
|
@@ -116,7 +116,7 @@ The only contract is that `buffers` is an array of `Uint8Array` instances and `i
|
|
|
116
116
|
- `loadGLTFWithResourcesFromURL` returns `{ gltf, resources }` if you prefer to inspect or cache the parsed data before rendering.
|
|
117
117
|
- `createSceneFromGLTF` builds draw calls ready for the software rasterizer.
|
|
118
118
|
- `computeSmoothNormals` and `computeWorldAABB` expose useful preprocessing helpers.
|
|
119
|
-
- `
|
|
120
|
-
- `
|
|
119
|
+
- `createUint8Bitmap` allocates a portable in-memory bitmap used by the renderer.
|
|
120
|
+
- `encodePNG` packs any `BitmapLike` into a `Uint8Array` PNG that can be written to disk or served over the network.
|
|
121
121
|
|
|
122
122
|
Happy rendering!
|
package/dist/index.d.ts
CHANGED
|
@@ -193,12 +193,8 @@ declare function drawInfiniteGrid(software_renderer: SoftwareRenderer, params: {
|
|
|
193
193
|
gamma_out?: boolean;
|
|
194
194
|
}): void;
|
|
195
195
|
|
|
196
|
-
declare const pureImageFactory: ImageFactory;
|
|
197
|
-
|
|
198
196
|
declare function encodePNG(image: BitmapLike): Promise<Uint8Array>;
|
|
199
197
|
|
|
200
|
-
declare function encodePNGToBuffer(image: BitmapLike): Promise<Buffer>;
|
|
201
|
-
|
|
202
198
|
interface RenderGLTFToPNGFromURLOptions extends RenderOptionsInput, LoadGLTFWithResourcesFromURLOptions {
|
|
203
199
|
}
|
|
204
200
|
declare function renderGLTFToPNGFromURL(url: string, options?: RenderGLTFToPNGFromURLOptions): Promise<Uint8Array>;
|
|
@@ -206,17 +202,6 @@ declare function renderGLTFToPNGFromURL(url: string, options?: RenderGLTFToPNGFr
|
|
|
206
202
|
type RenderGLTFToPNGFromGLBOptions = RenderOptionsInput;
|
|
207
203
|
declare function renderGLTFToPNGFromGLB(glb: ArrayBuffer | Uint8Array, options?: RenderGLTFToPNGFromGLBOptions): Promise<Uint8Array>;
|
|
208
204
|
|
|
209
|
-
interface RenderGLTFToPNGBufferFromURLOptions extends RenderOptionsInput, LoadGLTFWithResourcesFromURLOptions {
|
|
210
|
-
}
|
|
211
|
-
declare function renderGLTFToPNGBufferFromURL(url: string, options?: RenderGLTFToPNGBufferFromURLOptions): Promise<Buffer>;
|
|
212
|
-
|
|
213
|
-
type RenderGLTFToPNGBufferFromGLBBufferOptions = RenderOptionsInput;
|
|
214
|
-
declare function renderGLTFToPNGBufferFromGLBBuffer(glb: ArrayBuffer | Uint8Array, options?: RenderGLTFToPNGBufferFromGLBBufferOptions): Promise<Buffer>;
|
|
215
|
-
|
|
216
|
-
interface RenderGLTFToPNGBufferOptions extends RenderOptionsInput, LoadGLTFWithResourcesFromURLOptions {
|
|
217
|
-
}
|
|
218
|
-
declare function renderGLTFToPNGBuffer(gltfOrJson: string | any, options?: RenderGLTFToPNGBufferOptions, resources?: GLTFResources): Promise<Buffer>;
|
|
219
|
-
|
|
220
205
|
declare function renderSceneFromGLTF(scene: GLTFScene, options?: RenderOptionsInput, imageFactory?: ImageFactory): RenderResult;
|
|
221
206
|
|
|
222
|
-
export { type BitmapLike, type Camera, type CameraRotation, type CameraUp, DEFAULT_LIGHT_DIR, DEFAULT_RENDER_OPTIONS, type DebugPoint, type DrawCall, type FetchLike, type GLTFResources, type GLTFScene, type GridOptions, type ImageFactory, type LightSettings, type LoadGLTFWithResourcesFromURLOptions, type Material, type MutableRGBA, type RGBA, type
|
|
207
|
+
export { type BitmapLike, type Camera, type CameraRotation, type CameraUp, DEFAULT_LIGHT_DIR, DEFAULT_RENDER_OPTIONS, type DebugPoint, type DrawCall, type FetchLike, type GLTFResources, type GLTFScene, type GridOptions, type ImageFactory, type LightSettings, type LoadGLTFWithResourcesFromURLOptions, type Material, type MutableRGBA, type RGBA, type RenderGLTFToPNGFromGLBOptions, type RenderGLTFToPNGFromURLOptions, type RenderOptions, type RenderOptionsInput, type RenderResult, SoftwareRenderer, bufferFromDataURI, buildCamera, computeSmoothNormals, computeWorldAABB, createGrid, createInfiniteGrid, createSceneFromGLTF, createUint8Bitmap, decodeImageFromBuffer, drawInfiniteGrid, encodePNG, getDefaultRenderOptions, hexToRgb, isJPG, isPNG, loadGLTFWithResourcesFromURL, renderDrawCalls, renderGLTFToPNGFromGLB, renderGLTFToPNGFromURL, renderSceneFromGLTF, resolveRenderOptions };
|
package/dist/index.js
CHANGED
|
@@ -1620,21 +1620,6 @@ function getNodeBuffer() {
|
|
|
1620
1620
|
}
|
|
1621
1621
|
return maybeBuffer;
|
|
1622
1622
|
}
|
|
1623
|
-
function toUint8Array(chunk) {
|
|
1624
|
-
if (chunk instanceof Uint8Array) return chunk;
|
|
1625
|
-
if (chunk instanceof ArrayBuffer) return new Uint8Array(chunk);
|
|
1626
|
-
return new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
|
1627
|
-
}
|
|
1628
|
-
function concatUint8Arrays(chunks) {
|
|
1629
|
-
const totalLength = chunks.reduce((length, chunk) => length + chunk.length, 0);
|
|
1630
|
-
const result = new Uint8Array(totalLength);
|
|
1631
|
-
let offset = 0;
|
|
1632
|
-
for (const chunk of chunks) {
|
|
1633
|
-
result.set(chunk, offset);
|
|
1634
|
-
offset += chunk.length;
|
|
1635
|
-
}
|
|
1636
|
-
return result;
|
|
1637
|
-
}
|
|
1638
1623
|
function base64ToUint8Array(base64) {
|
|
1639
1624
|
if (typeof globalThis.atob === "function") {
|
|
1640
1625
|
const binary = globalThis.atob(base64);
|
|
@@ -1646,9 +1631,6 @@ function base64ToUint8Array(base64) {
|
|
|
1646
1631
|
}
|
|
1647
1632
|
return new Uint8Array(getNodeBuffer().from(base64, "base64"));
|
|
1648
1633
|
}
|
|
1649
|
-
function uint8ArrayToNodeBuffer(bytes) {
|
|
1650
|
-
return getNodeBuffer().from(bytes);
|
|
1651
|
-
}
|
|
1652
1634
|
|
|
1653
1635
|
// lib/gltf/resourceUtils.ts
|
|
1654
1636
|
function bufferFromDataURI(uri) {
|
|
@@ -1678,13 +1660,13 @@ async function decodeImageViaFastPng(buf) {
|
|
|
1678
1660
|
};
|
|
1679
1661
|
}
|
|
1680
1662
|
async function decodeImageViaPureImage(buf, mimeType) {
|
|
1681
|
-
const { PassThrough
|
|
1682
|
-
const
|
|
1683
|
-
const stream = new
|
|
1663
|
+
const { PassThrough } = await import("readable-stream");
|
|
1664
|
+
const PImage = await import("pureimage");
|
|
1665
|
+
const stream = new PassThrough();
|
|
1684
1666
|
stream.end(buf);
|
|
1685
|
-
if (mimeType === "image/png") return
|
|
1667
|
+
if (mimeType === "image/png") return PImage.decodePNGFromStream(stream);
|
|
1686
1668
|
if (mimeType === "image/jpeg" || mimeType === "image/jpg")
|
|
1687
|
-
return
|
|
1669
|
+
return PImage.decodeJPEGFromStream(stream);
|
|
1688
1670
|
throw new Error(`Unsupported embedded image mimeType: ${mimeType}`);
|
|
1689
1671
|
}
|
|
1690
1672
|
async function decodeImageFromBuffer(buf, mimeType) {
|
|
@@ -1852,10 +1834,6 @@ async function loadGLTFWithResourcesFromURL(url, options = {}) {
|
|
|
1852
1834
|
};
|
|
1853
1835
|
}
|
|
1854
1836
|
|
|
1855
|
-
// lib/image/pureImageFactory.ts
|
|
1856
|
-
import * as PImage from "pureimage";
|
|
1857
|
-
var pureImageFactory = (width, height) => PImage.make(width, height);
|
|
1858
|
-
|
|
1859
1837
|
// lib/image/encodePNG.ts
|
|
1860
1838
|
import { encode } from "fast-png";
|
|
1861
1839
|
async function encodePNG(image) {
|
|
@@ -1868,28 +1846,6 @@ async function encodePNG(image) {
|
|
|
1868
1846
|
});
|
|
1869
1847
|
}
|
|
1870
1848
|
|
|
1871
|
-
// lib/image/encodePNGToBuffer.ts
|
|
1872
|
-
import { PassThrough } from "readable-stream";
|
|
1873
|
-
import * as PImage2 from "pureimage";
|
|
1874
|
-
async function encodePNGToBuffer(image) {
|
|
1875
|
-
const passThrough = new PassThrough();
|
|
1876
|
-
const chunks = [];
|
|
1877
|
-
passThrough.on(
|
|
1878
|
-
"data",
|
|
1879
|
-
(chunk) => {
|
|
1880
|
-
chunks.push(toUint8Array(chunk));
|
|
1881
|
-
}
|
|
1882
|
-
);
|
|
1883
|
-
const resultPromise = new Promise((resolve, reject) => {
|
|
1884
|
-
passThrough.on("end", () => {
|
|
1885
|
-
resolve(uint8ArrayToNodeBuffer(concatUint8Arrays(chunks)));
|
|
1886
|
-
});
|
|
1887
|
-
passThrough.on("error", reject);
|
|
1888
|
-
});
|
|
1889
|
-
await PImage2.encodePNGToStream(image, passThrough);
|
|
1890
|
-
return await resultPromise;
|
|
1891
|
-
}
|
|
1892
|
-
|
|
1893
1849
|
// lib/render/renderGLTFToPNGFromURL.ts
|
|
1894
1850
|
async function renderGLTFToPNGFromURL(url, options = {}) {
|
|
1895
1851
|
const { fetchImpl, ...renderOptions } = options;
|
|
@@ -1983,213 +1939,6 @@ async function renderGLTFToPNGFromGLB(glb, options = {}) {
|
|
|
1983
1939
|
return encodePNG(bitmap);
|
|
1984
1940
|
}
|
|
1985
1941
|
|
|
1986
|
-
// lib/render/renderGLTFToPNGBufferFromURL.ts
|
|
1987
|
-
async function renderGLTFToPNGBufferFromURL(url, options = {}) {
|
|
1988
|
-
const { fetchImpl, ...renderOptions } = options;
|
|
1989
|
-
const { gltf, resources } = await loadGLTFWithResourcesFromURL(url, {
|
|
1990
|
-
fetchImpl
|
|
1991
|
-
});
|
|
1992
|
-
const scene = createSceneFromGLTF(gltf, resources);
|
|
1993
|
-
const { bitmap } = renderDrawCalls(
|
|
1994
|
-
scene.drawCalls,
|
|
1995
|
-
renderOptions,
|
|
1996
|
-
pureImageFactory
|
|
1997
|
-
);
|
|
1998
|
-
return encodePNGToBuffer(bitmap);
|
|
1999
|
-
}
|
|
2000
|
-
|
|
2001
|
-
// lib/render/renderGLTFToPNGBufferFromGLBBuffer.ts
|
|
2002
|
-
function normalizeToArrayBuffer2(source) {
|
|
2003
|
-
if (source instanceof ArrayBuffer) return source;
|
|
2004
|
-
const { buffer, byteOffset, byteLength } = source;
|
|
2005
|
-
const viewBuffer = buffer;
|
|
2006
|
-
return viewBuffer.slice(byteOffset, byteOffset + byteLength);
|
|
2007
|
-
}
|
|
2008
|
-
async function renderGLTFToPNGBufferFromGLBBuffer(glb, options = {}) {
|
|
2009
|
-
const arrayBuffer = normalizeToArrayBuffer2(glb);
|
|
2010
|
-
const { gltf, binaryChunk } = parseGLB(arrayBuffer);
|
|
2011
|
-
const totalBuffers = Array.isArray(gltf.buffers) ? gltf.buffers.length : 0;
|
|
2012
|
-
const buffers = new Array(totalBuffers);
|
|
2013
|
-
for (let index = 0; index < totalBuffers; index++) {
|
|
2014
|
-
const entry = gltf.buffers[index];
|
|
2015
|
-
if (entry?.uri) {
|
|
2016
|
-
if (!entry.uri.startsWith("data:")) {
|
|
2017
|
-
throw new Error(
|
|
2018
|
-
`Buffer ${index} references external resource ${entry.uri}. Use renderGLTFToPNGBufferFromURL for GLBs with external buffer URIs.`
|
|
2019
|
-
);
|
|
2020
|
-
}
|
|
2021
|
-
buffers[index] = bufferFromDataURI(entry.uri);
|
|
2022
|
-
continue;
|
|
2023
|
-
}
|
|
2024
|
-
if (!binaryChunk) {
|
|
2025
|
-
throw new Error(
|
|
2026
|
-
`GLB is missing the binary chunk required for buffer ${index}.`
|
|
2027
|
-
);
|
|
2028
|
-
}
|
|
2029
|
-
buffers[index] = binaryChunk;
|
|
2030
|
-
}
|
|
2031
|
-
const resolveBufferViewSlice = (bufferViewIndex) => {
|
|
2032
|
-
const bufferView = gltf.bufferViews?.[bufferViewIndex];
|
|
2033
|
-
if (!bufferView) {
|
|
2034
|
-
throw new Error(`Invalid bufferView index ${bufferViewIndex}.`);
|
|
2035
|
-
}
|
|
2036
|
-
const bufferIndex = bufferView.buffer;
|
|
2037
|
-
const buffer = buffers[bufferIndex];
|
|
2038
|
-
if (!buffer) {
|
|
2039
|
-
throw new Error(
|
|
2040
|
-
`Missing buffer data for bufferView ${bufferViewIndex} (buffer ${bufferIndex}).`
|
|
2041
|
-
);
|
|
2042
|
-
}
|
|
2043
|
-
const byteOffset = bufferView.byteOffset ?? 0;
|
|
2044
|
-
const byteLength = bufferView.byteLength;
|
|
2045
|
-
if (typeof byteLength !== "number") {
|
|
2046
|
-
throw new Error(`bufferView ${bufferViewIndex} is missing byteLength.`);
|
|
2047
|
-
}
|
|
2048
|
-
return buffer.subarray(byteOffset, byteOffset + byteLength);
|
|
2049
|
-
};
|
|
2050
|
-
const images = await Promise.all(
|
|
2051
|
-
(gltf.images ?? []).map(async (image, imageIndex) => {
|
|
2052
|
-
if (image.uri) {
|
|
2053
|
-
if (!image.uri.startsWith("data:")) {
|
|
2054
|
-
throw new Error(
|
|
2055
|
-
`Image ${imageIndex} references external resource ${image.uri}. Embed textures or load via renderGLTFToPNGBufferFromURL.`
|
|
2056
|
-
);
|
|
2057
|
-
}
|
|
2058
|
-
const data = bufferFromDataURI(image.uri);
|
|
2059
|
-
return decodeImageFromBuffer(data, image.mimeType);
|
|
2060
|
-
}
|
|
2061
|
-
if (typeof image.bufferView === "number") {
|
|
2062
|
-
const slice = resolveBufferViewSlice(image.bufferView);
|
|
2063
|
-
return decodeImageFromBuffer(slice, image.mimeType);
|
|
2064
|
-
}
|
|
2065
|
-
throw new Error(
|
|
2066
|
-
`Image ${imageIndex} must supply a data URI or bufferView for GLB rendering.`
|
|
2067
|
-
);
|
|
2068
|
-
})
|
|
2069
|
-
);
|
|
2070
|
-
const scene = createSceneFromGLTF(gltf, { buffers, images });
|
|
2071
|
-
const { bitmap } = renderDrawCalls(scene.drawCalls, options, pureImageFactory);
|
|
2072
|
-
return encodePNGToBuffer(bitmap);
|
|
2073
|
-
}
|
|
2074
|
-
|
|
2075
|
-
// lib/gltf/loadGLTFWithResourcesFromPath.ts
|
|
2076
|
-
async function loadGLTFWithResourcesFromPath(gltfPath) {
|
|
2077
|
-
const fs = await import("fs/promises");
|
|
2078
|
-
const path = await import("path");
|
|
2079
|
-
const baseDir = path.dirname(gltfPath);
|
|
2080
|
-
const gltf = JSON.parse(await fs.readFile(gltfPath, "utf8"));
|
|
2081
|
-
const buffers = await Promise.all(
|
|
2082
|
-
(gltf.buffers || []).map(async (buffer) => {
|
|
2083
|
-
if (buffer.uri?.startsWith("data:")) {
|
|
2084
|
-
return bufferFromDataURI(buffer.uri);
|
|
2085
|
-
}
|
|
2086
|
-
if (buffer.uri) {
|
|
2087
|
-
const resolved = path.resolve(baseDir, decodeURIComponent(buffer.uri));
|
|
2088
|
-
return fs.readFile(resolved);
|
|
2089
|
-
}
|
|
2090
|
-
throw new Error("Buffer without uri not supported in this loader.");
|
|
2091
|
-
})
|
|
2092
|
-
);
|
|
2093
|
-
const images = await Promise.all(
|
|
2094
|
-
(gltf.images || []).map(async (image) => {
|
|
2095
|
-
if (image.uri) {
|
|
2096
|
-
if (image.uri.startsWith("data:")) {
|
|
2097
|
-
const bytes = bufferFromDataURI(image.uri);
|
|
2098
|
-
return decodeImageFromBuffer(bytes, image.mimeType);
|
|
2099
|
-
}
|
|
2100
|
-
const filePath = path.resolve(baseDir, decodeURIComponent(image.uri));
|
|
2101
|
-
const fileBytes = await fs.readFile(filePath);
|
|
2102
|
-
const hintedMime = isPNG(image.uri) ? "image/png" : isJPG(image.uri) ? "image/jpeg" : image.mimeType;
|
|
2103
|
-
return decodeImageFromBuffer(fileBytes, hintedMime);
|
|
2104
|
-
}
|
|
2105
|
-
if (typeof image.bufferView === "number") {
|
|
2106
|
-
const bufferView = gltf.bufferViews?.[image.bufferView];
|
|
2107
|
-
if (!bufferView) {
|
|
2108
|
-
throw new Error(`Invalid image bufferView index ${image.bufferView}`);
|
|
2109
|
-
}
|
|
2110
|
-
const buffer = buffers[bufferView.buffer];
|
|
2111
|
-
if (!buffer) {
|
|
2112
|
-
throw new Error(
|
|
2113
|
-
`Missing buffer for image bufferView ${image.bufferView}`
|
|
2114
|
-
);
|
|
2115
|
-
}
|
|
2116
|
-
const byteOffset = bufferView.byteOffset ?? 0;
|
|
2117
|
-
const byteLength = bufferView.byteLength;
|
|
2118
|
-
if (typeof byteLength !== "number") {
|
|
2119
|
-
throw new Error(
|
|
2120
|
-
`bufferView ${image.bufferView} missing byteLength for image.`
|
|
2121
|
-
);
|
|
2122
|
-
}
|
|
2123
|
-
const slice = buffer.subarray(byteOffset, byteOffset + byteLength);
|
|
2124
|
-
return decodeImageFromBuffer(slice, image.mimeType);
|
|
2125
|
-
}
|
|
2126
|
-
throw new Error(
|
|
2127
|
-
"images[*] entry missing uri or bufferView; unsupported in this loader."
|
|
2128
|
-
);
|
|
2129
|
-
})
|
|
2130
|
-
);
|
|
2131
|
-
return {
|
|
2132
|
-
gltf,
|
|
2133
|
-
resources: {
|
|
2134
|
-
buffers,
|
|
2135
|
-
images
|
|
2136
|
-
}
|
|
2137
|
-
};
|
|
2138
|
-
}
|
|
2139
|
-
|
|
2140
|
-
// lib/gltf/resolveGLTFInput.ts
|
|
2141
|
-
function isNodeRuntime() {
|
|
2142
|
-
const runtimeProcess = globalThis.process;
|
|
2143
|
-
return !!runtimeProcess?.versions?.node;
|
|
2144
|
-
}
|
|
2145
|
-
function isFetchableURLInNode(source) {
|
|
2146
|
-
try {
|
|
2147
|
-
const url = new URL(source);
|
|
2148
|
-
return ["http:", "https:", "data:", "blob:"].includes(url.protocol);
|
|
2149
|
-
} catch {
|
|
2150
|
-
return false;
|
|
2151
|
-
}
|
|
2152
|
-
}
|
|
2153
|
-
function parseGLTFJSON(source) {
|
|
2154
|
-
try {
|
|
2155
|
-
return JSON.parse(source);
|
|
2156
|
-
} catch (error) {
|
|
2157
|
-
if (error instanceof SyntaxError) return null;
|
|
2158
|
-
throw error;
|
|
2159
|
-
}
|
|
2160
|
-
}
|
|
2161
|
-
async function resolveGLTFInput(source, options = {}) {
|
|
2162
|
-
const gltf = parseGLTFJSON(source);
|
|
2163
|
-
if (gltf !== null) {
|
|
2164
|
-
return {
|
|
2165
|
-
gltf,
|
|
2166
|
-
resources: { buffers: [], images: [] }
|
|
2167
|
-
};
|
|
2168
|
-
}
|
|
2169
|
-
if (!isNodeRuntime()) {
|
|
2170
|
-
return loadGLTFWithResourcesFromURL(source, options);
|
|
2171
|
-
}
|
|
2172
|
-
if (isFetchableURLInNode(source)) {
|
|
2173
|
-
return loadGLTFWithResourcesFromURL(source, options);
|
|
2174
|
-
}
|
|
2175
|
-
return loadGLTFWithResourcesFromPath(source);
|
|
2176
|
-
}
|
|
2177
|
-
|
|
2178
|
-
// lib/render/renderGLTFToPNGBuffer.ts
|
|
2179
|
-
function renderFromGLTF(gltf, options, resources) {
|
|
2180
|
-
const scene = createSceneFromGLTF(gltf, resources);
|
|
2181
|
-
const { bitmap } = renderDrawCalls(scene.drawCalls, options, pureImageFactory);
|
|
2182
|
-
return encodePNGToBuffer(bitmap);
|
|
2183
|
-
}
|
|
2184
|
-
async function renderGLTFToPNGBuffer(gltfOrJson, options = {}, resources = { buffers: [], images: [] }) {
|
|
2185
|
-
const { fetchImpl, ...renderOptions } = options;
|
|
2186
|
-
if (typeof gltfOrJson !== "string") {
|
|
2187
|
-
return renderFromGLTF(gltfOrJson, renderOptions, resources);
|
|
2188
|
-
}
|
|
2189
|
-
const loaded = await resolveGLTFInput(gltfOrJson, { fetchImpl });
|
|
2190
|
-
return renderFromGLTF(loaded.gltf, renderOptions, loaded.resources);
|
|
2191
|
-
}
|
|
2192
|
-
|
|
2193
1942
|
// lib/index.ts
|
|
2194
1943
|
function renderSceneFromGLTF(scene, options, imageFactory) {
|
|
2195
1944
|
return renderDrawCalls(scene.drawCalls, options, imageFactory);
|
|
@@ -2209,17 +1958,12 @@ export {
|
|
|
2209
1958
|
decodeImageFromBuffer,
|
|
2210
1959
|
drawInfiniteGrid,
|
|
2211
1960
|
encodePNG,
|
|
2212
|
-
encodePNGToBuffer,
|
|
2213
1961
|
getDefaultRenderOptions,
|
|
2214
1962
|
hexToRgb,
|
|
2215
1963
|
isJPG,
|
|
2216
1964
|
isPNG,
|
|
2217
1965
|
loadGLTFWithResourcesFromURL,
|
|
2218
|
-
pureImageFactory,
|
|
2219
1966
|
renderDrawCalls,
|
|
2220
|
-
renderGLTFToPNGBuffer,
|
|
2221
|
-
renderGLTFToPNGBufferFromGLBBuffer,
|
|
2222
|
-
renderGLTFToPNGBufferFromURL,
|
|
2223
1967
|
renderGLTFToPNGFromGLB,
|
|
2224
1968
|
renderGLTFToPNGFromURL,
|
|
2225
1969
|
renderSceneFromGLTF,
|