MikaFil commited on
Commit
84e939d
·
verified ·
1 Parent(s): ef2a675

Update viewer_ar.js

Browse files
Files changed (1) hide show
  1. viewer_ar.js +46 -36
viewer_ar.js CHANGED
@@ -1,6 +1,6 @@
1
  /* script_ar.js — AR PlayCanvas + GLB HuggingFace
2
  - Chargeur PlayCanvas robuste (ESM -> UMD avec fallbacks + timeout)
3
- - WebXR AR Hit Test, placement auto, drag + rotation Y via SLIDER
4
  - Aucune dépendance externe autre que PlayCanvas et le GLB
5
  */
6
 
@@ -79,9 +79,10 @@
79
  // 3) UI & utilitaires
80
  // =========================
81
  const css = `
 
82
  .pc-ar-msg {
83
  position: fixed; left: 50%; transform: translateX(-50%);
84
- bottom: 16px; z-index: 9999; padding: 10px 14px;
85
  background: rgba(0,0,0,.65); color: #fff; border-radius: 8px;
86
  font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
87
  font-size: 14px; line-height: 1.3; text-align: center;
@@ -91,19 +92,25 @@
91
  user-select: none;
92
  pointer-events: none;
93
  }
 
 
 
 
 
 
 
94
  /* --- UI Slider (DOM overlay) --- */
95
  .ar-ui {
96
- position: fixed;
97
  right: 12px;
98
  top: 50%;
99
  transform: translateY(-50%);
100
- z-index: 10000;
101
  background: rgba(0,0,0,0.55);
102
  color: #fff;
103
  padding: 12px 10px;
104
  border-radius: 12px;
105
  font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
106
- pointer-events: auto;
107
  width: 56px;
108
  display: flex; flex-direction: column; align-items: center; gap: 8px;
109
  box-shadow: 0 6px 18px rgba(0,0,0,.25);
@@ -114,45 +121,47 @@
114
  text-align: center;
115
  opacity: 0.9;
116
  }
117
- /* Slider vertical (on le tourne) */
118
  .ar-ui input[type="range"].rotY {
119
  -webkit-appearance: none;
120
- width: 220px; /* longueur avant rotation */
121
- height: 28px;
122
  transform: rotate(-90deg);
123
  outline: none;
124
  background: transparent;
125
  touch-action: none;
126
  }
127
  .ar-ui input[type="range"].rotY::-webkit-slider-thumb {
128
- -webkit-appearance: none;
129
- appearance: none;
130
- width: 20px; height: 20px;
131
- border-radius: 50%;
132
- background: #fff;
133
- border: none;
134
- box-shadow: 0 2px 8px rgba(0,0,0,.35);
135
  }
136
  .ar-ui input[type="range"].rotY::-webkit-slider-runnable-track {
137
- height: 6px;
138
- background: rgba(255,255,255,.6);
139
- border-radius: 4px;
140
- }
141
- .ar-ui .val {
142
- font-size: 11px;
143
- opacity: 0.85;
144
  }
 
145
  `;
146
  const styleTag = document.createElement("style");
147
  styleTag.textContent = css;
148
  document.head.appendChild(styleTag);
149
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  function message(msg) {
151
- let el = document.querySelector(".pc-ar-msg");
152
  if (!el) {
153
  el = document.createElement("div");
154
  el.className = "pc-ar-msg";
155
- document.body.appendChild(el);
156
  }
157
  el.textContent = msg;
158
  }
@@ -162,7 +171,6 @@
162
  if (!canvas) {
163
  canvas = document.createElement("canvas");
164
  canvas.id = "application-canvas";
165
- // optionnel: force plein écran si aucun style
166
  canvas.style.width = "100%";
167
  canvas.style.height = "100%";
168
  document.body.appendChild(canvas);
@@ -170,9 +178,9 @@
170
  return canvas;
171
  }
172
 
173
- // Crée le panneau slider (DOM overlay)
174
  function ensureSliderUI() {
175
- let panel = document.querySelector(".ar-ui");
176
  if (panel) return panel;
177
  panel = document.createElement("div");
178
  panel.className = "ar-ui";
@@ -181,7 +189,7 @@
181
  <input class="rotY" id="ar-rotY" type="range" min="0" max="360" step="1" value="0" />
182
  <div class="val" id="ar-rotY-val">0°</div>
183
  `;
184
- document.body.appendChild(panel);
185
  return panel;
186
  }
187
 
@@ -196,7 +204,6 @@
196
  message("Impossible de charger PlayCanvas (réseau/CDN). Réessaie plus tard.");
197
  return;
198
  }
199
- // PlayCanvas dispo -> démarrer
200
  initARApp();
201
  })();
202
 
@@ -310,20 +317,21 @@
310
  return;
311
  }
312
 
313
- // --- Démarrage AR ---
314
  const activateAR = () => {
315
  if (!app.xr.isAvailable(pc.XRTYPE_AR)) {
316
  message("AR immersive indisponible sur cet appareil.");
317
  return;
318
  }
319
- camera.camera.startXr(pc.XRTYPE_AR, pc.XRSPACE_LOCALFLOOR, {
320
- // DOM overlay pour pouvoir utiliser le slider en AR
321
- domOverlay: { root: document.body },
 
 
 
322
  requiredFeatures: ["hit-test", "dom-overlay"],
323
  optionalFeatures: ["plane-detection"],
324
- callback: (err) => {
325
- if (err) message(`Échec du démarrage AR : ${err.message}`);
326
- }
327
  });
328
  };
329
 
@@ -457,6 +465,8 @@
457
 
458
  // --- Événements AR globaux ---
459
  app.xr.on("start", () => {
 
 
460
  message("Session AR démarrée. Visez le sol pour détecter un plan…");
461
  reticle.enabled = true;
462
  });
 
1
  /* script_ar.js — AR PlayCanvas + GLB HuggingFace
2
  - Chargeur PlayCanvas robuste (ESM -> UMD avec fallbacks + timeout)
3
+ - WebXR AR Hit Test, placement auto, drag + rotation Y via SLIDER (DOM Overlay)
4
  - Aucune dépendance externe autre que PlayCanvas et le GLB
5
  */
6
 
 
79
  // 3) UI & utilitaires
80
  // =========================
81
  const css = `
82
+ /* Messages in-overlay */
83
  .pc-ar-msg {
84
  position: fixed; left: 50%; transform: translateX(-50%);
85
+ bottom: 16px; z-index: 2; padding: 10px 14px;
86
  background: rgba(0,0,0,.65); color: #fff; border-radius: 8px;
87
  font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
88
  font-size: 14px; line-height: 1.3; text-align: center;
 
92
  user-select: none;
93
  pointer-events: none;
94
  }
95
+ /* Racine DOM Overlay : tout ce qui doit rester visible en AR doit être descendant d’ici */
96
+ #xr-overlay-root {
97
+ position: fixed;
98
+ inset: 0;
99
+ z-index: 9999; /* au-dessus du canvas XR */
100
+ pointer-events: none; /* les enfants réactivent si besoin */
101
+ }
102
  /* --- UI Slider (DOM overlay) --- */
103
  .ar-ui {
104
+ position: absolute;
105
  right: 12px;
106
  top: 50%;
107
  transform: translateY(-50%);
 
108
  background: rgba(0,0,0,0.55);
109
  color: #fff;
110
  padding: 12px 10px;
111
  border-radius: 12px;
112
  font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
113
+ pointer-events: auto; /* capter les interactions pendant AR */
114
  width: 56px;
115
  display: flex; flex-direction: column; align-items: center; gap: 8px;
116
  box-shadow: 0 6px 18px rgba(0,0,0,.25);
 
121
  text-align: center;
122
  opacity: 0.9;
123
  }
 
124
  .ar-ui input[type="range"].rotY {
125
  -webkit-appearance: none;
126
+ width: 220px; height: 28px;
 
127
  transform: rotate(-90deg);
128
  outline: none;
129
  background: transparent;
130
  touch-action: none;
131
  }
132
  .ar-ui input[type="range"].rotY::-webkit-slider-thumb {
133
+ -webkit-appearance: none; appearance: none;
134
+ width: 20px; height: 20px; border-radius: 50%;
135
+ background: #fff; border: none; box-shadow: 0 2px 8px rgba(0,0,0,.35);
 
 
 
 
136
  }
137
  .ar-ui input[type="range"].rotY::-webkit-slider-runnable-track {
138
+ height: 6px; background: rgba(255,255,255,.6); border-radius: 4px;
 
 
 
 
 
 
139
  }
140
+ .ar-ui .val { font-size: 11px; opacity: 0.85; }
141
  `;
142
  const styleTag = document.createElement("style");
143
  styleTag.textContent = css;
144
  document.head.appendChild(styleTag);
145
 
146
+ // Racine d'overlay (toujours présente)
147
+ function ensureOverlayRoot() {
148
+ let root = document.getElementById("xr-overlay-root");
149
+ if (!root) {
150
+ root = document.createElement("div");
151
+ root.id = "xr-overlay-root";
152
+ document.body.appendChild(root);
153
+ }
154
+ return root;
155
+ }
156
+ const overlayRoot = ensureOverlayRoot();
157
+
158
+ // Message -> dans l'overlay (pour rester visible en AR)
159
  function message(msg) {
160
+ let el = overlayRoot.querySelector(".pc-ar-msg");
161
  if (!el) {
162
  el = document.createElement("div");
163
  el.className = "pc-ar-msg";
164
+ overlayRoot.appendChild(el);
165
  }
166
  el.textContent = msg;
167
  }
 
171
  if (!canvas) {
172
  canvas = document.createElement("canvas");
173
  canvas.id = "application-canvas";
 
174
  canvas.style.width = "100%";
175
  canvas.style.height = "100%";
176
  document.body.appendChild(canvas);
 
178
  return canvas;
179
  }
180
 
181
+ // Crée le panneau slider (DANS la racine overlay)
182
  function ensureSliderUI() {
183
+ let panel = overlayRoot.querySelector(".ar-ui");
184
  if (panel) return panel;
185
  panel = document.createElement("div");
186
  panel.className = "ar-ui";
 
189
  <input class="rotY" id="ar-rotY" type="range" min="0" max="360" step="1" value="0" />
190
  <div class="val" id="ar-rotY-val">0°</div>
191
  `;
192
+ overlayRoot.appendChild(panel);
193
  return panel;
194
  }
195
 
 
204
  message("Impossible de charger PlayCanvas (réseau/CDN). Réessaie plus tard.");
205
  return;
206
  }
 
207
  initARApp();
208
  })();
209
 
 
317
  return;
318
  }
319
 
320
+ // --- Démarrage AR — avec DOM Overlay correctement enregistré ---
321
  const activateAR = () => {
322
  if (!app.xr.isAvailable(pc.XRTYPE_AR)) {
323
  message("AR immersive indisponible sur cet appareil.");
324
  return;
325
  }
326
+
327
+ // 1) Enregistrer la racine DOM overlay AVANT le start
328
+ app.xr.domOverlay.root = document.getElementById("xr-overlay-root");
329
+
330
+ // 2) Démarrer via l’API PlayCanvas, en passant les features (dont dom-overlay)
331
+ app.xr.start(camera, pc.XRTYPE_AR, pc.XRSPACE_LOCALFLOOR, {
332
  requiredFeatures: ["hit-test", "dom-overlay"],
333
  optionalFeatures: ["plane-detection"],
334
+ domOverlay: { root: app.xr.domOverlay.root }
 
 
335
  });
336
  };
337
 
 
465
 
466
  // --- Événements AR globaux ---
467
  app.xr.on("start", () => {
468
+ // overlay présent pendant la session ?
469
+ console.log("[XR] start — domOverlay.supported:", app.xr.domOverlay.supported, "available:", app.xr.domOverlay.available);
470
  message("Session AR démarrée. Visez le sol pour détecter un plan…");
471
  reticle.enabled = true;
472
  });