Are camera controls determined by the size of the object's bounding box?

I am facing a challenge with the normal orbit controls from three.js when it comes to long objects, especially at close zoom levels. I am in search of a solution to address this issue.

It's difficult to explain in words, so please take a look at this webgl example from Google (zoom in all the way to see): https://www.google.com/o3d/shopping/viewer/360?q=ymMBhK8fu3C&o3ds=use_3d https://i.sstatic.net/5GgeK.gif

Here is a top view illustration of what I am aiming for: https://i.sstatic.net/5GgeK.gif

I have been considering modifying the default OrbitControls by continuously casting a ray from the camera to the bounding box and maintaining a constant distance. However, the issue is that the camera always focuses on the center of the object, unlike in the example above (where the camera only rotates when it reaches the corners of the object).

I would greatly appreciate any ideas or suggestions to tackle this challenge.

Answer №1

I've explored various approaches to address the issue you raised about using the existing THREE.OrbitControls and adjusting the target without achieving the desired results. Regardless, I've made some progress on this matter.

Throughout my experimentation, I consistently found that I needed to calculate (in any sequence) :

  1. the position of the camera ;
  2. the direction of the camera.

Essentially, the camera must rotate around a point. As such, my solutions are mostly based on leveraging THREE.OrbitControls to manage the rotation state and handle DOM event interactions.


Approach: Focusing on the Closest Point on the AABB

The concept I worked on involves:

  • Rotating the camera ;
  • Determining the closest point on the AABB from the camera as the target direction ;
  • Applying a set distance d to displace the camera from this point as its new position.

There are two scenarios to consider:

  1. The border
    https://i.sstatic.net/qdFRl.png

  2. The corner
    https://i.sstatic.net/FtZ7T.png

Tested on this (challenging) fiddle. However, adjustments are needed for the top and bottom faces due to rotation singularities.


Method: Raycasting on a Bounding Volume

This aligns with the concept you outlined:

  • Defining a bounding volume for the camera to follow ;
  • Performing raycasting from the camera position on this BV ;
  • Using the intersection point as the camera's new position ;
  • Setting the camera's new direction as the normal of the intersected face.

I experimented with a box geometry with rounded edges and corners to enable varied camera rotations.

https://i.sstatic.net/PFflV.png

While the surface smoothness promised convenience, the abrupt changes in camera direction upon normal alterations resulted in jarring motions.

View this (challenging again) fiddle.

To mitigate this, linearly interpolating the normal along the triangle could help, necessitating the calculation of vertex normals from face normals.

https://i.sstatic.net/PFflV.png

Note that this solution is resource-intensive (raycasting numerous faces) and might require preprocessing to establish the BV.


Strategy: Adapting the Basis of Classic Orbit Controls

While not precisely aligned with your requirements, this approach suits elongated objects and is relatively straightforward compared to other solutions I explored.

The notion involves adjusting the basis for conventional THREE.OrbitControls operations so that the position changes while retaining the direction, as depicted below:

https://i.sstatic.net/kXK7o.png

I partially implemented this concept with a custom version: THREE.BasisOrbitControls. Refer to this fiddle.

var basis = new THREE.Matrix4();
basis.makeScale(2.0, 3.0, 4.0); // My object is elongated and somewhat tall

var controls = new THREE.BasisOrbitControl(camera, basis, renderer.domElement);

It's worth noting that the resulting camera movement follows an ellipsoid path.


I hope this information proves helpful, and I too am keen on discovering a more streamlined solution.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Comparing two Objects in JavaScript results in automatic updates for the second Object when changes are made to the first

Can someone please assist me with a hash map issue I'm encountering in my for loop? When resetting the second object, it unintentionally alters the Map values of the previous Key in the Hash Map. Any guidance on how to prevent this behavior would be g ...

Is there a way to determine if a user has the ability to navigate forward in Next.js?

I am faced with a challenge of determining whether a user can navigate forward on a webpage. My goal is to have two buttons - one to go back and another to go forward, with the forward button disabled when navigation is not possible. For the back button f ...

What is the best way to align an avatar within a cardHeader component in the center?

Recently, I've been working on a frontend project using Material UI. In my design, I have cards that display data, and I wanted to include an avatar in the center of each card. Despite using a card header to insert the avatar, I struggled to align it ...

Effective strategies for integrating Bootstrap and AngularJS without relying on jQuery

Currently exploring AngularJS after experimenting with Twitter's Bootstrap. I appreciate Bootstrap for its simplicity, sleek design, and mobile-friendliness. On the other hand, I have noticed a trend where people recommend using AngularJS over jQuery, ...

Every time I attempt to destructure the state object in react typescript, I encounter the error message stating 'Object is possibly undefined'

Whenever I attempt to destructure my state object in react typescript, I encounter an error stating Object is possibly 'undefined'. When I try using optional chaining, a different error pops up saying const newUser: NewUser | undefined Argument o ...

Eliminate the alert message that appears when dynamically rendering a React styled component

When checking the browser console, I noticed a warning that reads as follows: react_devtools_backend.js:3973 The component styled.div with the id of "sc-dmRaPn" has been created dynamically. You may see this warning because you've called sty ...

Create a custom slider using jQuery that pulls in real-time data for a dynamic user

My goal is to implement a dynamic slider feature in my Django project by using jQuery and ajax. I have managed to create previous and next buttons for swiping through profiles with the help of others, but I am currently facing an issue with a NoReverseMatc ...

Having difficulty executing the npm test command for my Angular 2 application

I am currently working on an Angular 2 application, and I am fairly new to it. I have set it up with Cordova app and run it through npm. The app starts without any errors and runs smoothly. However, when I try to run the tests using node (i.e., npm test), ...

modify the color of a particular div element in real-time

I am looking to dynamically change the color of the divs based on values from my database. Here is what I have so far: Database: shape id is_success id1 0 id2 1 id3 0 id4 1 <div class="container" style="background: black; widt ...

Does the useState hook operate synchronously?

Previously, there has been a clear warning about the asynchronous nature of calling setState({myProperty}), where the value of this.state.myProperty is only valid after the callback or the next render() method. When using useState, how can I retrieve the ...

In JavaScript, when a condition is met, two strings are produced but only the last string is printed

My for loop with nested arrays is working fine, but it should display two strings and only shows the last one. for (i = 0; i < $scope.taskGroups.length; i++) { for (j = 0; j < $scope.taskGroups[i].tasks.length; j++) { ...

Utilizing Zoomdata data in conjunction with echarts index.js to create a dynamic stacked line chart

I am currently working on integrating Zoomdata with an echarts javascript chart to visualize data from 20 different computers in a stacked line chart format. While I can manually code this setup, I am looking for a way to dynamically link the data from Zoo ...

A Guide To Adding up Values and Assigning Them to Corresponding Objects in Vue

Currently, I'm in the process of creating a computed property that will generate a fresh Array of Objects The challenge I am facing is figuring out how to sum up the number of values that match a specific value and then insert that value into the cor ...

Unable to perform filtering on a nested array object within a computed property using Vue while displaying data in a table

Lately, I've been experimenting with different methods to filter data in my project. I've tried using various approaches like methods and watchers, but haven't quite achieved the desired outcome yet. Essentially, what I'm aiming for is ...

Tips for incorporating jQuery val() into a span element!

I am currently working on a plugin that involves interacting with select elements grouped within a span. I want to enhance the functionality of my plugin by adding support for the val() function, which will allow users to easily get or set the 'value& ...

js - stop form submission

After clicking on a button with type="submit", the front-end validation starts, but I also need to perform server-side validation using Ajax. This includes checking if the name is already being used by another person. The issue arises when switching the b ...

Exploring the possibilities of integrating JavaScript with Flash technology

Currently, there is a simple Flash project in development that connects to an RTMP server and streams video and audio from a webcam. The project allows users to create a stream with a specific name. This project also features an input for entering a strea ...

Instructions on converting XML data obtained from an AJAX call into a downloadable file

I've been struggling with converting an AJAX response containing XML text into a downloadable file. I've tried various methods but haven't had success. In the past, I was able to work with a similar scenario involving a pdf, where the conte ...

What is the best way to create this server backend route?

I'm currently working on a fullstack project that requires a specific sequence of events to take place: When a user submits an event: A request is sent to the backend server The server then initiates a function for processing This function should ru ...

Issues with flat shading in CanvasRenderer on Three.js - any solutions?

Does anyone know of a comparison page that explains the differences and limitations of using CanvasRenderer (three.js) as a fallback for devices that do not support WebGL? I am encountering two main issues: I am having trouble with flat shading and mis ...