@plasius/gpu-shared 0.1.11 → 0.1.14
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 +58 -3
- package/README.md +110 -4
- package/assets/brigantine.gltf +549 -24
- package/assets/cutter.gltf +538 -0
- package/assets/harbor-dock.gltf +680 -0
- package/assets/lighthouse.gltf +604 -0
- package/dist/chunk-2GM64LB6.js +9 -0
- package/dist/chunk-2GM64LB6.js.map +1 -0
- package/dist/chunk-3ARPGHCQ.js +119 -0
- package/dist/chunk-3ARPGHCQ.js.map +1 -0
- package/dist/chunk-4ZJ24VRS.js +402 -0
- package/dist/chunk-4ZJ24VRS.js.map +1 -0
- package/dist/chunk-W5GA3VA6.js +442 -0
- package/dist/chunk-W5GA3VA6.js.map +1 -0
- package/dist/gltf-loader-YDPLZS5Q.js +8 -0
- package/dist/index.cjs +2432 -6424
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +45 -6
- package/dist/index.js.map +1 -1
- package/dist/product-studio-runtime-HDAUDWYO.js +11 -0
- package/dist/showcase-inline-assets-WT4PSNKI.js +7 -0
- package/dist/showcase-inline-assets-WT4PSNKI.js.map +1 -0
- package/dist/showcase-runtime-SNCUFSSC.js +3785 -0
- package/dist/showcase-runtime-SNCUFSSC.js.map +1 -0
- package/package.json +20 -8
- package/src/asset-url.js +62 -11
- package/src/feature-flags.js +2 -0
- package/src/gltf-loader.js +330 -32
- package/src/i18n.js +71 -0
- package/src/index.d.ts +187 -2
- package/src/index.js +42 -1
- package/src/product-studio-runtime.js +465 -0
- package/src/showcase-inline-assets.js +3 -0
- package/src/showcase-runtime.js +1779 -252
- package/src/translations/en-GB.js +55 -0
- package/dist/chunk-DGUM43GV.js +0 -11
- package/dist/chunk-OTCJ3VOK.js +0 -35
- package/dist/chunk-OTCJ3VOK.js.map +0 -1
- package/dist/chunk-QBMXJ3V2.js +0 -142
- package/dist/chunk-QBMXJ3V2.js.map +0 -1
- package/dist/gltf-loader-LKALCZAV.js +0 -8
- package/dist/showcase-runtime-2ZNPKD7D.js +0 -8593
- package/dist/showcase-runtime-2ZNPKD7D.js.map +0 -1
- /package/dist/{chunk-DGUM43GV.js.map → gltf-loader-YDPLZS5Q.js.map} +0 -0
- /package/dist/{gltf-loader-LKALCZAV.js.map → product-studio-runtime-HDAUDWYO.js.map} +0 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loadGltfModel
|
|
3
|
+
} from "./chunk-W5GA3VA6.js";
|
|
4
|
+
|
|
5
|
+
// src/product-studio-runtime.js
|
|
6
|
+
var STYLE_ID = "plasius-product-studio-wavefront-style";
|
|
7
|
+
var DEFAULT_PRODUCT_ASSET_URL = "/data/models/eames-lounge-chair-ottoman/Eames_Lounge_Chair_Ottoman.gltf";
|
|
8
|
+
var DEFAULT_TARGET_CENTER = Object.freeze([0, 0.74, 0]);
|
|
9
|
+
var DEFAULT_TARGET_SIZE = 2.25;
|
|
10
|
+
function clamp(value, min, max) {
|
|
11
|
+
return Math.max(min, Math.min(max, value));
|
|
12
|
+
}
|
|
13
|
+
function isFiniteVector(value) {
|
|
14
|
+
return Array.isArray(value) && value.length >= 3 && Number.isFinite(value[0]) && Number.isFinite(value[1]) && Number.isFinite(value[2]);
|
|
15
|
+
}
|
|
16
|
+
function createEmptyBounds() {
|
|
17
|
+
return {
|
|
18
|
+
min: [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY],
|
|
19
|
+
max: [Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY]
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function expandBounds(bounds, point) {
|
|
23
|
+
bounds.min[0] = Math.min(bounds.min[0], point[0]);
|
|
24
|
+
bounds.min[1] = Math.min(bounds.min[1], point[1]);
|
|
25
|
+
bounds.min[2] = Math.min(bounds.min[2], point[2]);
|
|
26
|
+
bounds.max[0] = Math.max(bounds.max[0], point[0]);
|
|
27
|
+
bounds.max[1] = Math.max(bounds.max[1], point[1]);
|
|
28
|
+
bounds.max[2] = Math.max(bounds.max[2], point[2]);
|
|
29
|
+
}
|
|
30
|
+
function getBoundsSize(bounds) {
|
|
31
|
+
return [
|
|
32
|
+
bounds.max[0] - bounds.min[0],
|
|
33
|
+
bounds.max[1] - bounds.min[1],
|
|
34
|
+
bounds.max[2] - bounds.min[2]
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
function getBoundsCenter(bounds) {
|
|
38
|
+
return [
|
|
39
|
+
(bounds.min[0] + bounds.max[0]) * 0.5,
|
|
40
|
+
(bounds.min[1] + bounds.max[1]) * 0.5,
|
|
41
|
+
(bounds.min[2] + bounds.max[2]) * 0.5
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
function getModelBounds(model) {
|
|
45
|
+
if (isFiniteVector(model?.bounds?.min) && isFiniteVector(model?.bounds?.max)) {
|
|
46
|
+
return {
|
|
47
|
+
min: [...model.bounds.min],
|
|
48
|
+
max: [...model.bounds.max]
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const bounds = createEmptyBounds();
|
|
52
|
+
for (const primitive of model?.primitives ?? []) {
|
|
53
|
+
for (let index = 0; index < primitive.positions.length; index += 3) {
|
|
54
|
+
expandBounds(bounds, [
|
|
55
|
+
primitive.positions[index],
|
|
56
|
+
primitive.positions[index + 1],
|
|
57
|
+
primitive.positions[index + 2]
|
|
58
|
+
]);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return bounds;
|
|
62
|
+
}
|
|
63
|
+
function transformPoint(point, modelCenter, scale, targetCenter) {
|
|
64
|
+
return [
|
|
65
|
+
(point[0] - modelCenter[0]) * scale + targetCenter[0],
|
|
66
|
+
(point[1] - modelCenter[1]) * scale + targetCenter[1],
|
|
67
|
+
(point[2] - modelCenter[2]) * scale + targetCenter[2]
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
function readMaterialColor(material) {
|
|
71
|
+
const color = material?.color ?? {};
|
|
72
|
+
return [
|
|
73
|
+
Number.isFinite(color.r) ? color.r : 0.62,
|
|
74
|
+
Number.isFinite(color.g) ? color.g : 0.56,
|
|
75
|
+
Number.isFinite(color.b) ? color.b : 0.48,
|
|
76
|
+
Number.isFinite(color.a) ? color.a : 1
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
function readMaterialKind(material) {
|
|
80
|
+
const emissive = material?.emissive ?? {};
|
|
81
|
+
if ((emissive.r ?? 0) + (emissive.g ?? 0) + (emissive.b ?? 0) > 1e-3) {
|
|
82
|
+
return "emissive";
|
|
83
|
+
}
|
|
84
|
+
if ((material?.metallic ?? 0) >= 0.5) {
|
|
85
|
+
return "metal";
|
|
86
|
+
}
|
|
87
|
+
const alpha = readMaterialColor(material)[3];
|
|
88
|
+
if (alpha < 0.9) {
|
|
89
|
+
return "transparent";
|
|
90
|
+
}
|
|
91
|
+
return "diffuse";
|
|
92
|
+
}
|
|
93
|
+
function readEmission(material) {
|
|
94
|
+
const emissive = material?.emissive ?? {};
|
|
95
|
+
return [
|
|
96
|
+
Number.isFinite(emissive.r) ? emissive.r : 0,
|
|
97
|
+
Number.isFinite(emissive.g) ? emissive.g : 0,
|
|
98
|
+
Number.isFinite(emissive.b) ? emissive.b : 0,
|
|
99
|
+
1
|
|
100
|
+
];
|
|
101
|
+
}
|
|
102
|
+
function createQuadMesh({
|
|
103
|
+
id,
|
|
104
|
+
corners,
|
|
105
|
+
color,
|
|
106
|
+
emission = [0, 0, 0, 1],
|
|
107
|
+
materialKind = "diffuse",
|
|
108
|
+
roughness = 0.72,
|
|
109
|
+
metallic = 0,
|
|
110
|
+
opacity = color[3] ?? 1
|
|
111
|
+
}) {
|
|
112
|
+
const [a, b, c] = corners;
|
|
113
|
+
const edge1 = [b[0] - a[0], b[1] - a[1], b[2] - a[2]];
|
|
114
|
+
const edge2 = [c[0] - a[0], c[1] - a[1], c[2] - a[2]];
|
|
115
|
+
const normal = [
|
|
116
|
+
edge1[1] * edge2[2] - edge1[2] * edge2[1],
|
|
117
|
+
edge1[2] * edge2[0] - edge1[0] * edge2[2],
|
|
118
|
+
edge1[0] * edge2[1] - edge1[1] * edge2[0]
|
|
119
|
+
];
|
|
120
|
+
const length = Math.hypot(normal[0], normal[1], normal[2]) || 1;
|
|
121
|
+
const unitNormal = normal.map((value) => value / length);
|
|
122
|
+
return Object.freeze({
|
|
123
|
+
id,
|
|
124
|
+
positions: Object.freeze(corners.flat()),
|
|
125
|
+
indices: Object.freeze([0, 1, 2, 0, 2, 3]),
|
|
126
|
+
normals: Object.freeze([unitNormal, unitNormal, unitNormal, unitNormal].flat()),
|
|
127
|
+
color: Object.freeze([...color]),
|
|
128
|
+
emission: Object.freeze([...emission]),
|
|
129
|
+
materialKind,
|
|
130
|
+
roughness,
|
|
131
|
+
metallic,
|
|
132
|
+
opacity
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
function createProductStudioEnvironmentMeshes() {
|
|
136
|
+
return [
|
|
137
|
+
createQuadMesh({
|
|
138
|
+
id: 1,
|
|
139
|
+
corners: [
|
|
140
|
+
[-3.2, -0.08, 2.4],
|
|
141
|
+
[3.2, -0.08, 2.4],
|
|
142
|
+
[3.2, -0.08, -3.1],
|
|
143
|
+
[-3.2, -0.08, -3.1]
|
|
144
|
+
],
|
|
145
|
+
color: [0.48, 0.55, 0.55, 1],
|
|
146
|
+
roughness: 0.82
|
|
147
|
+
}),
|
|
148
|
+
createQuadMesh({
|
|
149
|
+
id: 2,
|
|
150
|
+
corners: [
|
|
151
|
+
[-3.2, -0.08, -2.45],
|
|
152
|
+
[3.2, -0.08, -2.45],
|
|
153
|
+
[3.2, 2.65, -2.45],
|
|
154
|
+
[-3.2, 2.65, -2.45]
|
|
155
|
+
],
|
|
156
|
+
color: [0.43, 0.42, 0.38, 1],
|
|
157
|
+
roughness: 0.86
|
|
158
|
+
}),
|
|
159
|
+
createQuadMesh({
|
|
160
|
+
id: 3,
|
|
161
|
+
corners: [
|
|
162
|
+
[-2.85, -0.08, -2.45],
|
|
163
|
+
[-2.85, 2.55, -2.45],
|
|
164
|
+
[-2.85, 2.55, 2.15],
|
|
165
|
+
[-2.85, -0.08, 2.15]
|
|
166
|
+
],
|
|
167
|
+
color: [0.36, 0.42, 0.45, 1],
|
|
168
|
+
roughness: 0.8
|
|
169
|
+
}),
|
|
170
|
+
createQuadMesh({
|
|
171
|
+
id: 4,
|
|
172
|
+
corners: [
|
|
173
|
+
[0.78, 2.55, -0.82],
|
|
174
|
+
[-0.78, 2.55, -0.82],
|
|
175
|
+
[-0.78, 2.55, -1.78],
|
|
176
|
+
[0.78, 2.55, -1.78]
|
|
177
|
+
],
|
|
178
|
+
color: [1, 0.94, 0.78, 1],
|
|
179
|
+
emission: [8.5, 7.2, 4.8, 1],
|
|
180
|
+
materialKind: "emissive",
|
|
181
|
+
roughness: 0
|
|
182
|
+
})
|
|
183
|
+
];
|
|
184
|
+
}
|
|
185
|
+
function createProductStudioMeshFromPrimitive(primitive, primitiveIndex, transform) {
|
|
186
|
+
if (!Array.isArray(primitive?.positions) || primitive.positions.length < 9) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
const positions = [];
|
|
190
|
+
for (let index = 0; index < primitive.positions.length; index += 3) {
|
|
191
|
+
const point = transform([
|
|
192
|
+
primitive.positions[index],
|
|
193
|
+
primitive.positions[index + 1],
|
|
194
|
+
primitive.positions[index + 2]
|
|
195
|
+
]);
|
|
196
|
+
positions.push(point[0], point[1], point[2]);
|
|
197
|
+
}
|
|
198
|
+
const indices = Array.isArray(primitive.indices) && primitive.indices.length >= 3 ? [...primitive.indices] : Array.from({ length: positions.length / 3 }, (_, index) => index);
|
|
199
|
+
const material = primitive.material ?? {};
|
|
200
|
+
const color = readMaterialColor(material);
|
|
201
|
+
return Object.freeze({
|
|
202
|
+
id: 1e3 + primitiveIndex,
|
|
203
|
+
positions: Object.freeze(positions),
|
|
204
|
+
indices: Object.freeze(indices),
|
|
205
|
+
normals: Array.isArray(primitive.normals) ? Object.freeze([...primitive.normals]) : null,
|
|
206
|
+
color: Object.freeze(color),
|
|
207
|
+
emission: Object.freeze(readEmission(material)),
|
|
208
|
+
materialKind: readMaterialKind(material),
|
|
209
|
+
materialRefId: 1e3 + primitiveIndex,
|
|
210
|
+
roughness: Number.isFinite(material.roughness) ? material.roughness : 0.72,
|
|
211
|
+
metallic: Number.isFinite(material.metallic) ? material.metallic : 0,
|
|
212
|
+
opacity: color[3]
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
function createProductStudioMeshes(model, options = {}) {
|
|
216
|
+
const primitives = Array.isArray(model?.primitives) ? model.primitives : [];
|
|
217
|
+
if (primitives.length === 0) {
|
|
218
|
+
throw new Error("Product Studio model must contain at least one renderable primitive.");
|
|
219
|
+
}
|
|
220
|
+
const targetCenter = isFiniteVector(options.targetCenter) ? [...options.targetCenter] : [...DEFAULT_TARGET_CENTER];
|
|
221
|
+
const targetSize = Number.isFinite(options.targetSize) ? Math.max(options.targetSize, 0.25) : DEFAULT_TARGET_SIZE;
|
|
222
|
+
const modelBounds = getModelBounds(model);
|
|
223
|
+
const modelSize = getBoundsSize(modelBounds);
|
|
224
|
+
const modelCenter = getBoundsCenter(modelBounds);
|
|
225
|
+
const scale = targetSize / Math.max(modelSize[0], modelSize[1], modelSize[2], 1e-6);
|
|
226
|
+
const transform = (point) => transformPoint(point, modelCenter, scale, targetCenter);
|
|
227
|
+
const modelMeshes = primitives.map((primitive, index) => createProductStudioMeshFromPrimitive(primitive, index, transform)).filter(Boolean);
|
|
228
|
+
return Object.freeze([...createProductStudioEnvironmentMeshes(), ...modelMeshes]);
|
|
229
|
+
}
|
|
230
|
+
function ensureStyles(documentRef) {
|
|
231
|
+
if (documentRef.getElementById?.(STYLE_ID)) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const style = documentRef.createElement("style");
|
|
235
|
+
style.id = STYLE_ID;
|
|
236
|
+
style.textContent = `
|
|
237
|
+
.plasius-product-studio-wavefront {
|
|
238
|
+
position: relative;
|
|
239
|
+
width: 100%;
|
|
240
|
+
min-height: 420px;
|
|
241
|
+
overflow: hidden;
|
|
242
|
+
background: #0f1418;
|
|
243
|
+
display: grid;
|
|
244
|
+
place-items: center;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.plasius-product-studio-wavefront canvas {
|
|
248
|
+
display: block;
|
|
249
|
+
width: 100%;
|
|
250
|
+
height: auto;
|
|
251
|
+
max-height: 100%;
|
|
252
|
+
aspect-ratio: 16 / 9;
|
|
253
|
+
min-height: 420px;
|
|
254
|
+
object-fit: contain;
|
|
255
|
+
}
|
|
256
|
+
`;
|
|
257
|
+
documentRef.head?.appendChild?.(style);
|
|
258
|
+
}
|
|
259
|
+
function resolveRoot(options) {
|
|
260
|
+
const documentRef = options.document ?? globalThis.document;
|
|
261
|
+
if (options.root) {
|
|
262
|
+
return options.root;
|
|
263
|
+
}
|
|
264
|
+
const root = documentRef?.querySelector?.("[data-plasius-gpu-product-studio]") ?? documentRef?.body;
|
|
265
|
+
if (!root) {
|
|
266
|
+
throw new Error("Product Studio requires a DOM root.");
|
|
267
|
+
}
|
|
268
|
+
return root;
|
|
269
|
+
}
|
|
270
|
+
function resolveRenderSize(root, options) {
|
|
271
|
+
const rect = root.getBoundingClientRect?.() ?? { width: 1280, height: 720 };
|
|
272
|
+
const devicePixelRatio = Number.isFinite(options.devicePixelRatio) ? options.devicePixelRatio : Number.isFinite(globalThis.window?.devicePixelRatio) ? globalThis.window.devicePixelRatio : 1;
|
|
273
|
+
const cssWidth = Number.isFinite(rect.width) && rect.width > 0 ? rect.width : 1280;
|
|
274
|
+
const cssHeight = Number.isFinite(rect.height) && rect.height > 0 ? rect.height : cssWidth * (9 / 16);
|
|
275
|
+
const width = Number.isFinite(options.width) ? Math.trunc(options.width) : clamp(Math.round(cssWidth * devicePixelRatio), 640, 1920);
|
|
276
|
+
const height = Number.isFinite(options.height) ? Math.trunc(options.height) : clamp(Math.round(cssHeight * devicePixelRatio), 360, 1080);
|
|
277
|
+
return {
|
|
278
|
+
width,
|
|
279
|
+
height
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
function installSnapshotHook(state) {
|
|
283
|
+
if (typeof globalThis.window === "undefined") {
|
|
284
|
+
return () => {
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
const previous = globalThis.window.render_game_to_text;
|
|
288
|
+
globalThis.window.render_game_to_text = () => JSON.stringify({
|
|
289
|
+
surface: "gpu-product-studio-wavefront",
|
|
290
|
+
model: state.modelName,
|
|
291
|
+
sourceTriangles: state.sourceTriangleCount,
|
|
292
|
+
meshCount: state.meshCount,
|
|
293
|
+
geometryMode: state.geometryMode,
|
|
294
|
+
requiresTriangleMeshRenderer: state.requiresTriangleMeshRenderer,
|
|
295
|
+
displayQuality: state.displayQuality,
|
|
296
|
+
requiresMeshBvhForDisplayQuality: state.requiresMeshBvhForDisplayQuality,
|
|
297
|
+
renderer: state.rendererStats
|
|
298
|
+
});
|
|
299
|
+
return () => {
|
|
300
|
+
if (previous === void 0) {
|
|
301
|
+
delete globalThis.window.render_game_to_text;
|
|
302
|
+
} else {
|
|
303
|
+
globalThis.window.render_game_to_text = previous;
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
function countSourceTriangles(model) {
|
|
308
|
+
return (model.primitives ?? []).reduce(
|
|
309
|
+
(total, primitive) => total + Math.floor((primitive.indices?.length ?? 0) / 3),
|
|
310
|
+
0
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
async function resolveWavefrontLightingOptions(options) {
|
|
314
|
+
const fallback = {
|
|
315
|
+
environmentColor: [0.35, 0.43, 0.49, 1],
|
|
316
|
+
ambientColor: [0.02, 0.024, 0.028, 1]
|
|
317
|
+
};
|
|
318
|
+
const lightingLoader = typeof options.__lightingLoader === "function" ? options.__lightingLoader : () => import("@plasius/gpu-lighting").catch(() => null);
|
|
319
|
+
const lightingModule = await lightingLoader();
|
|
320
|
+
if (typeof lightingModule?.createWavefrontEnvironmentLightingOptions !== "function") {
|
|
321
|
+
return fallback;
|
|
322
|
+
}
|
|
323
|
+
return lightingModule.createWavefrontEnvironmentLightingOptions({
|
|
324
|
+
preset: options.lightingPreset ?? "product-studio",
|
|
325
|
+
intensity: options.lightingIntensity
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
async function mountGpuProductStudio(options = {}, featureFlags = null) {
|
|
329
|
+
const root = resolveRoot(options);
|
|
330
|
+
const documentRef = options.document ?? root.ownerDocument ?? globalThis.document;
|
|
331
|
+
ensureStyles(documentRef);
|
|
332
|
+
const previousMarkup = root.innerHTML;
|
|
333
|
+
root.innerHTML = "";
|
|
334
|
+
root.classList?.add?.("plasius-product-studio-wavefront");
|
|
335
|
+
const canvas = documentRef.createElement("canvas");
|
|
336
|
+
canvas.dataset.plasiusGpuProductStudio = "wavefront";
|
|
337
|
+
root.appendChild(canvas);
|
|
338
|
+
const modelLoader = typeof options.__modelLoader === "function" ? options.__modelLoader : loadGltfModel;
|
|
339
|
+
const rendererLoader = typeof options.__rendererLoader === "function" ? options.__rendererLoader : () => import("@plasius/gpu-renderer");
|
|
340
|
+
const assetUrl = options.productAssetUrl ?? options.assetUrl ?? DEFAULT_PRODUCT_ASSET_URL;
|
|
341
|
+
const model = await modelLoader(assetUrl);
|
|
342
|
+
const meshes = createProductStudioMeshes(model, {
|
|
343
|
+
targetCenter: options.targetCenter,
|
|
344
|
+
targetSize: options.targetSize
|
|
345
|
+
});
|
|
346
|
+
const rendererModule = await rendererLoader();
|
|
347
|
+
if (typeof rendererModule.createWavefrontPathTracingComputeRenderer !== "function") {
|
|
348
|
+
throw new Error("Product Studio renderer loader must provide createWavefrontPathTracingComputeRenderer.");
|
|
349
|
+
}
|
|
350
|
+
const size = resolveRenderSize(root, options);
|
|
351
|
+
const lightingOptions = await resolveWavefrontLightingOptions(options);
|
|
352
|
+
const renderer = await rendererModule.createWavefrontPathTracingComputeRenderer({
|
|
353
|
+
canvas,
|
|
354
|
+
width: size.width,
|
|
355
|
+
height: size.height,
|
|
356
|
+
maxDepth: Number.isFinite(options.maxDepth) ? options.maxDepth : 6,
|
|
357
|
+
tileSize: Number.isFinite(options.tileSize) ? options.tileSize : 128,
|
|
358
|
+
samplesPerPixel: Number.isFinite(options.samplesPerPixel) ? options.samplesPerPixel : 8,
|
|
359
|
+
denoise: options.denoise !== false,
|
|
360
|
+
displayQuality: true,
|
|
361
|
+
meshes,
|
|
362
|
+
camera: {
|
|
363
|
+
position: [0, 1.12, 5.05],
|
|
364
|
+
target: [0, 0.72, 0],
|
|
365
|
+
up: [0, 1, 0],
|
|
366
|
+
fovYDegrees: 43
|
|
367
|
+
},
|
|
368
|
+
...lightingOptions
|
|
369
|
+
});
|
|
370
|
+
const rendererStats = renderer.renderOnce();
|
|
371
|
+
const state = Object.freeze({
|
|
372
|
+
featureFlags,
|
|
373
|
+
modelName: model.name,
|
|
374
|
+
sourceTriangleCount: countSourceTriangles(model),
|
|
375
|
+
meshCount: meshes.length,
|
|
376
|
+
geometryMode: "mesh-bvh-display-quality",
|
|
377
|
+
requiresTriangleMeshRenderer: true,
|
|
378
|
+
displayQuality: true,
|
|
379
|
+
requiresMeshBvhForDisplayQuality: true,
|
|
380
|
+
rendererStats
|
|
381
|
+
});
|
|
382
|
+
const restoreSnapshotHook = installSnapshotHook(state);
|
|
383
|
+
return Object.freeze({
|
|
384
|
+
state,
|
|
385
|
+
model,
|
|
386
|
+
canvas,
|
|
387
|
+
renderer,
|
|
388
|
+
meshes,
|
|
389
|
+
destroy() {
|
|
390
|
+
restoreSnapshotHook();
|
|
391
|
+
renderer.destroy();
|
|
392
|
+
root.classList?.remove?.("plasius-product-studio-wavefront");
|
|
393
|
+
root.innerHTML = previousMarkup;
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
export {
|
|
399
|
+
createProductStudioMeshes,
|
|
400
|
+
mountGpuProductStudio
|
|
401
|
+
};
|
|
402
|
+
//# sourceMappingURL=chunk-4ZJ24VRS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/product-studio-runtime.js"],"sourcesContent":["import { loadGltfModel } from \"./gltf-loader.js\";\n\nconst STYLE_ID = \"plasius-product-studio-wavefront-style\";\nconst DEFAULT_PRODUCT_ASSET_URL =\n \"/data/models/eames-lounge-chair-ottoman/Eames_Lounge_Chair_Ottoman.gltf\";\nconst DEFAULT_TARGET_CENTER = Object.freeze([0, 0.74, 0]);\nconst DEFAULT_TARGET_SIZE = 2.25;\n\nfunction clamp(value, min, max) {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction isFiniteVector(value) {\n return (\n Array.isArray(value) &&\n value.length >= 3 &&\n Number.isFinite(value[0]) &&\n Number.isFinite(value[1]) &&\n Number.isFinite(value[2])\n );\n}\n\nfunction createEmptyBounds() {\n return {\n min: [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY],\n max: [Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY],\n };\n}\n\nfunction expandBounds(bounds, point) {\n bounds.min[0] = Math.min(bounds.min[0], point[0]);\n bounds.min[1] = Math.min(bounds.min[1], point[1]);\n bounds.min[2] = Math.min(bounds.min[2], point[2]);\n bounds.max[0] = Math.max(bounds.max[0], point[0]);\n bounds.max[1] = Math.max(bounds.max[1], point[1]);\n bounds.max[2] = Math.max(bounds.max[2], point[2]);\n}\n\nfunction getBoundsSize(bounds) {\n return [\n bounds.max[0] - bounds.min[0],\n bounds.max[1] - bounds.min[1],\n bounds.max[2] - bounds.min[2],\n ];\n}\n\nfunction getBoundsCenter(bounds) {\n return [\n (bounds.min[0] + bounds.max[0]) * 0.5,\n (bounds.min[1] + bounds.max[1]) * 0.5,\n (bounds.min[2] + bounds.max[2]) * 0.5,\n ];\n}\n\nfunction getModelBounds(model) {\n if (isFiniteVector(model?.bounds?.min) && isFiniteVector(model?.bounds?.max)) {\n return {\n min: [...model.bounds.min],\n max: [...model.bounds.max],\n };\n }\n\n const bounds = createEmptyBounds();\n for (const primitive of model?.primitives ?? []) {\n for (let index = 0; index < primitive.positions.length; index += 3) {\n expandBounds(bounds, [\n primitive.positions[index],\n primitive.positions[index + 1],\n primitive.positions[index + 2],\n ]);\n }\n }\n return bounds;\n}\n\nfunction transformPoint(point, modelCenter, scale, targetCenter) {\n return [\n (point[0] - modelCenter[0]) * scale + targetCenter[0],\n (point[1] - modelCenter[1]) * scale + targetCenter[1],\n (point[2] - modelCenter[2]) * scale + targetCenter[2],\n ];\n}\n\nfunction readMaterialColor(material) {\n const color = material?.color ?? {};\n return [\n Number.isFinite(color.r) ? color.r : 0.62,\n Number.isFinite(color.g) ? color.g : 0.56,\n Number.isFinite(color.b) ? color.b : 0.48,\n Number.isFinite(color.a) ? color.a : 1,\n ];\n}\n\nfunction readMaterialKind(material) {\n const emissive = material?.emissive ?? {};\n if ((emissive.r ?? 0) + (emissive.g ?? 0) + (emissive.b ?? 0) > 0.001) {\n return \"emissive\";\n }\n if ((material?.metallic ?? 0) >= 0.5) {\n return \"metal\";\n }\n const alpha = readMaterialColor(material)[3];\n if (alpha < 0.9) {\n return \"transparent\";\n }\n return \"diffuse\";\n}\n\nfunction readEmission(material) {\n const emissive = material?.emissive ?? {};\n return [\n Number.isFinite(emissive.r) ? emissive.r : 0,\n Number.isFinite(emissive.g) ? emissive.g : 0,\n Number.isFinite(emissive.b) ? emissive.b : 0,\n 1,\n ];\n}\n\nfunction createQuadMesh({\n id,\n corners,\n color,\n emission = [0, 0, 0, 1],\n materialKind = \"diffuse\",\n roughness = 0.72,\n metallic = 0,\n opacity = color[3] ?? 1,\n}) {\n const [a, b, c] = corners;\n const edge1 = [b[0] - a[0], b[1] - a[1], b[2] - a[2]];\n const edge2 = [c[0] - a[0], c[1] - a[1], c[2] - a[2]];\n const normal = [\n edge1[1] * edge2[2] - edge1[2] * edge2[1],\n edge1[2] * edge2[0] - edge1[0] * edge2[2],\n edge1[0] * edge2[1] - edge1[1] * edge2[0],\n ];\n const length = Math.hypot(normal[0], normal[1], normal[2]) || 1;\n const unitNormal = normal.map((value) => value / length);\n\n return Object.freeze({\n id,\n positions: Object.freeze(corners.flat()),\n indices: Object.freeze([0, 1, 2, 0, 2, 3]),\n normals: Object.freeze([unitNormal, unitNormal, unitNormal, unitNormal].flat()),\n color: Object.freeze([...color]),\n emission: Object.freeze([...emission]),\n materialKind,\n roughness,\n metallic,\n opacity,\n });\n}\n\nfunction createProductStudioEnvironmentMeshes() {\n return [\n createQuadMesh({\n id: 1,\n corners: [\n [-3.2, -0.08, 2.4],\n [3.2, -0.08, 2.4],\n [3.2, -0.08, -3.1],\n [-3.2, -0.08, -3.1],\n ],\n color: [0.48, 0.55, 0.55, 1],\n roughness: 0.82,\n }),\n createQuadMesh({\n id: 2,\n corners: [\n [-3.2, -0.08, -2.45],\n [3.2, -0.08, -2.45],\n [3.2, 2.65, -2.45],\n [-3.2, 2.65, -2.45],\n ],\n color: [0.43, 0.42, 0.38, 1],\n roughness: 0.86,\n }),\n createQuadMesh({\n id: 3,\n corners: [\n [-2.85, -0.08, -2.45],\n [-2.85, 2.55, -2.45],\n [-2.85, 2.55, 2.15],\n [-2.85, -0.08, 2.15],\n ],\n color: [0.36, 0.42, 0.45, 1],\n roughness: 0.8,\n }),\n createQuadMesh({\n id: 4,\n corners: [\n [0.78, 2.55, -0.82],\n [-0.78, 2.55, -0.82],\n [-0.78, 2.55, -1.78],\n [0.78, 2.55, -1.78],\n ],\n color: [1, 0.94, 0.78, 1],\n emission: [8.5, 7.2, 4.8, 1],\n materialKind: \"emissive\",\n roughness: 0,\n }),\n ];\n}\n\nfunction createProductStudioMeshFromPrimitive(primitive, primitiveIndex, transform) {\n if (!Array.isArray(primitive?.positions) || primitive.positions.length < 9) {\n return null;\n }\n\n const positions = [];\n for (let index = 0; index < primitive.positions.length; index += 3) {\n const point = transform([\n primitive.positions[index],\n primitive.positions[index + 1],\n primitive.positions[index + 2],\n ]);\n positions.push(point[0], point[1], point[2]);\n }\n\n const indices =\n Array.isArray(primitive.indices) && primitive.indices.length >= 3\n ? [...primitive.indices]\n : Array.from({ length: positions.length / 3 }, (_, index) => index);\n const material = primitive.material ?? {};\n const color = readMaterialColor(material);\n\n return Object.freeze({\n id: 1000 + primitiveIndex,\n positions: Object.freeze(positions),\n indices: Object.freeze(indices),\n normals: Array.isArray(primitive.normals) ? Object.freeze([...primitive.normals]) : null,\n color: Object.freeze(color),\n emission: Object.freeze(readEmission(material)),\n materialKind: readMaterialKind(material),\n materialRefId: 1000 + primitiveIndex,\n roughness: Number.isFinite(material.roughness) ? material.roughness : 0.72,\n metallic: Number.isFinite(material.metallic) ? material.metallic : 0,\n opacity: color[3],\n });\n}\n\nexport function createProductStudioMeshes(model, options = {}) {\n const primitives = Array.isArray(model?.primitives) ? model.primitives : [];\n if (primitives.length === 0) {\n throw new Error(\"Product Studio model must contain at least one renderable primitive.\");\n }\n\n const targetCenter = isFiniteVector(options.targetCenter)\n ? [...options.targetCenter]\n : [...DEFAULT_TARGET_CENTER];\n const targetSize = Number.isFinite(options.targetSize)\n ? Math.max(options.targetSize, 0.25)\n : DEFAULT_TARGET_SIZE;\n const modelBounds = getModelBounds(model);\n const modelSize = getBoundsSize(modelBounds);\n const modelCenter = getBoundsCenter(modelBounds);\n const scale = targetSize / Math.max(modelSize[0], modelSize[1], modelSize[2], 0.000001);\n const transform = (point) => transformPoint(point, modelCenter, scale, targetCenter);\n const modelMeshes = primitives\n .map((primitive, index) => createProductStudioMeshFromPrimitive(primitive, index, transform))\n .filter(Boolean);\n\n return Object.freeze([...createProductStudioEnvironmentMeshes(), ...modelMeshes]);\n}\n\nfunction ensureStyles(documentRef) {\n if (documentRef.getElementById?.(STYLE_ID)) {\n return;\n }\n const style = documentRef.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = `\n .plasius-product-studio-wavefront {\n position: relative;\n width: 100%;\n min-height: 420px;\n overflow: hidden;\n background: #0f1418;\n display: grid;\n place-items: center;\n }\n\n .plasius-product-studio-wavefront canvas {\n display: block;\n width: 100%;\n height: auto;\n max-height: 100%;\n aspect-ratio: 16 / 9;\n min-height: 420px;\n object-fit: contain;\n }\n `;\n documentRef.head?.appendChild?.(style);\n}\n\nfunction resolveRoot(options) {\n const documentRef = options.document ?? globalThis.document;\n if (options.root) {\n return options.root;\n }\n const root =\n documentRef?.querySelector?.(\"[data-plasius-gpu-product-studio]\") ?? documentRef?.body;\n if (!root) {\n throw new Error(\"Product Studio requires a DOM root.\");\n }\n return root;\n}\n\nfunction resolveRenderSize(root, options) {\n const rect = root.getBoundingClientRect?.() ?? { width: 1280, height: 720 };\n const devicePixelRatio =\n Number.isFinite(options.devicePixelRatio)\n ? options.devicePixelRatio\n : Number.isFinite(globalThis.window?.devicePixelRatio)\n ? globalThis.window.devicePixelRatio\n : 1;\n const cssWidth = Number.isFinite(rect.width) && rect.width > 0 ? rect.width : 1280;\n const cssHeight =\n Number.isFinite(rect.height) && rect.height > 0 ? rect.height : cssWidth * (9 / 16);\n const width = Number.isFinite(options.width)\n ? Math.trunc(options.width)\n : clamp(Math.round(cssWidth * devicePixelRatio), 640, 1920);\n const height = Number.isFinite(options.height)\n ? Math.trunc(options.height)\n : clamp(Math.round(cssHeight * devicePixelRatio), 360, 1080);\n\n return {\n width,\n height,\n };\n}\n\nfunction installSnapshotHook(state) {\n if (typeof globalThis.window === \"undefined\") {\n return () => {};\n }\n const previous = globalThis.window.render_game_to_text;\n globalThis.window.render_game_to_text = () =>\n JSON.stringify({\n surface: \"gpu-product-studio-wavefront\",\n model: state.modelName,\n sourceTriangles: state.sourceTriangleCount,\n meshCount: state.meshCount,\n geometryMode: state.geometryMode,\n requiresTriangleMeshRenderer: state.requiresTriangleMeshRenderer,\n displayQuality: state.displayQuality,\n requiresMeshBvhForDisplayQuality: state.requiresMeshBvhForDisplayQuality,\n renderer: state.rendererStats,\n });\n return () => {\n if (previous === undefined) {\n delete globalThis.window.render_game_to_text;\n } else {\n globalThis.window.render_game_to_text = previous;\n }\n };\n}\n\nfunction countSourceTriangles(model) {\n return (model.primitives ?? []).reduce(\n (total, primitive) => total + Math.floor((primitive.indices?.length ?? 0) / 3),\n 0\n );\n}\n\nasync function resolveWavefrontLightingOptions(options) {\n const fallback = {\n environmentColor: [0.35, 0.43, 0.49, 1],\n ambientColor: [0.02, 0.024, 0.028, 1],\n };\n const lightingLoader =\n typeof options.__lightingLoader === \"function\"\n ? options.__lightingLoader\n : () => import(\"@plasius/gpu-lighting\").catch(() => null);\n const lightingModule = await lightingLoader();\n\n if (\n typeof lightingModule?.createWavefrontEnvironmentLightingOptions !== \"function\"\n ) {\n return fallback;\n }\n\n return lightingModule.createWavefrontEnvironmentLightingOptions({\n preset: options.lightingPreset ?? \"product-studio\",\n intensity: options.lightingIntensity,\n });\n}\n\nexport async function mountGpuProductStudio(options = {}, featureFlags = null) {\n const root = resolveRoot(options);\n const documentRef = options.document ?? root.ownerDocument ?? globalThis.document;\n ensureStyles(documentRef);\n const previousMarkup = root.innerHTML;\n root.innerHTML = \"\";\n root.classList?.add?.(\"plasius-product-studio-wavefront\");\n\n const canvas = documentRef.createElement(\"canvas\");\n canvas.dataset.plasiusGpuProductStudio = \"wavefront\";\n root.appendChild(canvas);\n\n const modelLoader =\n typeof options.__modelLoader === \"function\" ? options.__modelLoader : loadGltfModel;\n const rendererLoader =\n typeof options.__rendererLoader === \"function\"\n ? options.__rendererLoader\n : () => import(\"@plasius/gpu-renderer\");\n const assetUrl = options.productAssetUrl ?? options.assetUrl ?? DEFAULT_PRODUCT_ASSET_URL;\n const model = await modelLoader(assetUrl);\n const meshes = createProductStudioMeshes(model, {\n targetCenter: options.targetCenter,\n targetSize: options.targetSize,\n });\n const rendererModule = await rendererLoader();\n if (typeof rendererModule.createWavefrontPathTracingComputeRenderer !== \"function\") {\n throw new Error(\"Product Studio renderer loader must provide createWavefrontPathTracingComputeRenderer.\");\n }\n\n const size = resolveRenderSize(root, options);\n const lightingOptions = await resolveWavefrontLightingOptions(options);\n const renderer = await rendererModule.createWavefrontPathTracingComputeRenderer({\n canvas,\n width: size.width,\n height: size.height,\n maxDepth: Number.isFinite(options.maxDepth) ? options.maxDepth : 6,\n tileSize: Number.isFinite(options.tileSize) ? options.tileSize : 128,\n samplesPerPixel: Number.isFinite(options.samplesPerPixel) ? options.samplesPerPixel : 8,\n denoise: options.denoise !== false,\n displayQuality: true,\n meshes,\n camera: {\n position: [0, 1.12, 5.05],\n target: [0, 0.72, 0],\n up: [0, 1, 0],\n fovYDegrees: 43,\n },\n ...lightingOptions,\n });\n const rendererStats = renderer.renderOnce();\n const state = Object.freeze({\n featureFlags,\n modelName: model.name,\n sourceTriangleCount: countSourceTriangles(model),\n meshCount: meshes.length,\n geometryMode: \"mesh-bvh-display-quality\",\n requiresTriangleMeshRenderer: true,\n displayQuality: true,\n requiresMeshBvhForDisplayQuality: true,\n rendererStats,\n });\n const restoreSnapshotHook = installSnapshotHook(state);\n\n return Object.freeze({\n state,\n model,\n canvas,\n renderer,\n meshes,\n destroy() {\n restoreSnapshotHook();\n renderer.destroy();\n root.classList?.remove?.(\"plasius-product-studio-wavefront\");\n root.innerHTML = previousMarkup;\n },\n });\n}\n"],"mappings":"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","names":[]}
|