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,247 @@
1
+ <!doctype html>
2
+ <!-- reference: demos/measure -->
3
+ <html lang="en">
4
+ <head>
5
+ <title>Measure</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 type="importmap">
14
+ {
15
+ "imports": {
16
+ "three": "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.module.js",
17
+ "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.182.0/examples/jsm/",
18
+ "troika-three-text": "https://cdn.jsdelivr.net/gh/protectwise/troika@028b81cf308f0f22e5aa8e78196be56ec1997af5/packages/troika-three-text/src/index.js",
19
+ "troika-three-utils": "https://cdn.jsdelivr.net/gh/protectwise/troika@v0.52.4/packages/troika-three-utils/src/index.js",
20
+ "troika-worker-utils": "https://cdn.jsdelivr.net/gh/protectwise/troika@v0.52.4/packages/troika-worker-utils/src/index.js",
21
+ "bidi-js": "https://esm.sh/bidi-js@%5E1.0.2?target=es2022",
22
+ "webgl-sdf-generator": "https://esm.sh/webgl-sdf-generator@1.1.1/es2022/webgl-sdf-generator.mjs",
23
+ "lit": "https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.js",
24
+ "lit/": "https://esm.run/lit@3/",
25
+ "xrblocks": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/xrblocks.js",
26
+ "xrblocks/addons/": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/addons/"
27
+ }
28
+ }
29
+ </script>
30
+ </head>
31
+
32
+ <body>
33
+ <script type="module">
34
+ import 'xrblocks/addons/simulator/SimulatorAddons.js';
35
+
36
+ import * as THREE from 'three';
37
+ import {FontLoader} from 'three/addons/loaders/FontLoader.js';
38
+ import * as xb from 'xrblocks';
39
+
40
+ // --- MeasuringTape inlined ---
41
+ const fontLoader = new FontLoader();
42
+ const DEFAULT_FONT_PATH =
43
+ 'https://cdn.jsdelivr.net/gh/mrdoob/three.js@r180/examples/fonts/droid/droid_sans_regular.typeface.json';
44
+ const upVector = new THREE.Vector3(0.0, 1.0, 0.0);
45
+ const backwardsVector = new THREE.Vector3(0.0, 0.0, 1.0);
46
+
47
+ class MeasuringTape extends THREE.Object3D {
48
+ ignoreReticleRaycast = true;
49
+
50
+ constructor(
51
+ firstPoint,
52
+ secondPoint,
53
+ radius = 0.05,
54
+ visualColor = 0xffffff,
55
+ textColor = 0xff0000,
56
+ fontPath = DEFAULT_FONT_PATH
57
+ ) {
58
+ super();
59
+ this.firstPoint = firstPoint.clone();
60
+ this.secondPoint = secondPoint.clone();
61
+ this.radius = radius;
62
+
63
+ this.cylinder = new THREE.Mesh(
64
+ new THREE.CylinderGeometry(radius, radius),
65
+ new THREE.MeshStandardMaterial({
66
+ color: visualColor,
67
+ side: THREE.FrontSide,
68
+ })
69
+ );
70
+ this.visual = new THREE.Object3D();
71
+ this.visual.add(this.cylinder);
72
+ this.add(this.visual);
73
+ this.updateVisual();
74
+
75
+ this.textGeometry = null;
76
+ this.textMaterial = new THREE.MeshBasicMaterial({
77
+ color: textColor,
78
+ side: THREE.DoubleSide,
79
+ });
80
+ this.textMesh = null;
81
+ this.camera = null;
82
+ fontLoader.load(fontPath, (font) => {
83
+ this.textFont = font;
84
+ this.updateText();
85
+ });
86
+ }
87
+
88
+ getLengthText() {
89
+ const length = this.secondPoint.distanceTo(this.firstPoint);
90
+ return `${length.toFixed(2)} m`;
91
+ }
92
+
93
+ updateText() {
94
+ if (!this.textFont) {
95
+ return;
96
+ }
97
+ if (this.textGeometry) {
98
+ this.textGeometry.dispose();
99
+ }
100
+ const textShapes = this.textFont.generateShapes(this.getLengthText());
101
+ this.textGeometry = new THREE.ShapeGeometry(textShapes);
102
+ this.textGeometry.computeBoundingBox();
103
+ const tempVector = new THREE.Vector3();
104
+ this.textGeometry.boundingBox.getCenter(tempVector);
105
+ this.textGeometry.translate(-tempVector.x, -tempVector.y, -tempVector.z);
106
+ if (this.textMesh) {
107
+ this.remove(this.textMesh);
108
+ }
109
+ this.textMesh = new THREE.Mesh(this.textGeometry, this.textMaterial);
110
+ this.textMesh.position
111
+ .copy(this.firstPoint)
112
+ .add(this.secondPoint)
113
+ .multiplyScalar(0.5);
114
+ const offset = new THREE.Vector3(
115
+ 0.0,
116
+ 0.0,
117
+ 0.1 + 1.5 * this.radius
118
+ ).applyQuaternion(this.cylinder.quaternion);
119
+ this.textMesh.position.add(offset);
120
+ this.textMesh.scale.setScalar(0.0005);
121
+ this.add(this.textMesh);
122
+ }
123
+
124
+ setSecondPoint(point) {
125
+ this.secondPoint.copy(point);
126
+ this.updateVisual();
127
+ this.updateText();
128
+ }
129
+
130
+ rotateTextToFaceCamera(cameraPosition) {
131
+ if (this.textMesh) {
132
+ this.textMesh.quaternion.setFromUnitVectors(
133
+ backwardsVector,
134
+ cameraPosition.clone().sub(this.textMesh.position).normalize()
135
+ );
136
+ }
137
+ }
138
+
139
+ updateVisual() {
140
+ const tempVector = this.cylinder.position;
141
+ this.cylinder.quaternion.setFromUnitVectors(
142
+ upVector,
143
+ tempVector.copy(this.secondPoint).sub(this.firstPoint).normalize()
144
+ );
145
+ this.cylinder.scale.set(
146
+ 1.0,
147
+ tempVector.subVectors(this.secondPoint, this.firstPoint).length(),
148
+ 1.0
149
+ );
150
+ this.cylinder.position
151
+ .copy(this.firstPoint)
152
+ .add(this.secondPoint)
153
+ .multiplyScalar(0.5);
154
+ }
155
+ }
156
+
157
+ // --- MeasureScene inlined ---
158
+ const palette = [0x0f9d58, 0xf4b400, 0x4285f4, 0xdb4437];
159
+
160
+ class MeasureScene extends xb.Script {
161
+ activeMeasuringTapes = new Map();
162
+ currentColorIndex = 0;
163
+
164
+ init() {
165
+ xb.showReticleOnDepthMesh(true);
166
+ this.setupLights();
167
+ }
168
+
169
+ setupLights() {
170
+ const light = new THREE.DirectionalLight(0xffffff, 2.0);
171
+ light.position.set(0.5, 1, 0.866);
172
+ this.add(light);
173
+ const light2 = new THREE.DirectionalLight(0xffffff, 1.0);
174
+ light2.position.set(-1, 0.5, -0.5);
175
+ this.add(light2);
176
+ const light3 = new THREE.AmbientLight(0x404040, 2.0);
177
+ this.add(light3);
178
+ }
179
+
180
+ onSelectStart(event) {
181
+ const controller = event.target;
182
+ const intersections =
183
+ xb.core.input.intersectionsForController.get(controller);
184
+ if (intersections.length == 0) return;
185
+ if (this.activeMeasuringTapes.has(controller)) {
186
+ this.remove(this.activeMeasuringTapes.get(controller));
187
+ }
188
+ const closestIntersection = intersections[0];
189
+ const color = palette[this.currentColorIndex];
190
+ this.currentColorIndex = (this.currentColorIndex + 1) % palette.length;
191
+ const measuringTape = new MeasuringTape(
192
+ closestIntersection.point,
193
+ closestIntersection.point,
194
+ 0.05,
195
+ color
196
+ );
197
+ this.add(measuringTape);
198
+ this.activeMeasuringTapes.set(controller, measuringTape);
199
+ }
200
+
201
+ update() {
202
+ for (const [controller, tape] of this.activeMeasuringTapes) {
203
+ const intersections = xb.core.input.intersectionsForController
204
+ .get(controller)
205
+ .filter((intersection) => {
206
+ let target = intersection.object;
207
+ while (target) {
208
+ if (target.ignoreReticleRaycast === true) {
209
+ return false;
210
+ }
211
+ target = target.parent;
212
+ }
213
+ return true;
214
+ });
215
+ if (intersections.length > 0) {
216
+ tape.setSecondPoint(intersections[0].point);
217
+ }
218
+ }
219
+ }
220
+
221
+ onSelectEnd(event) {
222
+ const controller = event.target;
223
+ this.activeMeasuringTapes.delete(controller);
224
+ }
225
+ }
226
+
227
+ const options = new xb.Options({
228
+ antialias: true,
229
+ reticles: {enabled: true},
230
+ visualizeRays: true,
231
+ depth: xb.xrDepthMeshPhysicsOptions,
232
+ });
233
+ options.simulator.instructions.enabled = false;
234
+
235
+ function start() {
236
+ xb.add(new MeasureScene());
237
+ options.setAppTitle('XR Measure');
238
+ xb.init(options);
239
+ }
240
+
241
+ document.addEventListener('DOMContentLoaded', function () {
242
+ start();
243
+ });
244
+
245
+ </script>
246
+ </body>
247
+ </html>
@@ -0,0 +1,251 @@
1
+ <!doctype html>
2
+ <!-- reference: demos/occlusion -->
3
+ <html lang="en">
4
+ <head>
5
+ <title>Occlusion</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
+ "@material/web/": "https://esm.run/@material/web/",
29
+ "xrblocks": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/xrblocks.js",
30
+ "xrblocks/addons/": "https://cdn.jsdelivr.net/npm/xrblocks@0.11.0/build/addons/"
31
+ }
32
+ }
33
+ </script>
34
+ <script type="module">
35
+ import '@material/web/all.js';
36
+ import {styles as typescaleStyles} from '@material/web/typography/md-typescale-styles.js';
37
+
38
+ document.adoptedStyleSheets.push(typescaleStyles.styleSheet);
39
+ </script>
40
+ </head>
41
+
42
+ <body>
43
+ <div
44
+ class="background-image"
45
+ style="background-image: url('textures/background.webp')"
46
+ ></div>
47
+ <script type="module">
48
+ import * as THREE from 'three';
49
+ import * as xb from 'xrblocks';
50
+ import {ModelManager} from 'xrblocks/addons/ui/ModelManager.js';
51
+
52
+ // --- animals_data inlined ---
53
+ const ANIMALS_DATA = [
54
+ {
55
+ path: 'https://cdn.jsdelivr.net/gh/xrblocks/assets@main/',
56
+ model: 'models/Cat/cat.gltf',
57
+ thumbnail: 'thumbnail.png',
58
+ },
59
+ ];
60
+
61
+ // --- DepthMeshClone inlined ---
62
+ class DepthMeshClone extends THREE.Mesh {
63
+ constructor() {
64
+ super(
65
+ new THREE.PlaneGeometry(),
66
+ new THREE.ShadowMaterial({
67
+ opacity: xb.xrDepthMeshOptions.depthMesh.shadowOpacity,
68
+ depthWrite: false,
69
+ })
70
+ );
71
+ this.receiveShadow = true;
72
+ }
73
+
74
+ cloneDepthMesh(depthMesh) {
75
+ this.geometry.dispose();
76
+ this.geometry = depthMesh.geometry.clone();
77
+ depthMesh.getWorldPosition(this.position);
78
+ depthMesh.getWorldQuaternion(this.quaternion);
79
+ depthMesh.getWorldScale(this.scale);
80
+ }
81
+ }
82
+
83
+ // --- OcclusionScene inlined ---
84
+ const kLightX = xb.getUrlParamFloat('lightX', 0);
85
+ const kLightY = xb.getUrlParamFloat('lightY', 500);
86
+ const kLightZ = xb.getUrlParamFloat('lightZ', -10);
87
+
88
+ class OcclusionScene extends xb.Script {
89
+ constructor() {
90
+ super();
91
+ this.pointer = new THREE.Vector3();
92
+ this.depthMeshClone = new DepthMeshClone();
93
+ this.raycaster = new THREE.Raycaster();
94
+ this.modelManager = new ModelManager(
95
+ ANIMALS_DATA,
96
+ /*enableOcclusion=*/ true
97
+ );
98
+ this.modelManager.layers.enable(xb.OCCLUDABLE_ITEMS_LAYER);
99
+ this.add(this.modelManager);
100
+ this.instructionText =
101
+ 'Pinch on the environment and try hiding the cat behind sofa!';
102
+ this.instructionCol = null;
103
+ }
104
+
105
+ init() {
106
+ this.addLights();
107
+ xb.showReticleOnDepthMesh(true);
108
+ this.addPanel();
109
+ }
110
+
111
+ addPanel() {
112
+ const panel = new xb.SpatialPanel({
113
+ backgroundColor: '#00000000',
114
+ useDefaultPosition: false,
115
+ showEdge: false,
116
+ });
117
+ panel.position.set(0, 1.6, -1.0);
118
+ panel.isRoot = true;
119
+ this.add(panel);
120
+
121
+ const grid = panel.addGrid();
122
+ grid.addRow({weight: 0.05});
123
+ grid.addRow({weight: 0.1});
124
+
125
+ const controlRow = grid.addRow({weight: 0.3});
126
+ const ctrlPanel = controlRow.addPanel({backgroundColor: '#000000bb'});
127
+ const ctrlGrid = ctrlPanel.addGrid();
128
+
129
+ const midColumn = ctrlGrid.addCol({weight: 0.9});
130
+ midColumn.addRow({weight: 0.3});
131
+ const gesturesRow = midColumn.addRow({weight: 0.4});
132
+ gesturesRow.addCol({weight: 0.05});
133
+
134
+ const textCol = gesturesRow.addCol({weight: 1.0});
135
+ this.instructionCol = textCol.addRow({weight: 1.0}).addText({
136
+ text: `${this.instructionText}`,
137
+ fontColor: '#ffffff',
138
+ fontSize: 0.05,
139
+ });
140
+
141
+ gesturesRow.addCol({weight: 0.01});
142
+ midColumn.addRow({weight: 0.1});
143
+
144
+ const orbiter = ctrlGrid.addOrbiter();
145
+ orbiter.addExitButton();
146
+
147
+ panel.updateLayouts();
148
+
149
+ this.panel = panel;
150
+ this.frameId = 0;
151
+ }
152
+
153
+ onSimulatorStarted() {
154
+ this.instructionText =
155
+ 'Click on the environment and try hiding the cat behind sofa!';
156
+ if (this.instructionCol) {
157
+ this.instructionCol.setText(this.instructionText);
158
+ }
159
+ }
160
+
161
+ addLights() {
162
+ this.add(new THREE.HemisphereLight(0xbbbbbb, 0x888888, 3));
163
+ const light = new THREE.DirectionalLight(0xffffff, 2);
164
+ light.position.set(kLightX, kLightY, kLightZ);
165
+ light.castShadow = true;
166
+ light.shadow.mapSize.width = 2048;
167
+ light.shadow.mapSize.height = 2048;
168
+ this.add(light);
169
+ }
170
+
171
+ updatePointerPosition(event) {
172
+ this.pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
173
+ this.pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
174
+ this.pointer.x = 1 + 2 * this.pointer.x;
175
+ }
176
+
177
+ onSelectStart(event) {
178
+ const controller = event.target;
179
+ if (xb.core.input.intersectionsForController.get(controller).length > 0) {
180
+ const intersection =
181
+ xb.core.input.intersectionsForController.get(controller)[0];
182
+ if (intersection.handleSelectRaycast) {
183
+ intersection.handleSelectRaycast(intersection);
184
+ return;
185
+ } else if (intersection.object.handleSelectRaycast) {
186
+ intersection.object.handleSelectRaycast(intersection);
187
+ return;
188
+ } else if (intersection.object == xb.core.depth.depthMesh) {
189
+ this.onDepthMeshSelectStart(intersection);
190
+ return;
191
+ }
192
+ }
193
+ }
194
+
195
+ onDepthMeshSelectStart(intersection) {
196
+ this.modelManager.positionModelAtIntersection(intersection, xb.core.camera);
197
+ }
198
+
199
+ onPointerDown(event) {
200
+ this.updatePointerPosition(event);
201
+ const cameras = xb.core.renderer.xr.getCamera().cameras;
202
+ if (cameras.length == 0) return;
203
+ const camera = cameras[0];
204
+ this.raycaster.setFromCamera(this.pointer, camera);
205
+ const intersections = this.raycaster.intersectObjects(
206
+ xb.core.input.reticleTargets
207
+ );
208
+ for (let intersection of intersections) {
209
+ if (intersection.handleSelectRaycast) {
210
+ intersection.handleSelectRaycast(intersection);
211
+ return;
212
+ } else if (intersection.object.handleSelectRaycast) {
213
+ intersection.object.handleSelectRaycast(intersection);
214
+ return;
215
+ } else if (intersection.object == xb.core.depth.depthMesh) {
216
+ this.modelManager.positionModelAtIntersection(intersection, camera);
217
+ return;
218
+ }
219
+ }
220
+ }
221
+ }
222
+
223
+ const options = new xb.Options();
224
+ options.simulator.instructions.enabled = false;
225
+ options.reticles.enabled = true;
226
+ options.depth = new xb.DepthOptions(xb.xrDepthMeshOptions);
227
+ options.depth.depthMesh.updateFullResolutionGeometry = true;
228
+ options.depth.depthMesh.renderShadow = true;
229
+ options.depth.depthTexture.enabled = true;
230
+ options.depth.occlusion.enabled = true;
231
+ options.xrButton.startText = '<i id="xrlogo"></i> BRING IT TO LIFE';
232
+ options.xrButton.endText = '<i id="xrlogo"></i> MISSION COMPLETE';
233
+
234
+ async function start() {
235
+ const occlusion = new OcclusionScene();
236
+ await xb.init(options);
237
+ xb.add(occlusion);
238
+
239
+ window.addEventListener(
240
+ 'pointerdown',
241
+ occlusion.onPointerDown.bind(occlusion)
242
+ );
243
+ }
244
+
245
+ document.addEventListener('DOMContentLoaded', function () {
246
+ start();
247
+ });
248
+
249
+ </script>
250
+ </body>
251
+ </html>