Three.js - Object facing perpendicular to path while traveling at 90-degree angle

In my concept, a square room is depicted where an object moves smoothly from corner to corner. The camera follows the object, facing the walls at all times but curving around in such a way that it maintains a continuous transition between walls without being exactly perpendicular. I aim for the object and camera to adjust their angle of view by 90 degrees when transitioning from one wall to another.

Approach Taken

To achieve this, I utilized a CatmullRomCurve3 created from an array of four coordinate sets representing the corners of the room. Both the object and camera animate along this curve successfully with the code provided. However, they currently focus (lookAt) on the path ahead of them. My intention is for them to retain the same motion but face the adjacent wall instead, offsetting their rotation by 90 degrees.

Specifically, I seek:

  • Object and camera moving along the path while adjusting their rotation/lookAt to constantly face a wall or corner.
  • I understand how to position the camera slightly behind the object for an over-the-shoulder perspective. Nevertheless, this will likely change as the object faces the walls, necessitating a different camera axis positioning explanation.

Code Fragment for Creating the Curve

var curve;
function createCurvePath() {

// Array of points
var points = [
    [-80, 5, 35],
    [-80, 5, 192.5],
    [80, 5, 192.5],
    [80, 5, 35]
];

// Convert the array of points into vertices
for (var i = 0; i < points.length; i++) {
    var x = points[i][0];
    var y = points[i][1];
    var z = points[i][2];
    points[i] = new THREE.Vector3(x, y, z);
}

// Create a closed curve
curve = new THREE.CatmullRomCurve3(points);

curve.closed = true;

var points = curve.getPoints(200);
var geomCurvePath = new THREE.BufferGeometry().setFromPoints(points);

var matCurvePath = new THREE.LineBasicMaterial({ color: 0xff0000 });

// Create the final object to add to the scene
var CurvePath = new THREE.Line(geomCurvePath, matCurvePath);

scene.add(CurvePath);
}

Code for Animation within the Render Loop

// Loop that runs every frame to render scene and camera
function render() {
requestAnimationFrame(render);

// Move camera along the path
percentage += 0.0005;
var p1 = curve.getPointAt(percentage % 1);
var p2 = curve.getPointAt((percentage + 0.01) % 1);
camera.position.set(p1.x, p1.y, p1.z);
object.position.set(p1.x, p1.y, p1.z);
camera.lookAt(p2);
object.lookAt(p2);

renderer.render(scene, camera);
}

Answer №1

Consider using the .applyAxisAngle() method as an alternative approach:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 100, 300);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.target = new THREE.Vector3(0, 5, 100);
controls.update();

var points = [
  new THREE.Vector3(-80, 5, 35),
  new THREE.Vector3(-80, 5, 192.5),
  new THREE.Vector3(80, 5, 192.5),
  new THREE.Vector3(80, 5, 35)
];

var curve = new THREE.CatmullRomCurve3(points);
curve.closed = true;

var curvePoints = curve.getPoints(200);
var geomCurvePath = new THREE.BufferGeometry().setFromPoints(curvePoints);
var matCurvePath = new THREE.LineBasicMaterial({
  color: 0xff0000
});
var CurvePath = new THREE.Line(geomCurvePath, matCurvePath);
scene.add(CurvePath);

var pointerGeom = new THREE.ConeGeometry(4, 20, 4);
pointerGeom.translate(0, 10, 0);
pointerGeom.rotateX(Math.PI * 0.5);
var pointer = new THREE.Mesh(pointerGeom, new THREE.MeshNormalMaterial());
scene.add(pointer);

var p1 = new THREE.Vector3();
var p2 = new THREE.Vector3();
var lookAt = new THREE.Vector3();
var axis = new THREE.Vector3(0, 1, 0);
var percentage = 0;

render();

function render() {
  requestAnimationFrame(render);
  percentage += 0.0005;
  curve.getPointAt(percentage % 1, p1);
  curve.getPointAt((percentage + 0.001) % 1, p2);
  lookAt.copy(p2).sub(p1).applyAxisAngle(axis, -Math.PI * 0.5).add(p1); // adjust orientation by 90 degrees
  pointer.position.copy(p1);
  pointer.lookAt(lookAt);
  renderer.render(scene, camera);
}
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.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

React Server Component Warning: Server Functions cannot be invoked during the initial rendering stage

In my project, I have a client component named CampaignTable. This component requires a columns object to render the columns. Within the columns object, I include a server component called CampaignActions. The CampaignActions component is responsible for d ...

Performing an Ajax request in JavaScript

I've encountered an issue with my jQuery ajax call. It was working perfectly fine when placed in a jQuery file. Here's the code snippet: var request = $.ajax({ url: "kscript.jsp", type: "POST", data: {st:start, sp:stop}, dataType ...

Integrate Javascript Chart into Your Rails Application

As a newcomer to Rails, I am attempting to incorporate a JavaScript chart from Highcharts.com into my Rails application. However, I have encountered an issue where the view container remains empty. I have downloaded the package and added it to vendor/asse ...

Unable to trigger submission in jQuery validate function after validation check

I'm currently facing an issue with my form validation using the jQuery validate plugin. Although I have successfully implemented validation for the desired areas of the form, I am unable to submit the form even after filling in all the required input ...

AJAX cannot be used with the current session

I am facing an issue with a directory containing files that are used only as modal. These PHP files have the following format: "modal.filename.php". Here is an example: "modal.user.php": <?php session_start(); $_SESSION['test'] = 1; echo & ...

Determine the initial left position of a div element in CSS prior to applying

Scenario : const display = document.querySelector('.display'); const container = document.querySelector('.outer-div'); document.addEventListener("click", (event) => { if (!event.target.closest("button")) return; if(event ...

Tips for integrating html2canvas with Vue JS?

One hurdle I encountered was the absence of a shorthand for document.getElementById in Vue. To address this, I created a custom function similar to this one. Another challenge I am currently grappling with is the perceived limitations of the html2canvas do ...

Send the value of a JavaScript variable to a PHP file upon calling a JavaScript function

When a script button is clicked, a javascript function runs. The function looks like this: //script function oyCrosswordFooter.prototype.update = function(){ var buf = ""; if (!this.puzz.started){ buf += "Game has not ...

What are the Javascript Keycodes for the letter 'a' - is it 65 or

I am currently working with JavaScript on my MacBook Pro running OSX 10.11.x, using the Chrome browser. The function I am using is: window.onkeypress = function(e) { var key = e.keyCode ? e.keyCode : e.which; console.log("keypressed = " + key); } ...

A guide on retrieving styled text from a database and displaying it in TinyMCE

I am encountering an issue where I need to retrieve formatted text from a database and display it in my TinyMCE editor. The content stored in the database looks like this: <p style="text-align: justify;"><strong>Zdrav&iacute;m</strong ...

Leverage the controller's properties and methods within the directive

My situation involves a variety of inputs, each with specific directives: <input mask-value="ssn" validate="checkSsn"/> <input mask-value="pin" validate="checkPin"/> These properties are managed in the controller: app.controller("Ctrl", [&ap ...

Modifying the color temperature or warmth in Three.js can enhance the visual aesthetics

In my three.js project, I've set up a room scene with various lights added to it. Features such as exposure, power, and height adjustments have been included in the setup. You can view the progress so far by visiting this link. My next goal is to i ...

Tips for fetching the chosen choices from a drop-down menu and then performing multiplication with input fields

Hey there! I'm attempting to create a system that checks if the user has selected an item from a dropdown menu, and based on their selection, perform a multiplication operation with three different variables and display the result. For instance, if " ...

Exploring the Wonder of MVC with Ajax Calls Handling Multiple Parameters

I've been struggling to send 2 parameters from the View to the controller using an ajax call. Everything was working fine when I had only one parameter, but as soon as I added another, the function stopped working. Below is the Javascript code with a ...

What is the best way to incorporate a sliding effect into my cookie form?

I created a cookie consent form for my website and I'm looking to include a sliding effect when it first appears and when it disappears after the button is clicked. How can I implement this sliding effect into the form? Here's the HTML, CSS, and ...

Issue with JSON or Jquery: Uncaught error message: Cannot access property 'error' as it is null

I am attempting to initiate an ajax call using the jQuery code provided below. However, when I try this in Chrome, I encounter an error that says 'uncaught typeerror cannot read property 'error' of null'. This prevents the preloader fr ...

The challenges of $location.search().name and base href in application URLs

I am working on an Angular app and my URL appears as http://localhost:8080/personal?name=xyz. To extract the 'xyz' value in JavaScript, I am using $location.search().name. Here is a snippet of my code: app.js app.config(function ($locationProv ...

How come my Calendar is not showing up on the browser?

I came across a helpful guide on setting up a Calendar in HTML using JavaScript You can find it here: Unfortunately, the code I tried to use based on that guide isn't functioning as expected. <div class="row"> <div class="col-lg-4 text ...

Why does appending to a TextArea field fail in one scenario but succeed in another when using Javascript?

There is a JavaScript function that captures the value from a select dropdown and appends it to the end of a textarea field (mask) whenever a new selection is made. function addToEditMask(select, mask) { var selectedValue = document.getElementById(sel ...

How much does it typically cost to implement external libraries into a project?

Here are some of the most commonly used front-end web development libraries: jquery-min.js (95.9 kB) angular.min.js (108.0 kB) bootstrap.min.css (113.5 kB) bootstrap-theme.min.css (19.8 kB) bootstrap-fonts (185.7 kB) bootstrap.min.js (35.6 kB) All in al ...