MikaFil commited on
Commit
200e870
·
verified ·
1 Parent(s): fbbcde2

Update viewer.js

Browse files
Files changed (1) hide show
  1. viewer.js +66 -127
viewer.js CHANGED
@@ -23,19 +23,12 @@ function hexToRgbaArray(hex) {
23
  (num & 0xFF) / 255
24
  ];
25
  } catch (e) {
26
- alert("hexToRgbaArray error: " + e);
27
  return [1, 1, 1, 1];
28
  }
29
  }
30
 
31
  export async function initializeViewer(config, instanceId) {
32
- alert("initializeViewer: start");
33
-
34
- if (viewerInitialized) {
35
- alert("Already initialized!");
36
- return;
37
- }
38
-
39
  const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
40
  const isMobile = isIOS || /Android/i.test(navigator.userAgent);
41
 
@@ -106,12 +99,10 @@ export async function initializeViewer(config, instanceId) {
106
 
107
  if (progressDialog) progressDialog.style.display = 'block';
108
 
109
- alert("Canvas created. Loading PlayCanvas...");
110
 
111
  if (!pc) {
112
  pc = await import("https://cdn.jsdelivr.net/npm/playcanvas@latest/+esm");
113
  window.pc = pc;
114
- alert("PlayCanvas imported.");
115
  }
116
 
117
  // Create app and graphics device
@@ -124,9 +115,7 @@ export async function initializeViewer(config, instanceId) {
124
  antialias: false
125
  });
126
  device.maxPixelRatio = Math.min(window.devicePixelRatio, 2);
127
- alert("Graphics device created.");
128
  } catch (e) {
129
- alert("Graphics device error: " + e);
130
  throw e;
131
  }
132
 
@@ -154,14 +143,15 @@ export async function initializeViewer(config, instanceId) {
154
  app.setCanvasFillMode(pc.FILLMODE_NONE);
155
  app.setCanvasResolution(pc.RESOLUTION_AUTO);
156
 
157
- alert("App created.");
158
 
159
  // Resizing
160
  resizeObserver = new ResizeObserver(entries => {
161
  entries.forEach(entry => {
162
  try {
163
  app.resizeCanvas(entry.contentRect.width, entry.contentRect.height);
164
- } catch (e) { alert("resizeCanvas error: " + e); }
 
 
165
  });
166
  });
167
  resizeObserver.observe(viewerContainer);
@@ -169,7 +159,9 @@ export async function initializeViewer(config, instanceId) {
169
  window.addEventListener('resize', () => {
170
  try {
171
  app.resizeCanvas(viewerContainer.clientWidth, viewerContainer.clientHeight);
172
- } catch (e) { alert("resizeCanvas error: " + e); }
 
 
173
  });
174
  app.on('destroy', () => resizeObserver.disconnect());
175
 
@@ -181,142 +173,93 @@ export async function initializeViewer(config, instanceId) {
181
  };
182
  for (const key in assets) app.assets.add(assets[key]);
183
 
184
- // Individual asset error listeners
185
- assets.sogs.on('error', (err) => { alert("SOGS asset error: " + err); });
186
- assets.orbit.on('error', (err) => { alert("Orbit-camera.js asset error: " + err); });
187
- if (assets.glb) assets.glb.on('error', (err) => { alert("GLB asset error: " + err); });
188
-
189
- assets.sogs.ready(() => { alert("SOGS asset ready."); });
190
- assets.orbit.ready(() => { alert("orbit-camera.js asset ready."); });
191
- if (assets.glb) assets.glb.ready(() => { alert("GLB asset ready."); });
192
 
193
  const loader = new pc.AssetListLoader(Object.values(assets), app.assets);
194
 
195
- loader.on('error', (err) => { alert("Asset loader error: " + err); });
196
-
197
  loader.load(() => {
198
- alert("All assets loaded. Starting app...");
199
 
200
- try {
201
- app.start();
202
- } catch (e) {
203
- alert("app.start() error: " + e);
204
- throw e;
205
- }
206
 
207
  if (progressDialog) progressDialog.style.display = 'none';
208
 
209
  // Add SOGS model
210
- try {
211
- modelEntity = new pc.Entity('model');
212
- modelEntity.addComponent('gsplat', { asset: assets.sogs });
213
- modelEntity.setLocalPosition(modelX, modelY, modelZ);
214
- modelEntity.setLocalEulerAngles(modelRotationX, modelRotationY, modelRotationZ);
215
- modelEntity.setLocalScale(modelScale, modelScale, modelScale);
216
- app.root.addChild(modelEntity);
217
- alert("Model entity added!");
218
- } catch (e) {
219
- alert("Model entity error: " + e);
220
- throw e;
221
- }
222
 
223
  // Add the GLB entity if provided
224
- try {
225
- if (assets.glb && assets.glb.resource && assets.glb.resource.instantiateRenderEntity) {
226
- const glbEntity = assets.glb.resource.instantiateRenderEntity();
227
- app.root.addChild(glbEntity);
228
- alert("GLB entity added.");
229
- }
230
- } catch (e) {
231
- alert("GLB entity error: " + e);
232
  }
233
 
 
234
  // CAMERA
235
- try {
236
- cameraEntity = new pc.Entity('camera');
237
- // Support background color
238
- let bg = [1, 1, 1, 1];
239
- if (canvasBg && /^#?[0-9a-f]{6,8}$/i.test(canvasBg.replace("#", ""))) {
240
- bg = hexToRgbaArray(canvasBg);
241
- }
242
- cameraEntity.addComponent('camera', { clearColor: new pc.Color(bg[0], bg[1], bg[2], bg[3]) });
243
- cameraEntity.setPosition(chosenCameraX, chosenCameraY, chosenCameraZ);
244
- cameraEntity.lookAt(modelEntity.getPosition());
245
- cameraEntity.addComponent('script');
246
-
247
- // Pass all attributes to Orbit Camera script
248
- cameraEntity.script.create('orbitCamera', {
249
- attributes: {
250
- focusEntity: modelEntity,
251
- inertiaFactor: 0.2,
252
- distanceMax: maxZoom,
253
- distanceMin: minZoom,
254
- pitchAngleMax: maxAngle,
255
- pitchAngleMin: minAngle,
256
- yawAngleMax: maxAzimuth,
257
- yawAngleMin: minAzimuth,
258
- minY: minY,
259
- frameOnStart: false
260
- }
261
- });
262
- cameraEntity.script.create('orbitCameraInputMouse');
263
- cameraEntity.script.create('orbitCameraInputTouch');
264
- app.root.addChild(cameraEntity);
265
-
266
- alert("Camera added.");
267
- } catch (e) {
268
- alert("Camera error: " + e);
269
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
 
271
- try {
272
- app.resizeCanvas(viewerContainer.clientWidth, viewerContainer.clientHeight);
273
- alert("resizeCanvas called.");
274
- } catch (e) {
275
- alert("resizeCanvas error: " + e);
276
- }
277
 
278
- try {
279
- app.once('update', () => resetViewerCamera());
280
- alert("resetViewerCamera scheduled.");
281
- } catch (e) {
282
- alert("resetViewerCamera schedule error: " + e);
283
- }
284
 
285
  // Tooltips support (optional)
286
- try {
287
- if (config.tooltips_url) {
288
- import('https://mikafil-viewer-sgos.static.hf.space/tooltips.js').then(tooltipsModule => {
289
- tooltipsModule.initializeTooltips({
290
- app,
291
- cameraEntity,
292
- modelEntity,
293
- tooltipsUrl: config.tooltips_url,
294
- defaultVisible: !!config.showTooltipsDefault,
295
- moveDuration: config.tooltipMoveDuration || 0.6
296
- });
297
- alert("Tooltips loaded.");
298
- }).catch(e => { alert("Tooltips module error: " + e); });
299
- }
300
- } catch (e) {
301
- alert("Tooltips try-catch error: " + e);
302
  }
303
 
 
304
  viewerInitialized = true;
305
  alert("Viewer initialized success!");
306
  });
307
-
308
- alert("Asset loader started.");
309
- } catch (e) {
310
- alert("Main try-catch error: " + e);
311
- throw e;
312
- }
313
  }
314
 
315
  // Resets the viewer camera (as in your PLY example)
316
  export function resetViewerCamera() {
317
- alert("resetViewerCamera called.");
318
- try {
319
- if (!cameraEntity || !modelEntity || !app) {
320
  alert("resetViewerCamera: cameraEntity/modelEntity/app not ready");
321
  return;
322
  }
@@ -361,8 +304,4 @@ export function resetViewerCamera() {
361
  if (orbitCam._updatePosition) orbitCam._updatePosition();
362
 
363
  tempEnt.destroy();
364
- alert("resetViewerCamera: success");
365
- } catch (e) {
366
- alert("resetViewerCamera: error: " + e);
367
- }
368
  }
 
23
  (num & 0xFF) / 255
24
  ];
25
  } catch (e) {
 
26
  return [1, 1, 1, 1];
27
  }
28
  }
29
 
30
  export async function initializeViewer(config, instanceId) {
31
+
 
 
 
 
 
 
32
  const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
33
  const isMobile = isIOS || /Android/i.test(navigator.userAgent);
34
 
 
99
 
100
  if (progressDialog) progressDialog.style.display = 'block';
101
 
 
102
 
103
  if (!pc) {
104
  pc = await import("https://cdn.jsdelivr.net/npm/playcanvas@latest/+esm");
105
  window.pc = pc;
 
106
  }
107
 
108
  // Create app and graphics device
 
115
  antialias: false
116
  });
117
  device.maxPixelRatio = Math.min(window.devicePixelRatio, 2);
 
118
  } catch (e) {
 
119
  throw e;
120
  }
121
 
 
143
  app.setCanvasFillMode(pc.FILLMODE_NONE);
144
  app.setCanvasResolution(pc.RESOLUTION_AUTO);
145
 
 
146
 
147
  // Resizing
148
  resizeObserver = new ResizeObserver(entries => {
149
  entries.forEach(entry => {
150
  try {
151
  app.resizeCanvas(entry.contentRect.width, entry.contentRect.height);
152
+ } catch (e) {
153
+
154
+ }
155
  });
156
  });
157
  resizeObserver.observe(viewerContainer);
 
159
  window.addEventListener('resize', () => {
160
  try {
161
  app.resizeCanvas(viewerContainer.clientWidth, viewerContainer.clientHeight);
162
+ } catch (e) {
163
+
164
+ }
165
  });
166
  app.on('destroy', () => resizeObserver.disconnect());
167
 
 
173
  };
174
  for (const key in assets) app.assets.add(assets[key]);
175
 
 
 
 
 
 
 
 
 
176
 
177
  const loader = new pc.AssetListLoader(Object.values(assets), app.assets);
178
 
 
 
179
  loader.load(() => {
 
180
 
181
+ app.start();
182
+
 
 
 
 
183
 
184
  if (progressDialog) progressDialog.style.display = 'none';
185
 
186
  // Add SOGS model
187
+ modelEntity = new pc.Entity('model');
188
+ modelEntity.addComponent('gsplat', { asset: assets.sogs });
189
+ modelEntity.setLocalPosition(modelX, modelY, modelZ);
190
+ modelEntity.setLocalEulerAngles(modelRotationX, modelRotationY, modelRotationZ);
191
+ modelEntity.setLocalScale(modelScale, modelScale, modelScale);
192
+ app.root.addChild(modelEntity);
193
+
 
 
 
 
 
194
 
195
  // Add the GLB entity if provided
196
+ if (assets.glb && assets.glb.resource && assets.glb.resource.instantiateRenderEntity) {
197
+ const glbEntity = assets.glb.resource.instantiateRenderEntity();
198
+ app.root.addChild(glbEntity);
 
 
 
 
 
199
  }
200
 
201
+
202
  // CAMERA
203
+ cameraEntity = new pc.Entity('camera');
204
+ // Support background color
205
+ let bg = [1, 1, 1, 1];
206
+ if (canvasBg && /^#?[0-9a-f]{6,8}$/i.test(canvasBg.replace("#", ""))) {
207
+ bg = hexToRgbaArray(canvasBg);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  }
209
+ cameraEntity.addComponent('camera', { clearColor: new pc.Color(bg[0], bg[1], bg[2], bg[3]) });
210
+ cameraEntity.setPosition(chosenCameraX, chosenCameraY, chosenCameraZ);
211
+ cameraEntity.lookAt(modelEntity.getPosition());
212
+ cameraEntity.addComponent('script');
213
+
214
+ // Pass all attributes to Orbit Camera script
215
+ cameraEntity.script.create('orbitCamera', {
216
+ attributes: {
217
+ focusEntity: modelEntity,
218
+ inertiaFactor: 0.2,
219
+ distanceMax: maxZoom,
220
+ distanceMin: minZoom,
221
+ pitchAngleMax: maxAngle,
222
+ pitchAngleMin: minAngle,
223
+ yawAngleMax: maxAzimuth,
224
+ yawAngleMin: minAzimuth,
225
+ minY: minY,
226
+ frameOnStart: false
227
+ }
228
+ });
229
+ cameraEntity.script.create('orbitCameraInputMouse');
230
+ cameraEntity.script.create('orbitCameraInputTouch');
231
+ app.root.addChild(cameraEntity);
232
+
233
+ app.resizeCanvas(viewerContainer.clientWidth, viewerContainer.clientHeight);
234
+
235
+ app.once('update', () => resetViewerCamera());
236
 
 
 
 
 
 
 
237
 
 
 
 
 
 
 
238
 
239
  // Tooltips support (optional)
240
+ if (config.tooltips_url) {
241
+ import('https://mikafil-viewer-sgos.static.hf.space/tooltips.js').then(tooltipsModule => {
242
+ tooltipsModule.initializeTooltips({
243
+ app,
244
+ cameraEntity,
245
+ modelEntity,
246
+ tooltipsUrl: config.tooltips_url,
247
+ defaultVisible: !!config.showTooltipsDefault,
248
+ moveDuration: config.tooltipMoveDuration || 0.6
249
+ });
250
+ alert("Tooltips loaded.");
251
+ }).catch(e => { alert("Tooltips module error: " + e); });
 
 
 
 
252
  }
253
 
254
+
255
  viewerInitialized = true;
256
  alert("Viewer initialized success!");
257
  });
 
 
 
 
 
 
258
  }
259
 
260
  // Resets the viewer camera (as in your PLY example)
261
  export function resetViewerCamera() {
262
+ if (!cameraEntity || !modelEntity || !app) {
 
 
263
  alert("resetViewerCamera: cameraEntity/modelEntity/app not ready");
264
  return;
265
  }
 
304
  if (orbitCam._updatePosition) orbitCam._updatePosition();
305
 
306
  tempEnt.destroy();
 
 
 
 
307
  }