Three.js: How to Make a Camera Circle a Sphere?

How can we use Three.js and JavaScript/ WebGL to create a camera that orbits a sphere at a fixed height, with a fixed forward speed, and maintaining a fixed orientation in relation to the sphere? The user should only be able to steer the camera left and right.

Visualize an airplane connected by an invisible string to the center of a globe, skimming close to the ground and always keeping part of the sphere in view:

(I have code that currently rotates the sphere to create a flying effect for the camera, but the left and right steering feature has not been implemented yet. I'm considering repositioning the camera/ airplane instead of moving the sphere group before proceeding further.)

Any suggestions are appreciated! Thank you!

Answer №1

Did you see how I implemented this concept in my Ludum Dare 23 project? I must admit, it turned out to be more intricate than I initially thought. Nevertheless, it wasn't overly challenging.

Let's assume you have the latitude and longitude of the camera, along with its distance from the sphere's center (referred to as radius), and you aim to generate a transformation matrix for the camera.

To optimize performance, create the following objects just once instead of recreating them in every game loop:

var rotationY = new Matrix4();
var rotationX = new Matrix4();
var translation = new Matrix4();
var matrix = new Matrix4();

Whenever the camera shifts, construct the matrix in the following manner:

rotationY.setRotationY(longitude);
rotationX.setRotationX(-latitude);
translation.setTranslation(0, 0, radius);
matrix.multiply(rotationY, rotationX).multiplySelf(translation);

Then, simply assign this camera matrix (assuming 'camera' is your camera object):

// Reset the camera matrix.
// Interestingly, Object3D doesn't provide a direct method to SET the matrix(?)
camera.matrix.identity();
camera.applyMatrix(matrix);

Answer №2

Appreciation for the valuable input from Martin! I have successfully implemented a different approach that is working smoothly. Here is the revised method (Martin's original suggestion may also be ideal; a big shoutout to Lmg as well):

To start off, position the camera as a straight line above the sphere (with a higher y value, slightly exceeding the radius, which was 200 in my scenario); adjust the angle downwards:

camera.position.set(0, 210, 0);
camera.lookAt( new THREE.Vector3(0, 190, -50) );

Next, create an empty group (an Object3D) and place the camera inside:

camGroup = new THREE.Object3D();
camGroup.add(camera);
scene.add(camGroup);

Track the mouse position as a percentage relative to half of the screen:

var halfWidth = window.innerWidth / 2, halfHeight = window.innerHeight / 2;
app.mouseX = event.pageX - halfWidth;
app.mouseY = event.pageY - halfHeight;
app.mouseXPercent = Math.ceil( (app.mouseX / halfWidth) * 100 );
app.mouseYPercent = Math.ceil( (app.mouseY / halfHeight) * 100 );

During the animation loop, utilize this percentage for rotation, while simultaneously moving forward:

camGroup.matrix.rotateY(-app.mouseXPercent * .00025);
camGroup.matrix.rotateX(-.0025);
camGroup.rotation.getRotationFromMatrix(camGroup.matrix);

requestAnimationFrame(animate);
renderer.render(scene, camera);

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

Trying to assign a value to 'currentStatus' using "this" on an undefined property

In my attempt to display the state of formSubmit in vue js, I've encountered an issue. My lack of familiarity with using "this" has led to errors in the code, particularly when trying to indicate the status using "this.currentStatus". This is the cod ...

Web Browser cross-origin AJAX requests

Recently, I developed an Internet Explorer extension that injects a script every time a page is accessed. The purpose of this script is to send an AJAX request to my localhost. However, I have encountered a roadblock where the request only works if it&apos ...

Changing background color using jQuery ID selector

Within thisid, the id of an html element is stored. In order to modify its background color, the code below can be utilized: let thisid = 'test'; $("a#" + thisid).css("background-color", "yellow"); <script src="https://cdnjs.cloudflare.com/a ...

Utilizing Firefox and Selenium with Python: A guide to dynamically accessing HTML elements

Currently, I am utilizing a combination of Python, Selenium, Splinter, and Firefox to develop an interactive web crawler. The Python script provides the options, then Selenium launches Firefox and executes certain commands. At this point, I am looking fo ...

Vue.js - when it comes to rounding off digits, I keep getting unexpected results

Currently, I am in the process of calculating my totals and I need to ensure that they are fixed to 2 decimal places. Here is a snippet of my code: this.selectedCompaniesDetails.forEach((company) => { if(company.id == p.compa ...

Guide to Incorporating a Marker into an SVG Blinking Rectangular or Circular Border Image on Google Maps

I have a link that points to a specific location on Google Maps using latitude and longitude: http://www.google.com/intl/en_us/mapfiles/ms/micons/red-dot.png Now, I am looking to add a blinking border to this marker link. Is there a way to achieve this ...

What is the process for choosing all items and then canceling the selection in a

I utilized the information on this webpage to generate the following code snippet: https://getbootstrap.com/docs/5.0/forms/checks-radios/#indeterminate Upon clicking the checkbox with the ID of (flexCheckIndeterminate), all checkboxes located below it wil ...

Encountered a 'File is not defined' error in JavaScript when running code from the node.js command line

I'm encountering an issue with my JavaScript code that is supposed to read a file and print it on the console. Despite having the file test.txt in the same path, I keep getting an error saying "File is not defined." Below is the snippet of the code: ...

Unraveling the Mysteries of Node.js Application Logging

We've been having smooth sailing with our Kube cluster on AWS, but there seems to be a recurring issue with our Node app crashing and generating repetitive logs from our instances... I've scoured the internet for solutions but haven't had m ...

What assistance is available for building a JavaScript package that integrates and utilizes all necessary dependencies?

I am looking for a solution to include a third-party library in a JavaScript file that will be downloaded to our project only when we visit a specific page. This library is installed with npm and I want it to be part of the js package without includi ...

Is there a way to retrieve real-time information using momentjs in a Vue.js application without needing to refresh the

I have a unique table where I showcase details about a particular website. Among the displayed information is the timestamp indicating when the data was last updated. At the top of the table, my aim is to include an icon that will only appear if the dura ...

Alert-Enabled Random Number Generation Tool

I'm struggling to create a program that randomly generates a number between 1 and 20. If the number is less than 10, it should display "fail," and if it's greater than 10, it should display "success." I can't seem to figure out where I went ...

Enhancing PHP function speed through pre-compilation with Ajax

I am curious about compiling server side functions in PHP with Ajax, specifically when multiple asynchronous calls are made to the same server side script. Let's consider a PHP script called "msg.php": <?php function msg(){ $list1 = "hello world ...

Using Selenium and Python to download audio files that require JavaScript to load

Currently, I am in the process of developing a script to streamline the task of downloading text and audio files from a specific website using Python and Selenium. The targeted website is: (yyyymmdd) import requests from time import sleep from selenium ...

Tween.js - Can you animate a variable using tweens?

Recently, I've been experimenting with three.js and tween.js and I'm curious if it's possible to animate a variable using tweening? Here are some of my attempts: 1) tween = new TWEEN.Tween(renderergl.toneMappingExposure).to( "0.001&qu ...

Redirecting to another page with a simple link is not recommended

Once the user successfully logs in, I redirect them to the dashboard. Everything was working fine until I deployed it using tomcat. Now the URL is http://localhost:8080/myWar/ So when I use this: window.location.href = "/dashboard"; it redirects to ht ...

Optimal method for retrieving data from a JSON object using the object's ID with a map

Can you teach me how to locate a json object in JavaScript? Here is a sample Json: { "Employees" : [ { "userId":"rirani", "jobTitleName":"Developer", "preferredFullName":"Romin Irani", "employeeCode":"E1", "region":"CA", "phoneNumber":"408-1234567", " ...

Generate numerous div elements by utilizing ng-repeat

I am trying to generate 'n' red blocks with text (where n represents the number of elements in an array), but unfortunately, I am seeing a blank page. <html> <body> <script src="https://ajax.googleapis.com/ajax/libs/angu ...

The PHP code encountered a syntax error due to an unexpected $EOF on the final empty line

I've been tasked with maintaining an old website that went offline due to script errors. I managed to resolve most of the issues in the script, but there's one error that's giving me trouble. The site is showing a syntax error that says "une ...

The functionality of the JavaScript animated placeholder seems to be malfunctioning

I am currently working on a code that updates the placeholder text every 2 seconds. The idea is to have it type out the letters one by one, and then erase them in the same manner. Unfortunately, the code is not functioning as expected. As a newcomer to J ...