In Three.js, create a 3D object that is directed towards another vector while keeping the z axis frozen in place

Is there a way to utilize the object1.lookat(object2) function in Three.js while restricting the z rotation?

I have multiple objects positioned in the field and I need them to constantly face a new object2. Object2 is able to move around, but I want to keep the z rotation of object1 fixed. The issue with lookat() is that it rotates all axes. Are there any alternative methods to achieve this desired effect?

Answer №1

Perhaps you intended not to rotate in X? The lookAt function already avoids rotation in Z.

// Implementing Responsive Design in Three.js
// Source: https://threejsfundamentals.org/threejs/threejs-responsive.html

  'use strict';

/* global THREE */

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({canvas});

  const fov = 75;
  const aspect = 2;  // the default for canvas
  const near = 0.1;
  const far = 250;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.set(20, 10, 20);

  const controls = new THREE.OrbitControls(camera, canvas);
  controls.target.set(0, 0, 0);
  controls.update();
  
  const scene = new THREE.Scene();
  scene.background = new THREE.Color('white');

  function addLight(...pos) {
    const color = 0xFFFFFF;
    const intensity = 1;
    const light = new THREE.DirectionalLight(color, intensity);
    light.position.set(...pos);
    scene.add(light);
  }
  addLight(-1, 2, 4);
  addLight( 1, 2, 2);

  
  const shape = new THREE.Shape();
  shape.moveTo(-1, -1);
  shape.lineTo( 0, -1);
  shape.lineTo( 0, -2);
  shape.lineTo( 2,  0);
  shape.lineTo( 0,  2);
  shape.lineTo( 0,  1);
  shape.lineTo(-1,  1);
  const extrudeSettings = {
    depth: 1,
    bevelEnabled: false,
  };
  const geometry = new THREE.ExtrudeBufferGeometry(shape, extrudeSettings);
  geometry.applyMatrix(new THREE.Matrix4().makeRotationY(Math.PI * -0.5));

  const arrows = [];
  const spread = 5;
  for (let z = -3; z <= 3 ; ++z) {
    for (let x = -3; x <= 3; ++x) {
      const material = new THREE.MeshPhongMaterial({
        color: new THREE.Color().setHSL(Math.abs(Math.atan2(x, z)) / Math.PI, 1, 0.5),
      });
      const mesh = new THREE.Mesh(geometry, material);
      scene.add(mesh);
      arrows.push(mesh);
      mesh.position.set(x * spread, 0, z * spread);
    }
  }

  const geometry2 = new THREE.SphereBufferGeometry();
  const sphere = new THREE.Mesh(geometry2, new THREE.MeshPhongMaterial({color:'red'}));
  const base = new THREE.Object3D();
  scene.add(base)
  base.position.y = 10;
  const base2 = new THREE.Object3D();
  base.add(base2);
  base2.position.z = 15;
  const base3 = new THREE.Object3D();
  base2.add(base3);
  base3.position.z = 5;
  base3.add(sphere);
  sphere.position.y = 5;

  function resizeRendererToDisplaySize(renderer) {
    const canvas = renderer.domElement;
    const width = canvas.clientWidth;
    const height = canvas.clientHeight;
    const needResize = canvas.width !== width || canvas.height !== height;
    if (needResize) {
      renderer.setSize(width, height, false);
    }
    return needResize;
  }

  function render(time) {
    time *= 0.001;

    if (resizeRendererToDisplaySize(renderer)) {
      const canvas = renderer.domElement;
      camera.aspect = canvas.clientWidth / canvas.clientHeight;
      camera.updateProjectionMatrix();
    }

    base.rotation.y = time;
    base2.rotation.y = time * 0.77;
    base3.rotation.z = time * 2.33;
    
    const temp = new THREE.Vector3();
    for (const arrow of arrows) {
      sphere.getWorldPosition(temp);
      temp.y = arrow.position.y
      arrow.lookAt(temp);
    }

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }

  requestAnimationFrame(render);
}

main();
body { margin: 0; }
#c { width: 100vw; height: 100vh; display: block; }
<canvas id="c"></canvas>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r105/three.min.js"></script>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r105/js/controls/OrbitControls.js"></script>

It seems like you might want to avoid rotating in the X direction. If so, retrieve the target's position in a temporary Vector3, then adjust its Y coordinate to match that of the desired object before calling lookAt.

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

The Jquery hide function seems to be unresponsive when trying to close the span in my Dialog

$('.ui-dialog-titlebar-close ui-corner-all').hide(); I'm having trouble hiding the close 'X' span in my jQuery dialog. When I resize the dialog, it appears, but it's not showing correctly initially due to CSS issues. Could s ...

Sending a multi-level property object to the controller in a post request

I am facing a challenge where I need to transfer an object from the view to the controller, and the model comprises a list of objects, each containing another list of complex objects. Let's consider the following models: public class CourseVm { p ...

An issue occurred while attempting to retrieve information from the database table

'// Encounter: Unable to retrieve data from the table. // My Code const sql = require('mssql/msnodesqlv8'); const poolPromise = new sql.ConnectionPool({ driver: 'msnodesqlv8', server: "test.database.windows.net", ...

Data object constructor is not triggered during JSON parsing

Currently, I am retrieving data from a server and then parsing it into TypeScript classes. To incorporate inheritance in my classes, each class must be capable of reporting its type. Let me explain the process: Starting with the base class import { PageE ...

Exploring the (*ngFor) Directive to Iterate Through an [object Object]

Attempting to iterate through the array using *ngFor as shown below. let geographicalArea = [{ "_id": "5e77f43e48348935b4571fa7", "name": "Latin America", "employee": { "_id": "5e77c50c4476e734d8b30dc6", "name": "Thomas", ...

Removing redundant names from an array using Typescript

My task involves retrieving a list of names from an API, but there are many duplicates that need to be filtered out. However, when I attempt to execute the removeDuplicateNames function, it simply returns an empty array. const axios = require('axios&a ...

Is it possible to utilize a JS script generated within the body or head of an HTML file directly within CSS code?

As a beginner in webpage development, I have a query regarding the technical aspect. Is it possible to utilize variables from a JavaScript function, which is placed either in the head or body of an HTML file, directly in CSS code to make modifications such ...

Guide on incorporating dxTreeView with AngularJS

Hello there, I am trying to utilize the dx-tree-view component. In my Home.html file, I have included the following HTML code: <div dx-tree-view="treeViewOptions"></div> And in my HomeController.js: $scope.treeViewOptions = { binding ...

Sending template reference from one Angular component to another

I have a main grid component that includes smaller grid-item components. The majority of these grid items navigate to a specific route when clicked. However, there is one particular item that should open a modal window instead of navigating. Is there a wa ...

JavaScript: create a collision detection algorithm to find pairs of objects in an object, not an array

I'm in the process of developing a Javascript game and I'm facing the challenge of implementing collision detection. Each element rendered in the game has its own unique ID and is stored in an object. I opted for using an object as a container i ...

Introduce a pause using the raycaster function

When my raycaster intersects an object for 2 seconds, I want to update the object's texture. I attempted to use the clock function, but I am unsure of how to properly implement it. var clock = new THREE.Clock(); clock.autoStart = true; var inters ...

Guide to comparing the contents of two text fields and highlighting the altered characters using ReactJS

Is there a way to compare the contents of two Material-UI textfields and identify the characters that have changed in both? I came across a similar question, but it was specifically for ReactJS rather than C# Windows Forms: How can you highlight the chara ...

Guide to using Ajax to load a partial in Ruby on Rails

Whenever a search is triggered, I have a partial that needs to be loaded. This partial can take a significant amount of time to load, so I would prefer it to be loaded via Ajax after the page has fully loaded to avoid potential timeouts. Currently, my app ...

The mystery of the unassigned value in $(this).data(value) when using the jQuery click() method

In my Rails 5 application, I am working on creating a dynamic menu that will guide users to different parts of the site based on their location. The idea is that when they click on a specific menu item from the home page, a modal will appear allowing them ...

Return to a mention of a tree reference

Here is an example code snippet: <table> <tr> <td></td> <td></td> <td> <table> <tr> <td><a href="#" class="fav">click me</a></td> ...

Discovering the central point within an SVG path

I am currently working with a path that is part of a group and using Jquery to locate the specific path. My goal is to find the midpoint of that path. I came across an example here. However, when attempting to use .getTotalLength(); or .getPointAtLength(), ...

Troubleshooting issues with resizing multiple Echarts in React

I'm facing an issue with resizing Echarts components when the window size changes. I have two components rendered, but only one of them is able to resize properly. Below is the source code for your reference - you can observe the problem by resizing y ...

Serve the mobile version to mobile visitors and the desktop version to all other visitors

Can someone please explain to me how I can display the Mobile Version of a website when visiting on my phone, and the Desktop Version when viewing on anything larger than 500px? I have separately created both a Mobile Website and a Desktop Website. Is it ...

JavaScript Data Types in Node.js

Currently diving into the world of Node.js. Can someone clarify the meaning of the following code snippet? And also, what data type is being utilized here and what are its practical applications? var x = { a = { n: 0 } }; ...

Ordering two arrays in a for loop

I have two arrays to manage, one for numbers and the other for names. const number = ['91xxxx','1xxxx','92xxxx'] const name = ['Abhi','Arun','Aaron'] The goal is to pair each number with a corres ...