Spaces:
Running
Running
Update viewer.js
Browse files
viewer.js
CHANGED
|
@@ -165,7 +165,7 @@ export async function initializeViewer(config, instanceId) {
|
|
| 165 |
hdr: new pc.Asset(
|
| 166 |
'hdr',
|
| 167 |
'texture',
|
| 168 |
-
{ url: https://huggingface.co/datasets/bilca/ply_files/resolve/main/galeries/blanc.png },
|
| 169 |
{ type: pc.TEXTURETYPE_RGBP, mipmaps: false }
|
| 170 |
)
|
| 171 |
};
|
|
@@ -178,7 +178,7 @@ export async function initializeViewer(config, instanceId) {
|
|
| 178 |
});
|
| 179 |
assets.model.on('error', (err) => {
|
| 180 |
console.error("Error loading PLY file:", err);
|
| 181 |
-
progressDialog.innerHTML =
|
| 182 |
});
|
| 183 |
|
| 184 |
const checkProgress = () => {
|
|
@@ -255,59 +255,32 @@ export async function initializeViewer(config, instanceId) {
|
|
| 255 |
|
| 256 |
cameraEntity.addComponent('script');
|
| 257 |
cameraEntity.script.create('orbitCamera', {
|
| 258 |
-
attributes: {
|
| 259 |
-
inertiaFactor: 0.2,
|
| 260 |
-
focusEntity: modelEntity,
|
| 261 |
-
distanceMax: maxZoom,
|
| 262 |
-
distanceMin: minZoom,
|
| 263 |
-
pitchAngleMax: maxAngle,
|
| 264 |
-
pitchAngleMin: minAngle,
|
| 265 |
-
yawAngleMax: maxAzimuth,
|
| 266 |
-
yawAngleMin: minAzimuth,
|
| 267 |
-
minPivotY: minPivotY,
|
| 268 |
-
frameOnStart: false
|
| 269 |
-
}
|
| 270 |
});
|
| 271 |
cameraEntity.script.create('orbitCameraInputMouse', {
|
| 272 |
-
attributes: {
|
| 273 |
-
orbitSensitivity: isMobile ? 0.6 : 0.3,
|
| 274 |
-
distanceSensitivity: isMobile ? 0.5 : 0.4
|
| 275 |
-
}
|
| 276 |
});
|
| 277 |
-
// Disable default onMouseWheel in orbitCameraInputMouse so we handle it ourselves
|
| 278 |
if (cameraEntity.script.orbitCameraInputMouse) {
|
| 279 |
cameraEntity.script.orbitCameraInputMouse.onMouseWheel = function() {};
|
| 280 |
}
|
| 281 |
cameraEntity.script.create('orbitCameraInputTouch', {
|
| 282 |
-
attributes: {
|
| 283 |
-
orbitSensitivity: 0.6,
|
| 284 |
-
distanceSensitivity: 0.5
|
| 285 |
-
}
|
| 286 |
});
|
| 287 |
-
|
| 288 |
app.root.addChild(cameraEntity);
|
| 289 |
|
| 290 |
-
//
|
| 291 |
-
app.once('update',
|
| 292 |
-
// Call existing resetViewerCamera() so that pivot, yaw/pitch, and distance get
|
| 293 |
-
// recalculated correctly before the first render.
|
| 294 |
-
resetViewerCamera();
|
| 295 |
-
});
|
| 296 |
|
| 297 |
-
//
|
| 298 |
-
app.on('update',
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
if (pos.y < minY) {
|
| 302 |
-
cameraEntity.setPosition(pos.x, minY, pos.z);
|
| 303 |
-
}
|
| 304 |
-
}
|
| 305 |
});
|
| 306 |
|
| 307 |
-
//
|
| 308 |
app.resizeCanvas(viewerContainerElem.clientWidth, viewerContainerElem.clientHeight);
|
| 309 |
|
| 310 |
-
//
|
| 311 |
try {
|
| 312 |
const tooltipsModule = await import('./tooltips.js');
|
| 313 |
tooltipsModule.initializeTooltips({
|
|
@@ -316,7 +289,7 @@ export async function initializeViewer(config, instanceId) {
|
|
| 316 |
modelEntity,
|
| 317 |
tooltipsUrl: config.tooltips_url,
|
| 318 |
defaultVisible: !!config.showTooltipsDefault,
|
| 319 |
-
moveDuration: config.tooltipMoveDuration || 0.6
|
| 320 |
});
|
| 321 |
} catch (e) {
|
| 322 |
console.error("Error loading tooltips.js:", e);
|
|
@@ -328,15 +301,14 @@ export async function initializeViewer(config, instanceId) {
|
|
| 328 |
|
| 329 |
} catch (error) {
|
| 330 |
console.error("Error initializing PlayCanvas viewer:", error);
|
| 331 |
-
progressDialog.innerHTML =
|
| 332 |
}
|
| 333 |
-
}
|
| 334 |
|
| 335 |
/**
|
| 336 |
* resetViewerCamera()
|
| 337 |
*
|
| 338 |
* Re‐centers the camera on the model, using the chosenCameraXYZ from config.
|
| 339 |
-
* Exactly the same math as in the old index.js‘s resetCamera().
|
| 340 |
*/
|
| 341 |
export function resetViewerCamera() {
|
| 342 |
try {
|
|
@@ -345,18 +317,15 @@ export function resetViewerCamera() {
|
|
| 345 |
if (!orbitCam) return;
|
| 346 |
|
| 347 |
const modelPos = modelEntity.getPosition();
|
| 348 |
-
// Create a temporary entity at chosenCameraX,Y,Z to compute yaw/pitch
|
| 349 |
const tempEntity = new pc.Entity();
|
| 350 |
tempEntity.setPosition(chosenCameraX, chosenCameraY, chosenCameraZ);
|
| 351 |
tempEntity.lookAt(modelPos);
|
| 352 |
|
| 353 |
-
// Compute distance
|
| 354 |
const distance = new pc.Vec3().sub2(
|
| 355 |
new pc.Vec3(chosenCameraX, chosenCameraY, chosenCameraZ),
|
| 356 |
modelPos
|
| 357 |
).length();
|
| 358 |
|
| 359 |
-
// Reposition camera
|
| 360 |
cameraEntity.setPosition(chosenCameraX, chosenCameraY, chosenCameraZ);
|
| 361 |
cameraEntity.lookAt(modelPos);
|
| 362 |
|
|
@@ -364,7 +333,6 @@ export function resetViewerCamera() {
|
|
| 364 |
orbitCam._targetDistance = distance;
|
| 365 |
orbitCam._distance = distance;
|
| 366 |
|
| 367 |
-
// Compute yaw & pitch from the “tempEntity”
|
| 368 |
const rotation = tempEntity.getRotation();
|
| 369 |
const tempForward = new pc.Vec3();
|
| 370 |
rotation.transformVector(pc.Vec3.FORWARD, tempForward);
|
|
@@ -393,7 +361,7 @@ export function resetViewerCamera() {
|
|
| 393 |
/**
|
| 394 |
* cleanupViewer()
|
| 395 |
*
|
| 396 |
-
* Destroys the PlayCanvas app
|
| 397 |
*/
|
| 398 |
export function cleanupViewer() {
|
| 399 |
if (app) {
|
|
@@ -407,4 +375,4 @@ export function cleanupViewer() {
|
|
| 407 |
cameraEntity = null;
|
| 408 |
modelEntity = null;
|
| 409 |
viewerInitialized = false;
|
| 410 |
-
}
|
|
|
|
| 165 |
hdr: new pc.Asset(
|
| 166 |
'hdr',
|
| 167 |
'texture',
|
| 168 |
+
{ url: `https://huggingface.co/datasets/bilca/ply_files/resolve/main/galeries/blanc.png` },
|
| 169 |
{ type: pc.TEXTURETYPE_RGBP, mipmaps: false }
|
| 170 |
)
|
| 171 |
};
|
|
|
|
| 178 |
});
|
| 179 |
assets.model.on('error', (err) => {
|
| 180 |
console.error("Error loading PLY file:", err);
|
| 181 |
+
progressDialog.innerHTML = `<p style="color: red">Error loading model: ${err}</p>`;
|
| 182 |
});
|
| 183 |
|
| 184 |
const checkProgress = () => {
|
|
|
|
| 255 |
|
| 256 |
cameraEntity.addComponent('script');
|
| 257 |
cameraEntity.script.create('orbitCamera', {
|
| 258 |
+
attributes: { inertiaFactor: 0.2, focusEntity: modelEntity, distanceMax: maxZoom, distanceMin: minZoom, pitchAngleMax: maxAngle, pitchAngleMin: minAngle, yawAngleMax: maxAzimuth, yawAngleMin: minAzimuth, minPivotY, frameOnStart: false }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 259 |
});
|
| 260 |
cameraEntity.script.create('orbitCameraInputMouse', {
|
| 261 |
+
attributes: { orbitSensitivity: isMobile ? 0.6 : 0.3, distanceSensitivity: isMobile ? 0.5 : 0.4 }
|
|
|
|
|
|
|
|
|
|
| 262 |
});
|
|
|
|
| 263 |
if (cameraEntity.script.orbitCameraInputMouse) {
|
| 264 |
cameraEntity.script.orbitCameraInputMouse.onMouseWheel = function() {};
|
| 265 |
}
|
| 266 |
cameraEntity.script.create('orbitCameraInputTouch', {
|
| 267 |
+
attributes: { orbitSensitivity: 0.6, distanceSensitivity: 0.5 }
|
|
|
|
|
|
|
|
|
|
| 268 |
});
|
|
|
|
| 269 |
app.root.addChild(cameraEntity);
|
| 270 |
|
| 271 |
+
// Ensure camera is reset on the first frame
|
| 272 |
+
app.once('update', () => resetViewerCamera());
|
|
|
|
|
|
|
|
|
|
|
|
|
| 273 |
|
| 274 |
+
// Constrain camera’s Y so it never dips below minY
|
| 275 |
+
app.on('update', dt => {
|
| 276 |
+
const pos = cameraEntity.getPosition();
|
| 277 |
+
if (pos.y < minY) cameraEntity.setPosition(pos.x, minY, pos.z);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 278 |
});
|
| 279 |
|
| 280 |
+
// Final resize
|
| 281 |
app.resizeCanvas(viewerContainerElem.clientWidth, viewerContainerElem.clientHeight);
|
| 282 |
|
| 283 |
+
// Initialize tooltips
|
| 284 |
try {
|
| 285 |
const tooltipsModule = await import('./tooltips.js');
|
| 286 |
tooltipsModule.initializeTooltips({
|
|
|
|
| 289 |
modelEntity,
|
| 290 |
tooltipsUrl: config.tooltips_url,
|
| 291 |
defaultVisible: !!config.showTooltipsDefault,
|
| 292 |
+
moveDuration: config.tooltipMoveDuration || 0.6
|
| 293 |
});
|
| 294 |
} catch (e) {
|
| 295 |
console.error("Error loading tooltips.js:", e);
|
|
|
|
| 301 |
|
| 302 |
} catch (error) {
|
| 303 |
console.error("Error initializing PlayCanvas viewer:", error);
|
| 304 |
+
progressDialog.innerHTML = `<p style="color: red">Error loading viewer: ${error.message}</p>`;
|
| 305 |
}
|
| 306 |
+
} // ← Added this closing brace to balance initializeViewer
|
| 307 |
|
| 308 |
/**
|
| 309 |
* resetViewerCamera()
|
| 310 |
*
|
| 311 |
* Re‐centers the camera on the model, using the chosenCameraXYZ from config.
|
|
|
|
| 312 |
*/
|
| 313 |
export function resetViewerCamera() {
|
| 314 |
try {
|
|
|
|
| 317 |
if (!orbitCam) return;
|
| 318 |
|
| 319 |
const modelPos = modelEntity.getPosition();
|
|
|
|
| 320 |
const tempEntity = new pc.Entity();
|
| 321 |
tempEntity.setPosition(chosenCameraX, chosenCameraY, chosenCameraZ);
|
| 322 |
tempEntity.lookAt(modelPos);
|
| 323 |
|
|
|
|
| 324 |
const distance = new pc.Vec3().sub2(
|
| 325 |
new pc.Vec3(chosenCameraX, chosenCameraY, chosenCameraZ),
|
| 326 |
modelPos
|
| 327 |
).length();
|
| 328 |
|
|
|
|
| 329 |
cameraEntity.setPosition(chosenCameraX, chosenCameraY, chosenCameraZ);
|
| 330 |
cameraEntity.lookAt(modelPos);
|
| 331 |
|
|
|
|
| 333 |
orbitCam._targetDistance = distance;
|
| 334 |
orbitCam._distance = distance;
|
| 335 |
|
|
|
|
| 336 |
const rotation = tempEntity.getRotation();
|
| 337 |
const tempForward = new pc.Vec3();
|
| 338 |
rotation.transformVector(pc.Vec3.FORWARD, tempForward);
|
|
|
|
| 361 |
/**
|
| 362 |
* cleanupViewer()
|
| 363 |
*
|
| 364 |
+
* Destroys the PlayCanvas `app` and clears references.
|
| 365 |
*/
|
| 366 |
export function cleanupViewer() {
|
| 367 |
if (app) {
|
|
|
|
| 375 |
cameraEntity = null;
|
| 376 |
modelEntity = null;
|
| 377 |
viewerInitialized = false;
|
| 378 |
+
}
|