Understanding the significance of this code excerpt in JavaScript

Although I am still new to both the 3D and three JS worlds, I have managed to grasp most concepts. However, when it comes to matrices, I always find myself getting confused.

My goal is to drag a small object on top of other objects in such a way that the small object faces the same direction as the main object (similar to hanging a wall clock on the wall).

Initially, I tried placing an axis helper on top of a rotating cube and implemented a simple logic where the intersecting point provides the position for the small object placement and the face normal of the intersecting object gives the direction for the small object to look at. While this approach worked to some extent, it wasn't entirely effective.

After doing some calculations and researching code snippets for similar tasks, I eventually found success. However, I still don't fully comprehend the underlying logic behind why we perform these specific actions.

this.normalMatrix.getNormalMatrix(intersects[i].object.matrixWorld);
this.worldNormal.copy(intersects[i].face.normal).applyMatrix3(this.normalMatrix).normalize();
this.object.position.addVectors(intersects[i].point, this.worldNormal);
this.lookAtVec.addVectors(this.object.position,this.worldNormal.multiplyScalar(15));
this.object.lookAt(this.lookAtVec);

Another individual successfully created a wall and positioned a small object on top by modifying this line:

this.object.position.addVectors(intersects[i].point, this.worldNormal);

to

this.object.position.copy(intersects[i].point);

This adjustment worked for him, but unfortunately, the same modification did not yield the desired results with my axis helper.

Answer №1

Here is one way to approach it. Take a look at the end of the onMouseMove() function:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(-3, 5, 8);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x404040);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.setScalar(10);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));

var walls = [];

makeWall(Math.PI * 0.5);
makeWall(0);
makeWall(Math.PI * -0.5);

var clockGeom = new THREE.BoxBufferGeometry(1, 1, 0.1);
clockGeom.translate(0, 0, 0.05);
var clockMat = new THREE.MeshBasicMaterial({
  color: "orange"
});
var clock = new THREE.Mesh(clockGeom, clockMat);
scene.add(clock);

var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersects = [];
var lookAt = new THREE.Vector3();

renderer.domElement.addEventListener("mousemove", onMouseMove, false);

function onMouseMove(event) {

  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

  raycaster.setFromCamera(mouse, camera);

  intersects = raycaster.intersectObjects(walls);
  if (intersects.length === 0) return;

  clock.position.copy(intersects[0].point);
  clock.lookAt(lookAt.copy(intersects[0].point).add(intersects[0].face.normal));
}

render();

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}

function makeWall(rotY, color) {
  let geom = new THREE.BoxBufferGeometry(8, 8, 0.1);
  geom.translate(0, 0, -4);
  geom.rotateY(rotY);
  let mat = new THREE.MeshLambertMaterial({
    color: Math.random() * 0x777777 + 0x777777
  });
  let wall = new THREE.Mesh(geom, mat);
  scene.add(wall);
  walls.push(wall);
}
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/94/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

Retrieve the folder name after selecting the folder in the input field

I have used the code snippet below to select a folder and parse all the files within that folder. While I am able to retrieve a list of all files, I am unsure how to extract the folder name alone from the path. For example, if the folder path is C:/Folder ...

Guide to navigating to a particular element using PerfectScrollbar

Currently, I am facing a minor challenge while creating my website using the incredible Black Dashboard template for Bootstrap 4. This template, which can be found at (many thanks to Tim for this!), utilizes PerfectScrollbar for jQuery. Although I have ...

Unable to set options, such as the footer template, in Angular UI Typeahead

I am looking for a way to enhance the results page with a custom footer that includes pagination. I have noticed that there is an option to specify a footer template in the settings, but I am struggling to find examples of how to configure these options th ...

What is the best way to manage undefined status in react after the user chooses to cancel selecting a file?

Having an issue with my simple Input file type in React. I'm storing the selected file in state, but when I click the clear button, the state doesn't actually get cleared. This leads to {selectedFile.name} throwing an undefined error if the user ...

Including files in node package without specifying the name of the dist directory

In my library directory structure for seamless import by node js projects, it looks like this: my-lib/ ├─ dist/ │ ├─ index.js │ ├─ foo.js ├─ src/ │ ├─ index.ts │ ├─ foo.ts ├─ package.json Take a look at my package.j ...

Guide on integrating angular-schema-form into an Ionic 2.0 project using typescript

Recently, I embarked on creating an app with Ionic from scratch and decided to integrate the framework. While I faced no issues executing the example on a webpage, I encountered difficulties when attempting to do so with Ionic. To kickstart the project, ...

Sending information to components in Angular using Router

Should I pass data through the angular router to a component, or is it better to use a service? Currently, the component is receiving data in the following way: this.account = activatedRoute.snapshot.data.account ...

How can I access the value of a Mobx Store in a React Class Component?

I am trying to access a Hook within a React Class Component. Konva.tsx import * as React from "react"; import { Stage, Layer } from "react-konva"; import { useFrameItStore } from "../store/index"; import { BrowserWindow, Site ...

What is the proper way to call a function in an HTML document?

I'm currently working on an HTML file that displays the coordinates provided by the user on a map. Every time I try to submit the form, I encounter an error saying "UncaughtReferenceError: NewMap is not defined." I've attempted using both externa ...

Issue: TypeError - 'process.env' can only accept a configurable while installing windows-build-tools

Unable to successfully download installers. Encountered an error: TypeError: 'process.env' can only accept a configurable, writable, and enumerable data descriptor. I attempted to resolve this issue by running the command npm install --global wi ...

I encountered the following error: Failed to parse due to the module '@babel/preset-react' being missing

Encountering a parsing error: Module '@babel/preset-react' cannot be found. Upon creating schema.js, tweetSchema.js, userSchema.js, issues arose with import, export, and export from all three files showing red lines. schema.js: import createSche ...

Is there a way to implement seamless scrolling within an absolute element using Jquery?

Hey there! I recently implemented smooth scrolling on my website, but it seems to only work on single-page layouts. How can I make it function properly within an absolutely positioned scrollable element? Here are the link to my website and the correspond ...

Copy both the image and JSON object to the clipboard

I am attempting to utilize the clipboard API to write an image and JSON object to the window clipboard. I am working with Vue and Electron and have successfully written an image and plain text, but I encounter an error when trying to write a JSON object: ...

"Failure to Update: Ajax Auto-Refresh Table Failing to Refresh

I'm facing a tricky issue with my code that I just can't seem to resolve. Currently, I am using Ajax and setTimeout to retrieve data. The problem arises when the data doesn't refresh automatically (if I manually navigate to the page getdata. ...

Guide for creating a function that accepts an array containing multiple arrays as input

I am working with a function called drawSnake and it is being invoked in the following manner: drawSnake( [ [0, 0], [0, 1], [0, 2], [0, 3], [0, 4], ] ); How should I format the input for this function? I have attempted using Array<Array<[numb ...

JavaScript JSON request denied

As I develop a website, I am encountering an issue with my query requests from local host. Whenever I try to query from Google or the specific address provided, I do not receive any results. Is it possible that there are query limits set for certain URLs ...

Encountering issues with a React Native Application crashing in release mode, but successfully rendering a 3D .glb model using React Three Fiber in debug mode

Currently, I am working on a React Native app using expo-modules for expo-gl, react-three/fiber, and react-three/drei. My goal is to render a 3D .glb model with animations and external textures from a separate .jpg file. While everything works fine in debu ...

Trouble with Bootstrap 5 Dropdown Menu failing to drop down

I am attempting to utilize a dropdown menu on my Wordpress site with Bootstrap, but it is not working as expected. If I manually add the class "show" to my dropdown-menu div, the menu displays, but the button does not function. These are the scripts being ...

Updating a JSON file with new object using node.js

Currently, I am attempting to insert a single object into an extensive JSON file. My approach involves parsing the entire file using FS and JSON.Parse, adding the new JSON object in memory, and then rewriting the file. While I am aware of FS's append ...

Numerous toggles available for the mobile version

Hey there, I need some help! I have a footer navigation on my desktop website with 3 Ul elements. I want to turn each Ul into a toggle for the mobile version. Can anyone assist me with this? Thanks in advance! <footer class="footer"> <d ...