The camera constantly eludes the object, despite attempts to match its position and rotation

I am attempting to keep a sphere object centered in front of a moving camera. The camera's position and rotation are being animated using lookAt(), which is functioning correctly. However, the sphere object is not staying within the frame as desired. I have tried different approaches:

const centerSphereInCameraWithQuaternion = (sphere: THREE.Mesh, camera: THREE.PerspectiveCamera) => {
  const vec = new THREE.Vector3( 0, 0, - 4 );
  vec.applyQuaternion( camera.quaternion );

  sphere.position.copy( vec );
}

This method causes the sphere to disappear completely. Another attempt was made with:

const centerSphereInCamera = (sphere: THREE.Mesh, camera: THREE.PerspectiveCamera) => {
  sphere.position.copy( camera.position );
  sphere.rotation.copy( camera.rotation );
  sphere.updateMatrix();
  sphere.translateZ( - 4 );
}

While this nearly works, the sphere rotates opposite to the direction of the camera's facing. Additionally, I experimented with:

sphere.position.sub(camera.position);

However, this did not yield any visible results.

I even used a camera helper to verify that the camera's world matrix is updating correctly, which it appears to be.

What mistake am I making in my approach? Is there a way to achieve this without making the mesh a child of the camera?

Answer №1

If you're not getting creative with the camera's angle, all it takes is three simple lines of code to keep an object in front of the camera without embedding it within the camera:

sphere.position.copy(camera.position);
sphere.rotation.copy(camera.rotation);
sphere.translateZ(-40);

Feel free to test out the code snippet below to witness this method in action. Watch as I smoothly move the camera around the scene, and see how the sphere always stays directly in front of the camera thanks to those three lines of code. The relevant part of the code can be found in the animate() function towards the end:

var camera, scene, renderer;

// set up the scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0xe1e1e1);

// initialize the camera
camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 100);

const ambient = new THREE.DirectionalLight(0xddeeff, 1);
ambient.position.set(0, 1, 1);

const floor = new THREE.Mesh(
    new THREE.BoxBufferGeometry(20, 0.25, 20),
    new THREE.MeshPhongMaterial()
);
const wall = new THREE.Mesh(
    new THREE.BoxBufferGeometry(.5, 3, 10), 
    new THREE.MeshPhongMaterial({ color: 0xc4ffc4})
);
const sphere = new THREE.Mesh(
    new THREE.SphereBufferGeometry(3, 20, 20),
    new THREE.MeshPhongMaterial({ color: 0xff0000 })
);

scene.add(ambient, floor, wall, sphere);

renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, Infinity));

document.body.appendChild(renderer.domElement);

function animate(t) {
    // Move the camera
    const xPos = Math.sin(t / 777) * 50;
    const yPos = Math.sin(t / 666) * 25;
    const zPos = Math.cos(t / 1000) * 50;
    camera.position.set(xPos, yPos, zPos);
    camera.lookAt(0, 0, 0);
    
    // Keep the sphere in front of the camera
    sphere.position.copy(camera.position);
    sphere.rotation.copy(camera.rotation);
    sphere.translateZ(-40);
    
    renderer.render(scene, camera);
    requestAnimationFrame(animate);
}

animate(0);
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/104/three.min.js"></script>

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

Is Jasmine brushing off TypeScript test files?

I'm diving into my first project with Jasmine, and despite following a tutorial, I'm encountering some hurdles right from the start. After installing jasmine-node, typings, and typescript, I executed: typings install dt~jasmine --save-dev --glo ...

Steps for utilizing a Get() method to view a response within Angular

I am having trouble with implementing an API call on a page and I'm unsure about what's wrong with the Subscribe/Observe method. Currently, this is the code that I have: import { Component, OnInit } from '@angular/core'; import { Ro ...

Issue with Angular and OIDC - user data is missing upon logging in

I am in the process of developing an application using Angular along with IdentityServer as the Single Sign-On (SSO) provider in ASP.NET. After successfully logging in and retrieving user information from the authentication server: User info The followin ...

React: Eliminate the reliance on two interconnected contexts by implementing a globally accessible constant object

Working on a new significant update for react-xarrows, I encountered a complex situation that needs resolution. To help explain, let's visualize with an example - two draggable boxes connected by an arrow within a wrapping context. https://i.sstatic ...

Navigate through collections of objects containing sub-collections of more objects

The backend is sending an object that contains an array of objects, which in turn contain more arrays of objects, creating a tree structure. I need a way to navigate between these objects by following the array and then back again. What would be the most ...

Having trouble with the pitch of your rotating camera in Three.js?

I'm still getting the hang of three.js so please bear with me if this question seems a bit basic. My current challenge involves rotating a camera using the arrow keys. While the left and right (yaw) rotation works as expected, I'm encountering i ...

Encountering a 404 error for core.js and browser.js while loading an Angular 2 app through system.src.js

I am new to Angular2 and have followed the Angular2 quickstart and tutorial to get started. Just to provide some context, when a user clicks on a link in the top navigation bar of my webapp, it triggers a server side request. The resulting page returned t ...

The Google Books API has reached its limit for requests

Encountering a rate limit exceeded error from the Google Books API while using this demo: To reproduce, open the developer console in Chrome and perform some searches. The rate limit errors will be displayed in the console. [],"lazyUpdate":null},"status" ...

What is the best way to send a string literal as a parameter to a method triggered by a click event

I'm trying to pass a string literal to a method as a click handler. <button (click)="changeLanguage('en')">EN</button> The above code is not working. Any suggestions on how to achieve this? ...

Tips for exchanging elements in React Three Fiber / ThreeJs

Within my Card component, when clicked, it activates and expands the block. I want to make it so that clicking on one card and then another will cause them to switch positions. Here's an example: // Initial Board 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, ...

Some of the compiler options that are not commonly known are those for including and

Embarking on my first typescript-node-express project, I decided to create my own tsconfig file with the following configuration: { "compilerOptions": { "target": "es6", "module": "commonjs", "strict": true, "baseUrl": "./", "outDi ...

Testing MatDialog functions in Angular: Learning how to open and close dialogues

I am currently facing an issue with testing the MatDialog open and close functions. No matter what I try, I cannot seem to successfully test either the open or close functions. I am wondering how I can mock these functions in order to properly test them. W ...

Testing a callback function within a method in Angular

I am currently working with Angular 11 using TypeScript and I am unsure how to properly test scenarios where an exception is raised within my method. myMethod() { this.myService.callBackend(id).subscribe(() => { // do something when success ...

Navigate objects by typing

I am in search of a type that can describe any path through an object starting from the top (root) properties all the way down to every leaf property in the form of a string array. The following are the key characteristics required: The object's stru ...

What is the best approach to inheriting from an Injectable class with multiple Injections in Angular 2?

Could we potentially achieve something similar to this code snippet? I attempted it but didn't have any success: @Injectable() class X { constructor(private http: Http){ // <-- Injection in parent class } method(){ this.http.get()... ...

Issues with updating values in Angular form controls are not being resolved even with the use of [formControl].valueChanges

[formControl].valueChanges is not triggering .html <span>Test</span> <input type="number" [formControl]="testForm"> .ts testData: EventEmitter<any> = new EventEmitter<any>(); testForm: FromCo ...

Is there a way to store the result from LiquidJS as a variable?

On the homepage of , this code snippet is provided as an example: import { Liquid } from 'liquidjs' const engine = new Liquid() const tpl = engine.parse('Welcome to {{v}}!') engine.render(tpl, {v: "Liquid"}).then(console.log) ...

Ways to modify the access control to permit origin on a specific API URL in React

https://i.stack.imgur.com/tqQwO.png Is there a way to modify the access control allow origin for a URL API? I keep encountering error 500 whenever I try to load the page. After logging in, I included this code snippet: const options = { header ...

What is the most effective method for creating a multitude of 2D rectangles using Three.js?

As someone new to Three.JS, I am attempting to create a 2D visualization. Previously, I used d3.js to develop an interactive visualization incorporating thousands of rectangular nodes. However, performance issues arose during animation due to the need for ...

Interactions between faces in Three.js causing artifacts

I have successfully created two transparent boxes that are positioned so their faces touch. However, the issue arises when the faces of the boxes actually touch. // inner object var mesh2 = new THREE.Mesh(geometry, material); mesh2.position.x = 0; mesh2 ...