@vulfram/engine 0.17.1-alpha → 0.19.3-alpha

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.
Files changed (36) hide show
  1. package/README.md +3 -3
  2. package/package.json +10 -5
  3. package/src/engine/api.ts +12 -25
  4. package/src/engine/bridge/dispatch.ts +3 -8
  5. package/src/engine/ecs/components.ts +340 -0
  6. package/src/engine/ecs/index.ts +3 -661
  7. package/src/engine/ecs/intents.ts +184 -0
  8. package/src/engine/ecs/systems.ts +26 -0
  9. package/src/engine/intents/store.ts +72 -0
  10. package/src/engine/state.ts +3 -3
  11. package/src/engine/systems/command-intent.ts +11 -16
  12. package/src/engine/systems/diagnostics.ts +3 -13
  13. package/src/engine/systems/input-mirror.ts +156 -18
  14. package/src/engine/systems/resource-upload.ts +12 -14
  15. package/src/engine/systems/response-decode.ts +17 -0
  16. package/src/engine/systems/scene-sync.ts +12 -13
  17. package/src/engine/systems/ui-bridge.ts +31 -10
  18. package/src/engine/systems/utils.ts +46 -3
  19. package/src/engine/systems/world-lifecycle.ts +9 -15
  20. package/src/engine/world/entities.ts +201 -37
  21. package/src/engine/world/mount.ts +27 -6
  22. package/src/engine/world/world-ui.ts +77 -30
  23. package/src/engine/world/world3d.ts +282 -33
  24. package/src/helpers/collision.ts +487 -0
  25. package/src/helpers/index.ts +2 -0
  26. package/src/helpers/raycast.ts +442 -0
  27. package/src/types/cmds/geometry.ts +2 -2
  28. package/src/types/cmds/index.ts +42 -0
  29. package/src/types/cmds/input.ts +39 -0
  30. package/src/types/cmds/material.ts +10 -10
  31. package/src/types/cmds/realm.ts +0 -2
  32. package/src/types/cmds/system.ts +10 -0
  33. package/src/types/cmds/target.ts +14 -0
  34. package/src/types/events/keyboard.ts +2 -2
  35. package/src/types/events/pointer.ts +43 -0
  36. package/src/types/events/system.ts +44 -0
@@ -0,0 +1,442 @@
1
+ import {
2
+ mat4,
3
+ vec3,
4
+ vec4,
5
+ type ReadonlyMat4,
6
+ type ReadonlyVec2,
7
+ type ReadonlyVec3,
8
+ type vec3 as Vec3,
9
+ } from 'gl-matrix';
10
+
11
+ export interface Ray3 {
12
+ origin: Vec3;
13
+ direction: Vec3;
14
+ }
15
+
16
+ export interface RayHit {
17
+ distance: number;
18
+ point: Vec3;
19
+ }
20
+
21
+ export interface PointerRaycastInput {
22
+ pointer: ReadonlyVec2;
23
+ viewMatrix: ReadonlyMat4;
24
+ projectionMatrix: ReadonlyMat4;
25
+ viewportSize: ReadonlyVec2;
26
+ viewportOrigin?: ReadonlyVec2;
27
+ }
28
+
29
+ export interface PointerRaycastWgpuInput extends PointerRaycastInput {}
30
+
31
+ /**
32
+ * Builds a right-handed perspective projection in ZO depth range (0..1),
33
+ * with optional reverse-Z by swapping near/far.
34
+ *
35
+ * Matches glam::Mat4::perspective_rh semantics used by core.
36
+ */
37
+ export function createPerspectiveRhZo(
38
+ fovYRadians: number,
39
+ aspect: number,
40
+ near: number,
41
+ far: number,
42
+ ): mat4 {
43
+ const f = 1 / Math.tan(fovYRadians / 2);
44
+ const out = mat4.create();
45
+
46
+ out[0] = f / Math.max(1e-8, aspect);
47
+ out[1] = 0;
48
+ out[2] = 0;
49
+ out[3] = 0;
50
+
51
+ out[4] = 0;
52
+ out[5] = f;
53
+ out[6] = 0;
54
+ out[7] = 0;
55
+
56
+ out[8] = 0;
57
+ out[9] = 0;
58
+ out[10] = far / (near - far);
59
+ out[11] = -1;
60
+
61
+ out[12] = 0;
62
+ out[13] = 0;
63
+ out[14] = (near * far) / (near - far);
64
+ out[15] = 0;
65
+
66
+ return out;
67
+ }
68
+
69
+ export interface PointerEventRaycastData {
70
+ position: ReadonlyVec2;
71
+ positionTarget?: ReadonlyVec2;
72
+ windowWidth?: number;
73
+ windowHeight?: number;
74
+ targetWidth?: number;
75
+ targetHeight?: number;
76
+ }
77
+
78
+ export interface PointerEventRaycastInput {
79
+ pointerEvent: PointerEventRaycastData;
80
+ viewMatrix: ReadonlyMat4;
81
+ projectionMatrix: ReadonlyMat4;
82
+ fallbackViewportSize?: ReadonlyVec2;
83
+ viewportOrigin?: ReadonlyVec2;
84
+ }
85
+
86
+ function pointOnRay(ray: Ray3, distance: number): Vec3 {
87
+ return vec3.fromValues(
88
+ ray.origin[0]! + ray.direction[0]! * distance,
89
+ ray.origin[1]! + ray.direction[1]! * distance,
90
+ ray.origin[2]! + ray.direction[2]! * distance,
91
+ );
92
+ }
93
+
94
+ /**
95
+ * Creates a world-space ray from pointer coordinates plus camera matrices.
96
+ *
97
+ * Returns `null` if the camera matrix cannot be inverted.
98
+ */
99
+ export function createPointerRay(input: PointerRaycastInput): Ray3 | null {
100
+ const pointerX = input.pointer[0]!;
101
+ const pointerY = input.pointer[1]!;
102
+ const viewportWidth = input.viewportSize[0]!;
103
+ const viewportHeight = input.viewportSize[1]!;
104
+ const viewportSource = input.viewportOrigin;
105
+ const viewportX = viewportSource ? viewportSource[0]! : 0;
106
+ const viewportY = viewportSource ? viewportSource[1]! : 0;
107
+
108
+ if (viewportWidth <= 0 || viewportHeight <= 0) {
109
+ return null;
110
+ }
111
+
112
+ const normalizedX = ((pointerX - viewportX) / viewportWidth) * 2 - 1;
113
+ const normalizedY = 1 - ((pointerY - viewportY) / viewportHeight) * 2;
114
+
115
+ const viewProjection = mat4.multiply(
116
+ mat4.create(),
117
+ input.projectionMatrix,
118
+ input.viewMatrix,
119
+ );
120
+ const inverseViewProjection = mat4.invert(mat4.create(), viewProjection);
121
+ if (!inverseViewProjection) {
122
+ return null;
123
+ }
124
+
125
+ const nearClip = vec4.fromValues(normalizedX, normalizedY, -1, 1);
126
+ const farClip = vec4.fromValues(normalizedX, normalizedY, 1, 1);
127
+
128
+ const nearWorld4 = vec4.transformMat4(vec4.create(), nearClip, inverseViewProjection);
129
+ const farWorld4 = vec4.transformMat4(vec4.create(), farClip, inverseViewProjection);
130
+ if (nearWorld4[3] === 0 || farWorld4[3] === 0) {
131
+ return null;
132
+ }
133
+
134
+ const nearWorld = vec3.fromValues(
135
+ nearWorld4[0] / nearWorld4[3],
136
+ nearWorld4[1] / nearWorld4[3],
137
+ nearWorld4[2] / nearWorld4[3],
138
+ );
139
+ const farWorld = vec3.fromValues(
140
+ farWorld4[0] / farWorld4[3],
141
+ farWorld4[1] / farWorld4[3],
142
+ farWorld4[2] / farWorld4[3],
143
+ );
144
+
145
+ const direction = vec3.normalize(
146
+ vec3.create(),
147
+ vec3.subtract(vec3.create(), farWorld, nearWorld),
148
+ );
149
+
150
+ return {
151
+ origin: nearWorld,
152
+ direction,
153
+ };
154
+ }
155
+
156
+ /**
157
+ * Creates a world-space ray using WGPU reverse-Z clip conventions.
158
+ *
159
+ * This mirrors core picking logic:
160
+ * - NDC depth near=1 and far=0
161
+ * - direction corrected to follow camera forward when needed
162
+ */
163
+ export function createPointerRayWgpuReverseZ(
164
+ input: PointerRaycastWgpuInput,
165
+ ): Ray3 | null {
166
+ const pointerX = input.pointer[0]!;
167
+ const pointerY = input.pointer[1]!;
168
+ const viewportWidth = input.viewportSize[0]!;
169
+ const viewportHeight = input.viewportSize[1]!;
170
+ const viewportSource = input.viewportOrigin;
171
+ const viewportX = viewportSource ? viewportSource[0]! : 0;
172
+ const viewportY = viewportSource ? viewportSource[1]! : 0;
173
+
174
+ if (viewportWidth <= 0 || viewportHeight <= 0) {
175
+ return null;
176
+ }
177
+
178
+ const normalizedX = ((pointerX - viewportX) / viewportWidth) * 2 - 1;
179
+ const normalizedY = 1 - ((pointerY - viewportY) / viewportHeight) * 2;
180
+
181
+ const viewProjection = mat4.multiply(
182
+ mat4.create(),
183
+ input.projectionMatrix,
184
+ input.viewMatrix,
185
+ );
186
+ const inverseViewProjection = mat4.invert(mat4.create(), viewProjection);
187
+ if (!inverseViewProjection) {
188
+ return null;
189
+ }
190
+
191
+ const nearClip = vec4.fromValues(normalizedX, normalizedY, 1, 1);
192
+ const farClip = vec4.fromValues(normalizedX, normalizedY, 0, 1);
193
+
194
+ const nearWorld4 = vec4.transformMat4(vec4.create(), nearClip, inverseViewProjection);
195
+ const farWorld4 = vec4.transformMat4(vec4.create(), farClip, inverseViewProjection);
196
+ if (nearWorld4[3] === 0 || farWorld4[3] === 0) {
197
+ return null;
198
+ }
199
+
200
+ const nearWorld = vec3.fromValues(
201
+ nearWorld4[0] / nearWorld4[3],
202
+ nearWorld4[1] / nearWorld4[3],
203
+ nearWorld4[2] / nearWorld4[3],
204
+ );
205
+ const farWorld = vec3.fromValues(
206
+ farWorld4[0] / farWorld4[3],
207
+ farWorld4[1] / farWorld4[3],
208
+ farWorld4[2] / farWorld4[3],
209
+ );
210
+
211
+ let direction = vec3.normalize(
212
+ vec3.create(),
213
+ vec3.subtract(vec3.create(), farWorld, nearWorld),
214
+ );
215
+
216
+ const inverseView = mat4.invert(mat4.create(), input.viewMatrix);
217
+ if (!inverseView) {
218
+ return null;
219
+ }
220
+ const origin4 = vec4.transformMat4(
221
+ vec4.create(),
222
+ vec4.fromValues(0, 0, 0, 1),
223
+ inverseView,
224
+ );
225
+ if (origin4[3] === 0) {
226
+ return null;
227
+ }
228
+ const origin = vec3.fromValues(
229
+ origin4[0] / origin4[3],
230
+ origin4[1] / origin4[3],
231
+ origin4[2] / origin4[3],
232
+ );
233
+
234
+ const forward4 = vec4.transformMat4(
235
+ vec4.create(),
236
+ vec4.fromValues(0, 0, -1, 0),
237
+ inverseView,
238
+ );
239
+ const cameraForward = vec3.normalize(
240
+ vec3.create(),
241
+ vec3.fromValues(forward4[0], forward4[1], forward4[2]),
242
+ );
243
+ if (vec3.squaredLength(cameraForward) > 1e-8 && vec3.dot(direction, cameraForward) < 0) {
244
+ direction = vec3.scale(vec3.create(), direction, -1);
245
+ }
246
+
247
+ if (vec3.squaredLength(direction) <= 1e-8) {
248
+ return null;
249
+ }
250
+
251
+ return { origin, direction };
252
+ }
253
+
254
+ /**
255
+ * Creates a world-space ray using pointer event dimensions from core.
256
+ *
257
+ * Priority:
258
+ * 1) target-space pointer + target size (most accurate for routed targets)
259
+ * 2) window-space pointer + window size
260
+ * 3) fallback viewport size (if provided)
261
+ *
262
+ * Uses WGPU reverse-Z conventions to match core picking.
263
+ */
264
+ export function createPointerRayFromEvent(
265
+ input: PointerEventRaycastInput,
266
+ ): Ray3 | null {
267
+ const event = input.pointerEvent;
268
+ const targetWidth = event.targetWidth;
269
+ const targetHeight = event.targetHeight;
270
+ const windowWidth = event.windowWidth;
271
+ const windowHeight = event.windowHeight;
272
+
273
+ if (
274
+ event.positionTarget &&
275
+ typeof targetWidth === 'number' &&
276
+ typeof targetHeight === 'number' &&
277
+ targetWidth > 0 &&
278
+ targetHeight > 0
279
+ ) {
280
+ return createPointerRayWgpuReverseZ({
281
+ pointer: event.positionTarget,
282
+ viewMatrix: input.viewMatrix,
283
+ projectionMatrix: input.projectionMatrix,
284
+ viewportSize: [targetWidth, targetHeight],
285
+ viewportOrigin: [0, 0],
286
+ });
287
+ }
288
+
289
+ if (
290
+ typeof windowWidth === 'number' &&
291
+ typeof windowHeight === 'number' &&
292
+ windowWidth > 0 &&
293
+ windowHeight > 0
294
+ ) {
295
+ return createPointerRayWgpuReverseZ({
296
+ pointer: event.position,
297
+ viewMatrix: input.viewMatrix,
298
+ projectionMatrix: input.projectionMatrix,
299
+ viewportSize: [windowWidth, windowHeight],
300
+ viewportOrigin: input.viewportOrigin,
301
+ });
302
+ }
303
+
304
+ if (input.fallbackViewportSize) {
305
+ return createPointerRayWgpuReverseZ({
306
+ pointer: event.position,
307
+ viewMatrix: input.viewMatrix,
308
+ projectionMatrix: input.projectionMatrix,
309
+ viewportSize: input.fallbackViewportSize,
310
+ viewportOrigin: input.viewportOrigin,
311
+ });
312
+ }
313
+
314
+ return null;
315
+ }
316
+
317
+ /**
318
+ * Intersects a ray against a plane defined by one point and one normal.
319
+ *
320
+ * Returns `null` when the ray is parallel to the plane or the hit is behind the ray.
321
+ */
322
+ export function intersectRayPlane(
323
+ ray: Ray3,
324
+ planePoint: ReadonlyVec3,
325
+ planeNormal: ReadonlyVec3,
326
+ ): RayHit | null {
327
+ const origin = vec3.fromValues(ray.origin[0], ray.origin[1], ray.origin[2]);
328
+ const direction = vec3.fromValues(ray.direction[0], ray.direction[1], ray.direction[2]);
329
+ const normal = vec3.normalize(
330
+ vec3.create(),
331
+ vec3.fromValues(planeNormal[0], planeNormal[1], planeNormal[2]),
332
+ );
333
+ const point = vec3.fromValues(planePoint[0], planePoint[1], planePoint[2]);
334
+
335
+ const denominator = vec3.dot(direction, normal);
336
+ if (Math.abs(denominator) < 1e-6) {
337
+ return null;
338
+ }
339
+
340
+ const distance =
341
+ vec3.dot(vec3.subtract(vec3.create(), point, origin), normal) / denominator;
342
+ if (distance < 0) {
343
+ return null;
344
+ }
345
+
346
+ return {
347
+ distance,
348
+ point: pointOnRay(ray, distance),
349
+ };
350
+ }
351
+
352
+ /**
353
+ * Intersects a ray with a sphere and returns the closest hit in front of the ray origin.
354
+ */
355
+ export function intersectRaySphere(
356
+ ray: Ray3,
357
+ center: ReadonlyVec3,
358
+ radius: number,
359
+ ): RayHit | null {
360
+ const origin = vec3.fromValues(ray.origin[0], ray.origin[1], ray.origin[2]);
361
+ const direction = vec3.fromValues(ray.direction[0], ray.direction[1], ray.direction[2]);
362
+ const sphereCenter = vec3.fromValues(center[0], center[1], center[2]);
363
+
364
+ const oc = vec3.subtract(vec3.create(), origin, sphereCenter);
365
+ const a = vec3.dot(direction, direction);
366
+ const b = 2 * vec3.dot(oc, direction);
367
+ const c = vec3.dot(oc, oc) - radius * radius;
368
+ const discriminant = b * b - 4 * a * c;
369
+
370
+ if (discriminant < 0) {
371
+ return null;
372
+ }
373
+
374
+ const sqrtDiscriminant = Math.sqrt(discriminant);
375
+ const t0 = (-b - sqrtDiscriminant) / (2 * a);
376
+ const t1 = (-b + sqrtDiscriminant) / (2 * a);
377
+
378
+ const distance = t0 >= 0 ? t0 : t1 >= 0 ? t1 : -1;
379
+ if (distance < 0) {
380
+ return null;
381
+ }
382
+
383
+ return {
384
+ distance,
385
+ point: pointOnRay(ray, distance),
386
+ };
387
+ }
388
+
389
+ /**
390
+ * Intersects a ray with an axis-aligned bounding box.
391
+ */
392
+ export function intersectRayAabb(
393
+ ray: Ray3,
394
+ min: ReadonlyVec3,
395
+ max: ReadonlyVec3,
396
+ ): RayHit | null {
397
+ const origin = ray.origin;
398
+ const direction = ray.direction;
399
+
400
+ let tMin = -Infinity;
401
+ let tMax = Infinity;
402
+
403
+ const axes = [0, 1, 2] as const;
404
+ for (const axis of axes) {
405
+ const o = origin[axis]!;
406
+ const d = direction[axis]!;
407
+ const minAxis = min[axis]!;
408
+ const maxAxis = max[axis]!;
409
+
410
+ if (Math.abs(d) < 1e-8) {
411
+ if (o < minAxis || o > maxAxis) {
412
+ return null;
413
+ }
414
+ continue;
415
+ }
416
+
417
+ const invD = 1 / d;
418
+ let t0 = (minAxis - o) * invD;
419
+ let t1 = (maxAxis - o) * invD;
420
+ if (t0 > t1) {
421
+ const tmp = t0;
422
+ t0 = t1;
423
+ t1 = tmp;
424
+ }
425
+
426
+ tMin = Math.max(tMin, t0);
427
+ tMax = Math.min(tMax, t1);
428
+ if (tMax < tMin) {
429
+ return null;
430
+ }
431
+ }
432
+
433
+ const distance = tMin >= 0 ? tMin : tMax >= 0 ? tMax : -1;
434
+ if (distance < 0) {
435
+ return null;
436
+ }
437
+
438
+ return {
439
+ distance,
440
+ point: pointOnRay(ray, distance),
441
+ };
442
+ }
@@ -8,7 +8,7 @@ export type GeometryPrimitiveType =
8
8
  | 'normal'
9
9
  | 'tangent'
10
10
  | 'color'
11
- | 'uv'
11
+ | 'u-v'
12
12
  | 'skin-joints'
13
13
  | 'skin-weights';
14
14
 
@@ -19,7 +19,7 @@ export const GeometryPrimitiveType = {
19
19
  Normal: 'normal' as const,
20
20
  Tangent: 'tangent' as const,
21
21
  Color: 'color' as const,
22
- UV: 'uv' as const,
22
+ UV: 'u-v' as const,
23
23
  SkinJoints: 'skin-joints' as const,
24
24
  SkinWeights: 'skin-weights' as const,
25
25
  };
@@ -3,6 +3,7 @@ import * as Cam from './camera';
3
3
  import * as Env from './environment';
4
4
  import * as Geo from './geometry';
5
5
  import * as Giz from './gizmo';
6
+ import * as Input from './input';
6
7
  import * as Lite from './light';
7
8
  import * as Mat from './material';
8
9
  import * as Mod from './model';
@@ -18,6 +19,7 @@ export * from './camera';
18
19
  export * from './environment';
19
20
  export * from './geometry';
20
21
  export * from './gizmo';
22
+ export * from './input';
21
23
  export * from './light';
22
24
  export * from './material';
23
25
  export * from './model';
@@ -44,11 +46,27 @@ export type EngineCmd =
44
46
  type: 'cmd-system-diagnostics-set';
45
47
  content: Sys.CmdSystemDiagnosticsSetArgs;
46
48
  }
49
+ | {
50
+ type: 'cmd-system-build-version-get';
51
+ content: Sys.CmdSystemBuildVersionGetArgs;
52
+ }
47
53
  | { type: 'cmd-window-create'; content: Win.CmdWindowCreateArgs }
48
54
  | { type: 'cmd-window-close'; content: Win.CmdWindowCloseArgs }
49
55
  | { type: 'cmd-window-measurement'; content: Win.CmdWindowMeasurementArgs }
50
56
  | { type: 'cmd-window-cursor'; content: Win.CmdWindowCursorArgs }
51
57
  | { type: 'cmd-window-state'; content: Win.CmdWindowStateArgs }
58
+ | {
59
+ type: 'cmd-input-target-listener-upsert';
60
+ content: Input.CmdInputTargetListenerUpsertArgs;
61
+ }
62
+ | {
63
+ type: 'cmd-input-target-listener-dispose';
64
+ content: Input.CmdInputTargetListenerDisposeArgs;
65
+ }
66
+ | {
67
+ type: 'cmd-input-target-listener-list';
68
+ content: Input.CmdInputTargetListenerListArgs;
69
+ }
52
70
  | {
53
71
  type: 'cmd-upload-buffer-discard-all';
54
72
  content: Sys.CmdUploadBufferDiscardAllArgs;
@@ -116,6 +134,10 @@ export type EngineCmd =
116
134
  | { type: 'cmd-realm-create'; content: Realm.CmdRealmCreateArgs }
117
135
  | { type: 'cmd-realm-dispose'; content: Realm.CmdRealmDisposeArgs }
118
136
  | { type: 'cmd-target-upsert'; content: Target.CmdTargetUpsertArgs }
137
+ | {
138
+ type: 'cmd-target-measurement';
139
+ content: Target.CmdTargetMeasurementArgs;
140
+ }
119
141
  | { type: 'cmd-target-dispose'; content: Target.CmdTargetDisposeArgs }
120
142
  | {
121
143
  type: 'cmd-target-layer-upsert';
@@ -168,11 +190,27 @@ export type CommandResponse =
168
190
  type: 'system-diagnostics-set';
169
191
  content: Sys.CmdResultSystemDiagnosticsSet;
170
192
  }
193
+ | {
194
+ type: 'system-build-version-get';
195
+ content: Sys.CmdResultSystemBuildVersionGet;
196
+ }
171
197
  | { type: 'window-create'; content: Win.CmdResultWindowCreate }
172
198
  | { type: 'window-close'; content: Win.CmdResultWindowClose }
173
199
  | { type: 'window-measurement'; content: Win.CmdResultWindowMeasurement }
174
200
  | { type: 'window-cursor'; content: Win.CmdResultWindowCursor }
175
201
  | { type: 'window-state'; content: Win.CmdResultWindowState }
202
+ | {
203
+ type: 'input-target-listener-upsert';
204
+ content: Input.CmdResultInputTargetListenerUpsert;
205
+ }
206
+ | {
207
+ type: 'input-target-listener-dispose';
208
+ content: Input.CmdResultInputTargetListenerDispose;
209
+ }
210
+ | {
211
+ type: 'input-target-listener-list';
212
+ content: Input.CmdResultInputTargetListenerList;
213
+ }
176
214
  | {
177
215
  type: 'upload-buffer-discard-all';
178
216
  content: Sys.CmdResultUploadBufferDiscardAll;
@@ -240,6 +278,10 @@ export type CommandResponse =
240
278
  | { type: 'realm-create'; content: Realm.CmdResultRealmCreate }
241
279
  | { type: 'realm-dispose'; content: Realm.CmdResultRealmDispose }
242
280
  | { type: 'target-upsert'; content: Target.CmdResultTargetUpsert }
281
+ | {
282
+ type: 'target-measurement';
283
+ content: Target.CmdResultTargetMeasurement;
284
+ }
243
285
  | { type: 'target-dispose'; content: Target.CmdResultTargetDispose }
244
286
  | {
245
287
  type: 'target-layer-upsert';
@@ -0,0 +1,39 @@
1
+ export interface CmdInputTargetListenerUpsertArgs {
2
+ listenerId: number;
3
+ targetId: number;
4
+ enabled?: boolean;
5
+ events?: string[];
6
+ samplePercent?: number;
7
+ }
8
+
9
+ export interface CmdResultInputTargetListenerUpsert {
10
+ success: boolean;
11
+ message: string;
12
+ }
13
+
14
+ export interface CmdInputTargetListenerDisposeArgs {
15
+ listenerId: number;
16
+ }
17
+
18
+ export interface CmdResultInputTargetListenerDispose {
19
+ success: boolean;
20
+ message: string;
21
+ }
22
+
23
+ export interface CmdInputTargetListenerListArgs {
24
+ targetId?: number;
25
+ }
26
+
27
+ export interface InputTargetListenerSnapshot {
28
+ listenerId: number;
29
+ targetId: number;
30
+ enabled: boolean;
31
+ events: string[];
32
+ samplePercent: number;
33
+ }
34
+
35
+ export interface CmdResultInputTargetListenerList {
36
+ success: boolean;
37
+ message: string;
38
+ listeners: InputTargetListenerSnapshot[];
39
+ }
@@ -28,16 +28,16 @@ export interface PbrOptions {
28
28
  roughness: number;
29
29
  ao: number;
30
30
  normalScale: number;
31
- baseTexId: number;
32
- baseSampler: SamplerMode;
33
- normalTexId: number;
34
- normalSampler: SamplerMode;
35
- metallicRoughnessTexId: number;
36
- metallicRoughnessSampler: SamplerMode;
37
- emissiveTexId: number;
38
- emissiveSampler: SamplerMode;
39
- aoTexId: number;
40
- aoSampler: SamplerMode;
31
+ baseTexId?: number | null;
32
+ baseSampler?: SamplerMode | null;
33
+ normalTexId?: number | null;
34
+ normalSampler?: SamplerMode | null;
35
+ metallicRoughnessTexId?: number | null;
36
+ metallicRoughnessSampler?: SamplerMode | null;
37
+ emissiveTexId?: number | null;
38
+ emissiveSampler?: SamplerMode | null;
39
+ aoTexId?: number | null;
40
+ aoSampler?: SamplerMode | null;
41
41
  flags: number;
42
42
  }
43
43
 
@@ -2,8 +2,6 @@ export type RealmKind = 'three-d' | 'two-d';
2
2
 
3
3
  export interface CmdRealmCreateArgs {
4
4
  kind: RealmKind;
5
- outputSurfaceId?: number;
6
- hostWindowId?: number;
7
5
  importance?: number;
8
6
  cachePolicy?: number;
9
7
  flags?: number;
@@ -33,6 +33,16 @@ export interface CmdResultSystemDiagnosticsSet {
33
33
  message: string;
34
34
  }
35
35
 
36
+ /** Command payload for retrieving core build version. */
37
+ export interface CmdSystemBuildVersionGetArgs {}
38
+
39
+ /** Result payload for build version query. */
40
+ export interface CmdResultSystemBuildVersionGet {
41
+ success: boolean;
42
+ message: string;
43
+ buildVersion: string;
44
+ }
45
+
36
46
  /** Command payload for discarding all pending upload buffers. */
37
47
  export interface CmdUploadBufferDiscardAllArgs {}
38
48
 
@@ -49,6 +49,20 @@ export interface CmdResultTargetUpsert {
49
49
  message: string;
50
50
  }
51
51
 
52
+ export interface CmdTargetMeasurementArgs {
53
+ targetId: number;
54
+ getSize?: boolean;
55
+ getWindowSize?: boolean;
56
+ }
57
+
58
+ export interface CmdResultTargetMeasurement {
59
+ success: boolean;
60
+ message: string;
61
+ size?: [number, number];
62
+ windowSize?: [number, number];
63
+ sourceKind?: string;
64
+ }
65
+
52
66
  export interface CmdTargetDisposeArgs {
53
67
  targetId: number;
54
68
  }
@@ -120,8 +120,8 @@ export enum KeyCode {
120
120
  ControlLeft = 55,
121
121
  ControlRight = 56,
122
122
  Enter = 57,
123
- SuperLeft = 58,
124
- SuperRight = 59,
123
+ MetaLeft = 58,
124
+ MetaRight = 59,
125
125
  ShiftLeft = 60,
126
126
  ShiftRight = 61,
127
127
  Space = 62,