Tips for rotating a THREE.PerspectiveCamera around an object

I'm currently working on a program that allows users to click on an object, zoom in on it, and then view it from all angles by holding the right mouse button and dragging. I want the camera to orbit around the object instead of rotating the object itself while the camera stays fixed. Unfortunately, I'm struggling with the math involved!

During testing, we already have a game object with specific xyz coordinates that we've chosen to focus on.

var g = new GameObject(500, 0, 0);//The game object with xyz
this.selected = g;//set selected to g

//Create and set the camera
this.camera = new THREE.PerspectiveCamera(45, w/h, 1, 10000);
this.camera.position.x = 0;
this.camera.position.y = 0;
this.camera.position.z = 0;

//set camera to look at the object which is 500 away in the x direction
this.camera.lookAt(new THREE.Vector3(this.selected.x, this.selected.y, this.selected.z));

The distance between the camera and the object is 500 units, and as the user rotates the camera should always maintain this distance.

I'm handling scene updates here:

Main.prototype.update = function(){

    this.renderer.render(this.scene, this.camera);//scene is just some ambient lighting

    //what to do when mouse right is held down
    if(this.rightMouseDown){

        //placeholder functionality, needs to rotate around object based on mouse movements
        this.camera.position.x -= 5;

    }
}

How can I make the camera rotate around 'g' with a radius of 500? Help would be greatly appreciated!

Answer №1

As mentioned by gaitat, starting with trackball controls is the ideal way to begin due to its numerous customizable features that simplify camera rotation and revolution. One major advantage of using this method (particularly for your specific project) is the avoidance of "gimbal lock," a common frustration when dealing with rotations. For more information on Trackball controls and Orbitcontrols, you can refer to the following link:

Rotate camera in Three.js with mouse

Alternatively, another approach would be manually setting the camera coordinates within the animation loop, which is relatively straightforward:

var angle = 0;
var radius = 500; 

function animate() {
...
// Use Math.cos and Math.sin to determine camera X and Z values based on the angle. 
camera.position.x = radius * Math.cos( angle );  
camera.position.z = radius * Math.sin( angle );
angle += 0.01;
...
}

Another option involves connecting the camera to a pivot object and rotating the pivot instead:

var camera_pivot = new THREE.Object3D()
var Y_AXIS = new THREE.Vector3( 0, 1, 0 );

scene.add( camera_pivot );
camera_pivot.add( camera );
camera.position.set( 500, 0, 0 );
camera.lookAt( camera_pivot.position );
...
camera_pivot.rotateOnAxis( Y_AXIS, 0.01 );    // in radians

If you decide to go with this method, keep in mind that the camera object exists in "camera pivot space," which may present challenges for further manipulation.

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

An issue has been identified where the Export to Excel and PDF functionality is not functioning properly within a Datatable after applying a

I am using multiple select option filtering with ajax, jQuery, and PHP in a datatable. The records are being filtered correctly, but after changing the select option, the Export to Excel/ PDF functionality is not working properly. Note:- (1) It always do ...

Guide to creating a Javascript API wrapper

I'm currently working on a React client and I have a question regarding the implementation of a JavaScript wrapper. The APIs I am using return more data than is necessary for the client, so I want to create an index.js file where I can call the API, r ...

Guide on creating CSS for webkit scrollbar through the use of Javascript

I have a div named 'dynamic' with text inside, and I am applying styling to it using javascript. var styleElement = document.createElement("style"); styleElement.appendChild(document.createTextNode("#dynamic { color: red; }")); document.getEleme ...

Is it possible for me to utilize window.top within the .js file?

Within my GWT code, I am transferring a variable to a JSP file. The process looks like this: <html> <head> <script type="text/javascript"> alert("Inside the JSP file"); var criticalPath = window.top.criticalPath; ...

Discovering an Element in jQuery through its ID using Spaces and Variables

My issue involves locating an element within another element using an ID and then adding a class when the ID is hardcoded. For example: var tableId = el.id; $('#' + tableId).find("[id='Checkout On']").addClass('highlight'); ...

PHP file not receiving data when using JavaScript Ajax with a 'post' request and URL

Could you assist me with a problem I am facing? I need help passing variable length HTML or any data to a PHP file via POST using JavaScript AJAX. I want to utilize vanilla JavaScript for my project as I want to gain more experience with it. While jQuery ...

Axios continues to encounter the issue of downloading a faulty PDF file

Every time I attempt to download a PDF file to the client side using axios, it ends up corrupted. In my MERN stack webapp, a user can click a button to initiate the download of a PDF file. This button triggers an axios GET request to the Node.js web server ...

What could be the reason that the painting application is not functioning properly on mobile devices?

I am facing an issue with my painting app where it works perfectly on desktop browsers but fails to function on mobile devices. I tried adding event listeners for mobile events, which are understood by mobile devices, but unfortunately, that did not solve ...

"Php makes it easy to organize seating arrangements with drag-and-drop functionality

We are currently in the process of developing a website dedicated to bus services and booking tickets. Our main goal is to allow the administrator to easily create and modify seating arrangements through drag-and-drop functionality, including the ability t ...

The framework of AngularJS modules

As I delve into structuring multiple modules for our company's application, I find myself at a crossroads trying to design the most optimal architecture. Research suggests two prevalent approaches - one module per page or a holistic 'master' ...

Refreshing the page reveals the complete local storage object

I've successfully created a todo list using Vanilla Javascript along with local storage. The todo list includes the following key-value pairs: key: todolist value: [[\"id:0\",\"title:buy groceries\",\"done:false\"], [&b ...

Is there a method to track the number of active onSnapshot listeners from Firestore in my application?

In my app, I am implementing a feature that dynamically removes query onSnapshot listeners and replaces them with new ones. To ensure that resources are properly freed up, I need to test the effectiveness of the unsubscribe function. Unfortunately, I do n ...

Issue with content overlapping when hamburger icon is tapped on mobile device

When the hamburger menu is pressed on smaller screens, I want my navbar to cover the entire screen. To achieve this, I included the .push class in my code (see the jQuery and CSS) to trigger when the .navbar-toggle-icon is pushed. However, after implemen ...

Encountering an error code of 500 when executing the createIndex function in Pouch

I'm currently working on setting up a basic index, and I have the following code snippet: currentDB.createIndex({ index: { fields: ['name'] } }).then((result) => { }).catch((error) => { }) However, when I try to r ...

Shader in THREE.js designed to accommodate ControlNet for normal calculations

Is there a way to adjust this standard shader to bypass the preprocessor for controlnet? Check out the code here: https://jsfiddle.net/lunchie/mpuanxL3/4/ skinnedMesh.material = new THREE.ShaderMaterial( { vertexShader: [ '# ...

What is the process for using the GitHub API to access a repository's README document?

For my project, I'm utilizing the GitHub API to access the raw README.md file using /repos/{owner}/{repo}/readme. I've successfully executed the call using Thunderclient in VSCode and retrieved the raw file. https://i.sstatic.net/FtkfW.png Howev ...

Ways to transfer a button click event to a callback function

Fiddle: http://jsfiddle.net/cmw0s2rk/ function HandleTopNavClick($elem, pretext = "", replace = false, e) { debugger; e.preventDefault(); var href = $elem.href; } $("ul.check-it li a").on("click", HandleTopNavClick($(this), "clickhere_", true, even ...

`At a loss: jQuery failing to retrieve JSON data`

I'm having trouble with a basic script that is supposed to fetch data from a JSON feed and display it in an alert. Despite having loaded jQuery correctly and checked for common issues, the code doesn't seem to be working. I am using jQuery and ca ...

Guide on showing a message on the server side when pressing a button in the web browser

I need the following question to function seamlessly on all major browsers including Opera, Internet Explorer, Chrome, Safari, and Firefox I am working on an application that requires users to follow a specific order of pages Text1.php, Text2.php, Text3.p ...

Setting a value in Ionic 3 HTML template

Attempting to assign a value in an Ionic 3 template from the ts file while also adding css properties but encountered an issue. PROBLEM Error: Uncaught (in promise): Error: No value accessor for form control with name: 'image' Error: No va ...