@displayxr/inline3d 1.11.0 → 1.12.0
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 +55 -0
- package/README.md +18 -5
- package/js/inline3d-model-entry.js +242 -0
- package/js/inline3d-model-playcanvas.js +754 -0
- package/js/inline3d-playcanvas-engine.js +77 -0
- package/js/inline3d-splat-playcanvas.js +30 -8
- package/model.d.ts +109 -30
- package/package.json +15 -3
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// inline3d-playcanvas-engine.js — the slice of `playcanvas` the SDK's two PlayCanvas backends use,
|
|
2
|
+
// as NAMED re-exports.
|
|
3
|
+
//
|
|
4
|
+
// Internal. ./model and ./splat import THIS module (dynamically) instead of `import('playcanvas')`.
|
|
5
|
+
// A dynamic import of the package hands back its whole namespace, and a bundler cannot know which
|
|
6
|
+
// members a namespace object will be asked for — so it keeps all of them: the full engine
|
|
7
|
+
// (physics, UI, audio, particles, XR, the WebGPU backend …) lands in the page's bundle. Naming
|
|
8
|
+
// the members here is what lets a bundler drop everything else. The page's own `import … from
|
|
9
|
+
// 'playcanvas'` still resolves to the SAME module instance, so entities a page adds under
|
|
10
|
+
// `handle.engine.root` are the engine's own types.
|
|
11
|
+
//
|
|
12
|
+
// Adding an engine member to either adapter? Add it here too; test/playcanvas-engine.test.mjs
|
|
13
|
+
// fails on a `pc.X` the adapters read that this list does not export.
|
|
14
|
+
export {
|
|
15
|
+
// app + device
|
|
16
|
+
AppBase,
|
|
17
|
+
AppOptions,
|
|
18
|
+
createGraphicsDevice,
|
|
19
|
+
DEVICETYPE_WEBGL2,
|
|
20
|
+
RESOLUTION_FIXED,
|
|
21
|
+
// component systems + resource handlers (PLAYCANVAS_SYSTEMS / PLAYCANVAS_HANDLERS)
|
|
22
|
+
CameraComponentSystem,
|
|
23
|
+
GSplatComponentSystem,
|
|
24
|
+
RenderComponentSystem,
|
|
25
|
+
LightComponentSystem,
|
|
26
|
+
AnimComponentSystem,
|
|
27
|
+
TextureHandler,
|
|
28
|
+
GSplatHandler,
|
|
29
|
+
ContainerHandler,
|
|
30
|
+
// scene graph + cameras
|
|
31
|
+
Entity,
|
|
32
|
+
GraphNode,
|
|
33
|
+
Camera,
|
|
34
|
+
RenderView,
|
|
35
|
+
Asset,
|
|
36
|
+
Color,
|
|
37
|
+
Vec4,
|
|
38
|
+
Quat,
|
|
39
|
+
LAYERID_SKYBOX,
|
|
40
|
+
LAYERID_UI,
|
|
41
|
+
// materials / meshes (the edge feather)
|
|
42
|
+
Mesh,
|
|
43
|
+
MeshInstance,
|
|
44
|
+
ShaderMaterial,
|
|
45
|
+
BlendState,
|
|
46
|
+
BLENDEQUATION_ADD,
|
|
47
|
+
BLENDMODE_SRC_ALPHA,
|
|
48
|
+
BLENDMODE_ZERO,
|
|
49
|
+
CULLFACE_NONE,
|
|
50
|
+
SEMANTIC_POSITION,
|
|
51
|
+
SEMANTIC_TEXCOORD0,
|
|
52
|
+
ShaderChunks,
|
|
53
|
+
SHADERLANGUAGE_GLSL,
|
|
54
|
+
// splats
|
|
55
|
+
WORKBUFFER_UPDATE_ALWAYS,
|
|
56
|
+
WORKBUFFER_UPDATE_ONCE,
|
|
57
|
+
// tone mapping (TONE_MAPPINGS)
|
|
58
|
+
TONEMAP_NONE,
|
|
59
|
+
TONEMAP_LINEAR,
|
|
60
|
+
TONEMAP_NEUTRAL,
|
|
61
|
+
TONEMAP_ACES,
|
|
62
|
+
TONEMAP_ACES2,
|
|
63
|
+
TONEMAP_FILMIC,
|
|
64
|
+
TONEMAP_HEJL,
|
|
65
|
+
// lighting (./model)
|
|
66
|
+
Texture,
|
|
67
|
+
EnvLighting,
|
|
68
|
+
PIXELFORMAT_RGBA8,
|
|
69
|
+
TEXTURETYPE_RGBE,
|
|
70
|
+
TEXTUREPROJECTION_EQUIRECT,
|
|
71
|
+
ADDRESS_REPEAT,
|
|
72
|
+
ADDRESS_CLAMP_TO_EDGE,
|
|
73
|
+
// compressed glTF (./model)
|
|
74
|
+
dracoInitialize,
|
|
75
|
+
basisInitialize,
|
|
76
|
+
version,
|
|
77
|
+
} from 'playcanvas';
|
|
@@ -145,6 +145,17 @@ const PAGE_POSE_ERROR =
|
|
|
145
145
|
|
|
146
146
|
const DEG = Math.PI / 180;
|
|
147
147
|
|
|
148
|
+
/** Tone-mapping names the viewer takes → the engine's constant names. */
|
|
149
|
+
export const TONE_MAPPINGS = Object.freeze({
|
|
150
|
+
none: 'TONEMAP_NONE',
|
|
151
|
+
linear: 'TONEMAP_LINEAR',
|
|
152
|
+
neutral: 'TONEMAP_NEUTRAL',
|
|
153
|
+
aces: 'TONEMAP_ACES',
|
|
154
|
+
aces2: 'TONEMAP_ACES2',
|
|
155
|
+
filmic: 'TONEMAP_FILMIC',
|
|
156
|
+
hejl: 'TONEMAP_HEJL',
|
|
157
|
+
});
|
|
158
|
+
|
|
148
159
|
// ── pure matrix arithmetic (column-major, the layout XRView, three and the engine all use) ──
|
|
149
160
|
|
|
150
161
|
/** three's `Matrix4.makePerspective(left, right, top, bottom, near, far)`, element for element. */
|
|
@@ -606,6 +617,7 @@ export class PlayCanvasSplatViewer {
|
|
|
606
617
|
farClip,
|
|
607
618
|
sky = false,
|
|
608
619
|
pageCamera = false,
|
|
620
|
+
toneMapping = 'none',
|
|
609
621
|
} = opts;
|
|
610
622
|
this.canvas = canvas;
|
|
611
623
|
// controls:'page': the PAGE owns the camera (setPageCamera). No orbit, no idle, no fit; the
|
|
@@ -620,6 +632,10 @@ export class PlayCanvasSplatViewer {
|
|
|
620
632
|
// hidden (mid-setSource, or a page showing only its meshes). The SDK's contract is a
|
|
621
633
|
// transparent canvas the page shows through, so the sky layer is off unless asked for.
|
|
622
634
|
this.sky = sky === true;
|
|
635
|
+
// The eye camera's tone mapping, by name (the engine constant is looked up once the engine has
|
|
636
|
+
// loaded). 'none' for splats — their colours are already display-referred; ./model's mesh
|
|
637
|
+
// tiles pass 'neutral' (Khronos PBR Neutral), the glTF Sample Viewer's default.
|
|
638
|
+
this.toneMapping = toneMapping;
|
|
623
639
|
// Depth range for a MIXED scene (meshes under handle.engine.root depth-test against each
|
|
624
640
|
// other; splats only test against them). The projections' own near/far stay the adapter's —
|
|
625
641
|
// these only raise the near (floor) and lower the far (cap). Unset: untouched.
|
|
@@ -972,13 +988,15 @@ export class PlayCanvasSplatViewer {
|
|
|
972
988
|
* @param {object} o.perf the resolved playcanvasPerfSettings().
|
|
973
989
|
* @param {string} [o.viewPath] force 'cameras' | 'renderview' (diagnostics).
|
|
974
990
|
*/
|
|
975
|
-
async attachEngine(pc, { preserveDrawingBuffer = false, perf, viewPath } = {}) {
|
|
991
|
+
async attachEngine(pc, { preserveDrawingBuffer = false, perf, viewPath, antialias = false, patchSplats = true } = {}) {
|
|
976
992
|
this.pc = pc;
|
|
977
993
|
const device = await pc.createGraphicsDevice(this.canvas, {
|
|
978
994
|
deviceTypes: [pc.DEVICETYPE_WEBGL2],
|
|
979
995
|
alpha: true,
|
|
980
996
|
premultipliedAlpha: true,
|
|
981
|
-
|
|
997
|
+
// Off for splats (alpha-blended quads gain nothing from MSAA); ./model turns it on, as
|
|
998
|
+
// three's SceneViewer has it, because mesh silhouettes alias visibly without it.
|
|
999
|
+
antialias,
|
|
982
1000
|
xrCompatible: false,
|
|
983
1001
|
preserveDrawingBuffer,
|
|
984
1002
|
});
|
|
@@ -1022,10 +1040,12 @@ export class PlayCanvasSplatViewer {
|
|
|
1022
1040
|
// Footprint fix (§ patchGsplatFootprint) and the perf quad-extent cap, both as chunk
|
|
1023
1041
|
// overrides. The gsplat chunks are registered by GSplatComponentSystem during init, so
|
|
1024
1042
|
// after it; before any gsplat material compiles.
|
|
1025
|
-
|
|
1026
|
-
|
|
1043
|
+
// ./model passes patchSplats:false: its subject is a mesh, and a page adding a splat under
|
|
1044
|
+
// handle.engine.root on a model tile gets the engine's stock footprint (documented).
|
|
1045
|
+
const chunks = patchSplats ? pc.ShaderChunks.get(device, pc.SHADERLANGUAGE_GLSL) : null;
|
|
1046
|
+
const corner = chunks ? patchGsplatFootprint(chunks.get('gsplatCornerVS')) : { ok: false, skipped: true };
|
|
1027
1047
|
if (corner.ok) chunks.set('gsplatCornerVS', corner.src);
|
|
1028
|
-
else if (!warnedFootprint) {
|
|
1048
|
+
else if (!corner.skipped && !warnedFootprint) {
|
|
1029
1049
|
warnedFootprint = true;
|
|
1030
1050
|
console.warn(
|
|
1031
1051
|
'[inline3d/splat] engine:playcanvas — this engine build does not have the gsplatCornerVS ' +
|
|
@@ -1035,7 +1055,7 @@ export class PlayCanvasSplatViewer {
|
|
|
1035
1055
|
);
|
|
1036
1056
|
}
|
|
1037
1057
|
this.footprintPatched = corner.ok;
|
|
1038
|
-
if (perf?.quadExtent) {
|
|
1058
|
+
if (chunks && perf?.quadExtent) {
|
|
1039
1059
|
const q = patchPlayCanvasQuadExtent(chunks.get('gsplatCommonVS'), perf.quadExtent);
|
|
1040
1060
|
if (q.ok) chunks.set('gsplatCommonVS', q.src);
|
|
1041
1061
|
else if (!warnedQuadExtent) {
|
|
@@ -1184,7 +1204,7 @@ export class PlayCanvasSplatViewer {
|
|
|
1184
1204
|
// The engine's default camera tonemap is LINEAR, which routes every splat colour through
|
|
1185
1205
|
// decodeGamma → toneMap → gammaCorrectOutput. Spark writes the stored colour straight out;
|
|
1186
1206
|
// NONE is the same thing here (GAMMA_SRGB alone leaves a gamma-space colour untouched).
|
|
1187
|
-
e.camera.toneMapping = pc.TONEMAP_NONE;
|
|
1207
|
+
e.camera.toneMapping = TONE_MAPPINGS[this.toneMapping] ? pc[TONE_MAPPINGS[this.toneMapping]] ?? pc.TONEMAP_NONE : pc.TONEMAP_NONE;
|
|
1188
1208
|
this.rigNode.addChild(e);
|
|
1189
1209
|
return e;
|
|
1190
1210
|
}
|
|
@@ -2415,7 +2435,9 @@ export function attachPlayCanvasSplat(out, wall, canvas, src, opts, pending = []
|
|
|
2415
2435
|
|
|
2416
2436
|
let pcModule = null;
|
|
2417
2437
|
const booted = (async () => {
|
|
2418
|
-
|
|
2438
|
+
// Named re-exports, not the package namespace: lets a bundler drop the ~40% of the engine the
|
|
2439
|
+
// SDK never touches (./inline3d-playcanvas-engine.js).
|
|
2440
|
+
const pc = opts.playcanvas || (await import('./inline3d-playcanvas-engine.js'));
|
|
2419
2441
|
if (removed) return null;
|
|
2420
2442
|
const app = await viewer.attachEngine(pc, {
|
|
2421
2443
|
preserveDrawingBuffer,
|
package/model.d.ts
CHANGED
|
@@ -1,13 +1,25 @@
|
|
|
1
|
-
// Type definitions for @displayxr/inline3d/model.
|
|
1
|
+
// Type definitions for @displayxr/inline3d/model (and ./model/three).
|
|
2
2
|
// EXPERIMENTAL — not covered by the 1.x semver promise. See docs/sdk-stability.md.
|
|
3
3
|
|
|
4
4
|
import type { SceneViewer, SubjectBounds, OrbitPose } from './viewer.js';
|
|
5
5
|
import type { FirstWovenResult } from './index.js';
|
|
6
|
+
import type { PlayCanvasSplatViewer, SplatCameraPose, SplatFrameInfo } from './splat.js';
|
|
6
7
|
|
|
7
8
|
export interface ModelOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Which engine renders the model (1.12). `'playcanvas'` is the DEFAULT (optional peer
|
|
11
|
+
* `playcanvas >=2.22.3 <3`); `'three'` is the 1.11 renderer, byte for byte (optional peer
|
|
12
|
+
* `three`). Both are imported dynamically, so a page loads only the engine it renders with.
|
|
13
|
+
*
|
|
14
|
+
* With no `engine`: a three.js object in `GLTFLoader` / `DRACOLoader` / `KTX2Loader` / `envMap`
|
|
15
|
+
* selects three; otherwise PlayCanvas, falling back to three (one console warning) when
|
|
16
|
+
* `playcanvas` cannot be imported, and rejecting `ready` naming both when neither can. An
|
|
17
|
+
* explicit `engine` never falls back. Anything else throws at call time.
|
|
18
|
+
*/
|
|
19
|
+
engine?: 'playcanvas' | 'three';
|
|
8
20
|
/** Metres of world the tile's height spans (default 0.24). */
|
|
9
21
|
virtualDisplayHeight?: number;
|
|
10
|
-
/** Precomputed subject bounds. Rarely needed for a mesh —
|
|
22
|
+
/** Precomputed subject bounds. Rarely needed for a mesh — its bounds are exact. */
|
|
11
23
|
frame?: SubjectBounds;
|
|
12
24
|
/** Degrees/second of turntable once idle (default 8). */
|
|
13
25
|
idleSpin?: number;
|
|
@@ -25,26 +37,42 @@ export interface ModelOptions {
|
|
|
25
37
|
/** Per-eye buffer scale; 0.5–0.7 is usually free (default 1). */
|
|
26
38
|
renderScale?: number;
|
|
27
39
|
feather?: number;
|
|
28
|
-
/** Built-in three-point lighting. Meshes arrive unlit; splats do not need this. */
|
|
29
40
|
/**
|
|
30
|
-
* How the mesh is lit.
|
|
31
|
-
*
|
|
32
|
-
*
|
|
41
|
+
* How the mesh is lit.
|
|
42
|
+
*
|
|
43
|
+
* PlayCanvas (default engine): `room` (default; `neutral` is an alias) is image-based lighting
|
|
44
|
+
* from an in-memory neutral photo studio fitted to the Khronos glTF Sample Viewer's "Studio
|
|
45
|
+
* Neutral", with Khronos PBR Neutral tone mapping and exposure 1 — the Sample Viewer's look.
|
|
46
|
+
* three: `room` bakes three's procedural RoomEnvironment, untonemapped (unchanged since 1.11).
|
|
47
|
+
*
|
|
48
|
+
* Both: `studio` is the three-point punctual rig (metal renders dark under it — nothing to
|
|
49
|
+
* reflect); `none` adds no light at all. Anything else throws on PlayCanvas.
|
|
33
50
|
*/
|
|
34
|
-
environment?: 'room' | 'studio' | 'none';
|
|
35
|
-
/**
|
|
36
|
-
|
|
37
|
-
|
|
51
|
+
environment?: 'room' | 'neutral' | 'studio' | 'none';
|
|
52
|
+
/**
|
|
53
|
+
* PlayCanvas only: yaw of the environment about +Y, degrees (default 0 = the Sample Viewer's
|
|
54
|
+
* default orientation).
|
|
55
|
+
*/
|
|
56
|
+
environmentRotation?: number;
|
|
57
|
+
/**
|
|
58
|
+
* Your own environment; overrides `environment`.
|
|
59
|
+
* three: a PMREM-processed texture. PlayCanvas: a URL of an equirect image (.hdr/.png/.jpg) or
|
|
60
|
+
* a `pc.Texture` (equirect or cubemap), prefiltered for you. A three texture on
|
|
61
|
+
* `engine: 'playcanvas'` throws; with no `engine` it selects three.
|
|
62
|
+
*/
|
|
63
|
+
envMap?: object | string;
|
|
64
|
+
/** three only: hand in the GLTFLoader class instead of resolving it from `three/addons/`. */
|
|
38
65
|
GLTFLoader?: unknown;
|
|
39
66
|
|
|
40
67
|
/**
|
|
41
|
-
* Where **your page** serves
|
|
68
|
+
* Where **your page** serves the Draco decoder and Basis (KTX2) transcoder — the SAME files on
|
|
69
|
+
* both engines: three's `libs/draco/` (`draco_wasm_wrapper.js` + `draco_decoder.wasm`) and
|
|
70
|
+
* `libs/basis/` (`basis_transcoder.js` + `.wasm`). The PlayCanvas engine's own Draco and Basis
|
|
71
|
+
* workers load them.
|
|
42
72
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* offline build must not acquire a network dependency by loading a compressed file. Copy the
|
|
47
|
-
* files out of `three` and serve them yourself:
|
|
73
|
+
* The asset's `extensionsUsed` decides which decoders are wired, so an uncompressed model never
|
|
74
|
+
* touches any of this. The default is deliberately **not a CDN** — a page shipping an offline
|
|
75
|
+
* build must not acquire a network dependency by loading a compressed file:
|
|
48
76
|
*
|
|
49
77
|
* ```sh
|
|
50
78
|
* cp -r node_modules/three/examples/jsm/libs/draco/ public/draco/
|
|
@@ -52,25 +80,48 @@ export interface ModelOptions {
|
|
|
52
80
|
* ```
|
|
53
81
|
*
|
|
54
82
|
* A string is a parent directory holding `draco/` and `basis/`; an object overrides either key.
|
|
55
|
-
*
|
|
83
|
+
* On PlayCanvas the engine keeps ONE Draco and ONE Basis worker pool per page: the first tile
|
|
84
|
+
* that needs one sets its path, and a later tile asking for another path is warned.
|
|
56
85
|
*
|
|
57
86
|
* @default {draco:'/draco/', basis:'/basis/'}
|
|
58
87
|
*/
|
|
59
88
|
decoderPath?: string | { draco?: string; basis?: string };
|
|
60
|
-
/**
|
|
61
|
-
* DRACOLoader class **or** a ready instance, instead of resolving `three/addons/`. A class is
|
|
62
|
-
* constructed and pointed at `decoderPath`; an instance is used exactly as you configured it.
|
|
63
|
-
*/
|
|
89
|
+
/** three only: DRACOLoader class **or** a ready instance, instead of resolving `three/addons/`. */
|
|
64
90
|
DRACOLoader?: unknown;
|
|
91
|
+
/** three only: KTX2Loader class or instance. */
|
|
92
|
+
KTX2Loader?: unknown;
|
|
65
93
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
94
|
+
* The `MeshoptDecoder` for `EXT_meshopt_compression`. Nothing to serve (pure JS). Default: three
|
|
95
|
+
* resolves `three/addons/libs/meshopt_decoder.module.js`; PlayCanvas resolves
|
|
96
|
+
* `meshoptimizer/decoder` (optional peer `meshoptimizer >=1`), only for an asset that declares it.
|
|
69
97
|
*/
|
|
70
|
-
KTX2Loader?: unknown;
|
|
71
|
-
/** The `MeshoptDecoder` namespace, instead of resolving `three/addons/`. Nothing to serve. */
|
|
72
98
|
meshoptDecoder?: unknown;
|
|
73
99
|
|
|
100
|
+
/** PlayCanvas only: the `playcanvas` module (or a namespace with the same members) to use. */
|
|
101
|
+
playcanvas?: object;
|
|
102
|
+
/** PlayCanvas only: MSAA on the tile's WebGL context (default true, as three's renderer). */
|
|
103
|
+
antialias?: boolean;
|
|
104
|
+
/** PlayCanvas only: the context's `preserveDrawingBuffer` (default false). */
|
|
105
|
+
preserveDrawingBuffer?: boolean;
|
|
106
|
+
/** PlayCanvas only: raise every projection's near plane to at least this (depth mapping only). */
|
|
107
|
+
nearClip?: number;
|
|
108
|
+
/** PlayCanvas only: lower every projection's far plane to at most this. */
|
|
109
|
+
farClip?: number;
|
|
110
|
+
/** PlayCanvas only: the drag's tilt cap in degrees (default 15, tilt-and-relax). */
|
|
111
|
+
orbitMaxDeg?: number;
|
|
112
|
+
/** PlayCanvas only: the orbit's easing time constants, seconds. */
|
|
113
|
+
orbitEase?: { drag?: number; rest?: number };
|
|
114
|
+
/**
|
|
115
|
+
* PlayCanvas only: who owns the camera — the SDK's viewer (default) or the page, through
|
|
116
|
+
* {@link ModelHandle.setCameraPose} every frame (the attach rig; converges on the model's bounds
|
|
117
|
+
* centre unless the pose gives a `convergence`).
|
|
118
|
+
*/
|
|
119
|
+
controls?: 'viewer' | 'page';
|
|
120
|
+
/** `controls: 'page'`: the comfort depth of the declared rig, in (0, 1] (default 0.3). */
|
|
121
|
+
comfortDepth?: number;
|
|
122
|
+
/** `controls: 'page'` only: runs inside the adapter's frame, before the draw. */
|
|
123
|
+
onBeforeFrame?: (frame: SplatFrameInfo) => void;
|
|
124
|
+
|
|
74
125
|
/** Element whose visibility gates the lazy create/close lifecycle. */
|
|
75
126
|
observe?: Element;
|
|
76
127
|
/** Forwarded to the core window: see `TileOptions.firstWovenHoldMs`. */
|
|
@@ -79,16 +130,43 @@ export interface ModelOptions {
|
|
|
79
130
|
|
|
80
131
|
/** What {@link addModel} returns — the same shape as addSplat's handle. */
|
|
81
132
|
export interface ModelHandle {
|
|
82
|
-
|
|
83
|
-
|
|
133
|
+
/** Which engine renders this tile. Can change from `'playcanvas'` to `'three'` on the fallback. */
|
|
134
|
+
readonly backend: 'playcanvas' | 'three';
|
|
135
|
+
/**
|
|
136
|
+
* three: the SceneViewer. PlayCanvas: the backend's viewer (the SceneViewer pose surface
|
|
137
|
+
* without three). Null until the backend module has loaded — one module fetch after addModel
|
|
138
|
+
* returns (1.11 returned it synchronously; `@displayxr/inline3d/model/three` still does).
|
|
139
|
+
*/
|
|
140
|
+
readonly viewer: SceneViewer | PlayCanvasSplatViewer | null;
|
|
141
|
+
/**
|
|
142
|
+
* The loaded glTF root — a three `Object3D`, or on PlayCanvas the render `pc.Entity`
|
|
143
|
+
* (`instantiateRenderEntity()`). Null until `ready` resolves.
|
|
144
|
+
*/
|
|
84
145
|
model: object | null;
|
|
146
|
+
/** PlayCanvas only: the container resource (animations, materials, textures). */
|
|
147
|
+
readonly container?: unknown;
|
|
148
|
+
/**
|
|
149
|
+
* PlayCanvas only (ADVANCED, not covered by the semver promise): `app` is the tile's AppBase,
|
|
150
|
+
* `root` the content root (the model's parent — add entities, lights or an `anim` component
|
|
151
|
+
* under it), `camera` the eye camera. Null on three and until the engine has booted.
|
|
152
|
+
*/
|
|
153
|
+
readonly engine: { readonly app: unknown; readonly root: unknown; readonly camera: unknown } | null;
|
|
85
154
|
/** Bounds used for framing; null until `ready` resolves. */
|
|
86
155
|
frame: SubjectBounds | null;
|
|
87
156
|
/** Resolves once the model has loaded and been framed; rejects if the load failed. */
|
|
88
157
|
readonly ready: Promise<ModelHandle>;
|
|
89
158
|
|
|
159
|
+
/** Throws on `controls: 'page'`. */
|
|
90
160
|
setPose(pose?: OrbitPose): void;
|
|
161
|
+
/** Throws on `controls: 'page'`. */
|
|
91
162
|
resetPose(): void;
|
|
163
|
+
/** `controls: 'page'` only (throws otherwise): the camera for the next frame, model space. */
|
|
164
|
+
setCameraPose(
|
|
165
|
+
matrixWorld: ArrayLike<number>,
|
|
166
|
+
opts: { verticalFovDeg: number; near?: number; far?: number; convergence?: number | null },
|
|
167
|
+
): ModelHandle;
|
|
168
|
+
/** The last pose the page set (a copy), or null. */
|
|
169
|
+
getCameraPose(): SplatCameraPose | null;
|
|
92
170
|
|
|
93
171
|
remove(): void;
|
|
94
172
|
exclude(el: Element): void;
|
|
@@ -102,10 +180,11 @@ export interface ModelHandle {
|
|
|
102
180
|
|
|
103
181
|
/**
|
|
104
182
|
* Load a glTF/GLB into an inline-3D window. Safe to call with an unsupported wall — it renders a
|
|
105
|
-
* flat, orbitable view instead, so pages need no branch.
|
|
183
|
+
* flat, orbitable view instead, so pages need no branch. Renders with PlayCanvas by default
|
|
184
|
+
* (1.12); pass `engine: 'three'` for the 1.11 renderer.
|
|
106
185
|
*
|
|
107
186
|
* Compressed assets (Draco, meshopt, KTX2/Basis) load too: the asset's declared extensions decide
|
|
108
|
-
* which decoders are
|
|
187
|
+
* which decoders are wired, and nothing is wired for an asset that declares none. Draco and
|
|
109
188
|
* KTX2 additionally need their runtime files served by your page — see {@link ModelOptions.decoderPath}.
|
|
110
189
|
* When a decoder is needed and unavailable, `ready` rejects with an Error naming the glTF
|
|
111
190
|
* extension, the option that fixes it and the path it looked in; the extension is also on the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@displayxr/inline3d",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "Turn any HTML <canvas> into a glasses-free-3D window on a DisplayXR display, inside an ordinary web page. Dependency-free; progressive enhancement (falls back to plain 2D everywhere else).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./index.d.ts",
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
"import": "./js/inline3d-splat.js"
|
|
25
25
|
},
|
|
26
26
|
"./model": {
|
|
27
|
+
"types": "./model.d.ts",
|
|
28
|
+
"import": "./js/inline3d-model-entry.js"
|
|
29
|
+
},
|
|
30
|
+
"./model/three": {
|
|
27
31
|
"types": "./model.d.ts",
|
|
28
32
|
"import": "./js/inline3d-model.js"
|
|
29
33
|
},
|
|
@@ -47,6 +51,9 @@
|
|
|
47
51
|
"js/inline3d-splat-playcanvas.js",
|
|
48
52
|
"js/inline3d-splat-shared.js",
|
|
49
53
|
"js/inline3d-model.js",
|
|
54
|
+
"js/inline3d-model-entry.js",
|
|
55
|
+
"js/inline3d-model-playcanvas.js",
|
|
56
|
+
"js/inline3d-playcanvas-engine.js",
|
|
50
57
|
"index.d.ts",
|
|
51
58
|
"three.d.ts",
|
|
52
59
|
"viewer.d.ts",
|
|
@@ -64,7 +71,8 @@
|
|
|
64
71
|
"stereo",
|
|
65
72
|
"3d-display",
|
|
66
73
|
"lightfield",
|
|
67
|
-
"three"
|
|
74
|
+
"three",
|
|
75
|
+
"playcanvas"
|
|
68
76
|
],
|
|
69
77
|
"homepage": "https://displayxr.github.io/displayxr-web/",
|
|
70
78
|
"repository": {
|
|
@@ -78,7 +86,8 @@
|
|
|
78
86
|
"peerDependencies": {
|
|
79
87
|
"three": ">=0.150.0",
|
|
80
88
|
"@sparkjsdev/spark": ">=2.0.0",
|
|
81
|
-
"playcanvas": ">=2.22.3 <3"
|
|
89
|
+
"playcanvas": ">=2.22.3 <3",
|
|
90
|
+
"meshoptimizer": ">=1.0.0"
|
|
82
91
|
},
|
|
83
92
|
"peerDependenciesMeta": {
|
|
84
93
|
"three": {
|
|
@@ -89,6 +98,9 @@
|
|
|
89
98
|
},
|
|
90
99
|
"playcanvas": {
|
|
91
100
|
"optional": true
|
|
101
|
+
},
|
|
102
|
+
"meshoptimizer": {
|
|
103
|
+
"optional": true
|
|
92
104
|
}
|
|
93
105
|
},
|
|
94
106
|
"publishConfig": {
|