@scenography/plugin-cardboard 0.2.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/dist/index.cjs ADDED
@@ -0,0 +1,91 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let three = require("three");
3
+ //#region src/DeviceOrientationControls.ts
4
+ const DEG2RAD = Math.PI / 180;
5
+ const ZEE = new three.Vector3(0, 0, 1);
6
+ const SCREEN_TO_VIEW = new three.Quaternion(-Math.SQRT1_2, 0, 0, Math.SQRT1_2);
7
+ const tmpEuler = new three.Euler();
8
+ const tmpScreenAdjust = new three.Quaternion();
9
+ /**
10
+ * Orient the camera from the device gyroscope (DeviceOrientation API) for
11
+ * cardboard/VR head-look. It only writes the camera while it has live sensor
12
+ * data, so on a desktop (no gyro) it's a no-op and the other controls keep the
13
+ * camera. iOS needs a permission prompt that must come from a user gesture —
14
+ * `enable()` is meant to be called from the cardboard button's click handler.
15
+ */
16
+ var DeviceOrientationControls = class {
17
+ camera;
18
+ enabled = false;
19
+ hasData = false;
20
+ alpha = 0;
21
+ beta = 0;
22
+ gamma = 0;
23
+ screenAngle = 0;
24
+ constructor(camera) {
25
+ this.camera = camera;
26
+ this.readScreenAngle();
27
+ }
28
+ /** Request permission (iOS) and start listening. Safe to call repeatedly. */
29
+ enable() {
30
+ if (this.enabled) return;
31
+ this.enabled = true;
32
+ const DOE = window.DeviceOrientationEvent;
33
+ if (DOE && typeof DOE.requestPermission === "function") DOE.requestPermission().then((state) => state === "granted" ? this.attach() : this.enabled = false).catch(() => this.enabled = false);
34
+ else this.attach();
35
+ }
36
+ disable() {
37
+ if (!this.enabled) return;
38
+ this.enabled = false;
39
+ this.hasData = false;
40
+ window.removeEventListener("deviceorientation", this.onOrientation);
41
+ window.removeEventListener("orientationchange", this.onScreenChange);
42
+ }
43
+ /** Apply the latest reading to the camera. No-op until sensor data arrives. */
44
+ update() {
45
+ if (!this.enabled || !this.hasData) return;
46
+ tmpEuler.set(this.beta, this.alpha, -this.gamma, "YXZ");
47
+ this.camera.quaternion.setFromEuler(tmpEuler);
48
+ this.camera.quaternion.multiply(SCREEN_TO_VIEW);
49
+ this.camera.quaternion.multiply(tmpScreenAdjust.setFromAxisAngle(ZEE, -this.screenAngle));
50
+ }
51
+ attach() {
52
+ window.addEventListener("deviceorientation", this.onOrientation);
53
+ window.addEventListener("orientationchange", this.onScreenChange);
54
+ }
55
+ readScreenAngle() {
56
+ this.screenAngle = (screen.orientation?.angle ?? 0) * DEG2RAD;
57
+ }
58
+ onScreenChange = () => this.readScreenAngle();
59
+ onOrientation = (event) => {
60
+ if (event.alpha == null) return;
61
+ this.alpha = event.alpha * DEG2RAD;
62
+ this.beta = (event.beta ?? 0) * DEG2RAD;
63
+ this.gamma = (event.gamma ?? 0) * DEG2RAD;
64
+ this.hasData = true;
65
+ };
66
+ };
67
+ //#endregion
68
+ //#region src/plugin.ts
69
+ /**
70
+ * Cardboard head-look — a *system* plugin. It orients the kernel camera from the
71
+ * device gyroscope for phone-in-a-headset viewing, taking the final say on
72
+ * orientation each frame (so it must be registered *after* the roaming/framing
73
+ * systems). The kernel's stereo-render `cardboard` toggle drives its `setEnabled`
74
+ * (which requests the iOS motion-sensor permission, hence a user gesture).
75
+ */
76
+ const cardboard = () => ({
77
+ name: "cardboard",
78
+ setup: (ctx) => {
79
+ const gyro = new DeviceOrientationControls(ctx.camera);
80
+ return {
81
+ update: () => gyro.update(),
82
+ dispose: () => gyro.disable(),
83
+ api: { setEnabled: (enabled) => enabled ? gyro.enable() : gyro.disable() }
84
+ };
85
+ }
86
+ });
87
+ //#endregion
88
+ exports.DeviceOrientationControls = DeviceOrientationControls;
89
+ exports.cardboard = cardboard;
90
+
91
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["Vector3","Quaternion","Euler"],"sources":["../src/DeviceOrientationControls.ts","../src/plugin.ts"],"sourcesContent":["import { Euler, Quaternion, Vector3, type PerspectiveCamera } from \"three\";\n\nconst DEG2RAD = Math.PI / 180;\nconst ZEE = new Vector3(0, 0, 1);\n// -90° about X: the phone's screen faces the user, but the camera looks out its\n// back, so the sensor frame is rotated into the viewing direction.\nconst SCREEN_TO_VIEW = new Quaternion(-Math.SQRT1_2, 0, 0, Math.SQRT1_2);\n\nconst tmpEuler = new Euler();\nconst tmpScreenAdjust = new Quaternion();\n\n/** iOS 13+ gates the motion sensors behind an async permission prompt. */\ninterface DeviceOrientationEventStatic {\n requestPermission?: () => Promise<\"granted\" | \"denied\">;\n}\n\n/**\n * Orient the camera from the device gyroscope (DeviceOrientation API) for\n * cardboard/VR head-look. It only writes the camera while it has live sensor\n * data, so on a desktop (no gyro) it's a no-op and the other controls keep the\n * camera. iOS needs a permission prompt that must come from a user gesture —\n * `enable()` is meant to be called from the cardboard button's click handler.\n */\nexport class DeviceOrientationControls {\n private enabled = false;\n private hasData = false;\n private alpha = 0;\n private beta = 0;\n private gamma = 0;\n private screenAngle = 0;\n\n constructor(private readonly camera: PerspectiveCamera) {\n this.readScreenAngle();\n }\n\n /** Request permission (iOS) and start listening. Safe to call repeatedly. */\n enable(): void {\n if (this.enabled) return;\n this.enabled = true;\n const DOE = (window as unknown as { DeviceOrientationEvent?: DeviceOrientationEventStatic })\n .DeviceOrientationEvent;\n if (DOE && typeof DOE.requestPermission === \"function\") {\n DOE.requestPermission()\n .then((state) => (state === \"granted\" ? this.attach() : (this.enabled = false)))\n .catch(() => (this.enabled = false));\n } else {\n this.attach();\n }\n }\n\n disable(): void {\n if (!this.enabled) return;\n this.enabled = false;\n this.hasData = false;\n window.removeEventListener(\"deviceorientation\", this.onOrientation);\n window.removeEventListener(\"orientationchange\", this.onScreenChange);\n }\n\n /** Apply the latest reading to the camera. No-op until sensor data arrives. */\n update(): void {\n if (!this.enabled || !this.hasData) return;\n tmpEuler.set(this.beta, this.alpha, -this.gamma, \"YXZ\");\n this.camera.quaternion.setFromEuler(tmpEuler);\n this.camera.quaternion.multiply(SCREEN_TO_VIEW);\n this.camera.quaternion.multiply(tmpScreenAdjust.setFromAxisAngle(ZEE, -this.screenAngle));\n }\n\n private attach(): void {\n window.addEventListener(\"deviceorientation\", this.onOrientation);\n window.addEventListener(\"orientationchange\", this.onScreenChange);\n }\n\n private readScreenAngle(): void {\n this.screenAngle = (screen.orientation?.angle ?? 0) * DEG2RAD;\n }\n\n private readonly onScreenChange = (): void => this.readScreenAngle();\n\n private readonly onOrientation = (event: DeviceOrientationEvent): void => {\n if (event.alpha == null) return;\n this.alpha = event.alpha * DEG2RAD;\n this.beta = (event.beta ?? 0) * DEG2RAD;\n this.gamma = (event.gamma ?? 0) * DEG2RAD;\n this.hasData = true;\n };\n}\n","import type { SystemPlugin } from \"@scenography/engine\";\n\nimport { DeviceOrientationControls } from \"./DeviceOrientationControls\";\n\n/** What the kernel's cardboard render toggle drives on this system. */\nexport interface CardboardApi {\n /** Turn gyroscope head-look on/off (must run in a user gesture on iOS). */\n setEnabled(enabled: boolean): void;\n}\n\n/**\n * Cardboard head-look — a *system* plugin. It orients the kernel camera from the\n * device gyroscope for phone-in-a-headset viewing, taking the final say on\n * orientation each frame (so it must be registered *after* the roaming/framing\n * systems). The kernel's stereo-render `cardboard` toggle drives its `setEnabled`\n * (which requests the iOS motion-sensor permission, hence a user gesture).\n */\nexport const cardboard = (): SystemPlugin<CardboardApi> => ({\n name: \"cardboard\",\n setup: (ctx) => {\n const gyro = new DeviceOrientationControls(ctx.camera);\n return {\n update: () => gyro.update(),\n dispose: () => gyro.disable(),\n api: { setEnabled: (enabled) => (enabled ? gyro.enable() : gyro.disable()) },\n };\n },\n});\n"],"mappings":";;;AAEA,MAAM,UAAU,KAAK,KAAK;AAC1B,MAAM,MAAM,IAAIA,MAAAA,QAAQ,GAAG,GAAG,CAAC;AAG/B,MAAM,iBAAiB,IAAIC,MAAAA,WAAW,CAAC,KAAK,SAAS,GAAG,GAAG,KAAK,OAAO;AAEvE,MAAM,WAAW,IAAIC,MAAAA,MAAM;AAC3B,MAAM,kBAAkB,IAAID,MAAAA,WAAW;;;;;;;;AAcvC,IAAa,4BAAb,MAAuC;CAQR;CAP7B,UAAkB;CAClB,UAAkB;CAClB,QAAgB;CAChB,OAAe;CACf,QAAgB;CAChB,cAAsB;CAEtB,YAAY,QAA4C;EAA3B,KAAA,SAAA;EAC3B,KAAK,gBAAgB;CACvB;;CAGA,SAAe;EACb,IAAI,KAAK,SAAS;EAClB,KAAK,UAAU;EACf,MAAM,MAAO,OACV;EACH,IAAI,OAAO,OAAO,IAAI,sBAAsB,YAC1C,IAAI,kBAAkB,CAAC,CACpB,MAAM,UAAW,UAAU,YAAY,KAAK,OAAO,IAAK,KAAK,UAAU,KAAO,CAAC,CAC/E,YAAa,KAAK,UAAU,KAAM;OAErC,KAAK,OAAO;CAEhB;CAEA,UAAgB;EACd,IAAI,CAAC,KAAK,SAAS;EACnB,KAAK,UAAU;EACf,KAAK,UAAU;EACf,OAAO,oBAAoB,qBAAqB,KAAK,aAAa;EAClE,OAAO,oBAAoB,qBAAqB,KAAK,cAAc;CACrE;;CAGA,SAAe;EACb,IAAI,CAAC,KAAK,WAAW,CAAC,KAAK,SAAS;EACpC,SAAS,IAAI,KAAK,MAAM,KAAK,OAAO,CAAC,KAAK,OAAO,KAAK;EACtD,KAAK,OAAO,WAAW,aAAa,QAAQ;EAC5C,KAAK,OAAO,WAAW,SAAS,cAAc;EAC9C,KAAK,OAAO,WAAW,SAAS,gBAAgB,iBAAiB,KAAK,CAAC,KAAK,WAAW,CAAC;CAC1F;CAEA,SAAuB;EACrB,OAAO,iBAAiB,qBAAqB,KAAK,aAAa;EAC/D,OAAO,iBAAiB,qBAAqB,KAAK,cAAc;CAClE;CAEA,kBAAgC;EAC9B,KAAK,eAAe,OAAO,aAAa,SAAS,KAAK;CACxD;CAEA,uBAA8C,KAAK,gBAAgB;CAEnE,iBAAkC,UAAwC;EACxE,IAAI,MAAM,SAAS,MAAM;EACzB,KAAK,QAAQ,MAAM,QAAQ;EAC3B,KAAK,QAAQ,MAAM,QAAQ,KAAK;EAChC,KAAK,SAAS,MAAM,SAAS,KAAK;EAClC,KAAK,UAAU;CACjB;AACF;;;;;;;;;;ACpEA,MAAa,mBAA+C;CAC1D,MAAM;CACN,QAAQ,QAAQ;EACd,MAAM,OAAO,IAAI,0BAA0B,IAAI,MAAM;EACrD,OAAO;GACL,cAAc,KAAK,OAAO;GAC1B,eAAe,KAAK,QAAQ;GAC5B,KAAK,EAAE,aAAa,YAAa,UAAU,KAAK,OAAO,IAAI,KAAK,QAAQ,EAAG;EAC7E;CACF;AACF"}
@@ -0,0 +1,48 @@
1
+ import { SystemPlugin } from "@scenography/engine";
2
+ import { PerspectiveCamera } from "three";
3
+
4
+ //#region src/plugin.d.ts
5
+ /** What the kernel's cardboard render toggle drives on this system. */
6
+ interface CardboardApi {
7
+ /** Turn gyroscope head-look on/off (must run in a user gesture on iOS). */
8
+ setEnabled(enabled: boolean): void;
9
+ }
10
+ /**
11
+ * Cardboard head-look — a *system* plugin. It orients the kernel camera from the
12
+ * device gyroscope for phone-in-a-headset viewing, taking the final say on
13
+ * orientation each frame (so it must be registered *after* the roaming/framing
14
+ * systems). The kernel's stereo-render `cardboard` toggle drives its `setEnabled`
15
+ * (which requests the iOS motion-sensor permission, hence a user gesture).
16
+ */
17
+ declare const cardboard: () => SystemPlugin<CardboardApi>;
18
+ //#endregion
19
+ //#region src/DeviceOrientationControls.d.ts
20
+ /**
21
+ * Orient the camera from the device gyroscope (DeviceOrientation API) for
22
+ * cardboard/VR head-look. It only writes the camera while it has live sensor
23
+ * data, so on a desktop (no gyro) it's a no-op and the other controls keep the
24
+ * camera. iOS needs a permission prompt that must come from a user gesture —
25
+ * `enable()` is meant to be called from the cardboard button's click handler.
26
+ */
27
+ declare class DeviceOrientationControls {
28
+ private readonly camera;
29
+ private enabled;
30
+ private hasData;
31
+ private alpha;
32
+ private beta;
33
+ private gamma;
34
+ private screenAngle;
35
+ constructor(camera: PerspectiveCamera);
36
+ /** Request permission (iOS) and start listening. Safe to call repeatedly. */
37
+ enable(): void;
38
+ disable(): void;
39
+ /** Apply the latest reading to the camera. No-op until sensor data arrives. */
40
+ update(): void;
41
+ private attach;
42
+ private readScreenAngle;
43
+ private readonly onScreenChange;
44
+ private readonly onOrientation;
45
+ }
46
+ //#endregion
47
+ export { type CardboardApi, DeviceOrientationControls, cardboard };
48
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1,48 @@
1
+ import { PerspectiveCamera } from "three";
2
+ import { SystemPlugin } from "@scenography/engine";
3
+
4
+ //#region src/plugin.d.ts
5
+ /** What the kernel's cardboard render toggle drives on this system. */
6
+ interface CardboardApi {
7
+ /** Turn gyroscope head-look on/off (must run in a user gesture on iOS). */
8
+ setEnabled(enabled: boolean): void;
9
+ }
10
+ /**
11
+ * Cardboard head-look — a *system* plugin. It orients the kernel camera from the
12
+ * device gyroscope for phone-in-a-headset viewing, taking the final say on
13
+ * orientation each frame (so it must be registered *after* the roaming/framing
14
+ * systems). The kernel's stereo-render `cardboard` toggle drives its `setEnabled`
15
+ * (which requests the iOS motion-sensor permission, hence a user gesture).
16
+ */
17
+ declare const cardboard: () => SystemPlugin<CardboardApi>;
18
+ //#endregion
19
+ //#region src/DeviceOrientationControls.d.ts
20
+ /**
21
+ * Orient the camera from the device gyroscope (DeviceOrientation API) for
22
+ * cardboard/VR head-look. It only writes the camera while it has live sensor
23
+ * data, so on a desktop (no gyro) it's a no-op and the other controls keep the
24
+ * camera. iOS needs a permission prompt that must come from a user gesture —
25
+ * `enable()` is meant to be called from the cardboard button's click handler.
26
+ */
27
+ declare class DeviceOrientationControls {
28
+ private readonly camera;
29
+ private enabled;
30
+ private hasData;
31
+ private alpha;
32
+ private beta;
33
+ private gamma;
34
+ private screenAngle;
35
+ constructor(camera: PerspectiveCamera);
36
+ /** Request permission (iOS) and start listening. Safe to call repeatedly. */
37
+ enable(): void;
38
+ disable(): void;
39
+ /** Apply the latest reading to the camera. No-op until sensor data arrives. */
40
+ update(): void;
41
+ private attach;
42
+ private readScreenAngle;
43
+ private readonly onScreenChange;
44
+ private readonly onOrientation;
45
+ }
46
+ //#endregion
47
+ export { type CardboardApi, DeviceOrientationControls, cardboard };
48
+ //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs ADDED
@@ -0,0 +1,89 @@
1
+ import { Euler, Quaternion, Vector3 } from "three";
2
+ //#region src/DeviceOrientationControls.ts
3
+ const DEG2RAD = Math.PI / 180;
4
+ const ZEE = new Vector3(0, 0, 1);
5
+ const SCREEN_TO_VIEW = new Quaternion(-Math.SQRT1_2, 0, 0, Math.SQRT1_2);
6
+ const tmpEuler = new Euler();
7
+ const tmpScreenAdjust = new Quaternion();
8
+ /**
9
+ * Orient the camera from the device gyroscope (DeviceOrientation API) for
10
+ * cardboard/VR head-look. It only writes the camera while it has live sensor
11
+ * data, so on a desktop (no gyro) it's a no-op and the other controls keep the
12
+ * camera. iOS needs a permission prompt that must come from a user gesture —
13
+ * `enable()` is meant to be called from the cardboard button's click handler.
14
+ */
15
+ var DeviceOrientationControls = class {
16
+ camera;
17
+ enabled = false;
18
+ hasData = false;
19
+ alpha = 0;
20
+ beta = 0;
21
+ gamma = 0;
22
+ screenAngle = 0;
23
+ constructor(camera) {
24
+ this.camera = camera;
25
+ this.readScreenAngle();
26
+ }
27
+ /** Request permission (iOS) and start listening. Safe to call repeatedly. */
28
+ enable() {
29
+ if (this.enabled) return;
30
+ this.enabled = true;
31
+ const DOE = window.DeviceOrientationEvent;
32
+ if (DOE && typeof DOE.requestPermission === "function") DOE.requestPermission().then((state) => state === "granted" ? this.attach() : this.enabled = false).catch(() => this.enabled = false);
33
+ else this.attach();
34
+ }
35
+ disable() {
36
+ if (!this.enabled) return;
37
+ this.enabled = false;
38
+ this.hasData = false;
39
+ window.removeEventListener("deviceorientation", this.onOrientation);
40
+ window.removeEventListener("orientationchange", this.onScreenChange);
41
+ }
42
+ /** Apply the latest reading to the camera. No-op until sensor data arrives. */
43
+ update() {
44
+ if (!this.enabled || !this.hasData) return;
45
+ tmpEuler.set(this.beta, this.alpha, -this.gamma, "YXZ");
46
+ this.camera.quaternion.setFromEuler(tmpEuler);
47
+ this.camera.quaternion.multiply(SCREEN_TO_VIEW);
48
+ this.camera.quaternion.multiply(tmpScreenAdjust.setFromAxisAngle(ZEE, -this.screenAngle));
49
+ }
50
+ attach() {
51
+ window.addEventListener("deviceorientation", this.onOrientation);
52
+ window.addEventListener("orientationchange", this.onScreenChange);
53
+ }
54
+ readScreenAngle() {
55
+ this.screenAngle = (screen.orientation?.angle ?? 0) * DEG2RAD;
56
+ }
57
+ onScreenChange = () => this.readScreenAngle();
58
+ onOrientation = (event) => {
59
+ if (event.alpha == null) return;
60
+ this.alpha = event.alpha * DEG2RAD;
61
+ this.beta = (event.beta ?? 0) * DEG2RAD;
62
+ this.gamma = (event.gamma ?? 0) * DEG2RAD;
63
+ this.hasData = true;
64
+ };
65
+ };
66
+ //#endregion
67
+ //#region src/plugin.ts
68
+ /**
69
+ * Cardboard head-look — a *system* plugin. It orients the kernel camera from the
70
+ * device gyroscope for phone-in-a-headset viewing, taking the final say on
71
+ * orientation each frame (so it must be registered *after* the roaming/framing
72
+ * systems). The kernel's stereo-render `cardboard` toggle drives its `setEnabled`
73
+ * (which requests the iOS motion-sensor permission, hence a user gesture).
74
+ */
75
+ const cardboard = () => ({
76
+ name: "cardboard",
77
+ setup: (ctx) => {
78
+ const gyro = new DeviceOrientationControls(ctx.camera);
79
+ return {
80
+ update: () => gyro.update(),
81
+ dispose: () => gyro.disable(),
82
+ api: { setEnabled: (enabled) => enabled ? gyro.enable() : gyro.disable() }
83
+ };
84
+ }
85
+ });
86
+ //#endregion
87
+ export { DeviceOrientationControls, cardboard };
88
+
89
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/DeviceOrientationControls.ts","../src/plugin.ts"],"sourcesContent":["import { Euler, Quaternion, Vector3, type PerspectiveCamera } from \"three\";\n\nconst DEG2RAD = Math.PI / 180;\nconst ZEE = new Vector3(0, 0, 1);\n// -90° about X: the phone's screen faces the user, but the camera looks out its\n// back, so the sensor frame is rotated into the viewing direction.\nconst SCREEN_TO_VIEW = new Quaternion(-Math.SQRT1_2, 0, 0, Math.SQRT1_2);\n\nconst tmpEuler = new Euler();\nconst tmpScreenAdjust = new Quaternion();\n\n/** iOS 13+ gates the motion sensors behind an async permission prompt. */\ninterface DeviceOrientationEventStatic {\n requestPermission?: () => Promise<\"granted\" | \"denied\">;\n}\n\n/**\n * Orient the camera from the device gyroscope (DeviceOrientation API) for\n * cardboard/VR head-look. It only writes the camera while it has live sensor\n * data, so on a desktop (no gyro) it's a no-op and the other controls keep the\n * camera. iOS needs a permission prompt that must come from a user gesture —\n * `enable()` is meant to be called from the cardboard button's click handler.\n */\nexport class DeviceOrientationControls {\n private enabled = false;\n private hasData = false;\n private alpha = 0;\n private beta = 0;\n private gamma = 0;\n private screenAngle = 0;\n\n constructor(private readonly camera: PerspectiveCamera) {\n this.readScreenAngle();\n }\n\n /** Request permission (iOS) and start listening. Safe to call repeatedly. */\n enable(): void {\n if (this.enabled) return;\n this.enabled = true;\n const DOE = (window as unknown as { DeviceOrientationEvent?: DeviceOrientationEventStatic })\n .DeviceOrientationEvent;\n if (DOE && typeof DOE.requestPermission === \"function\") {\n DOE.requestPermission()\n .then((state) => (state === \"granted\" ? this.attach() : (this.enabled = false)))\n .catch(() => (this.enabled = false));\n } else {\n this.attach();\n }\n }\n\n disable(): void {\n if (!this.enabled) return;\n this.enabled = false;\n this.hasData = false;\n window.removeEventListener(\"deviceorientation\", this.onOrientation);\n window.removeEventListener(\"orientationchange\", this.onScreenChange);\n }\n\n /** Apply the latest reading to the camera. No-op until sensor data arrives. */\n update(): void {\n if (!this.enabled || !this.hasData) return;\n tmpEuler.set(this.beta, this.alpha, -this.gamma, \"YXZ\");\n this.camera.quaternion.setFromEuler(tmpEuler);\n this.camera.quaternion.multiply(SCREEN_TO_VIEW);\n this.camera.quaternion.multiply(tmpScreenAdjust.setFromAxisAngle(ZEE, -this.screenAngle));\n }\n\n private attach(): void {\n window.addEventListener(\"deviceorientation\", this.onOrientation);\n window.addEventListener(\"orientationchange\", this.onScreenChange);\n }\n\n private readScreenAngle(): void {\n this.screenAngle = (screen.orientation?.angle ?? 0) * DEG2RAD;\n }\n\n private readonly onScreenChange = (): void => this.readScreenAngle();\n\n private readonly onOrientation = (event: DeviceOrientationEvent): void => {\n if (event.alpha == null) return;\n this.alpha = event.alpha * DEG2RAD;\n this.beta = (event.beta ?? 0) * DEG2RAD;\n this.gamma = (event.gamma ?? 0) * DEG2RAD;\n this.hasData = true;\n };\n}\n","import type { SystemPlugin } from \"@scenography/engine\";\n\nimport { DeviceOrientationControls } from \"./DeviceOrientationControls\";\n\n/** What the kernel's cardboard render toggle drives on this system. */\nexport interface CardboardApi {\n /** Turn gyroscope head-look on/off (must run in a user gesture on iOS). */\n setEnabled(enabled: boolean): void;\n}\n\n/**\n * Cardboard head-look — a *system* plugin. It orients the kernel camera from the\n * device gyroscope for phone-in-a-headset viewing, taking the final say on\n * orientation each frame (so it must be registered *after* the roaming/framing\n * systems). The kernel's stereo-render `cardboard` toggle drives its `setEnabled`\n * (which requests the iOS motion-sensor permission, hence a user gesture).\n */\nexport const cardboard = (): SystemPlugin<CardboardApi> => ({\n name: \"cardboard\",\n setup: (ctx) => {\n const gyro = new DeviceOrientationControls(ctx.camera);\n return {\n update: () => gyro.update(),\n dispose: () => gyro.disable(),\n api: { setEnabled: (enabled) => (enabled ? gyro.enable() : gyro.disable()) },\n };\n },\n});\n"],"mappings":";;AAEA,MAAM,UAAU,KAAK,KAAK;AAC1B,MAAM,MAAM,IAAI,QAAQ,GAAG,GAAG,CAAC;AAG/B,MAAM,iBAAiB,IAAI,WAAW,CAAC,KAAK,SAAS,GAAG,GAAG,KAAK,OAAO;AAEvE,MAAM,WAAW,IAAI,MAAM;AAC3B,MAAM,kBAAkB,IAAI,WAAW;;;;;;;;AAcvC,IAAa,4BAAb,MAAuC;CAQR;CAP7B,UAAkB;CAClB,UAAkB;CAClB,QAAgB;CAChB,OAAe;CACf,QAAgB;CAChB,cAAsB;CAEtB,YAAY,QAA4C;EAA3B,KAAA,SAAA;EAC3B,KAAK,gBAAgB;CACvB;;CAGA,SAAe;EACb,IAAI,KAAK,SAAS;EAClB,KAAK,UAAU;EACf,MAAM,MAAO,OACV;EACH,IAAI,OAAO,OAAO,IAAI,sBAAsB,YAC1C,IAAI,kBAAkB,CAAC,CACpB,MAAM,UAAW,UAAU,YAAY,KAAK,OAAO,IAAK,KAAK,UAAU,KAAO,CAAC,CAC/E,YAAa,KAAK,UAAU,KAAM;OAErC,KAAK,OAAO;CAEhB;CAEA,UAAgB;EACd,IAAI,CAAC,KAAK,SAAS;EACnB,KAAK,UAAU;EACf,KAAK,UAAU;EACf,OAAO,oBAAoB,qBAAqB,KAAK,aAAa;EAClE,OAAO,oBAAoB,qBAAqB,KAAK,cAAc;CACrE;;CAGA,SAAe;EACb,IAAI,CAAC,KAAK,WAAW,CAAC,KAAK,SAAS;EACpC,SAAS,IAAI,KAAK,MAAM,KAAK,OAAO,CAAC,KAAK,OAAO,KAAK;EACtD,KAAK,OAAO,WAAW,aAAa,QAAQ;EAC5C,KAAK,OAAO,WAAW,SAAS,cAAc;EAC9C,KAAK,OAAO,WAAW,SAAS,gBAAgB,iBAAiB,KAAK,CAAC,KAAK,WAAW,CAAC;CAC1F;CAEA,SAAuB;EACrB,OAAO,iBAAiB,qBAAqB,KAAK,aAAa;EAC/D,OAAO,iBAAiB,qBAAqB,KAAK,cAAc;CAClE;CAEA,kBAAgC;EAC9B,KAAK,eAAe,OAAO,aAAa,SAAS,KAAK;CACxD;CAEA,uBAA8C,KAAK,gBAAgB;CAEnE,iBAAkC,UAAwC;EACxE,IAAI,MAAM,SAAS,MAAM;EACzB,KAAK,QAAQ,MAAM,QAAQ;EAC3B,KAAK,QAAQ,MAAM,QAAQ,KAAK;EAChC,KAAK,SAAS,MAAM,SAAS,KAAK;EAClC,KAAK,UAAU;CACjB;AACF;;;;;;;;;;ACpEA,MAAa,mBAA+C;CAC1D,MAAM;CACN,QAAQ,QAAQ;EACd,MAAM,OAAO,IAAI,0BAA0B,IAAI,MAAM;EACrD,OAAO;GACL,cAAc,KAAK,OAAO;GAC1B,eAAe,KAAK,QAAQ;GAC5B,KAAK,EAAE,aAAa,YAAa,UAAU,KAAK,OAAO,IAAI,KAAK,QAAQ,EAAG;EAC7E;CACF;AACF"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@scenography/plugin-cardboard",
3
+ "version": "0.2.0",
4
+ "description": "Cardboard plugin for scenography: gyroscope head-look (DeviceOrientation) for phone-in-a-headset viewing. A system plugin driven by the kernel's stereo-render toggle.",
5
+ "license": "MIT",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "type": "module",
10
+ "main": "./dist/index.cjs",
11
+ "module": "./dist/index.mjs",
12
+ "types": "./dist/index.d.cts",
13
+ "exports": {
14
+ ".": {
15
+ "import": {
16
+ "types": "./dist/index.d.mts",
17
+ "default": "./dist/index.mjs"
18
+ },
19
+ "require": {
20
+ "types": "./dist/index.d.cts",
21
+ "default": "./dist/index.cjs"
22
+ }
23
+ }
24
+ },
25
+ "dependencies": {
26
+ "@scenography/scene": "0.2.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/three": "^0.160.0",
30
+ "three": "^0.160.0",
31
+ "@scenography/engine": "0.2.0"
32
+ },
33
+ "peerDependencies": {
34
+ "three": ">=0.160.0",
35
+ "@scenography/engine": "0.2.0"
36
+ },
37
+ "scripts": {
38
+ "build": "tsdown",
39
+ "dev": "tsdown --watch",
40
+ "typecheck": "tsc --noEmit"
41
+ }
42
+ }