MikaFil commited on
Commit
66cc1a4
·
verified ·
1 Parent(s): 28e8e3c

Update viewer.js

Browse files
Files changed (1) hide show
  1. viewer.js +45 -18
viewer.js CHANGED
@@ -1,5 +1,4 @@
1
  // viewer.js
2
- // ==============================
3
 
4
  let pc; // will hold the PlayCanvas module once imported
5
  export let app = null;
@@ -13,17 +12,20 @@ let minZoom, maxZoom, minAngle, maxAngle, minAzimuth, maxAzimuth, minPivotY, min
13
  let modelX, modelY, modelZ, modelScale, modelRotationX, modelRotationY, modelRotationZ;
14
  let plyUrl, glbUrl;
15
 
 
 
 
 
 
 
 
 
16
  /**
17
  * initializeViewer(config, instanceId)
18
  */
19
  export async function initializeViewer(config, instanceId) {
20
  if (viewerInitialized) return;
21
 
22
- // Detect iOS and Safari
23
- const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
24
- const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
25
- const isMobile = isIOS || /Android/i.test(navigator.userAgent);
26
-
27
  // 1. Read config
28
  plyUrl = config.ply_url;
29
  glbUrl = config.glb_url;
@@ -51,9 +53,10 @@ export async function initializeViewer(config, instanceId) {
51
  const cameraYPhone = (config.cameraYPhone !== undefined) ? parseFloat(config.cameraYPhone) : cameraY;
52
  const cameraZPhone = (config.cameraZPhone !== undefined) ? parseFloat(config.cameraZPhone) : (cameraZ * 1.5);
53
 
54
- chosenCameraX = isMobile ? cameraXPhone : cameraX;
55
- chosenCameraY = isMobile ? cameraYPhone : cameraY;
56
- chosenCameraZ = isMobile ? cameraZPhone : cameraZ;
 
57
 
58
  // 2. Grab DOM
59
  const canvasId = 'canvas-' + instanceId;
@@ -91,18 +94,21 @@ export async function initializeViewer(config, instanceId) {
91
  if (!pc) {
92
  pc = await import("https://esm.run/playcanvas");
93
  window.pc = pc;
 
94
  }
95
 
96
  try {
97
  // 6. Setup device & app
 
98
  const device = await pc.createGraphicsDevice(canvas, {
99
  deviceTypes: ["webgl2"],
100
  glslangUrl: "https://playcanvas.vercel.app/static/lib/glslang/glslang.js",
101
  twgslUrl: "https://playcanvas.vercel.app/static/lib/twgsl/twgsl.js",
102
  antialias: false,
103
- // ---- CRUCIAL FOR iOS/Safari BLANK SCREEN BUG: ----
104
- preserveDrawingBuffer: isIOS || isSafari ? true : false
105
  });
 
106
  device.maxPixelRatio = Math.min(window.devicePixelRatio, 2);
107
 
108
  const opts = new pc.AppOptions();
@@ -129,6 +135,8 @@ export async function initializeViewer(config, instanceId) {
129
  app.setCanvasFillMode(pc.FILLMODE_NONE);
130
  app.setCanvasResolution(pc.RESOLUTION_AUTO);
131
 
 
 
132
  // Attach ResizeObserver to keep canvas in sync with container size
133
  resizeObserver = new ResizeObserver(entries => {
134
  for (const entry of entries) {
@@ -159,9 +167,12 @@ export async function initializeViewer(config, instanceId) {
159
 
160
  const loader = new pc.AssetListLoader(Object.values(assets), app.assets);
161
  let lastProg = 0;
162
- assets.model.on('load', () => progressDialog.style.display = 'none');
 
 
 
163
  assets.model.on('error', err => {
164
- console.error("Error loading PLY file:", err);
165
  progressDialog.innerHTML = `<p style="color: red">Error loading model: ${err}</p>`;
166
  });
167
 
@@ -177,6 +188,7 @@ export async function initializeViewer(config, instanceId) {
177
  }, 100);
178
 
179
  loader.load(async () => {
 
180
  app.start();
181
  app.scene.envAtlas = assets.hdr.resource;
182
 
@@ -187,6 +199,7 @@ export async function initializeViewer(config, instanceId) {
187
  modelEntity.setLocalEulerAngles(modelRotationX, modelRotationY, modelRotationZ);
188
  modelEntity.setLocalScale(modelScale, modelScale, modelScale);
189
  app.root.addChild(modelEntity);
 
190
 
191
  // Light
192
  const dirLight = new pc.Entity('Cascaded Light');
@@ -210,8 +223,11 @@ export async function initializeViewer(config, instanceId) {
210
  app.root.addChild(dirLight);
211
 
212
  // Gallery GLB
213
- const galleryEntity = assets.galerie.resource.instantiateRenderEntity();
214
- app.root.addChild(galleryEntity);
 
 
 
215
 
216
  // Camera setup
217
  cameraEntity = new pc.Entity('camera');
@@ -240,8 +256,8 @@ export async function initializeViewer(config, instanceId) {
240
  });
241
  cameraEntity.script.create('orbitCameraInputMouse', {
242
  attributes: {
243
- orbitSensitivity: isMobile ? 0.6 : 0.3,
244
- distanceSensitivity: isMobile ? 0.5 : 0.4
245
  }
246
  });
247
  if (cameraEntity.script.orbitCameraInputMouse) {
@@ -254,9 +270,13 @@ export async function initializeViewer(config, instanceId) {
254
  }
255
  });
256
  app.root.addChild(cameraEntity);
 
257
 
258
  // Reset & constrain updates
259
- app.once('update', () => resetViewerCamera());
 
 
 
260
  app.on('update', dt => {
261
  if (cameraEntity) {
262
  const pos = cameraEntity.getPosition();
@@ -264,6 +284,11 @@ export async function initializeViewer(config, instanceId) {
264
  cameraEntity.setPosition(pos.x, minY, pos.z);
265
  }
266
  }
 
 
 
 
 
267
  });
268
 
269
  // Final resize
@@ -286,9 +311,11 @@ export async function initializeViewer(config, instanceId) {
286
 
287
  progressDialog.style.display = 'none';
288
  viewerInitialized = true;
 
289
  });
290
 
291
  } catch (error) {
 
292
  console.error("Error initializing PlayCanvas viewer:", error);
293
  progressDialog.innerHTML = `<p style="color: red">Error loading viewer: ${error.message}</p>`;
294
  }
 
1
  // viewer.js
 
2
 
3
  let pc; // will hold the PlayCanvas module once imported
4
  export let app = null;
 
12
  let modelX, modelY, modelZ, modelScale, modelRotationX, modelRotationY, modelRotationZ;
13
  let plyUrl, glbUrl;
14
 
15
+ // iOS & Safari detection
16
+ function isIOS() {
17
+ return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
18
+ }
19
+ function isSafari() {
20
+ return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
21
+ }
22
+
23
  /**
24
  * initializeViewer(config, instanceId)
25
  */
26
  export async function initializeViewer(config, instanceId) {
27
  if (viewerInitialized) return;
28
 
 
 
 
 
 
29
  // 1. Read config
30
  plyUrl = config.ply_url;
31
  glbUrl = config.glb_url;
 
53
  const cameraYPhone = (config.cameraYPhone !== undefined) ? parseFloat(config.cameraYPhone) : cameraY;
54
  const cameraZPhone = (config.cameraZPhone !== undefined) ? parseFloat(config.cameraZPhone) : (cameraZ * 1.5);
55
 
56
+ const mobile = isIOS() || /Android/i.test(navigator.userAgent);
57
+ chosenCameraX = mobile ? cameraXPhone : cameraX;
58
+ chosenCameraY = mobile ? cameraYPhone : cameraY;
59
+ chosenCameraZ = mobile ? cameraZPhone : cameraZ;
60
 
61
  // 2. Grab DOM
62
  const canvasId = 'canvas-' + instanceId;
 
94
  if (!pc) {
95
  pc = await import("https://esm.run/playcanvas");
96
  window.pc = pc;
97
+ alert('[viewer.js] PlayCanvas module loaded.');
98
  }
99
 
100
  try {
101
  // 6. Setup device & app
102
+ alert('[viewer.js] Creating graphics device...');
103
  const device = await pc.createGraphicsDevice(canvas, {
104
  deviceTypes: ["webgl2"],
105
  glslangUrl: "https://playcanvas.vercel.app/static/lib/glslang/glslang.js",
106
  twgslUrl: "https://playcanvas.vercel.app/static/lib/twgsl/twgsl.js",
107
  antialias: false,
108
+ preserveDrawingBuffer: isIOS() || isSafari() ? true : false,
109
+ alpha: false
110
  });
111
+ alert('[viewer.js] Graphics device created!');
112
  device.maxPixelRatio = Math.min(window.devicePixelRatio, 2);
113
 
114
  const opts = new pc.AppOptions();
 
135
  app.setCanvasFillMode(pc.FILLMODE_NONE);
136
  app.setCanvasResolution(pc.RESOLUTION_AUTO);
137
 
138
+ alert('[viewer.js] PlayCanvas application created!');
139
+
140
  // Attach ResizeObserver to keep canvas in sync with container size
141
  resizeObserver = new ResizeObserver(entries => {
142
  for (const entry of entries) {
 
167
 
168
  const loader = new pc.AssetListLoader(Object.values(assets), app.assets);
169
  let lastProg = 0;
170
+ assets.model.on('load', () => {
171
+ progressDialog.style.display = 'none';
172
+ alert('[viewer.js] PLY/GSplat asset loaded!');
173
+ });
174
  assets.model.on('error', err => {
175
+ alert('[viewer.js] Error loading model: ' + err);
176
  progressDialog.innerHTML = `<p style="color: red">Error loading model: ${err}</p>`;
177
  });
178
 
 
188
  }, 100);
189
 
190
  loader.load(async () => {
191
+ alert('[viewer.js] All assets loaded; starting app.');
192
  app.start();
193
  app.scene.envAtlas = assets.hdr.resource;
194
 
 
199
  modelEntity.setLocalEulerAngles(modelRotationX, modelRotationY, modelRotationZ);
200
  modelEntity.setLocalScale(modelScale, modelScale, modelScale);
201
  app.root.addChild(modelEntity);
202
+ alert('[viewer.js] Model entity added to scene!');
203
 
204
  // Light
205
  const dirLight = new pc.Entity('Cascaded Light');
 
223
  app.root.addChild(dirLight);
224
 
225
  // Gallery GLB
226
+ if (assets.galerie && assets.galerie.resource) {
227
+ const galleryEntity = assets.galerie.resource.instantiateRenderEntity();
228
+ app.root.addChild(galleryEntity);
229
+ alert('[viewer.js] GLB entity added to scene!');
230
+ }
231
 
232
  // Camera setup
233
  cameraEntity = new pc.Entity('camera');
 
256
  });
257
  cameraEntity.script.create('orbitCameraInputMouse', {
258
  attributes: {
259
+ orbitSensitivity: mobile ? 0.6 : 0.3,
260
+ distanceSensitivity: mobile ? 0.5 : 0.4
261
  }
262
  });
263
  if (cameraEntity.script.orbitCameraInputMouse) {
 
270
  }
271
  });
272
  app.root.addChild(cameraEntity);
273
+ alert('[viewer.js] Camera entity added to scene!');
274
 
275
  // Reset & constrain updates
276
+ app.once('update', () => {
277
+ alert('[viewer.js] First app update! Resetting camera.');
278
+ resetViewerCamera();
279
+ });
280
  app.on('update', dt => {
281
  if (cameraEntity) {
282
  const pos = cameraEntity.getPosition();
 
284
  cameraEntity.setPosition(pos.x, minY, pos.z);
285
  }
286
  }
287
+ // Diagnostics: Only show once
288
+ if (!window._pcFirstUpdate) {
289
+ window._pcFirstUpdate = true;
290
+ alert('[viewer.js] Entered update/render loop!');
291
+ }
292
  });
293
 
294
  // Final resize
 
311
 
312
  progressDialog.style.display = 'none';
313
  viewerInitialized = true;
314
+ alert('[viewer.js] Viewer fully initialized and running!');
315
  });
316
 
317
  } catch (error) {
318
+ alert("[viewer.js] Error initializing PlayCanvas viewer: " + error.message);
319
  console.error("Error initializing PlayCanvas viewer:", error);
320
  progressDialog.innerHTML = `<p style="color: red">Error loading viewer: ${error.message}</p>`;
321
  }