`Achieving object placement on top of another object in ThreeJS`

Being new to ThreeJS, I am seeking help with a basic question. I have loaded multiple GLTF files into my scene and I need to position one object on top of another (but the position should be adjustable later on)

For instance: https://i.sstatic.net/oJq1BIiA.png

Below is the code snippet I am working with:

import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

const backgroundColor = new THREE.Color('rgb(67, 177, 232)');

const scene = new THREE.Scene();
scene.background = backgroundColor;

const light = new THREE.AmbientLight(0x222222, 200)
light.position.set(10, 130, 15)
scene.add(light)

const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 10000 );

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

const loader = new GLTFLoader();

// Load in cup
loader.load('assets/models/Cup.glb', (gltf) => {
    scene.add(gltf.scene);
}
)

// Load in laptop
loader.load('assets/models/Laptop.glb', (gltf) => {
    scene.add(gltf.scene);
}
)

//controls.update() must be called after any manual changes to the camera's transform
camera.position.set(-0.03, 0.859, 1.59);
controls.update();

window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
    // render()
}

function animate() {

    requestAnimationFrame(animate );

    // required if controls.enableDamping or controls.autoRotate are set to true
    controls.update();

    renderer.render(scene, camera);
}

renderer.setAnimationLoop(animate)
animate()

I am looking for an official method to place the cup on top of the desk without manually inputting the coordinates. Any suggestions?

Answer №1

When the laptop aligns with the xz plane, we can perform calculations on the bounding boxes as follows...

function positionCupOnLaptop(cup, laptop) {
  const laptopBox = new THREE.Box3().setFromObject(laptop);
  const cupBox = new THREE.Box3().setFromObject(cup);

  const { x: laptopX, y: laptopY, z: laptopZ } = laptopBox.max;
  const cupHeight = cupBox.max.y - cupBox.min.y;

  // the concept is to match the cup's position to the laptop's, while adjusting
  // in the y direction to fit the laptop surface (and considering half of the cup height)
  cup.position.set(laptopX, laptopTopY + cupHeight / 2, laptopZ);
}

This function should be invoked once both models have been loaded. A straightforward method would involve checking for the other model in each load callback. Alternatively, a more elegant solution would be to encapsulate loader.load within a promise.

let cup, laptop;

loader.load('assets/models/Cup.glb', (gltf) => {
    cup = gltf.scene;
    scene.add(cup);
    if (laptop) positionCupOnLaptop();
});

loader.load('assets/models/Laptop.glb', (gltf) => {
    laptop = gltf.scene;
    scene.add(laptop);
    if (cup) positionCupOnLaptop();
});

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

What sets apart the process of installing AngularJS and AngularJS Core using NuGet?

I am curious about the difference between these two packages in my packages.config file. Would it be advisable to uninstall one of them? <?xml version="1.0" encoding="utf-8"?> <packages> <package id="angularjs" version="1.3.15" targetFr ...

Retrieve and dynamically load an entire webpage using AJAX

Although it's typically not recommended, I am interested in displaying the progress of a download on a heavy page to show the user when it's ready. Is there a way for me to track and display the actual progress of the download? Can I monitor how ...

Tips for concurrently and asynchronously executing multiple AJAX requests

I am working with a javascript object named Agendamento which includes the following key parts: const Agendamento = { // ... storeResultados: async function (consulta) { //... $.ajax({ type: 'POST', ...

Access within the identical window (PHP file) as opposed to an Iframe

I am currently working with a PHP file that retrieves data from my database. <?php $cdb = new PDO('mysql:dbname=xxx;host=localhost', 'xxx', 'xxx'); foreach ($cdb->query("SELECT * FROM images ORDER BY posted DESC LIMIT ...

The wordpress jquery dependency is failing to respond

After converting an HTML ecommerce template into WooCommerce, I am experiencing issues with the functionality. The Nivo slider and some other product features are not working properly. It seems like they are having trouble finding WordPress jQuery, even th ...

Why is it necessary to define a property outside the constructor in Typescript, when in Javascript I wouldn't have to do that?

When working with Javascript, creating a class like the one below allows us to avoid declaring and initializing a property named logs outside of the constructor: class Logger { constructor() { this.logs = []; } } However, transitioning to TypeScri ...

I'm curious to know why my jQuery function fadeOut is functioning properly while slice isn't working as expected

I'm trying to create a button that displays three consecutive posts After clicking on "view all", the three "div" elements should become visible I'm attempting to use jQuery to make the three 'div' elements appear when the view all bu ...

Converting a string to HTML in Angular 2 with proper formatting

I'm facing a challenge that I have no clue how to tackle. My goal is to create an object similar to this: { text: "hello {param1}", param1: { text:"world", class: "bla" } } The tricky part is that I want to ...

How can I extract a substring from a URL and then save it to the clipboard?

Hi there! I'm working on a project for my school and could really use your expertise. I need help extracting a substring from a URL, like this one: URL = https://www.example.com/blah/blah&code=12432 The substring is: 12432 I also want to display ...

Manually assigning a value to a model in Angular for data-binding

Currently utilizing angular.js 1.4 and I have a data-binding input setup as follows: <input ng-model="name"> Is there a way to manually change the value without physically entering text into the input field? Perhaps by accessing the angular object, ...

Issue: Catching errors in proxy function calls

I am currently using Vue 3 along with the latest Quasar Framework. To simplify my API calls, I created an Api class as a wrapper for Axios with various methods such as get, post, etc. Now, I need to intercept these method calls. In order to achieve this ...

Retrieve the chosen item from the autocomplete feature

Unfortunately, I have encountered an issue with this solution as I was unable to get it to work correctly in my code. The objective is to retrieve the selected item and then call another function to utilize it. The script is as follows: <script type=" ...

Is it possible to trigger a script tag based on certain conditions using a JavaScript function?

I'm currently working with Angular and have a requirement to trigger a third party script from a function located within another script tag. Here's an example scenario: Within the index.html file let displayOnHomepage = () => { if (win ...

The Hover Hover textbox stays in place once clicked on

I have implemented a search bar that displays a textbox when a user hovers over a button. I am looking to modify the code so that the textbox remains visible even after the user has clicked on it. This way, if the user accidentally moves their mouse away f ...

The ability to submit a conversation chat is currently

I encountered an issue when attempting to submit a chat, and I received the error message 'handlebar is not define'. I followed the code tutorial provided in this link: https://codepen.io/drehimself/pen/KdXwxR This is the screenshot of the error ...

Input for uncomplicated changing identifier

I am looking to create types for dynamic keys that will be of type number. I have two similar types defined as follows: type UseCalculatePayments = () => { totalPayments: number; aggregate: number; condition: boolean; }; type UseCalculateCommissio ...

Turning JavaScript Object into a Decimal Value

I've been working on an application where I want to be able to add up the columns of an HTML table. I managed to add inputs to the table successfully, but when trying to sum up the columns, I keep getting a "NaN" error. /* Function for calculating ...

I am experiencing some unwanted movement of divs when I hide one element and show another. Is there a way to prevent this from happening

My webpage features a dynamic div that transforms into another div upon clicking a button. Although both divs share similar properties, clicking the button causes some elements to shift unexpectedly. Strangely enough, when the height of the replacing div i ...

A simple guide on accessing a local PDF file and returning it as the response for an ExpressJS application

In my ExpressJS application, I have a method for generating a PDF file and sending it to the client. However, there are cases where I need to retrieve an existing local PDF file and return it as the response. I'm unsure how to handle this scenario. ...

Rotate a sphere in three.js in order to align the mapped image of the globe with the GeoJSON data that is displayed in the same three

I have successfully implemented a globe in three.js with an image mapped onto the sphere. Furthermore, I am utilizing the ThreeGeoJSON library to visualize geojson data on top of the globe. However, the geographies from the geojson data do not align corr ...