@uptimizr/playcanvas 0.1.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/LICENSE +201 -0
- package/README.md +193 -0
- package/dist/collector.d.ts +259 -0
- package/dist/collector.d.ts.map +1 -0
- package/dist/collector.js +1081 -0
- package/dist/collector.js.map +1 -0
- package/dist/connector.d.ts +17 -0
- package/dist/connector.d.ts.map +1 -0
- package/dist/connector.js +30 -0
- package/dist/connector.js.map +1 -0
- package/dist/device.d.ts +17 -0
- package/dist/device.d.ts.map +1 -0
- package/dist/device.js +40 -0
- package/dist/device.js.map +1 -0
- package/dist/graphics.d.ts +16 -0
- package/dist/graphics.d.ts.map +1 -0
- package/dist/graphics.js +57 -0
- package/dist/graphics.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/proxy.d.ts +46 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.js +225 -0
- package/dist/proxy.js.map +1 -0
- package/dist/raycast.d.ts +68 -0
- package/dist/raycast.d.ts.map +1 -0
- package/dist/raycast.js +163 -0
- package/dist/raycast.js.map +1 -0
- package/dist/renderer.d.ts +48 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +62 -0
- package/dist/renderer.js.map +1 -0
- package/dist/scene.d.ts +21 -0
- package/dist/scene.d.ts.map +1 -0
- package/dist/scene.js +51 -0
- package/dist/scene.js.map +1 -0
- package/dist/trackScene.d.ts +114 -0
- package/dist/trackScene.d.ts.map +1 -0
- package/dist/trackScene.js +72 -0
- package/dist/trackScene.js.map +1 -0
- package/dist/uptimizr-playcanvas.global.js +66 -0
- package/dist/uptimizr-playcanvas.js +66 -0
- package/dist/vec.d.ts +10 -0
- package/dist/vec.d.ts.map +1 -0
- package/dist/vec.js +9 -0
- package/dist/vec.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { AppBase, Entity, GraphNode } from "playcanvas";
|
|
2
|
+
import type { Vec3 as SchemaVec3 } from "@uptimizr/schema";
|
|
3
|
+
/** A raycast result: the world-space hit point and the hit object's name. */
|
|
4
|
+
export interface RaycastHit {
|
|
5
|
+
/** Hit point in the source (PlayCanvas, right-handed) world frame. */
|
|
6
|
+
point: SchemaVec3;
|
|
7
|
+
/** The hit object's `name` (empty string when unnamed). */
|
|
8
|
+
name: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Probe the scene at the given normalized device coordinates (NDC, each in
|
|
12
|
+
* `[-1, 1]`, y-up) and return the nearest visible hit, or `undefined` for a miss.
|
|
13
|
+
*
|
|
14
|
+
* The point is in the **source** world frame; the collector normalizes it to the
|
|
15
|
+
* canonical frame at the emission boundary (it owns the coordinate contract).
|
|
16
|
+
*/
|
|
17
|
+
export type RaycastProbe = (ndcX: number, ndcY: number) => RaycastHit | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Build a {@link RaycastProbe} backed by PlayCanvas' own `Ray` + per-mesh-instance
|
|
20
|
+
* world `BoundingBox.intersectsRay`. This is the PlayCanvas stand-in for Babylon's
|
|
21
|
+
* `scene.onPointerObservable` pick info: the connector raycasts explicitly per
|
|
22
|
+
* pointer event.
|
|
23
|
+
*
|
|
24
|
+
* Picking is **physics-free** — it tests render/model mesh-instance world AABBs and
|
|
25
|
+
* never touches the rigidbody system (so no `ammo` dependency). Overlay meshes
|
|
26
|
+
* (`uptimizr-` prefix) are skipped so analytics overlays never register as hits.
|
|
27
|
+
* Reads only — it never mutates the scene.
|
|
28
|
+
*/
|
|
29
|
+
export declare function createSceneRaycaster(app: AppBase, cameraEntity: Entity): RaycastProbe;
|
|
30
|
+
/** Gaze raycast tuning (`camera_sample.hitPoint`/`hitMesh`, ADR 0030). */
|
|
31
|
+
export interface GazeProbeOptions {
|
|
32
|
+
/**
|
|
33
|
+
* Max gaze-ray length in world units. Caps how far the camera-forward ray
|
|
34
|
+
* reaches before it counts as a miss (keeps `hitPoint` meaningful and skips
|
|
35
|
+
* sky/backdrop geometry). Default 1000.
|
|
36
|
+
*/
|
|
37
|
+
maxDistance?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Allowlist of object names eligible for a gaze hit (low-cardinality,
|
|
40
|
+
* app-defined — ADR 0003). When omitted, any visible object can be hit. Provide
|
|
41
|
+
* this to keep `hitMesh` cardinality meaningful and to exclude ground/sky/helper
|
|
42
|
+
* objects from "what did people look at".
|
|
43
|
+
*/
|
|
44
|
+
meshes?: string[];
|
|
45
|
+
/**
|
|
46
|
+
* Predicate escape hatch: return `false` to exclude a node from gaze picking
|
|
47
|
+
* (e.g. sky, ground, gizmos). Combined with {@link meshes} (a node must pass both
|
|
48
|
+
* the allowlist, if any, and the predicate, if any).
|
|
49
|
+
*/
|
|
50
|
+
predicate?: (node: GraphNode) => boolean;
|
|
51
|
+
}
|
|
52
|
+
/** A camera-forward gaze probe: returns the nearest surface hit, or `undefined`. */
|
|
53
|
+
export type GazeProbe = () => RaycastHit | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Build a {@link GazeProbe} that casts the camera's forward ray — NDC centre
|
|
56
|
+
* `(0, 0)`, i.e. the screen centre pixel — into the scene (ADR 0030). This is the
|
|
57
|
+
* PlayCanvas stand-in for Babylon's `camera.getForwardRay()` + `scene.pickWithRay()`.
|
|
58
|
+
*
|
|
59
|
+
* Performance: a single reused `Ray` + scratch vectors (no per-sample allocation),
|
|
60
|
+
* `maxDistance` clamps the ray, and the caller rides the throttled, idle-suppressed
|
|
61
|
+
* camera cadence so a pick runs at most once per emitted pose. Picking is
|
|
62
|
+
* physics-free (mesh-instance world AABBs only — no `ammo`), overlay meshes
|
|
63
|
+
* (`uptimizr-` prefix) are skipped, and the allowlist/predicate are applied during
|
|
64
|
+
* traversal so an occluding non-match never hides an eligible hit behind it. Reads
|
|
65
|
+
* only — it never mutates the scene.
|
|
66
|
+
*/
|
|
67
|
+
export declare function createGazeRaycaster(app: AppBase, cameraEntity: Entity, options?: GazeProbeOptions): GazeProbe;
|
|
68
|
+
//# sourceMappingURL=raycast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raycast.d.ts","sourceRoot":"","sources":["../src/raycast.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAe,MAAM,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,KAAK,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE3D,6EAA6E;AAC7E,MAAM,WAAW,UAAU;IACzB,sEAAsE;IACtE,KAAK,EAAE,UAAU,CAAC;IAClB,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;AA0ClF;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,YAAY,CA0DrF;AAED,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;CAC1C;AAED,oFAAoF;AACpF,MAAM,MAAM,SAAS,GAAG,MAAM,UAAU,GAAG,SAAS,CAAC;AAErD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,OAAO,EACZ,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,gBAAqB,GAC7B,SAAS,CAgEX"}
|
package/dist/raycast.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// playcanvas is a peer dependency; `Ray` / `Vec3` are the engine's own geometry
|
|
2
|
+
// primitives and have no WebGL/DOM dependency (pure math), so importing them at
|
|
3
|
+
// runtime is both necessary and safe. esbuild keeps `playcanvas` external — it is
|
|
4
|
+
// never bundled. This is the one place the connector touches `playcanvas` at
|
|
5
|
+
// runtime: the camera-pose path reads world transforms structurally instead (see
|
|
6
|
+
// `collector.ts`), because raycasting has no faithful structural substitute.
|
|
7
|
+
import { Ray, Vec3 } from "playcanvas";
|
|
8
|
+
const OVERLAY_PREFIX = "uptimizr-";
|
|
9
|
+
/**
|
|
10
|
+
* Build a {@link RaycastProbe} backed by PlayCanvas' own `Ray` + per-mesh-instance
|
|
11
|
+
* world `BoundingBox.intersectsRay`. This is the PlayCanvas stand-in for Babylon's
|
|
12
|
+
* `scene.onPointerObservable` pick info: the connector raycasts explicitly per
|
|
13
|
+
* pointer event.
|
|
14
|
+
*
|
|
15
|
+
* Picking is **physics-free** — it tests render/model mesh-instance world AABBs and
|
|
16
|
+
* never touches the rigidbody system (so no `ammo` dependency). Overlay meshes
|
|
17
|
+
* (`uptimizr-` prefix) are skipped so analytics overlays never register as hits.
|
|
18
|
+
* Reads only — it never mutates the scene.
|
|
19
|
+
*/
|
|
20
|
+
export function createSceneRaycaster(app, cameraEntity) {
|
|
21
|
+
const ray = new Ray();
|
|
22
|
+
const near = new Vec3();
|
|
23
|
+
const far = new Vec3();
|
|
24
|
+
const hitPoint = new Vec3();
|
|
25
|
+
const best = new Vec3();
|
|
26
|
+
return (ndcX, ndcY) => {
|
|
27
|
+
const cam = cameraEntity.camera;
|
|
28
|
+
const lowLevel = cam?.camera;
|
|
29
|
+
if (!cam || !lowLevel)
|
|
30
|
+
return undefined;
|
|
31
|
+
const device = app.graphicsDevice;
|
|
32
|
+
const canvas = device?.canvas;
|
|
33
|
+
const cw = canvas?.clientWidth || canvas?.width || device?.width || 1;
|
|
34
|
+
const ch = canvas?.clientHeight || canvas?.height || device?.height || 1;
|
|
35
|
+
// NDC (-1..1, y-up) → PlayCanvas screen pixels (top-left origin).
|
|
36
|
+
const sx = ((ndcX + 1) / 2) * cw;
|
|
37
|
+
const sy = ((1 - ndcY) / 2) * ch;
|
|
38
|
+
const nearClip = cam.nearClip ?? 0.1;
|
|
39
|
+
const farClip = cam.farClip ?? 1000;
|
|
40
|
+
lowLevel.screenToWorld(sx, sy, nearClip, cw, ch, near);
|
|
41
|
+
lowLevel.screenToWorld(sx, sy, farClip, cw, ch, far);
|
|
42
|
+
ray.origin.copy(near);
|
|
43
|
+
ray.direction.copy(far).sub(near).normalize();
|
|
44
|
+
let bestDist = Infinity;
|
|
45
|
+
let bestName;
|
|
46
|
+
const root = app.root;
|
|
47
|
+
root?.forEach?.((raw) => {
|
|
48
|
+
const node = raw;
|
|
49
|
+
if (node.enabled === false)
|
|
50
|
+
return;
|
|
51
|
+
const instances = node.render?.meshInstances ?? node.model?.meshInstances;
|
|
52
|
+
if (!instances)
|
|
53
|
+
return;
|
|
54
|
+
for (const mi of instances) {
|
|
55
|
+
if (mi.visible === false)
|
|
56
|
+
continue;
|
|
57
|
+
const name = mi.node?.name ?? "";
|
|
58
|
+
if (name.startsWith(OVERLAY_PREFIX))
|
|
59
|
+
continue;
|
|
60
|
+
const box = mi.aabb;
|
|
61
|
+
if (!box || typeof box.intersectsRay !== "function")
|
|
62
|
+
continue;
|
|
63
|
+
if (!box.intersectsRay(ray, hitPoint))
|
|
64
|
+
continue;
|
|
65
|
+
const dx = hitPoint.x - ray.origin.x;
|
|
66
|
+
const dy = hitPoint.y - ray.origin.y;
|
|
67
|
+
const dz = hitPoint.z - ray.origin.z;
|
|
68
|
+
const dist = dx * dx + dy * dy + dz * dz;
|
|
69
|
+
if (dist < bestDist) {
|
|
70
|
+
bestDist = dist;
|
|
71
|
+
bestName = name;
|
|
72
|
+
best.copy(hitPoint);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
if (bestName === undefined)
|
|
77
|
+
return undefined;
|
|
78
|
+
return { point: [best.x, best.y, best.z], name: bestName };
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Build a {@link GazeProbe} that casts the camera's forward ray — NDC centre
|
|
83
|
+
* `(0, 0)`, i.e. the screen centre pixel — into the scene (ADR 0030). This is the
|
|
84
|
+
* PlayCanvas stand-in for Babylon's `camera.getForwardRay()` + `scene.pickWithRay()`.
|
|
85
|
+
*
|
|
86
|
+
* Performance: a single reused `Ray` + scratch vectors (no per-sample allocation),
|
|
87
|
+
* `maxDistance` clamps the ray, and the caller rides the throttled, idle-suppressed
|
|
88
|
+
* camera cadence so a pick runs at most once per emitted pose. Picking is
|
|
89
|
+
* physics-free (mesh-instance world AABBs only — no `ammo`), overlay meshes
|
|
90
|
+
* (`uptimizr-` prefix) are skipped, and the allowlist/predicate are applied during
|
|
91
|
+
* traversal so an occluding non-match never hides an eligible hit behind it. Reads
|
|
92
|
+
* only — it never mutates the scene.
|
|
93
|
+
*/
|
|
94
|
+
export function createGazeRaycaster(app, cameraEntity, options = {}) {
|
|
95
|
+
const ray = new Ray();
|
|
96
|
+
const near = new Vec3();
|
|
97
|
+
const far = new Vec3();
|
|
98
|
+
const hitPoint = new Vec3();
|
|
99
|
+
const best = new Vec3();
|
|
100
|
+
const maxDistance = options.maxDistance ?? 1000;
|
|
101
|
+
const maxDistanceSq = maxDistance * maxDistance;
|
|
102
|
+
const allow = options.meshes && options.meshes.length > 0 ? new Set(options.meshes) : null;
|
|
103
|
+
const predicate = options.predicate;
|
|
104
|
+
return () => {
|
|
105
|
+
const cam = cameraEntity.camera;
|
|
106
|
+
const lowLevel = cam?.camera;
|
|
107
|
+
if (!cam || !lowLevel)
|
|
108
|
+
return undefined;
|
|
109
|
+
const device = app.graphicsDevice;
|
|
110
|
+
const canvas = device?.canvas;
|
|
111
|
+
const cw = canvas?.clientWidth || canvas?.width || device?.width || 1;
|
|
112
|
+
const ch = canvas?.clientHeight || canvas?.height || device?.height || 1;
|
|
113
|
+
// Camera-forward ray = screen centre (NDC origin).
|
|
114
|
+
const sx = cw / 2;
|
|
115
|
+
const sy = ch / 2;
|
|
116
|
+
const nearClip = cam.nearClip ?? 0.1;
|
|
117
|
+
const farClip = cam.farClip ?? 1000;
|
|
118
|
+
lowLevel.screenToWorld(sx, sy, nearClip, cw, ch, near);
|
|
119
|
+
lowLevel.screenToWorld(sx, sy, farClip, cw, ch, far);
|
|
120
|
+
ray.origin.copy(near);
|
|
121
|
+
ray.direction.copy(far).sub(near).normalize();
|
|
122
|
+
let bestDist = Infinity;
|
|
123
|
+
let bestName;
|
|
124
|
+
const root = app.root;
|
|
125
|
+
root?.forEach?.((raw) => {
|
|
126
|
+
const node = raw;
|
|
127
|
+
if (node.enabled === false)
|
|
128
|
+
return;
|
|
129
|
+
const instances = node.render?.meshInstances ?? node.model?.meshInstances;
|
|
130
|
+
if (!instances)
|
|
131
|
+
return;
|
|
132
|
+
for (const mi of instances) {
|
|
133
|
+
if (mi.visible === false)
|
|
134
|
+
continue;
|
|
135
|
+
const name = mi.node?.name ?? "";
|
|
136
|
+
if (name.startsWith(OVERLAY_PREFIX))
|
|
137
|
+
continue;
|
|
138
|
+
if (allow && !allow.has(name))
|
|
139
|
+
continue;
|
|
140
|
+
if (predicate && mi.node && !predicate(mi.node))
|
|
141
|
+
continue;
|
|
142
|
+
const box = mi.aabb;
|
|
143
|
+
if (!box || typeof box.intersectsRay !== "function")
|
|
144
|
+
continue;
|
|
145
|
+
if (!box.intersectsRay(ray, hitPoint))
|
|
146
|
+
continue;
|
|
147
|
+
const dx = hitPoint.x - ray.origin.x;
|
|
148
|
+
const dy = hitPoint.y - ray.origin.y;
|
|
149
|
+
const dz = hitPoint.z - ray.origin.z;
|
|
150
|
+
const dist = dx * dx + dy * dy + dz * dz;
|
|
151
|
+
if (dist < bestDist) {
|
|
152
|
+
bestDist = dist;
|
|
153
|
+
bestName = name;
|
|
154
|
+
best.copy(hitPoint);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
if (bestName === undefined || bestDist > maxDistanceSq)
|
|
159
|
+
return undefined;
|
|
160
|
+
return { point: [best.x, best.y, best.z], name: bestName };
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=raycast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raycast.js","sourceRoot":"","sources":["../src/raycast.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defensive readers for a PlayCanvas graphics device's underlying graphics
|
|
3
|
+
* context. Shared by {@link "./device".readDeviceCaps} and
|
|
4
|
+
* {@link "./graphics".readGraphics}.
|
|
5
|
+
*
|
|
6
|
+
* PlayCanvas exposes one `GraphicsDevice` with two backends — `WebglGraphicsDevice`
|
|
7
|
+
* and `WebgpuGraphicsDevice` — whose surfaces differ, so we read structurally via
|
|
8
|
+
* minimal views rather than binding to concrete classes (which would also force a
|
|
9
|
+
* runtime dependency on `playcanvas`).
|
|
10
|
+
*/
|
|
11
|
+
/** Minimal structural view of `app.graphicsDevice`. */
|
|
12
|
+
export interface GraphicsDeviceView {
|
|
13
|
+
/** `true` on a PlayCanvas `WebgpuGraphicsDevice`. */
|
|
14
|
+
isWebGPU?: boolean;
|
|
15
|
+
/** `true` on a WebGL2 device. */
|
|
16
|
+
isWebGL2?: boolean;
|
|
17
|
+
/** Maximum 2D texture size, when reported. */
|
|
18
|
+
maxTextureSize?: number;
|
|
19
|
+
/** The WebGL rendering context (present on `WebglGraphicsDevice`). */
|
|
20
|
+
gl?: unknown;
|
|
21
|
+
/** The backing canvas element. */
|
|
22
|
+
canvas?: {
|
|
23
|
+
width?: number;
|
|
24
|
+
height?: number;
|
|
25
|
+
clientWidth?: number;
|
|
26
|
+
clientHeight?: number;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export interface GlInfo {
|
|
30
|
+
vendor?: string;
|
|
31
|
+
renderer?: string;
|
|
32
|
+
version?: string;
|
|
33
|
+
}
|
|
34
|
+
/** True when the device is a PlayCanvas `WebgpuGraphicsDevice`. */
|
|
35
|
+
export declare function isWebGpu(device: unknown): boolean;
|
|
36
|
+
/** Read `maxTextureSize`, when exposed. */
|
|
37
|
+
export declare function maxTextureSize(device: unknown): number | undefined;
|
|
38
|
+
/** True when the device reports a WebGL2 context (or no WebGL1 fallback). */
|
|
39
|
+
export declare function isWebGl2(device: unknown): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Read vendor / renderer / version strings from the device's WebGL context,
|
|
42
|
+
* preferring the **unmasked** strings exposed by `WEBGL_debug_renderer_info` (the
|
|
43
|
+
* driver behind ANGLE) and falling back to the masked `VENDOR`/`RENDERER`. All
|
|
44
|
+
* reads are best-effort: some contexts withhold these, and a WebGPU device has no
|
|
45
|
+
* WebGL context at all — in which case an empty object is returned.
|
|
46
|
+
*/
|
|
47
|
+
export declare function readGlInfo(device: unknown): GlInfo;
|
|
48
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAcH,uDAAuD;AACvD,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,kCAAkC;IAClC,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3F;AAED,MAAM,WAAW,MAAM;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,mEAAmE;AACnE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAEjD;AAED,2CAA2C;AAC3C,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAGlE;AAED,6EAA6E;AAC7E,wBAAgB,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAMjD;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAsBlD"}
|
package/dist/renderer.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defensive readers for a PlayCanvas graphics device's underlying graphics
|
|
3
|
+
* context. Shared by {@link "./device".readDeviceCaps} and
|
|
4
|
+
* {@link "./graphics".readGraphics}.
|
|
5
|
+
*
|
|
6
|
+
* PlayCanvas exposes one `GraphicsDevice` with two backends — `WebglGraphicsDevice`
|
|
7
|
+
* and `WebgpuGraphicsDevice` — whose surfaces differ, so we read structurally via
|
|
8
|
+
* minimal views rather than binding to concrete classes (which would also force a
|
|
9
|
+
* runtime dependency on `playcanvas`).
|
|
10
|
+
*/
|
|
11
|
+
/** True when the device is a PlayCanvas `WebgpuGraphicsDevice`. */
|
|
12
|
+
export function isWebGpu(device) {
|
|
13
|
+
return device.isWebGPU === true;
|
|
14
|
+
}
|
|
15
|
+
/** Read `maxTextureSize`, when exposed. */
|
|
16
|
+
export function maxTextureSize(device) {
|
|
17
|
+
const max = device.maxTextureSize;
|
|
18
|
+
return typeof max === "number" ? max : undefined;
|
|
19
|
+
}
|
|
20
|
+
/** True when the device reports a WebGL2 context (or no WebGL1 fallback). */
|
|
21
|
+
export function isWebGl2(device) {
|
|
22
|
+
const view = device;
|
|
23
|
+
if (view.isWebGPU)
|
|
24
|
+
return false;
|
|
25
|
+
// PlayCanvas 2.x is WebGL2-only on the WebGL path and may omit the flag — treat
|
|
26
|
+
// absence as WebGL2.
|
|
27
|
+
return view.isWebGL2 !== false;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Read vendor / renderer / version strings from the device's WebGL context,
|
|
31
|
+
* preferring the **unmasked** strings exposed by `WEBGL_debug_renderer_info` (the
|
|
32
|
+
* driver behind ANGLE) and falling back to the masked `VENDOR`/`RENDERER`. All
|
|
33
|
+
* reads are best-effort: some contexts withhold these, and a WebGPU device has no
|
|
34
|
+
* WebGL context at all — in which case an empty object is returned.
|
|
35
|
+
*/
|
|
36
|
+
export function readGlInfo(device) {
|
|
37
|
+
const view = device;
|
|
38
|
+
const gl = view.gl;
|
|
39
|
+
if (!gl)
|
|
40
|
+
return {};
|
|
41
|
+
const c = gl;
|
|
42
|
+
const info = {};
|
|
43
|
+
try {
|
|
44
|
+
const ext = typeof c.getExtension === "function" ? c.getExtension("WEBGL_debug_renderer_info") : null;
|
|
45
|
+
const vendorParam = ext ? ext.UNMASKED_VENDOR_WEBGL : c.VENDOR;
|
|
46
|
+
const rendererParam = ext ? ext.UNMASKED_RENDERER_WEBGL : c.RENDERER;
|
|
47
|
+
const vendor = c.getParameter(vendorParam);
|
|
48
|
+
const renderer = c.getParameter(rendererParam);
|
|
49
|
+
const version = c.getParameter(c.VERSION);
|
|
50
|
+
if (typeof vendor === "string" && vendor)
|
|
51
|
+
info.vendor = vendor;
|
|
52
|
+
if (typeof renderer === "string" && renderer)
|
|
53
|
+
info.renderer = renderer;
|
|
54
|
+
if (typeof version === "string" && version)
|
|
55
|
+
info.version = version;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Best-effort: a context may disallow these reads. Leave fields unset.
|
|
59
|
+
}
|
|
60
|
+
return info;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkCH,mEAAmE;AACnE,MAAM,UAAU,QAAQ,CAAC,MAAe;IACtC,OAAQ,MAA6B,CAAC,QAAQ,KAAK,IAAI,CAAC;AAC1D,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,cAAc,CAAC,MAAe;IAC5C,MAAM,GAAG,GAAI,MAA6B,CAAC,cAAc,CAAC;IAC1D,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AACnD,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,QAAQ,CAAC,MAAe;IACtC,MAAM,IAAI,GAAG,MAA4B,CAAC;IAC1C,IAAI,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAChC,gFAAgF;IAChF,qBAAqB;IACrB,OAAO,IAAI,CAAC,QAAQ,KAAK,KAAK,CAAC;AACjC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,MAAe;IACxC,MAAM,IAAI,GAAG,MAA4B,CAAC;IAC1C,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC;IAEnB,MAAM,CAAC,GAAG,EAAiB,CAAC;IAC5B,MAAM,IAAI,GAAW,EAAE,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GACP,OAAO,CAAC,CAAC,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,2BAA2B,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5F,MAAM,WAAW,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC/D,MAAM,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QACrE,MAAM,MAAM,GAAG,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,CAAC,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM;YAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAC/D,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ;YAAE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACvE,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO;YAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;IACzE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/scene.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AppBase, Entity } from "playcanvas";
|
|
2
|
+
import type { CameraKind, SceneMeta } from "@uptimizr/schema";
|
|
3
|
+
/**
|
|
4
|
+
* Classify a PlayCanvas camera into a coarse {@link CameraKind}. PlayCanvas has no
|
|
5
|
+
* built-in "driver" taxonomy (orbit/fly/etc. live in optional scripts the
|
|
6
|
+
* connector can't see), so this reflects the *projection*: a perspective camera
|
|
7
|
+
* maps to `"free"` (the closest free-roaming analogue) and an orthographic camera
|
|
8
|
+
* to `"static"`. Anything else is `"other"`.
|
|
9
|
+
*/
|
|
10
|
+
export declare function classifyCamera(camera: Entity | null | undefined): CameraKind;
|
|
11
|
+
/**
|
|
12
|
+
* Read a coarse {@link SceneMeta} block from a PlayCanvas app + camera Entity: the
|
|
13
|
+
* camera's kind/name and the mesh count. Pass the result to
|
|
14
|
+
* `client.start({ scene })` (or via `trackScene`) so it rides along on the
|
|
15
|
+
* `session_start` event.
|
|
16
|
+
*
|
|
17
|
+
* It only reads from the scene — never mutates it. Caller-supplied fields like a
|
|
18
|
+
* scene `description` should be merged in by the caller.
|
|
19
|
+
*/
|
|
20
|
+
export declare function readSceneMeta(app: AppBase, camera: Entity): SceneMeta;
|
|
21
|
+
//# sourceMappingURL=scene.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAKlD,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAuB9D;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,UAAU,CAM5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAsBrE"}
|
package/dist/scene.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// `PROJECTION_PERSPECTIVE` / `PROJECTION_ORTHOGRAPHIC` are plain numeric module
|
|
2
|
+
// constants (no WebGL / DOM), so importing them to classify the camera is safe.
|
|
3
|
+
// esbuild keeps `playcanvas` external — it is never bundled.
|
|
4
|
+
import { PROJECTION_ORTHOGRAPHIC, PROJECTION_PERSPECTIVE } from "playcanvas";
|
|
5
|
+
/**
|
|
6
|
+
* Classify a PlayCanvas camera into a coarse {@link CameraKind}. PlayCanvas has no
|
|
7
|
+
* built-in "driver" taxonomy (orbit/fly/etc. live in optional scripts the
|
|
8
|
+
* connector can't see), so this reflects the *projection*: a perspective camera
|
|
9
|
+
* maps to `"free"` (the closest free-roaming analogue) and an orthographic camera
|
|
10
|
+
* to `"static"`. Anything else is `"other"`.
|
|
11
|
+
*/
|
|
12
|
+
export function classifyCamera(camera) {
|
|
13
|
+
const view = camera;
|
|
14
|
+
const projection = view?.camera?.projection;
|
|
15
|
+
if (projection === PROJECTION_PERSPECTIVE)
|
|
16
|
+
return "free";
|
|
17
|
+
if (projection === PROJECTION_ORTHOGRAPHIC)
|
|
18
|
+
return "static";
|
|
19
|
+
return "other";
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Read a coarse {@link SceneMeta} block from a PlayCanvas app + camera Entity: the
|
|
23
|
+
* camera's kind/name and the mesh count. Pass the result to
|
|
24
|
+
* `client.start({ scene })` (or via `trackScene`) so it rides along on the
|
|
25
|
+
* `session_start` event.
|
|
26
|
+
*
|
|
27
|
+
* It only reads from the scene — never mutates it. Caller-supplied fields like a
|
|
28
|
+
* scene `description` should be merged in by the caller.
|
|
29
|
+
*/
|
|
30
|
+
export function readSceneMeta(app, camera) {
|
|
31
|
+
const meta = {};
|
|
32
|
+
const view = camera;
|
|
33
|
+
if (view) {
|
|
34
|
+
meta.cameraType = classifyCamera(camera);
|
|
35
|
+
if (typeof view.name === "string" && view.name)
|
|
36
|
+
meta.cameraName = view.name;
|
|
37
|
+
}
|
|
38
|
+
const root = app.root;
|
|
39
|
+
if (root && typeof root.forEach === "function") {
|
|
40
|
+
let meshCount = 0;
|
|
41
|
+
root.forEach((raw) => {
|
|
42
|
+
const node = raw;
|
|
43
|
+
const renderInstances = node.render?.meshInstances?.length ?? 0;
|
|
44
|
+
const modelInstances = node.model?.meshInstances?.length ?? 0;
|
|
45
|
+
meshCount += renderInstances + modelInstances;
|
|
46
|
+
});
|
|
47
|
+
meta.meshCount = meshCount;
|
|
48
|
+
}
|
|
49
|
+
return meta;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=scene.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene.js","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"AACA,gFAAgF;AAChF,gFAAgF;AAChF,6DAA6D;AAC7D,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAwB7E;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,MAAiC;IAC9D,MAAM,IAAI,GAAG,MAAwD,CAAC;IACtE,MAAM,UAAU,GAAG,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC;IAC5C,IAAI,UAAU,KAAK,sBAAsB;QAAE,OAAO,MAAM,CAAC;IACzD,IAAI,UAAU,KAAK,uBAAuB;QAAE,OAAO,QAAQ,CAAC;IAC5D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,GAAY,EAAE,MAAc;IACxD,MAAM,IAAI,GAAc,EAAE,CAAC;IAE3B,MAAM,IAAI,GAAG,MAA4C,CAAC;IAC1D,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI;YAAE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC;IAC9E,CAAC;IAED,MAAM,IAAI,GAAI,GAA8B,CAAC,IAAI,CAAC;IAClD,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAC/C,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACnB,MAAM,IAAI,GAAG,GAAyB,CAAC;YACvC,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC,CAAC;YAChE,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC,CAAC;YAC9D,SAAS,IAAI,eAAe,GAAG,cAAc,CAAC;QAChD,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { UptimizrClient } from "@uptimizr/sdk-core";
|
|
2
|
+
import type { StartMeta, Transport, SamplingProfile } from "@uptimizr/sdk-core";
|
|
3
|
+
import type { CameraKind, SessionUser } from "@uptimizr/schema";
|
|
4
|
+
import type { AppBase, Entity } from "playcanvas";
|
|
5
|
+
import type { PlayCanvasActor, PlayCanvasCaptureOptions, PlayCanvasGazeOptions } from "./collector.js";
|
|
6
|
+
/**
|
|
7
|
+
* Options for {@link trackScene} — the project/endpoint plus the same sampling and
|
|
8
|
+
* capture knobs as {@link playcanvasCollector}, flattened for one-call setup.
|
|
9
|
+
*/
|
|
10
|
+
export interface TrackSceneOptions {
|
|
11
|
+
/** Project identifier (public, non-secret). */
|
|
12
|
+
projectId: string;
|
|
13
|
+
/** Collector endpoint base URL, e.g. `https://collect.example.com`. */
|
|
14
|
+
endpoint: string;
|
|
15
|
+
/** Camera-pose sampling interval in ms. Default 1000. */
|
|
16
|
+
sampleCameraMs?: number;
|
|
17
|
+
/** Performance (FPS) sampling interval in ms. Default 2000. */
|
|
18
|
+
samplePerfMs?: number;
|
|
19
|
+
/** Minimum gap between `pointer_move` samples in ms. Default 250. */
|
|
20
|
+
pointerMoveThrottleMs?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Per-channel capture-fidelity dial in Hz / `"frame"` / `0`-off (ADR 0012),
|
|
23
|
+
* e.g. `{ camera: 10, pointerMove: 60, perf: 0.5 }`. Governs continuous channels
|
|
24
|
+
* only; discrete events (clicks, picks, ...) are always captured. Overrides the
|
|
25
|
+
* matching legacy ms knob; omitted channels keep the conservative defaults.
|
|
26
|
+
*/
|
|
27
|
+
sampling?: SamplingProfile;
|
|
28
|
+
/** Skip timer-based camera samples while the pose is unchanged. Default true. */
|
|
29
|
+
suppressIdleSamples?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Dedupe `frame_perf` samples while FPS is steady (within {@link perfFpsThreshold}).
|
|
32
|
+
* Default false — a steady FPS is meaningful telemetry, so perf reports continuously.
|
|
33
|
+
*/
|
|
34
|
+
suppressIdlePerfSamples?: boolean;
|
|
35
|
+
/** Max per-axis pose change treated as "unchanged" for camera dedupe. Default 1e-3. */
|
|
36
|
+
cameraEpsilon?: number;
|
|
37
|
+
/** Max FPS change treated as "unchanged" for perf dedupe. Default 1. */
|
|
38
|
+
perfFpsThreshold?: number;
|
|
39
|
+
/** Toggle individual capture channels. */
|
|
40
|
+
capture?: PlayCanvasCaptureOptions;
|
|
41
|
+
/**
|
|
42
|
+
* Gaze probe tuning (`camera_sample.hitPoint`/`hitMesh`, ADR 0030). Only used
|
|
43
|
+
* when `capture.gaze` is enabled. Casts the camera-forward ray per sample.
|
|
44
|
+
*/
|
|
45
|
+
gaze?: PlayCanvasGazeOptions;
|
|
46
|
+
/**
|
|
47
|
+
* Scene-actor map for `node_transform` capture (ADR 0027 Tier 1): self-moving
|
|
48
|
+
* nodes (NPCs, lifts, vehicles) whose world transform is recorded so replay can
|
|
49
|
+
* reproduce them. Pair each id with a rate in `sampling.nodes` to enable it.
|
|
50
|
+
*/
|
|
51
|
+
actors?: Record<string, PlayCanvasActor>;
|
|
52
|
+
/**
|
|
53
|
+
* Keyboard bindings to capture as `input_action` events (ADR 0023): a map from
|
|
54
|
+
* `KeyboardEvent.code` (e.g. `"KeyW"`, `"ArrowLeft"`) to a semantic app action
|
|
55
|
+
* (e.g. `"move-forward"`). **Only bound keys are recorded** — unbound keys are
|
|
56
|
+
* never seen, so arbitrary typing is never captured (privacy, ADR 0003).
|
|
57
|
+
*/
|
|
58
|
+
keyBindings?: Record<string, string>;
|
|
59
|
+
/** Flush at least this often, in ms. Default 5000. Set 0 to disable the timer. */
|
|
60
|
+
flushIntervalMs?: number;
|
|
61
|
+
/** Provide a custom transport (e.g. to observe delivery). Defaults to beacon/fetch. */
|
|
62
|
+
transport?: Transport;
|
|
63
|
+
/** When true, collect nothing (e.g. respect Do-Not-Track). */
|
|
64
|
+
disabled?: boolean;
|
|
65
|
+
/** Emit debug logs to the console. */
|
|
66
|
+
debug?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Free-text label for the scene/experience (e.g. `"product-configurator"`),
|
|
69
|
+
* merged into the auto-detected scene metadata on `session_start`.
|
|
70
|
+
*/
|
|
71
|
+
sceneDescription?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Override the detected camera/navigation model on `session_start`. PlayCanvas
|
|
74
|
+
* camera entities carry no orbit-vs-free-fly distinction, so a host that knows
|
|
75
|
+
* its navigation model — e.g. an orbit viewer vs. a first-person walkthrough —
|
|
76
|
+
* should declare it here so sessions segment correctly (ADR 0026). When omitted,
|
|
77
|
+
* the connector's structural guess is used.
|
|
78
|
+
*/
|
|
79
|
+
cameraType?: CameraKind;
|
|
80
|
+
/**
|
|
81
|
+
* Caller-supplied, anonymized user context attached to the session. Opt-in.
|
|
82
|
+
* Privacy: `user.id` MUST be pseudonymous/hashed — never PII (ADR 0003).
|
|
83
|
+
*/
|
|
84
|
+
user?: SessionUser;
|
|
85
|
+
/** Page metadata / URL overrides for `session_start` (device + scene are filled in for you). */
|
|
86
|
+
meta?: Omit<StartMeta, "device" | "graphics" | "scene" | "user">;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* One-call PlayCanvas integration: create a client, register the PlayCanvas
|
|
90
|
+
* collector, read device/GPU caps, and start the session. Returns the
|
|
91
|
+
* {@link UptimizrClient} so the host can read `sessionId`, emit custom events, or
|
|
92
|
+
* `stop()` on teardown.
|
|
93
|
+
*
|
|
94
|
+
* PlayCanvas supports multiple camera entities with no single "active" camera, and
|
|
95
|
+
* the connector reads FPS / the canvas from the app's graphics device, so — unlike
|
|
96
|
+
* Babylon's `trackScene(scene, options)` — the `camera` Entity is an explicit
|
|
97
|
+
* positional argument (mirroring the three connector).
|
|
98
|
+
*
|
|
99
|
+
* ```ts
|
|
100
|
+
* import { trackScene } from "@uptimizr/playcanvas";
|
|
101
|
+
*
|
|
102
|
+
* const client = trackScene(app, cameraEntity, {
|
|
103
|
+
* projectId: "your-project",
|
|
104
|
+
* endpoint: "https://collect.example.com",
|
|
105
|
+
* });
|
|
106
|
+
* // ... later
|
|
107
|
+
* await client.stop("manual");
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* For finer control (custom transport, `beforeSend`, registering multiple
|
|
111
|
+
* collectors), use {@link playcanvasCollector} with a {@link UptimizrClient} directly.
|
|
112
|
+
*/
|
|
113
|
+
export declare function trackScene(app: AppBase, camera: Entity, options: TrackSceneOptions): UptimizrClient;
|
|
114
|
+
//# sourceMappingURL=trackScene.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trackScene.d.ts","sourceRoot":"","sources":["../src/trackScene.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAGlD,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,EACxB,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AAMxB;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,iFAAiF;IACjF,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0CAA0C;IAC1C,OAAO,CAAC,EAAE,wBAAwB,CAAC;IACnC;;;OAGG;IACH,IAAI,CAAC,EAAE,qBAAqB,CAAC;IAC7B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACzC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,kFAAkF;IAClF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uFAAuF;IACvF,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sCAAsC;IACtC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;OAGG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,gGAAgG;IAChG,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;CAClE;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,iBAAiB,GACzB,cAAc,CA4ChB"}
|