Handling Different Model Orientations in Three.js Panoramic Viewer
The issue you're experiencing with Z-UP models versus Y-UP models is related to how coordinate systems and camera orientations interact in Three.js. When switching between models with different "up" directions, you need to account for these differences in your camera and controls setup.
Understanding the Problem
In Three.js, the default coordinate system is Y-UP (where Y axis points upward). When working with Z-UP models (where Z axis points upward), the camera's orientation and the orbit controls need to be adjusted accordingly.
Solution Approach
To create a generalized solution that works with both Y-UP and Z-UP models (or any orientation), you can:
- Detect or specify the model's up vector
- Adjust the camera and orbit controls based on this up vector
- Ensure the lookAt point is calculated correctly for the panoramic view
Here's a modified version of your switchToSphericalView
function that should work with different model orientations:
function switchToSphericalView(upVector = new THREE.Vector3(0, 1, 0)) {
// Get the current camera direction
const direction = new THREE.Vector3();
camera.getWorldDirection(direction);
// Create a right vector perpendicular to the up vector and direction
const right = new THREE.Vector3().crossVectors(direction, upVector).normalize();
// Recalculate a corrected direction that's perpendicular to both up and right
const correctedDirection = new THREE.Vector3().crossVectors(upVector, right).normalize();
// Calculate the look-at point using the corrected direction
const lookAtPoint = camera.position.clone().add(correctedDirection);
// Configure the orbit controls
controls.enableZoom = false;
controls.enablePan = false;
// Set the up vector for the controls
controls.up.copy(upVector);
// Set the target for orbit controls
controls.target.copy(lookAtPoint);
controls.update();
}
Usage
For a Y-UP model:
// Default Y-UP
switchToSphericalView();
For a Z-UP model:
// Z-UP model
switchToSphericalView(new THREE.Vector3(0, 0, 1));
Additional Considerations
-
You might need to adjust the camera's up vector as well:
camera.up.copy(upVector);
-
When initializing your OrbitControls, make sure to set the up vector:
controls = new OrbitControls(camera, renderer.domElement);
controls.up.copy(upVector); // Set this based on your model's orientation
-
You may need to adjust the initial camera position and rotation based on the model's orientation to ensure the panoramic view starts from a sensible direction.
This approach should provide a more generalized solution that works with models of different orientations by explicitly accounting for the up vector in your calculations.