mudra-skills 1.0.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.
Files changed (149) hide show
  1. package/.claude-plugin/plugin.json +19 -0
  2. package/CLAUDE.md +35 -0
  3. package/bin/install.js +25 -0
  4. package/package.json +28 -0
  5. package/skills/mudra-master/SKILL.md +202 -0
  6. package/skills/mudra-master/mudra-preview/SKILL.md +151 -0
  7. package/skills/mudra-master/mudra-preview/assets/ar-menu.html +382 -0
  8. package/skills/mudra-master/mudra-preview/assets/document-scroller.html +468 -0
  9. package/skills/mudra-master/mudra-preview/assets/drum-machine.html +788 -0
  10. package/skills/mudra-master/mudra-preview/assets/emg-visualizer.html +390 -0
  11. package/skills/mudra-master/mudra-preview/assets/generative-art.html +408 -0
  12. package/skills/mudra-master/mudra-preview/assets/gesture-assistant.html +342 -0
  13. package/skills/mudra-master/mudra-preview/assets/gesture-speech.html +444 -0
  14. package/skills/mudra-master/mudra-preview/assets/hands-free-desktop.html +376 -0
  15. package/skills/mudra-master/mudra-preview/assets/model-rotator.html +365 -0
  16. package/skills/mudra-master/mudra-preview/assets/mudra-duel.html +3200 -0
  17. package/skills/mudra-master/mudra-preview/assets/mudra-monitor.html +1451 -0
  18. package/skills/mudra-master/mudra-preview/assets/mudra-ultimate-template.html +891 -0
  19. package/skills/mudra-master/mudra-preview/assets/music-sequencer.html +455 -0
  20. package/skills/mudra-master/mudra-preview/assets/neural-pong.html +380 -0
  21. package/skills/mudra-master/mudra-preview/assets/neural-snake.html +364 -0
  22. package/skills/mudra-master/mudra-preview/assets/presentation-controller.html +345 -0
  23. package/skills/mudra-master/mudra-preview/assets/pressure-painter.html +285 -0
  24. package/skills/mudra-master/mudra-preview/assets/runner.html +1812 -0
  25. package/skills/mudra-master/mudra-preview/assets/smart-home.html +461 -0
  26. package/skills/mudra-master/mudra-preview/assets/space-invaders.html +1154 -0
  27. package/skills/mudra-master/mudra-preview/assets/waterful-ring-toss.html +1624 -0
  28. package/skills/mudra-master/mudra-preview/references/agent_protocol.json +646 -0
  29. package/skills/mudra-master/mudra-preview/references/promt.md +16829 -0
  30. package/skills/mudra-master/mudra-xr/SKILL.md +245 -0
  31. package/skills/mudra-master/mudra-xr/assets/demos/3dgs-walkthrough.html +242 -0
  32. package/skills/mudra-master/mudra-xr/assets/demos/aisimulator.html +792 -0
  33. package/skills/mudra-master/mudra-xr/assets/demos/balloonpop.html +422 -0
  34. package/skills/mudra-master/mudra-xr/assets/demos/ballpit.html +284 -0
  35. package/skills/mudra-master/mudra-xr/assets/demos/drone.html +41 -0
  36. package/skills/mudra-master/mudra-xr/assets/demos/gemini-icebreakers.html +338 -0
  37. package/skills/mudra-master/mudra-xr/assets/demos/gemini-xrobject.html +302 -0
  38. package/skills/mudra-master/mudra-xr/assets/demos/math3d.html +188 -0
  39. package/skills/mudra-master/mudra-xr/assets/demos/measure.html +247 -0
  40. package/skills/mudra-master/mudra-xr/assets/demos/occlusion.html +251 -0
  41. package/skills/mudra-master/mudra-xr/assets/demos/rain.html +498 -0
  42. package/skills/mudra-master/mudra-xr/assets/demos/screenwiper.html +432 -0
  43. package/skills/mudra-master/mudra-xr/assets/demos/splash.html +519 -0
  44. package/skills/mudra-master/mudra-xr/assets/demos/webcam_gestures.html +253 -0
  45. package/skills/mudra-master/mudra-xr/assets/demos/xremoji.html +833 -0
  46. package/skills/mudra-master/mudra-xr/assets/demos/xrpoet.html +151 -0
  47. package/skills/mudra-master/mudra-xr/assets/samples/depthmap.html +266 -0
  48. package/skills/mudra-master/mudra-xr/assets/samples/depthmesh.html +100 -0
  49. package/skills/mudra-master/mudra-xr/assets/samples/game_rps.html +1099 -0
  50. package/skills/mudra-master/mudra-xr/assets/samples/gestures_custom.html +467 -0
  51. package/skills/mudra-master/mudra-xr/assets/samples/gestures_heuristic.html +256 -0
  52. package/skills/mudra-master/mudra-xr/assets/samples/lighting.html +163 -0
  53. package/skills/mudra-master/mudra-xr/assets/samples/mesh_detection.html +46 -0
  54. package/skills/mudra-master/mudra-xr/assets/samples/modelviewer.html +183 -0
  55. package/skills/mudra-master/mudra-xr/assets/samples/paint.html +133 -0
  56. package/skills/mudra-master/mudra-xr/assets/samples/planar-vst.html +45 -0
  57. package/skills/mudra-master/mudra-xr/assets/samples/reticle.html +95 -0
  58. package/skills/mudra-master/mudra-xr/assets/samples/skybox_agent.html +384 -0
  59. package/skills/mudra-master/mudra-xr/assets/samples/sound.html +390 -0
  60. package/skills/mudra-master/mudra-xr/assets/samples/ui.html +496 -0
  61. package/skills/mudra-master/mudra-xr/assets/samples/virtual-screens.html +808 -0
  62. package/skills/mudra-master/mudra-xr/assets/templates/0_basic.html +64 -0
  63. package/skills/mudra-master/mudra-xr/assets/templates/1_ui.html +107 -0
  64. package/skills/mudra-master/mudra-xr/assets/templates/2_hands.html +183 -0
  65. package/skills/mudra-master/mudra-xr/assets/templates/3_depth.html +89 -0
  66. package/skills/mudra-master/mudra-xr/assets/templates/4_stereo.html +84 -0
  67. package/skills/mudra-master/mudra-xr/assets/templates/5_camera.html +117 -0
  68. package/skills/mudra-master/mudra-xr/assets/templates/6_ai.html +154 -0
  69. package/skills/mudra-master/mudra-xr/assets/templates/7_ai_live.html +253 -0
  70. package/skills/mudra-master/mudra-xr/assets/templates/8_objects.html +95 -0
  71. package/skills/mudra-master/mudra-xr/assets/templates/9_xr-toggle.html +90 -0
  72. package/skills/mudra-master/mudra-xr/assets/templates/heuristic_hand_gestures.html +102 -0
  73. package/skills/mudra-master/mudra-xr/assets/templates/meshes.html +47 -0
  74. package/skills/mudra-master/mudra-xr/assets/templates/planes.html +47 -0
  75. package/skills/mudra-master/mudra-xr/assets/templates/uikit.html +187 -0
  76. package/skills/mudra-master/mudra-xr/references/agent_protocol.json +878 -0
  77. package/skills/mudra-master/mudra-xr/references/promt.md +1516 -0
  78. package/skills/mudra-preview/SKILL.md +151 -0
  79. package/skills/mudra-preview/assets/ar-menu.html +382 -0
  80. package/skills/mudra-preview/assets/document-scroller.html +468 -0
  81. package/skills/mudra-preview/assets/drum-machine.html +788 -0
  82. package/skills/mudra-preview/assets/emg-visualizer.html +390 -0
  83. package/skills/mudra-preview/assets/generative-art.html +408 -0
  84. package/skills/mudra-preview/assets/gesture-assistant.html +342 -0
  85. package/skills/mudra-preview/assets/gesture-speech.html +444 -0
  86. package/skills/mudra-preview/assets/hands-free-desktop.html +376 -0
  87. package/skills/mudra-preview/assets/model-rotator.html +365 -0
  88. package/skills/mudra-preview/assets/mudra-duel.html +3200 -0
  89. package/skills/mudra-preview/assets/mudra-monitor.html +1451 -0
  90. package/skills/mudra-preview/assets/mudra-ultimate-template.html +891 -0
  91. package/skills/mudra-preview/assets/music-sequencer.html +455 -0
  92. package/skills/mudra-preview/assets/neural-pong.html +380 -0
  93. package/skills/mudra-preview/assets/neural-snake.html +364 -0
  94. package/skills/mudra-preview/assets/presentation-controller.html +345 -0
  95. package/skills/mudra-preview/assets/pressure-painter.html +285 -0
  96. package/skills/mudra-preview/assets/runner.html +1812 -0
  97. package/skills/mudra-preview/assets/smart-home.html +461 -0
  98. package/skills/mudra-preview/assets/space-invaders.html +1154 -0
  99. package/skills/mudra-preview/assets/waterful-ring-toss.html +1624 -0
  100. package/skills/mudra-preview/references/agent_protocol.json +646 -0
  101. package/skills/mudra-preview/references/promt.md +16829 -0
  102. package/skills/mudra-xr/SKILL.md +245 -0
  103. package/skills/mudra-xr/assets/demos/3dgs-walkthrough.html +242 -0
  104. package/skills/mudra-xr/assets/demos/aisimulator.html +792 -0
  105. package/skills/mudra-xr/assets/demos/balloonpop.html +422 -0
  106. package/skills/mudra-xr/assets/demos/ballpit.html +284 -0
  107. package/skills/mudra-xr/assets/demos/drone.html +41 -0
  108. package/skills/mudra-xr/assets/demos/gemini-icebreakers.html +338 -0
  109. package/skills/mudra-xr/assets/demos/gemini-xrobject.html +302 -0
  110. package/skills/mudra-xr/assets/demos/math3d.html +188 -0
  111. package/skills/mudra-xr/assets/demos/measure.html +247 -0
  112. package/skills/mudra-xr/assets/demos/occlusion.html +251 -0
  113. package/skills/mudra-xr/assets/demos/rain.html +498 -0
  114. package/skills/mudra-xr/assets/demos/screenwiper.html +432 -0
  115. package/skills/mudra-xr/assets/demos/splash.html +519 -0
  116. package/skills/mudra-xr/assets/demos/webcam_gestures.html +253 -0
  117. package/skills/mudra-xr/assets/demos/xremoji.html +833 -0
  118. package/skills/mudra-xr/assets/demos/xrpoet.html +151 -0
  119. package/skills/mudra-xr/assets/samples/depthmap.html +266 -0
  120. package/skills/mudra-xr/assets/samples/depthmesh.html +100 -0
  121. package/skills/mudra-xr/assets/samples/game_rps.html +1099 -0
  122. package/skills/mudra-xr/assets/samples/gestures_custom.html +467 -0
  123. package/skills/mudra-xr/assets/samples/gestures_heuristic.html +256 -0
  124. package/skills/mudra-xr/assets/samples/lighting.html +163 -0
  125. package/skills/mudra-xr/assets/samples/mesh_detection.html +46 -0
  126. package/skills/mudra-xr/assets/samples/modelviewer.html +183 -0
  127. package/skills/mudra-xr/assets/samples/paint.html +133 -0
  128. package/skills/mudra-xr/assets/samples/planar-vst.html +45 -0
  129. package/skills/mudra-xr/assets/samples/reticle.html +95 -0
  130. package/skills/mudra-xr/assets/samples/skybox_agent.html +384 -0
  131. package/skills/mudra-xr/assets/samples/sound.html +390 -0
  132. package/skills/mudra-xr/assets/samples/ui.html +496 -0
  133. package/skills/mudra-xr/assets/samples/virtual-screens.html +808 -0
  134. package/skills/mudra-xr/assets/templates/0_basic.html +64 -0
  135. package/skills/mudra-xr/assets/templates/1_ui.html +107 -0
  136. package/skills/mudra-xr/assets/templates/2_hands.html +183 -0
  137. package/skills/mudra-xr/assets/templates/3_depth.html +89 -0
  138. package/skills/mudra-xr/assets/templates/4_stereo.html +84 -0
  139. package/skills/mudra-xr/assets/templates/5_camera.html +117 -0
  140. package/skills/mudra-xr/assets/templates/6_ai.html +154 -0
  141. package/skills/mudra-xr/assets/templates/7_ai_live.html +253 -0
  142. package/skills/mudra-xr/assets/templates/8_objects.html +95 -0
  143. package/skills/mudra-xr/assets/templates/9_xr-toggle.html +90 -0
  144. package/skills/mudra-xr/assets/templates/heuristic_hand_gestures.html +102 -0
  145. package/skills/mudra-xr/assets/templates/meshes.html +47 -0
  146. package/skills/mudra-xr/assets/templates/planes.html +47 -0
  147. package/skills/mudra-xr/assets/templates/uikit.html +187 -0
  148. package/skills/mudra-xr/references/agent_protocol.json +878 -0
  149. package/skills/mudra-xr/references/promt.md +1516 -0
@@ -0,0 +1,64 @@
1
+ <!doctype html>
2
+ <!-- reference: templates/0_basic -->
3
+ <html lang="en">
4
+ <head>
5
+ <title>Basic: Pinch to Set Color | XR Blocks Template</title>
6
+
7
+ <meta
8
+ name="viewport"
9
+ content="width=device-width, initial-scale=1.0, user-scalable=no"
10
+ />
11
+ <link type="text/css" rel="stylesheet" href="https://xrblocks.github.io/css/xr.css" />
12
+ <script>
13
+ window.litDisableBundleWarning = true;
14
+ </script>
15
+ <script type="importmap">
16
+ {
17
+ "imports": {
18
+ "three": "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.module.js",
19
+ "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.182.0/examples/jsm/",
20
+ "xrblocks": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/xrblocks.js",
21
+ "xrblocks/addons/": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/addons/"
22
+ }
23
+ }
24
+ </script>
25
+ </head>
26
+
27
+ <body>
28
+ <script type="module">
29
+ import * as THREE from 'three';
30
+ import * as xb from 'xrblocks';
31
+
32
+ class MainScript extends xb.Script {
33
+ init() {
34
+ this.add(new THREE.HemisphereLight(0xffffff, 0x666666, 3));
35
+
36
+ const geometry = new THREE.CylinderGeometry(0.2, 0.2, 0.4, 32);
37
+ const material = new THREE.MeshPhongMaterial({
38
+ color: 0xffffff,
39
+ transparent: true,
40
+ opacity: 0.8,
41
+ });
42
+ this.player = new THREE.Mesh(geometry, material);
43
+ this.player.position.set(0, xb.user.height - 0.5, -xb.user.objectDistance);
44
+ this.add(this.player);
45
+ }
46
+
47
+ onSelectEnd(event) {
48
+ this.player.material.color.set(Math.random() * 0xffffff);
49
+ }
50
+
51
+ onSelecting(event) {
52
+ this.player.material.color.set(0x66ccff);
53
+ }
54
+ }
55
+
56
+ document.addEventListener('DOMContentLoaded', function () {
57
+ xb.add(new MainScript());
58
+ const options = new xb.Options();
59
+ options.simulator.instructions.enabled = false;
60
+ xb.init(options);
61
+ });
62
+ </script>
63
+ </body>
64
+ </html>
@@ -0,0 +1,107 @@
1
+ <!doctype html>
2
+ <!-- reference: templates/1_ui -->
3
+ <html lang="en">
4
+ <head>
5
+ <title>UI: Spatial Panels | XR Blocks Template</title>
6
+
7
+ <meta
8
+ name="viewport"
9
+ content="width=device-width, initial-scale=1.0, user-scalable=no"
10
+ />
11
+ <link type="text/css" rel="stylesheet" href="https://xrblocks.github.io/css/xr.css" />
12
+ <script>
13
+ window.litDisableBundleWarning = true;
14
+ </script>
15
+ <script type="importmap">
16
+ {
17
+ "imports": {
18
+ "three": "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.module.js",
19
+ "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.182.0/examples/jsm/",
20
+ "troika-three-text": "https://cdn.jsdelivr.net/gh/protectwise/troika@028b81cf308f0f22e5aa8e78196be56ec1997af5/packages/troika-three-text/src/index.js",
21
+ "troika-three-utils": "https://cdn.jsdelivr.net/gh/protectwise/troika@v0.52.4/packages/troika-three-utils/src/index.js",
22
+ "troika-worker-utils": "https://cdn.jsdelivr.net/gh/protectwise/troika@v0.52.4/packages/troika-worker-utils/src/index.js",
23
+ "bidi-js": "https://esm.sh/bidi-js@%5E1.0.2?target=es2022",
24
+ "webgl-sdf-generator": "https://esm.sh/webgl-sdf-generator@1.1.1/es2022/webgl-sdf-generator.mjs",
25
+ "lit": "https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.js",
26
+ "lit/": "https://esm.run/lit@3/",
27
+ "xrblocks": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/xrblocks.js",
28
+ "xrblocks/addons/": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/addons/"
29
+ }
30
+ }
31
+ </script>
32
+ </head>
33
+
34
+ <body>
35
+ <script type="module">
36
+ import 'xrblocks/addons/simulator/SimulatorAddons.js';
37
+
38
+ import * as xb from 'xrblocks';
39
+
40
+ // Inlined from UIManager.js
41
+ /**
42
+ * Rending a draggable spatial UI panel with SDF font libraries, and icons
43
+ * buttons using XR Blocks.
44
+ */
45
+ class UIManager extends xb.Script {
46
+ constructor() {
47
+ super();
48
+
49
+ // Adds an interactive SpatialPanel as a container for UI elements.
50
+ const panel = new xb.SpatialPanel({backgroundColor: '#2b2b2baa'});
51
+ this.add(panel);
52
+
53
+ const grid = panel.addGrid();
54
+ // `weight` defines the perentage of a view's dimension to its parent.
55
+ // Here, question occupies 70% of the height of the panel.
56
+ const question = grid.addRow({weight: 0.7}).addText({
57
+ text: 'Welcome to UI Playground! Is it your first time here?',
58
+ fontColor: '#ffffff',
59
+ fontSize: 0.08,
60
+ });
61
+ this.question = question;
62
+
63
+ // ctrlRow occupies 30% of the height of the panel.
64
+ const ctrlRow = grid.addRow({weight: 0.3});
65
+
66
+ // The `text` field defines the icon of the button from Material Icons in
67
+ // https://fonts.google.com/icons
68
+ const yesButton = ctrlRow
69
+ .addCol({weight: 0.5})
70
+ .addIconButton({text: 'check_circle', fontSize: 0.5});
71
+
72
+ // onTriggered defines unified behavior for `onSelected`, `onClicked`,
73
+ // `onPinched`, `onTouched` for buttons.
74
+ yesButton.onTriggered = () => {
75
+ this._onYes();
76
+ };
77
+
78
+ const noButton = ctrlRow
79
+ .addCol({weight: 0.5})
80
+ .addIconButton({text: 'cancel', fontSize: 0.5});
81
+
82
+ noButton.onTriggered = () => {
83
+ this._onNo();
84
+ };
85
+ }
86
+
87
+ _onYes() {
88
+ console.log('yes');
89
+ }
90
+
91
+ _onNo() {
92
+ console.log('no');
93
+ }
94
+ }
95
+
96
+ const options = new xb.Options();
97
+ options.simulator.instructions.enabled = false;
98
+ options.enableUI();
99
+
100
+ document.addEventListener('DOMContentLoaded', function () {
101
+ xb.add(new UIManager());
102
+ xb.init(options);
103
+ });
104
+
105
+ </script>
106
+ </body>
107
+ </html>
@@ -0,0 +1,183 @@
1
+ <!doctype html>
2
+ <!-- reference: templates/2_hands -->
3
+ <html lang="en">
4
+ <head>
5
+ <title>Hands: Mesh and Touch | XR Blocks Template</title>
6
+
7
+ <meta
8
+ name="viewport"
9
+ content="width=device-width, initial-scale=1.0, user-scalable=no"
10
+ />
11
+ <link type="text/css" rel="stylesheet" href="https://xrblocks.github.io/css/xr.css" />
12
+ <script>
13
+ window.litDisableBundleWarning = true;
14
+ </script>
15
+ <script type="importmap">
16
+ {
17
+ "imports": {
18
+ "three": "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.module.js",
19
+ "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.182.0/examples/jsm/",
20
+ "troika-three-text": "https://cdn.jsdelivr.net/gh/protectwise/troika@028b81cf308f0f22e5aa8e78196be56ec1997af5/packages/troika-three-text/src/index.js",
21
+ "troika-three-utils": "https://cdn.jsdelivr.net/gh/protectwise/troika@v0.52.4/packages/troika-three-utils/src/index.js",
22
+ "troika-worker-utils": "https://cdn.jsdelivr.net/gh/protectwise/troika@v0.52.4/packages/troika-worker-utils/src/index.js",
23
+ "bidi-js": "https://esm.sh/bidi-js@%5E1.0.2?target=es2022",
24
+ "webgl-sdf-generator": "https://esm.sh/webgl-sdf-generator@1.1.1/es2022/webgl-sdf-generator.mjs",
25
+ "lit": "https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.js",
26
+ "lit/": "https://esm.run/lit@3/",
27
+ "xrblocks": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/xrblocks.js",
28
+ "xrblocks/addons/": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/addons/"
29
+ }
30
+ }
31
+ </script>
32
+ </head>
33
+
34
+ <body>
35
+ <script type="module">
36
+ // Provides optional 2D UIs for simulator on desktop.
37
+ import 'xrblocks/addons/simulator/SimulatorAddons.js';
38
+
39
+ import * as THREE from 'three';
40
+ import * as xb from 'xrblocks';
41
+
42
+ // Inlined from HandsInteraction.js
43
+ class HandsInteraction extends xb.Script {
44
+ init() {
45
+ // Touch state.
46
+ this.leftHandTouching = false;
47
+ this.rightHandTouching = false;
48
+
49
+ // Grab state.
50
+ this.isGrabbing = false;
51
+ this._handToObject = null;
52
+
53
+ // Add a cylinder to touch and grab.
54
+ this.originalColor = new THREE.Color(0xfbbc05);
55
+ const geometry = new THREE.CylinderGeometry(0.1, 0.1, 0.2, 32).translate(
56
+ 0,
57
+ 1.45,
58
+ -0.4
59
+ );
60
+ const material = new THREE.MeshPhongMaterial({color: this.originalColor});
61
+ this.target = new THREE.Mesh(geometry, material);
62
+ this.add(this.target);
63
+
64
+ // Add a light.
65
+ this.add(new THREE.HemisphereLight(0xbbbbbb, 0x888888, 3));
66
+ const light = new THREE.DirectionalLight(0xffffff, 2);
67
+ light.position.set(1, 1, 1).normalize();
68
+ this.add(light);
69
+ }
70
+
71
+ _updateColor() {
72
+ if (this.leftHandTouching && this.rightHandTouching) {
73
+ this.target.material.color.setHex(0xdb4437); // Red
74
+ } else if (this.leftHandTouching) {
75
+ this.target.material.color.setHex(0x34a853); // Green
76
+ } else if (this.rightHandTouching) {
77
+ this.target.material.color.setHex(0x4285f4); // Blue
78
+ } else {
79
+ this.target.material.color.copy(this.originalColor); // Yellow
80
+ }
81
+ }
82
+
83
+ onObjectTouchStart(event) {
84
+ const handName = event.handIndex === xb.Handedness.LEFT ? 'left' : 'right';
85
+ console.log(`Touch started with ${handName} hand!`);
86
+
87
+ if (event.handIndex === xb.Handedness.LEFT) {
88
+ this.leftHandTouching = true;
89
+ } else if (event.handIndex === xb.Handedness.RIGHT) {
90
+ this.rightHandTouching = true;
91
+ }
92
+ this._updateColor();
93
+ }
94
+
95
+ onObjectTouchEnd(event) {
96
+ const handName = event.handIndex === xb.Handedness.LEFT ? 'left' : 'right';
97
+ console.log(`Touch ended with ${handName} hand!`);
98
+
99
+ if (event.handIndex === xb.Handedness.LEFT) {
100
+ this.leftHandTouching = false;
101
+ } else if (event.handIndex === xb.Handedness.RIGHT) {
102
+ this.rightHandTouching = false;
103
+ }
104
+ this._updateColor();
105
+ }
106
+
107
+ onObjectGrabStart(event) {
108
+ if (this.isGrabbing) return;
109
+ this.isGrabbing = true;
110
+
111
+ const handName = event.handIndex === xb.Handedness.LEFT ? 'left' : 'right';
112
+ console.log(`Grab started with ${handName} hand!`);
113
+
114
+ // Make sure matrices are fresh.
115
+ this.target.updateMatrixWorld(true);
116
+ event.hand.updateMatrixWorld(true);
117
+
118
+ // Save the initial hand to object delta transform.
119
+ const H0 = new THREE.Matrix4().copy(event.hand.matrixWorld);
120
+ const O0 = new THREE.Matrix4().copy(this.target.matrixWorld);
121
+ this._handToObject = new THREE.Matrix4().copy(H0).invert().multiply(O0);
122
+ }
123
+
124
+ onObjectGrabbing(event) {
125
+ if (!this.isGrabbing || !this._handToObject) return;
126
+
127
+ event.hand.updateMatrixWorld(true);
128
+ const H = new THREE.Matrix4().copy(event.hand.matrixWorld);
129
+ const O = new THREE.Matrix4().multiplyMatrices(H, this._handToObject);
130
+ const parent = this.target.parent;
131
+ if (parent) parent.updateMatrixWorld(true);
132
+ const parentInv = parent
133
+ ? new THREE.Matrix4().copy(parent.matrixWorld).invert()
134
+ : new THREE.Matrix4().identity();
135
+
136
+ const Olocal = new THREE.Matrix4().multiplyMatrices(parentInv, O);
137
+ const pos = new THREE.Vector3();
138
+ const quat = new THREE.Quaternion();
139
+ const scl = new THREE.Vector3();
140
+ Olocal.decompose(pos, quat, scl);
141
+
142
+ this.target.position.copy(pos);
143
+ this.target.quaternion.copy(quat);
144
+
145
+ this.target.updateMatrix();
146
+ }
147
+
148
+ onObjectGrabEnd(event) {
149
+ if (!this.isGrabbing) return;
150
+ const handName = event.handIndex === xb.Handedness.LEFT ? 'left' : 'right';
151
+ console.log(`Grab ended with ${handName} hand!`);
152
+
153
+ this.isGrabbing = false;
154
+ this._handToObject = null;
155
+ }
156
+ }
157
+
158
+ const options = new xb.Options();
159
+ options.simulator.instructions.enabled = false;
160
+ options.enableReticles();
161
+ options.enableHands();
162
+
163
+ options.hands.enabled = true;
164
+ options.hands.visualization = true;
165
+ // Visualize hand joints.
166
+ options.hands.visualizeJoints = true;
167
+ // Visualize hand meshes.
168
+ options.hands.visualizeMeshes = true;
169
+
170
+ options.simulator.defaultMode = xb.SimulatorMode.POSE;
171
+
172
+ function start() {
173
+ xb.add(new HandsInteraction());
174
+ xb.init(options);
175
+ }
176
+
177
+ document.addEventListener('DOMContentLoaded', function () {
178
+ start();
179
+ });
180
+
181
+ </script>
182
+ </body>
183
+ </html>
@@ -0,0 +1,89 @@
1
+ <!doctype html>
2
+ <!-- reference: templates/3_depth -->
3
+ <html lang="en">
4
+ <head>
5
+ <title>Depth | XR Blocks Template</title>
6
+
7
+ <meta
8
+ name="viewport"
9
+ content="width=device-width, initial-scale=1.0, user-scalable=no"
10
+ />
11
+
12
+ <link type="text/css" rel="stylesheet" href="https://xrblocks.github.io/css/xr.css" />
13
+ <script>
14
+ window.litDisableBundleWarning = true;
15
+ </script>
16
+ <script type="importmap">
17
+ {
18
+ "imports": {
19
+ "three": "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.module.js",
20
+ "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.182.0/examples/jsm/",
21
+ "lit": "https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.js",
22
+ "lit/": "https://esm.run/lit@3/",
23
+ "xrblocks": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/xrblocks.js",
24
+ "xrblocks/addons/": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/addons/"
25
+ }
26
+ }
27
+ </script>
28
+ </head>
29
+
30
+ <body>
31
+ <script type="module">
32
+ import 'xrblocks/addons/simulator/SimulatorAddons.js';
33
+
34
+ import * as THREE from 'three';
35
+ import * as xb from 'xrblocks';
36
+
37
+ const pawnModelPath =
38
+ 'https://cdn.jsdelivr.net/gh/xrblocks/assets@main/models/arcore_pawn_compressed.glb';
39
+
40
+ class PawnPlacer extends xb.Script {
41
+ async init() {
42
+ this.addLights();
43
+ await this.loadPawnModel();
44
+ }
45
+
46
+ async loadPawnModel() {
47
+ const pawnGltf = await new xb.ModelLoader().load({
48
+ url: pawnModelPath,
49
+ renderer: xb.core.renderer,
50
+ });
51
+ pawnGltf.scene.scale.setScalar(0.5);
52
+ this.pawnModel = pawnGltf.scene;
53
+ }
54
+
55
+ addLights() {
56
+ const directionalLight = new THREE.DirectionalLight(0xffffff, 2);
57
+ directionalLight.position.set(0, 1, 0);
58
+ this.add(directionalLight);
59
+ const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
60
+ this.add(ambientLight);
61
+ }
62
+
63
+ onSelectStart(event) {
64
+ const intersection = xb.user.select(xb.core.depth.depthMesh, event.target);
65
+ if (intersection) {
66
+ this.add(
67
+ xb.placeObjectAtIntersectionFacingTarget(
68
+ this.pawnModel.clone(),
69
+ intersection,
70
+ xb.core.camera
71
+ )
72
+ );
73
+ }
74
+ }
75
+ }
76
+
77
+ document.addEventListener('DOMContentLoaded', async function () {
78
+ const options = new xb.Options();
79
+ options.simulator.instructions.enabled = false;
80
+ options.reticles.enabled = true;
81
+ options.depth = new xb.DepthOptions(xb.xrDepthMeshOptions);
82
+ await xb.init(options);
83
+ xb.showReticleOnDepthMesh(true);
84
+ xb.add(new PawnPlacer());
85
+ });
86
+
87
+ </script>
88
+ </body>
89
+ </html>
@@ -0,0 +1,84 @@
1
+ <!doctype html>
2
+ <!-- reference: templates/4_stereo -->
3
+ <html lang="en">
4
+ <head>
5
+ <title>Stereo | XR Blocks Template</title>
6
+
7
+ <meta
8
+ name="viewport"
9
+ content="width=device-width, initial-scale=1.0, user-scalable=no"
10
+ />
11
+
12
+ <link type="text/css" rel="stylesheet" href="https://xrblocks.github.io/css/xr.css" />
13
+ <script>
14
+ window.litDisableBundleWarning = true;
15
+ </script>
16
+ <script type="importmap">
17
+ {
18
+ "imports": {
19
+ "three": "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.module.js",
20
+ "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.182.0/examples/jsm/",
21
+ "lit": "https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.js",
22
+ "lit/": "https://esm.run/lit@3/",
23
+ "xrblocks": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/xrblocks.js",
24
+ "xrblocks/addons/": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/addons/"
25
+ }
26
+ }
27
+ </script>
28
+ </head>
29
+
30
+ <body>
31
+ <script type="module">
32
+ import 'xrblocks/addons/simulator/SimulatorAddons.js';
33
+
34
+ import * as THREE from 'three';
35
+ import * as xb from 'xrblocks';
36
+
37
+ const stereoTextureFile = 'SV_20241216_144600.webp';
38
+
39
+ class StereoImage extends xb.Script {
40
+ async init() {
41
+ await this.addStereoQuad();
42
+ }
43
+
44
+ async addStereoQuad() {
45
+ const stereoObject = new THREE.Group();
46
+ const [leftTexture, rightTexture] =
47
+ await xb.loadStereoImageAsTextures(stereoTextureFile);
48
+ const geometry = new THREE.PlaneGeometry(1, 1);
49
+ const leftMesh = new THREE.Mesh(
50
+ geometry,
51
+ new THREE.MeshBasicMaterial({
52
+ map: leftTexture,
53
+ side: THREE.DoubleSide,
54
+ })
55
+ );
56
+
57
+ xb.showOnlyInLeftEye(leftMesh);
58
+ stereoObject.add(leftMesh);
59
+ const rightMesh = new THREE.Mesh(
60
+ geometry,
61
+ new THREE.MeshBasicMaterial({
62
+ map: rightTexture,
63
+ side: THREE.DoubleSide,
64
+ })
65
+ );
66
+
67
+ xb.showOnlyInRightEye(rightMesh);
68
+ stereoObject.add(rightMesh);
69
+ stereoObject.position.set(0.0, 1.5, -1.5);
70
+ this.add(stereoObject);
71
+ }
72
+ }
73
+
74
+ document.addEventListener('DOMContentLoaded', function () {
75
+ const options = new xb.Options();
76
+ options.simulator.instructions.enabled = false;
77
+ options.simulator.stereo.enabled = true;
78
+ xb.add(new StereoImage());
79
+ xb.init(options);
80
+ });
81
+
82
+ </script>
83
+ </body>
84
+ </html>
@@ -0,0 +1,117 @@
1
+ <!doctype html>
2
+ <!-- reference: templates/5_camera -->
3
+ <html lang="en">
4
+ <head>
5
+ <title>Camera | XR Blocks Template</title>
6
+
7
+ <meta
8
+ name="viewport"
9
+ content="width=device-width, initial-scale=1.0, user-scalable=no"
10
+ />
11
+
12
+ <link type="text/css" rel="stylesheet" href="https://xrblocks.github.io/css/xr.css" />
13
+ <script>
14
+ window.litDisableBundleWarning = true;
15
+ </script>
16
+ <script type="importmap">
17
+ {
18
+ "imports": {
19
+ "three": "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.module.js",
20
+ "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.182.0/examples/jsm/",
21
+ "troika-three-text": "https://cdn.jsdelivr.net/gh/protectwise/troika@028b81cf308f0f22e5aa8e78196be56ec1997af5/packages/troika-three-text/src/index.js",
22
+ "troika-three-utils": "https://cdn.jsdelivr.net/gh/protectwise/troika@v0.52.4/packages/troika-three-utils/src/index.js",
23
+ "troika-worker-utils": "https://cdn.jsdelivr.net/gh/protectwise/troika@v0.52.4/packages/troika-worker-utils/src/index.js",
24
+ "bidi-js": "https://esm.sh/bidi-js@%5E1.0.2?target=es2022",
25
+ "webgl-sdf-generator": "https://esm.sh/webgl-sdf-generator@1.1.1/es2022/webgl-sdf-generator.mjs",
26
+ "lit": "https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.js",
27
+ "lit/": "https://esm.run/lit@3/",
28
+ "xrblocks": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/xrblocks.js",
29
+ "xrblocks/addons/": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/addons/"
30
+ }
31
+ }
32
+ </script>
33
+ </head>
34
+
35
+ <body>
36
+ <script type="module">
37
+ import 'xrblocks/addons/simulator/SimulatorAddons.js';
38
+
39
+ import * as xb from 'xrblocks';
40
+
41
+ /**
42
+ * A class that provides UI to display and cycle through device cameras.
43
+ */
44
+ class CameraViewManager extends xb.Script {
45
+ /** @private {XRDeviceCamera|null} */
46
+ cameraStream_ = null;
47
+
48
+ constructor() {
49
+ super();
50
+ this.panel = new xb.SpatialPanel({
51
+ backgroundColor: '#2b2b2baa',
52
+ useDefaultPosition: true,
53
+ });
54
+ const grid = this.panel.addGrid();
55
+ this.videoView = grid.addRow({weight: 0.7}).addVideo();
56
+ const txtRow = grid.addRow({weight: 0.15});
57
+ this.cameraLabel = txtRow
58
+ .addCol({weight: 1})
59
+ .addText({text: 'Camera', fontColor: '#ffffff', fontSize: 0.05});
60
+ const ctrlRow = grid.addRow({weight: 0.2});
61
+ this.prevCameraButton = ctrlRow.addCol({weight: 0.5}).addIconButton({
62
+ text: 'skip_previous',
63
+ fontSize: 0.5,
64
+ });
65
+ this.nextCameraButton = ctrlRow.addCol({weight: 0.5}).addIconButton({
66
+ text: 'skip_next',
67
+ fontSize: 0.5,
68
+ });
69
+
70
+ this.prevCameraButton.onTriggered = () => this.cycleCamera_(-1);
71
+ this.nextCameraButton.onTriggered = () => this.cycleCamera_(1);
72
+
73
+ this.add(this.panel);
74
+ }
75
+
76
+ async init() {
77
+ this.cameraStream_ = xb.core.deviceCamera;
78
+
79
+ // Listen for camera state changes to update UI
80
+ this.cameraStream_.addEventListener('statechange', (event) => {
81
+ this.cameraLabel.setText(event.device?.label || event.state || 'Camera');
82
+ if (event.state === 'streaming') {
83
+ this.videoView.load(this.cameraStream_);
84
+ }
85
+ });
86
+ this.cameraLabel.setText(
87
+ this.cameraStream_.getCurrentDevice()?.label || 'Camera'
88
+ );
89
+ this.videoView.load(this.cameraStream_);
90
+ }
91
+
92
+ /**
93
+ * Cycle to the next or previous device.
94
+ * @param {number} offset - The direction to cycle (-1 for prev, 1 for next).
95
+ */
96
+ async cycleCamera_(offset) {
97
+ const devices = this.cameraStream_.getAvailableDevices();
98
+ if (devices.length <= 1) return;
99
+ const newIndex =
100
+ (this.cameraStream_.getCurrentDeviceIndex() + offset + devices.length) %
101
+ devices.length;
102
+ await this.cameraStream_.setDeviceId(devices[newIndex].deviceId);
103
+ }
104
+ }
105
+
106
+ document.addEventListener('DOMContentLoaded', function () {
107
+ const options = new xb.Options();
108
+ options.simulator.instructions.enabled = false;
109
+ options.enableUI();
110
+ options.enableCamera();
111
+ xb.add(new CameraViewManager());
112
+ xb.init(options);
113
+ });
114
+
115
+ </script>
116
+ </body>
117
+ </html>