sceneview-web 1.5.0 → 3.5.1

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/sceneview.js DELETED
@@ -1,591 +0,0 @@
1
- /**
2
- * SceneView Web — Simple 3D for the web.
3
- *
4
- * One line to render a 3D model:
5
- * SceneView.modelViewer("canvas", "model.glb")
6
- *
7
- * Powered by Filament.js v1.70.1 (Google's PBR renderer, WASM).
8
- * https://sceneview.github.io
9
- *
10
- * @version 1.5.0
11
- * @license MIT
12
- */
13
- (function(global) {
14
- 'use strict';
15
-
16
- function _ensureFilament() {
17
- return new Promise(function(resolve, reject) {
18
- if (typeof Filament !== 'undefined') { resolve(); return; }
19
- var attempts = 0;
20
- var check = setInterval(function() {
21
- if (typeof Filament !== 'undefined') { clearInterval(check); resolve(); }
22
- if (++attempts > 100) { clearInterval(check); reject(new Error('SceneView: Filament.js not loaded')); }
23
- }, 50);
24
- });
25
- }
26
-
27
- class SceneViewInstance {
28
- constructor(canvas, engine, scene, renderer, view, swapChain, camera, cameraEntity, loader) {
29
- this._canvas = canvas;
30
- this._engine = engine;
31
- this._scene = scene;
32
- this._renderer = renderer;
33
- this._view = view;
34
- this._swapChain = swapChain;
35
- this._camera = camera;
36
- this._cameraEntity = cameraEntity;
37
- this._loader = loader;
38
- this._asset = null;
39
- this._angle = 0.785;
40
- this._autoRotate = true;
41
- this._orbitRadius = 3.5;
42
- this._orbitHeight = 0.8;
43
- this._orbitTarget = [0, 0, 0];
44
- this._running = true;
45
- this._isDragging = false;
46
- this._lastMouse = { x: 0, y: 0 };
47
- this._velocityAngle = 0;
48
- this._velocityHeight = 0;
49
- this._dampingFactor = 0.95;
50
- this._wantsAutoRotate = true;
51
- this._autoRotateTimer = null;
52
- this._userLights = [];
53
- this._setupControls();
54
- this._setupResizeObserver();
55
- this._startRenderLoop();
56
- }
57
-
58
- // ── Model loading ──
59
-
60
- loadModel(url) {
61
- var self = this;
62
- return new Promise(function(resolve, reject) {
63
- fetch(url)
64
- .then(function(resp) { return resp.arrayBuffer(); })
65
- .then(function(buffer) {
66
- Filament.assets = Filament.assets || {};
67
- Filament.assets[url] = new Uint8Array(buffer);
68
- try { self._showModel(url); resolve(self); } catch (e) { reject(e); }
69
- })
70
- .catch(reject);
71
- });
72
- }
73
-
74
- _showModel(url) {
75
- if (this._asset) {
76
- try {
77
- this._asset.getRenderableEntities().forEach(function(e) { this._scene.remove(e); }.bind(this));
78
- this._scene.remove(this._asset.getRoot());
79
- } catch (e) {}
80
- this._asset = null;
81
- }
82
- var data = Filament.assets[url];
83
- if (!data) throw new Error('Failed to fetch model: ' + url);
84
- var asset = this._loader.createAsset(data);
85
- if (!asset) throw new Error('Failed to parse model: ' + url);
86
- asset.loadResources();
87
- this._scene.addEntity(asset.getRoot());
88
- this._scene.addEntities(asset.getRenderableEntities());
89
- this._asset = asset;
90
- this._autoFrame(asset);
91
- }
92
-
93
- _autoFrame(asset) {
94
- try {
95
- var bbox = asset.getBoundingBox();
96
- var cx = (bbox.min[0] + bbox.max[0]) / 2;
97
- var cy = (bbox.min[1] + bbox.max[1]) / 2;
98
- var cz = (bbox.min[2] + bbox.max[2]) / 2;
99
- var maxDim = Math.max(bbox.max[0] - bbox.min[0], bbox.max[1] - bbox.min[1], bbox.max[2] - bbox.min[2]);
100
- if (maxDim > 0) {
101
- this._orbitTarget = [cx, cy, cz];
102
- this._orbitRadius = maxDim * 1.8;
103
- this._orbitHeight = cy;
104
- }
105
- } catch (e) {}
106
- }
107
-
108
- addModel(url) {
109
- var self = this;
110
- return new Promise(function(resolve, reject) {
111
- fetch(url)
112
- .then(function(resp) { return resp.arrayBuffer(); })
113
- .then(function(buffer) {
114
- try {
115
- var asset = self._loader.createAsset(new Uint8Array(buffer));
116
- if (!asset) { reject(new Error('Failed to parse: ' + url)); return; }
117
- asset.loadResources();
118
- self._scene.addEntity(asset.getRoot());
119
- self._scene.addEntities(asset.getRenderableEntities());
120
- resolve(asset);
121
- } catch (e) { reject(e); }
122
- })
123
- .catch(reject);
124
- });
125
- }
126
-
127
- loadGLBBuffer(buffer) {
128
- var asset = this._loader.createAsset(buffer);
129
- if (!asset) return null;
130
- asset.loadResources();
131
- this._scene.addEntity(asset.getRoot());
132
- this._scene.addEntities(asset.getRenderableEntities());
133
- return asset;
134
- }
135
-
136
- removeAsset(asset) {
137
- if (!asset) return;
138
- try {
139
- asset.getRenderableEntities().forEach(function(e) { this._scene.remove(e); }.bind(this));
140
- this._scene.remove(asset.getRoot());
141
- } catch (e) {}
142
- }
143
-
144
- get engine() { return this._engine; }
145
- get scene() { return this._scene; }
146
- get view() { return this._view; }
147
- get camera() { return this._camera; }
148
-
149
- // ── Basic setters ──
150
-
151
- setAutoRotate(enabled) { this._autoRotate = enabled; this._wantsAutoRotate = enabled; return this; }
152
- setCameraDistance(d) { this._orbitRadius = d; return this; }
153
-
154
- setBackgroundColor(r, g, b, a) {
155
- this._renderer.setClearOptions({ clearColor: [r, g, b, a !== undefined ? a : 1], clear: true });
156
- return this;
157
- }
158
-
159
- // ── Post-processing ──
160
-
161
- setBloom(opts) {
162
- try { this._view.setBloomOptions(Object.assign({ enabled: true, strength: 0.1, resolution: 360, levels: 6, blendMode: 0 }, opts)); } catch (e) {}
163
- return this;
164
- }
165
-
166
- setFog(opts) {
167
- try { this._view.setFogOptions(Object.assign({ enabled: true, distance: 10, maximumOpacity: 0.8, color: [0.5, 0.55, 0.65] }, opts)); } catch (e) {}
168
- return this;
169
- }
170
-
171
- setVignette(opts) {
172
- try { this._view.setVignetteOptions(Object.assign({ enabled: true, midPoint: 0.5, roundness: 0.5, feather: 0.5 }, opts)); } catch (e) {}
173
- return this;
174
- }
175
-
176
- setDOF(opts) {
177
- try { this._view.setDepthOfFieldOptions(Object.assign({ enabled: true, cocScale: 1.0 }, opts)); } catch (e) {}
178
- return this;
179
- }
180
-
181
- setMSAA(opts) {
182
- try { this._view.setMultiSampleAntiAliasingOptions(Object.assign({ enabled: true, sampleCount: 4 }, opts)); } catch (e) {}
183
- return this;
184
- }
185
-
186
- setTAA(opts) {
187
- try { this._view.setTemporalAntiAliasingOptions(Object.assign({ enabled: true }, opts)); } catch (e) {}
188
- return this;
189
- }
190
-
191
- setSSR(opts) {
192
- try { this._view.setScreenSpaceReflectionsOptions(Object.assign({ enabled: true }, opts)); } catch (e) {}
193
- return this;
194
- }
195
-
196
- setQuality(level) {
197
- if (level === 'low') {
198
- this.setBloom({ enabled: false }); this.setMSAA({ enabled: false });
199
- } else if (level === 'medium') {
200
- this.setBloom({ enabled: true, strength: 0.05 }); this.setMSAA({ enabled: true, sampleCount: 2 });
201
- } else if (level === 'high') {
202
- this.setBloom({ enabled: true, strength: 0.1 }); this.setMSAA({ enabled: true, sampleCount: 4 }); this.setVignette({ enabled: true });
203
- } else if (level === 'ultra') {
204
- this.setBloom({ enabled: true, strength: 0.15 }); this.setMSAA({ enabled: true, sampleCount: 4 });
205
- this.setTAA({ enabled: true }); this.setSSR({ enabled: true }); this.setVignette({ enabled: true });
206
- }
207
- return this;
208
- }
209
-
210
- // ── Camera helpers ──
211
-
212
- setCameraPosition(x, y, z) {
213
- this._orbitRadius = Math.sqrt(x * x + z * z);
214
- this._orbitHeight = y;
215
- this._angle = Math.atan2(x, z);
216
- return this;
217
- }
218
-
219
- setCameraTarget(x, y, z) { this._orbitTarget = [x, y, z]; return this; }
220
-
221
- setCameraFOV(degrees) {
222
- this._fov = degrees;
223
- var c = this._canvas;
224
- this._camera.setProjectionFov(degrees, c.width / c.height, 0.1, 1000, Filament.Camera$Fov.VERTICAL);
225
- return this;
226
- }
227
-
228
- setOrbitSpeed(speed) { this._orbitSpeed = speed; return this; }
229
-
230
- setOrbitLimits(opts) {
231
- if (opts.minDistance !== undefined) this._minRadius = opts.minDistance;
232
- if (opts.maxDistance !== undefined) this._maxRadius = opts.maxDistance;
233
- return this;
234
- }
235
-
236
- animateCamera(opts) {
237
- var self = this;
238
- var duration = opts.duration || 1000;
239
- var startTime = performance.now();
240
- var sA = this._angle, sR = this._orbitRadius, sH = this._orbitHeight;
241
- var sT = this._orbitTarget.slice();
242
- var eT = opts.target || sT;
243
- var eR = opts.distance !== undefined ? opts.distance : sR;
244
- var eH = opts.height !== undefined ? opts.height : sH;
245
- var eA = opts.angle !== undefined ? opts.angle : sA;
246
- var wasAuto = this._autoRotate;
247
- this._autoRotate = false;
248
- this._cameraAnimating = true;
249
-
250
- function ease(t) { return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2; }
251
- function lerp(a, b, t) { return a + (b - a) * t; }
252
-
253
- function step(now) {
254
- if (!self._running || !self._cameraAnimating) return;
255
- var t = ease(Math.min((now - startTime) / duration, 1));
256
- self._angle = lerp(sA, eA, t);
257
- self._orbitRadius = lerp(sR, eR, t);
258
- self._orbitHeight = lerp(sH, eH, t);
259
- self._orbitTarget = [lerp(sT[0], eT[0], t), lerp(sT[1], eT[1], t), lerp(sT[2], eT[2], t)];
260
- if (t < 1) { requestAnimationFrame(step); }
261
- else { self._cameraAnimating = false; if (wasAuto) self._autoRotate = true; if (opts.onComplete) opts.onComplete(); }
262
- }
263
- requestAnimationFrame(step);
264
- return this;
265
- }
266
-
267
- // ── Dynamic lights ──
268
-
269
- addLight(type, opts) {
270
- opts = opts || {};
271
- var entity = Filament.EntityManager.get().create();
272
- var typeMap = { sun: Filament.LightManager$Type.SUN, directional: Filament.LightManager$Type.DIRECTIONAL, point: Filament.LightManager$Type.POINT, spot: Filament.LightManager$Type.SPOT };
273
- var builder = Filament.LightManager.Builder(typeMap[type] || Filament.LightManager$Type.POINT)
274
- .color(opts.color || [1, 1, 1]).intensity(opts.intensity || 100000);
275
- if (opts.direction) builder.direction(opts.direction);
276
- if (opts.position) builder.position(opts.position);
277
- if (opts.falloff) builder.falloff(opts.falloff);
278
- if (opts.castShadows) builder.castShadows(true);
279
- if (type === 'spot') builder.spotLightCone(opts.innerCone || 0.5, opts.outerCone || 0.7);
280
- if (type === 'sun') { builder.sunAngularRadius(opts.angularRadius || 1.9); builder.sunHaloSize(opts.haloSize || 10.0); builder.sunHaloFalloff(opts.haloFalloff || 80.0); }
281
- builder.build(this._engine, entity);
282
- this._scene.addEntity(entity);
283
- this._userLights.push(entity);
284
- return entity;
285
- }
286
-
287
- removeLight(entity) {
288
- this._scene.remove(entity);
289
- var i = this._userLights.indexOf(entity);
290
- if (i >= 0) this._userLights.splice(i, 1);
291
- return this;
292
- }
293
-
294
- clearLights() {
295
- this._userLights.forEach(function(e) { this._scene.remove(e); }.bind(this));
296
- this._userLights = [];
297
- return this;
298
- }
299
-
300
- // ── Skybox control ──
301
-
302
- setSkyboxColor(r, g, b) {
303
- try { this._scene.setSkybox(Filament.Skybox.Builder().color([r, g, b, 1]).build(this._engine)); } catch (e) {}
304
- return this;
305
- }
306
-
307
- removeSkybox() { try { this._scene.setSkybox(null); } catch (e) {} return this; }
308
-
309
- // ── Asset querying ──
310
-
311
- getEntitiesByName(name) { if (!this._asset) return []; try { return this._asset.getEntitiesByName(name); } catch (e) { return []; } }
312
- getEntitiesByPrefix(prefix) { if (!this._asset) return []; try { return this._asset.getEntitiesByPrefix(prefix); } catch (e) { return []; } }
313
-
314
- // ── Lifecycle ──
315
-
316
- dispose() {
317
- this._running = false;
318
- if (this._resizeObserver) this._resizeObserver.disconnect();
319
- _activeCanvases.delete(this._canvas);
320
- try { Filament.Engine.destroy(this._engine); } catch (e) {}
321
- }
322
-
323
- _setupControls() {
324
- var canvas = this._canvas;
325
- var self = this;
326
-
327
- canvas.addEventListener('mousedown', function(e) {
328
- self._isDragging = true;
329
- self._lastMouse = { x: e.clientX, y: e.clientY };
330
- self._autoRotate = false;
331
- self._velocityAngle = 0;
332
- self._velocityHeight = 0;
333
- if (self._autoRotateTimer) { clearTimeout(self._autoRotateTimer); self._autoRotateTimer = null; }
334
- });
335
- canvas.addEventListener('mousemove', function(e) {
336
- if (!self._isDragging) return;
337
- var dx = (e.clientX - self._lastMouse.x) * 0.005;
338
- var dy = (e.clientY - self._lastMouse.y) * 0.01;
339
- self._velocityAngle = -dx;
340
- self._velocityHeight = dy;
341
- self._angle -= dx;
342
- self._orbitHeight += dy;
343
- self._lastMouse = { x: e.clientX, y: e.clientY };
344
- });
345
- canvas.addEventListener('mouseup', function() {
346
- self._isDragging = false;
347
- if (self._wantsAutoRotate) {
348
- self._autoRotateTimer = setTimeout(function() { self._autoRotate = true; }, 3000);
349
- }
350
- });
351
- canvas.addEventListener('mouseleave', function() {
352
- self._isDragging = false;
353
- if (self._wantsAutoRotate) {
354
- self._autoRotateTimer = setTimeout(function() { self._autoRotate = true; }, 3000);
355
- }
356
- });
357
-
358
- canvas.addEventListener('wheel', function(e) {
359
- e.preventDefault();
360
- self._orbitRadius *= (1 + e.deltaY * 0.001);
361
- var minR = self._minRadius || 0.5;
362
- var maxR = self._maxRadius || 50;
363
- self._orbitRadius = Math.max(minR, Math.min(maxR, self._orbitRadius));
364
- }, { passive: false });
365
-
366
- canvas.addEventListener('touchstart', function(e) {
367
- if (e.touches.length === 1) {
368
- self._isDragging = true;
369
- self._lastMouse = { x: e.touches[0].clientX, y: e.touches[0].clientY };
370
- self._autoRotate = false;
371
- self._velocityAngle = 0;
372
- self._velocityHeight = 0;
373
- if (self._autoRotateTimer) { clearTimeout(self._autoRotateTimer); self._autoRotateTimer = null; }
374
- }
375
- });
376
- canvas.addEventListener('touchmove', function(e) {
377
- if (!self._isDragging || e.touches.length !== 1) return;
378
- e.preventDefault();
379
- var dx = (e.touches[0].clientX - self._lastMouse.x) * 0.005;
380
- var dy = (e.touches[0].clientY - self._lastMouse.y) * 0.01;
381
- self._velocityAngle = -dx;
382
- self._velocityHeight = dy;
383
- self._angle -= dx;
384
- self._orbitHeight += dy;
385
- self._lastMouse = { x: e.touches[0].clientX, y: e.touches[0].clientY };
386
- }, { passive: false });
387
- canvas.addEventListener('touchend', function() {
388
- self._isDragging = false;
389
- if (self._wantsAutoRotate) {
390
- self._autoRotateTimer = setTimeout(function() { self._autoRotate = true; }, 3000);
391
- }
392
- });
393
- }
394
-
395
- _setupResizeObserver() {
396
- var self = this;
397
- this._resizeObserver = new ResizeObserver(function() {
398
- var canvas = self._canvas;
399
- var dpr = Math.min(devicePixelRatio, 2);
400
- canvas.width = canvas.clientWidth * dpr;
401
- canvas.height = canvas.clientHeight * dpr;
402
- self._view.setViewport([0, 0, canvas.width, canvas.height]);
403
- self._camera.setProjectionFov(
404
- self._fov || 45, canvas.width / canvas.height, 0.1, 1000,
405
- Filament.Camera$Fov.VERTICAL
406
- );
407
- });
408
- this._resizeObserver.observe(this._canvas);
409
- }
410
-
411
- _startRenderLoop() {
412
- var self = this;
413
- function render() {
414
- if (!self._running) return;
415
- if (self._autoRotate) self._angle += (self._orbitSpeed || 0.00873);
416
- if (!self._isDragging && !self._cameraAnimating) {
417
- self._angle += self._velocityAngle;
418
- self._orbitHeight += self._velocityHeight;
419
- self._velocityAngle *= self._dampingFactor;
420
- self._velocityHeight *= self._dampingFactor;
421
- if (Math.abs(self._velocityAngle) < 0.00005) self._velocityAngle = 0;
422
- if (Math.abs(self._velocityHeight) < 0.00005) self._velocityHeight = 0;
423
- }
424
- var t = self._orbitTarget;
425
- var r = self._orbitRadius;
426
- var h = self._orbitHeight;
427
- self._camera.lookAt(
428
- [t[0] + Math.sin(self._angle) * r, h, t[2] + Math.cos(self._angle) * r],
429
- t, [0, 1, 0]
430
- );
431
- self._engine.execute();
432
- try {
433
- if (self._renderer.beginFrame(self._swapChain)) {
434
- self._renderer.renderView(self._view);
435
- self._renderer.endFrame();
436
- }
437
- } catch (e) {
438
- console.error('SceneView render error:', e.message);
439
- self._running = false;
440
- }
441
- requestAnimationFrame(render);
442
- }
443
- render();
444
- }
445
- }
446
-
447
- var _activeCanvases = new Set();
448
-
449
- function _createEngine(canvasOrId, options) {
450
- options = options || {};
451
- var canvas = typeof canvasOrId === 'string' ? document.getElementById(canvasOrId) : canvasOrId;
452
- if (!canvas) throw new Error('Canvas not found: ' + canvasOrId);
453
- if (_activeCanvases.has(canvas)) { console.warn('SceneView: Canvas already initialized, skipping'); return null; }
454
- _activeCanvases.add(canvas);
455
-
456
- var dpr = Math.min(devicePixelRatio, 2);
457
- var cssW = canvas.clientWidth || canvas.offsetWidth || 500;
458
- var cssH = canvas.clientHeight || canvas.offsetHeight || 500;
459
- canvas.width = cssW * dpr;
460
- canvas.height = cssH * dpr;
461
-
462
- var engine = Filament.Engine.create(canvas);
463
- var scene = engine.createScene();
464
- var renderer = engine.createRenderer();
465
- var cameraEntity = Filament.EntityManager.get().create();
466
- var camera = engine.createCamera(cameraEntity);
467
- var view = engine.createView();
468
- var swapChain = engine.createSwapChain();
469
-
470
- view.setCamera(camera);
471
- view.setScene(scene);
472
- view.setViewport([0, 0, canvas.width, canvas.height]);
473
-
474
- var bg = options.backgroundColor || [0.05, 0.06, 0.1, 1.0];
475
- renderer.setClearOptions({ clearColor: bg, clear: true });
476
-
477
- var fov = options.fov || 45;
478
- camera.setProjectionFov(fov, canvas.width / canvas.height, 0.1, 1000, Filament.Camera$Fov.VERTICAL);
479
- camera.lookAt([0, 1, 5], [0, 0, 0], [0, 1, 0]);
480
-
481
- try { view.setAmbientOcclusionOptions({ enabled: true, radius: 0.3, bias: 0.0005, intensity: 1.0, quality: 1 }); } catch (e) {}
482
-
483
- var sun = Filament.EntityManager.get().create();
484
- Filament.LightManager.Builder(Filament.LightManager$Type.SUN)
485
- .color([0.98, 0.92, 0.89]).intensity(options.lightIntensity || 110000)
486
- .direction([0.6, -1.0, -0.8]).sunAngularRadius(1.9).sunHaloSize(10.0).sunHaloFalloff(80.0)
487
- .build(engine, sun);
488
- scene.addEntity(sun);
489
-
490
- var fill = Filament.EntityManager.get().create();
491
- Filament.LightManager.Builder(Filament.LightManager$Type.DIRECTIONAL)
492
- .color([0.7, 0.75, 0.9]).intensity(60000).direction([-0.5, 0.5, 1.0])
493
- .build(engine, fill);
494
- scene.addEntity(fill);
495
-
496
- var back = Filament.EntityManager.get().create();
497
- Filament.LightManager.Builder(Filament.LightManager$Type.DIRECTIONAL)
498
- .color([0.5, 0.6, 0.9]).intensity(50000).direction([0, 0.3, 1.0])
499
- .build(engine, back);
500
- scene.addEntity(back);
501
-
502
- var iblUrl = options.iblUrl || 'environments/neutral_ibl.ktx';
503
- fetch(iblUrl)
504
- .then(function(r) {
505
- if (!r.ok) throw new Error('HTTP ' + r.status);
506
- return r.arrayBuffer().then(function(ab) { return new Uint8Array(ab); });
507
- })
508
- .then(function(buffer) {
509
- try {
510
- var ibl = engine.createIblFromKtx1(buffer);
511
- ibl.setIntensity(options.iblIntensity || 40000);
512
- scene.setIndirectLight(ibl);
513
- if (options.skybox !== false) {
514
- try {
515
- var reflections = ibl.getReflectionsTexture();
516
- if (reflections) {
517
- scene.setSkybox(Filament.Skybox.Builder().environment(reflections).build(engine));
518
- console.log('SceneView: Skybox created from IBL cubemap');
519
- }
520
- } catch (skyErr) { console.log('SceneView: Skybox not available (IBL-only mode)'); }
521
- }
522
- console.log('SceneView: KTX IBL loaded (' + Math.round(buffer.length / 1024) + 'KB)');
523
- } catch (e) {
524
- console.warn('SceneView: createIblFromKtx1 failed, using SH fallback', e);
525
- _applySyntheticIBL(engine, scene);
526
- }
527
- })
528
- .catch(function() { _applySyntheticIBL(engine, scene); });
529
-
530
- var loader = engine.createAssetLoader();
531
- var instance = new SceneViewInstance(canvas, engine, scene, renderer, view, swapChain, camera, cameraEntity, loader);
532
- instance._fov = fov;
533
-
534
- if (options.autoRotate === false) instance.setAutoRotate(false);
535
- if (options.quality) instance.setQuality(options.quality);
536
- if (options.bloom) instance.setBloom(typeof options.bloom === 'object' ? options.bloom : {});
537
- if (options.fog) instance.setFog(typeof options.fog === 'object' ? options.fog : {});
538
- if (options.vignette) instance.setVignette(typeof options.vignette === 'object' ? options.vignette : {});
539
- if (options.dof) instance.setDOF(typeof options.dof === 'object' ? options.dof : {});
540
- if (options.msaa) instance.setMSAA(typeof options.msaa === 'object' ? options.msaa : {});
541
-
542
- return instance;
543
- }
544
-
545
- function _applySyntheticIBL(engine, scene) {
546
- try {
547
- var ibl = Filament.IndirectLight.Builder()
548
- .irradiance(3, [
549
- 0.65, 0.65, 0.70, 0.10, 0.10, 0.12, 0.15, 0.15, 0.18,
550
- -0.02, -0.02, -0.01, 0.04, 0.04, 0.05, 0.08, 0.08, 0.10,
551
- 0.01, 0.01, 0.01, -0.02, -0.02, -0.02, 0.03, 0.03, 0.03
552
- ])
553
- .intensity(35000).build(engine);
554
- scene.setIndirectLight(ibl);
555
- console.log('SceneView: Using synthetic SH IBL');
556
- } catch (e) {}
557
- }
558
-
559
- function create(canvasOrId, options) {
560
- return _ensureFilament().then(function() {
561
- return new Promise(function(resolve, reject) {
562
- if (typeof Filament.Engine !== 'undefined') {
563
- try {
564
- var instance = _createEngine(canvasOrId, options);
565
- if (instance) resolve(instance); else reject(new Error('SceneView: Canvas already initialized'));
566
- } catch (e) { reject(e); }
567
- return;
568
- }
569
- Filament.init([], function() {
570
- try {
571
- var instance = _createEngine(canvasOrId, options);
572
- if (instance) resolve(instance); else reject(new Error('SceneView: Canvas already initialized'));
573
- } catch (e) { reject(e); }
574
- });
575
- });
576
- });
577
- }
578
-
579
- function modelViewer(canvasOrId, modelUrl, options) {
580
- return create(canvasOrId, options).then(function(instance) {
581
- return instance.loadModel(modelUrl);
582
- });
583
- }
584
-
585
- global.SceneView = {
586
- version: '1.5.0',
587
- create: create,
588
- modelViewer: modelViewer
589
- };
590
-
591
- })(typeof globalThis !== 'undefined' ? globalThis : window);