Spaces:
Running
Running
Update js_scripts/index.js
Browse files- js_scripts/index.js +67 -26
js_scripts/index.js
CHANGED
|
@@ -177,6 +177,18 @@ const currentScriptTag = document.currentScript;
|
|
| 177 |
const progressDialog = document.getElementById('progress-dialog-' + instanceId);
|
| 178 |
const progressIndicator = document.getElementById('progress-indicator-' + instanceId);
|
| 179 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
// Set help instructions based on device type.
|
| 181 |
if (isMobile) {
|
| 182 |
menuContent.innerHTML = `
|
|
@@ -276,7 +288,7 @@ const currentScriptTag = document.currentScript;
|
|
| 276 |
menuContent.style.display = (menuContent.style.display === 'block') ? 'none' : 'block';
|
| 277 |
});
|
| 278 |
|
| 279 |
-
// --- Camera Reset Function
|
| 280 |
function resetCamera() {
|
| 281 |
if (!cameraEntity || !modelEntity || !app) return;
|
| 282 |
|
|
@@ -288,7 +300,7 @@ const currentScriptTag = document.currentScript;
|
|
| 288 |
// Store model position
|
| 289 |
const modelPos = modelEntity.getPosition();
|
| 290 |
|
| 291 |
-
// 1.
|
| 292 |
const tempEntity = new pc.Entity();
|
| 293 |
tempEntity.setPosition(chosenCameraX, chosenCameraY, chosenCameraZ);
|
| 294 |
tempEntity.lookAt(modelPos);
|
|
@@ -303,36 +315,33 @@ const currentScriptTag = document.currentScript;
|
|
| 303 |
cameraEntity.setPosition(chosenCameraX, chosenCameraY, chosenCameraZ);
|
| 304 |
cameraEntity.lookAt(modelPos);
|
| 305 |
|
| 306 |
-
// 4.
|
| 307 |
orbitCam.pivotPoint = new pc.Vec3(modelPos.x, modelPos.y, modelPos.z);
|
| 308 |
|
| 309 |
-
// 5. Set the distance
|
| 310 |
orbitCam._targetDistance = distance;
|
| 311 |
orbitCam._distance = distance;
|
| 312 |
|
| 313 |
-
// 6.
|
| 314 |
-
// Get the current camera rotation
|
| 315 |
const rotation = tempEntity.getRotation();
|
| 316 |
const tempForward = new pc.Vec3();
|
| 317 |
rotation.transformVector(pc.Vec3.FORWARD, tempForward);
|
| 318 |
|
| 319 |
-
// Calculate yaw from the forward vector
|
| 320 |
const yaw = Math.atan2(-tempForward.x, -tempForward.z) * pc.math.RAD_TO_DEG;
|
| 321 |
|
| 322 |
-
// Calculate pitch
|
| 323 |
const yawQuat = new pc.Quat().setFromEulerAngles(0, -yaw, 0);
|
| 324 |
const rotWithoutYaw = new pc.Quat().mul2(yawQuat, rotation);
|
| 325 |
const forwardWithoutYaw = new pc.Vec3();
|
| 326 |
rotWithoutYaw.transformVector(pc.Vec3.FORWARD, forwardWithoutYaw);
|
| 327 |
const pitch = Math.atan2(forwardWithoutYaw.y, -forwardWithoutYaw.z) * pc.math.RAD_TO_DEG;
|
| 328 |
|
| 329 |
-
// Set yaw and pitch directly on
|
| 330 |
orbitCam._targetYaw = yaw;
|
| 331 |
orbitCam._yaw = yaw;
|
| 332 |
orbitCam._targetPitch = pitch;
|
| 333 |
orbitCam._pitch = pitch;
|
| 334 |
|
| 335 |
-
//
|
| 336 |
if (typeof orbitCam._updatePosition === 'function') {
|
| 337 |
orbitCam._updatePosition();
|
| 338 |
}
|
|
@@ -370,6 +379,27 @@ const currentScriptTag = document.currentScript;
|
|
| 370 |
}
|
| 371 |
});
|
| 372 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 373 |
// --- Initialize the 3D PLY Viewer using PlayCanvas ---
|
| 374 |
async function initializeViewer() {
|
| 375 |
progressDialog.style.display = 'block';
|
|
@@ -430,7 +460,7 @@ const currentScriptTag = document.currentScript;
|
|
| 430 |
// Load required assets
|
| 431 |
const assets = {
|
| 432 |
model: new pc.Asset('gsplat', 'gsplat', { url: plyUrl }),
|
| 433 |
-
orbit: new pc.Asset('script', 'script', { url: `https://bilca-
|
| 434 |
};
|
| 435 |
|
| 436 |
// Create asset loader with progress tracking
|
|
@@ -511,7 +541,32 @@ const currentScriptTag = document.currentScript;
|
|
| 511 |
}
|
| 512 |
});
|
| 513 |
|
| 514 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 515 |
setTimeout(() => {
|
| 516 |
if (cameraEntity.script.orbitCamera) {
|
| 517 |
// Calculate distance from camera to model
|
|
@@ -528,20 +583,6 @@ const currentScriptTag = document.currentScript;
|
|
| 528 |
}
|
| 529 |
}, 100);
|
| 530 |
|
| 531 |
-
// Add input controllers
|
| 532 |
-
cameraEntity.script.create('orbitCameraInputMouse', {
|
| 533 |
-
attributes: {
|
| 534 |
-
orbitSensitivity: isMobile ? 0.6 : 0.3,
|
| 535 |
-
distanceSensitivity: isMobile ? 0.5 : 0.4
|
| 536 |
-
}
|
| 537 |
-
});
|
| 538 |
-
cameraEntity.script.create('orbitCameraInputTouch', {
|
| 539 |
-
attributes: {
|
| 540 |
-
orbitSensitivity: 0.6,
|
| 541 |
-
distanceSensitivity: 0.5
|
| 542 |
-
}
|
| 543 |
-
});
|
| 544 |
-
|
| 545 |
app.root.addChild(cameraEntity);
|
| 546 |
|
| 547 |
// Initial resize to match container
|
|
|
|
| 177 |
const progressDialog = document.getElementById('progress-dialog-' + instanceId);
|
| 178 |
const progressIndicator = document.getElementById('progress-indicator-' + instanceId);
|
| 179 |
|
| 180 |
+
// Flag to track if mouse is over the viewer
|
| 181 |
+
let isMouseOverViewer = false;
|
| 182 |
+
|
| 183 |
+
// Add mouse hover tracking for the viewer container
|
| 184 |
+
viewerContainer.addEventListener('mouseenter', function() {
|
| 185 |
+
isMouseOverViewer = true;
|
| 186 |
+
});
|
| 187 |
+
|
| 188 |
+
viewerContainer.addEventListener('mouseleave', function() {
|
| 189 |
+
isMouseOverViewer = false;
|
| 190 |
+
});
|
| 191 |
+
|
| 192 |
// Set help instructions based on device type.
|
| 193 |
if (isMobile) {
|
| 194 |
menuContent.innerHTML = `
|
|
|
|
| 288 |
menuContent.style.display = (menuContent.style.display === 'block') ? 'none' : 'block';
|
| 289 |
});
|
| 290 |
|
| 291 |
+
// --- Camera Reset Function ---
|
| 292 |
function resetCamera() {
|
| 293 |
if (!cameraEntity || !modelEntity || !app) return;
|
| 294 |
|
|
|
|
| 300 |
// Store model position
|
| 301 |
const modelPos = modelEntity.getPosition();
|
| 302 |
|
| 303 |
+
// 1. Create a temporary entity to help calculate new values
|
| 304 |
const tempEntity = new pc.Entity();
|
| 305 |
tempEntity.setPosition(chosenCameraX, chosenCameraY, chosenCameraZ);
|
| 306 |
tempEntity.lookAt(modelPos);
|
|
|
|
| 315 |
cameraEntity.setPosition(chosenCameraX, chosenCameraY, chosenCameraZ);
|
| 316 |
cameraEntity.lookAt(modelPos);
|
| 317 |
|
| 318 |
+
// 4. Update the orbit camera's pivot point
|
| 319 |
orbitCam.pivotPoint = new pc.Vec3(modelPos.x, modelPos.y, modelPos.z);
|
| 320 |
|
| 321 |
+
// 5. Set the distance
|
| 322 |
orbitCam._targetDistance = distance;
|
| 323 |
orbitCam._distance = distance;
|
| 324 |
|
| 325 |
+
// 6. Calculate and set yaw and pitch from the camera's rotation
|
|
|
|
| 326 |
const rotation = tempEntity.getRotation();
|
| 327 |
const tempForward = new pc.Vec3();
|
| 328 |
rotation.transformVector(pc.Vec3.FORWARD, tempForward);
|
| 329 |
|
|
|
|
| 330 |
const yaw = Math.atan2(-tempForward.x, -tempForward.z) * pc.math.RAD_TO_DEG;
|
| 331 |
|
|
|
|
| 332 |
const yawQuat = new pc.Quat().setFromEulerAngles(0, -yaw, 0);
|
| 333 |
const rotWithoutYaw = new pc.Quat().mul2(yawQuat, rotation);
|
| 334 |
const forwardWithoutYaw = new pc.Vec3();
|
| 335 |
rotWithoutYaw.transformVector(pc.Vec3.FORWARD, forwardWithoutYaw);
|
| 336 |
const pitch = Math.atan2(forwardWithoutYaw.y, -forwardWithoutYaw.z) * pc.math.RAD_TO_DEG;
|
| 337 |
|
| 338 |
+
// Set yaw and pitch directly on internal variables
|
| 339 |
orbitCam._targetYaw = yaw;
|
| 340 |
orbitCam._yaw = yaw;
|
| 341 |
orbitCam._targetPitch = pitch;
|
| 342 |
orbitCam._pitch = pitch;
|
| 343 |
|
| 344 |
+
// Force update
|
| 345 |
if (typeof orbitCam._updatePosition === 'function') {
|
| 346 |
orbitCam._updatePosition();
|
| 347 |
}
|
|
|
|
| 379 |
}
|
| 380 |
});
|
| 381 |
|
| 382 |
+
// --- Handle wheel events at the document level ---
|
| 383 |
+
// This allows normal scrolling when mouse is not over the viewer
|
| 384 |
+
document.addEventListener('wheel', function(event) {
|
| 385 |
+
// Only prevent default if mouse is over viewer
|
| 386 |
+
// This allows normal page scrolling otherwise
|
| 387 |
+
if (isMouseOverViewer && cameraEntity && cameraEntity.script && cameraEntity.script.orbitCameraInputMouse) {
|
| 388 |
+
event.preventDefault();
|
| 389 |
+
|
| 390 |
+
// Manually handle the zoom
|
| 391 |
+
if (cameraEntity.camera.projection === pc.PROJECTION_PERSPECTIVE) {
|
| 392 |
+
const sensitivity = cameraEntity.script.orbitCameraInputMouse.distanceSensitivity || 0.4;
|
| 393 |
+
const distance = cameraEntity.script.orbitCamera.distance;
|
| 394 |
+
cameraEntity.script.orbitCamera.distance -= event.deltaY * 0.01 * sensitivity * (distance * 0.1);
|
| 395 |
+
} else {
|
| 396 |
+
const sensitivity = cameraEntity.script.orbitCameraInputMouse.distanceSensitivity || 0.4;
|
| 397 |
+
const orthoHeight = cameraEntity.script.orbitCamera.orthoHeight;
|
| 398 |
+
cameraEntity.script.orbitCamera.orthoHeight -= event.deltaY * 0.01 * sensitivity * (orthoHeight * 0.1);
|
| 399 |
+
}
|
| 400 |
+
}
|
| 401 |
+
}, { passive: false });
|
| 402 |
+
|
| 403 |
// --- Initialize the 3D PLY Viewer using PlayCanvas ---
|
| 404 |
async function initializeViewer() {
|
| 405 |
progressDialog.style.display = 'block';
|
|
|
|
| 460 |
// Load required assets
|
| 461 |
const assets = {
|
| 462 |
model: new pc.Asset('gsplat', 'gsplat', { url: plyUrl }),
|
| 463 |
+
orbit: new pc.Asset('script', 'script', { url: `https://bilca-visionneur-play-canva-2.static.hf.space/orbit-camera.js` })
|
| 464 |
};
|
| 465 |
|
| 466 |
// Create asset loader with progress tracking
|
|
|
|
| 541 |
}
|
| 542 |
});
|
| 543 |
|
| 544 |
+
// Create input controllers but don't add mouse wheel handling - we handle that at document level
|
| 545 |
+
cameraEntity.script.create('orbitCameraInputMouse', {
|
| 546 |
+
attributes: {
|
| 547 |
+
orbitSensitivity: isMobile ? 0.6 : 0.3,
|
| 548 |
+
distanceSensitivity: isMobile ? 0.5 : 0.4
|
| 549 |
+
}
|
| 550 |
+
});
|
| 551 |
+
|
| 552 |
+
// Disable wheel event in the orbit camera input
|
| 553 |
+
if (cameraEntity.script.orbitCameraInputMouse) {
|
| 554 |
+
// Store the original function
|
| 555 |
+
const originalOnWheel = cameraEntity.script.orbitCameraInputMouse.onMouseWheel;
|
| 556 |
+
|
| 557 |
+
// Replace with empty function - we handle wheel at document level
|
| 558 |
+
cameraEntity.script.orbitCameraInputMouse.onMouseWheel = function() {};
|
| 559 |
+
}
|
| 560 |
+
|
| 561 |
+
// Add touch input controller
|
| 562 |
+
cameraEntity.script.create('orbitCameraInputTouch', {
|
| 563 |
+
attributes: {
|
| 564 |
+
orbitSensitivity: 0.6,
|
| 565 |
+
distanceSensitivity: 0.5
|
| 566 |
+
}
|
| 567 |
+
});
|
| 568 |
+
|
| 569 |
+
// Initialize the orbit controller
|
| 570 |
setTimeout(() => {
|
| 571 |
if (cameraEntity.script.orbitCamera) {
|
| 572 |
// Calculate distance from camera to model
|
|
|
|
| 583 |
}
|
| 584 |
}, 100);
|
| 585 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 586 |
app.root.addChild(cameraEntity);
|
| 587 |
|
| 588 |
// Initial resize to match container
|