Guide on manipulating the position and orientation of external elements in three.js

I'm currently working on a small project that involves creating an interactive 3D scene on the web. To achieve this, I utilized three.js to import objects designed in Blender. Initially, I attempted to export the objects as JSON files, but encountered issues with importing them onto the web. As a result, I resorted to exporting the objects as individual .obj files and then imported each one separately.

My current task is to enable users to move and rotate each object along the Y-axis only. Since my design is based on a house plan, I specifically need the ability to manipulate each room through rotation and movement. Any assistance in finding a source for implementing this feature would be greatly appreciated.

Below is the code after setting up the scene and importing the objects individually:

  
var obj1 = {
  // Initialization
  scene: null,
  camera: null,
  renderer: null,
  container: null,
  controls: null,
  clock: null,
  stats: null,

  init: function() { 

    // create main scene
    this.scene = new THREE.Scene();
    this.scene.fog = new THREE.FogExp2(0xcce0ff, 0.0003);

    var SCREEN_WIDTH = window.innerWidth,
        SCREEN_HEIGHT = window.innerHeight;

    // prepare camera
    var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 1, FAR = 2000;
    this.camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
    this.scene.add(this.camera);
    this.camera.position.set(0, 100, 300);
    this.camera.lookAt(new THREE.Vector3(0,0,0));

    // prepare renderer
    this.renderer = new THREE.WebGLRenderer({ antialias:true });
    this.renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
    this.renderer.setClearColor(this.scene.fog.color);
    this.renderer.shadowMapEnabled = true;
    this.renderer.shadowMapSoft = true;

    // prepare container
    this.container = document.createElement('div');
    document.body.appendChild(this.container);
    this.container.appendChild(this.renderer.domElement);

    // events
    THREEx.WindowResize(this.renderer, this.camera);


    // prepare controls (OrbitControls)
    this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
    this.controls.target = new THREE.Vector3(0, 0, 0);
    this.controls.maxDistance = 2000;

    // prepare clock
    this.clock = new THREE.Clock();

    // prepare stats
    this.stats = new Stats();
    this.stats.domElement.style.position = 'absolute';
    this.stats.domElement.style.left = '50px';
    this.stats.domElement.style.bottom = '50px';
    this.stats.domElement.style.zIndex = 1;
    this.container.appendChild( this.stats.domElement );

    // add spot light
    var spLight = new THREE.SpotLight(0xffffff, 1.75, 2000, Math.PI / 3);
    spLight.castShadow = true;
    spLight.position.set(-100, 300, -50);
    this.scene.add(spLight);

    // add simple ground
    var ground = new THREE.Mesh( new THREE.PlaneGeometry(200, 200, 10, 10), new THREE.MeshLambertMaterial({color:0x999999}) );
    ground.receiveShadow = true;
    ground.position.set(0, 0, 0);
    ground.rotation.x = -Math.PI / 2;
    this.scene.add(ground);

    // load a model
    this.loadModel();
  },

  loadModel: function() {
    // Loading models of different rooms
    
     // Add multiple loader functions for each room here

  } 
};

// Animate the scene
function animate() {
  requestAnimationFrame(animate);
  render();
  update();
}

// Update controls and stats
function update() {
  obj1.controls.update(obj1.clock.getDelta());
  obj1.stats.update();
}

// Render the scene
function render() {
  if (obj1.renderer) {
    obj1.renderer.render(obj1.scene, obj1.camera);
  }
}

// Initialize lesson on page load
function initializeObj() {
  obj1.init();
  animate();
}

if (window.addEventListener)
  window.addEventListener('load', initializeObj, false);
else if (window.attachEvent)
  window.attachEvent('onload', initializeObj);
else 
  window.onload = initializeObj;

Answer №1

One way to manipulate objects in a 3D scene is by storing them in variables for easy access:

- Start by creating a variable: var myObj;

- When loading the object, assign it to the variable

oLoader.load('models/Living.obj', 'models/Living.mtl', function(object) {
      myObj = object;
      object.scale.set(10, 10, 10);
      obj1.scene.add(object);
    });

- In your animation loop, apply rotation to the object:

myObj.rotation.y = Date.now()*.002;

or perform other actions as needed


Alternatively, if your scene structure remains consistent, you can directly rotate the object using:

obj1.scene.children[4].rotation.y = Date.now()*.002;

Keep in mind that this method may require adjustments when modifying the scene setup, so caution is advised

To enable mouse-controlled rotation:

// Store previous mouse position to calculate movement
var lastMPos = {};

// Function triggered on mouse movement
function mousemove(event){

    // Calculate distance moved if there was a previous event
    if (typeof(lastMPos.x) != 'undefined') {

        var deltaX = lastMPos.x - event.clientX,
            deltaY = lastMPos.y - event.clientY;

        // Rotate the object based on mouse movement
        obj1.scene.children[4].rotation.y += deltaX  *.005;  
    }

    // Save current mouse position for next calculation
    lastMPos = {
        x : event.clientX,
        y : event.clientY
    };
}

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

Meshes eliminated following the update of buffer geometry vertex locations

After adjusting the buffer geometry vertex positions of certain objects, they are getting frustrum culled. I'm reluctant to disable frustrumCulled = false and changing the mesh position to anything other than (0,0,0) is not a viable option either. Wha ...

When you use ReactDOM.render inside a <div>, it does not instantly generate HTML code

I am currently working with React version 16.7 and attempting to embed React components into a third-party JavaScript library (specifically, Highcharts) that requires me to output HTML from a function. This is the approach I am taking at the moment: funct ...

Retrieve the div element by calling a scriptlet with JavaScript

I am facing an issue with a web page that includes a scriptlet like this: <div id="flash_chart"> <%=content_data['report_text']%> </div> The variable content_data['report_text'] contains a lengthy string ...

What is the best way to set the keyframes CSS value for an element to 0%?

Would like to create a progress indicator div using CSS animations? Check out the JSBin link provided. The desired behavior is to have the div width increase from 30% to 100% when the user clicks on stage3 after stage1, rather than starting from 0%. Althou ...

send information via an ajax call to trigger a callback function

Can data be passed through an Ajax request to the Callback function without using global variables? For example, can the request function pass the passData through the callback function while also getting normal response data? function makeRequest(callba ...

Refresh the angular list filter by clicking on it

I'm struggling with updating an Angular list after the filter is changed. Below is the HTML code I am using: <li ng-repeat="items in list | filter:filterList" style="list-style-type:none"> {{items}} </li> Additionally, here is the o ...

Use AngularJS to take tab delimited text copied and pasted into a textarea, and then convert it into a table

One of the features in my app requires users to copy and paste tab delimited text. I need to convert this text into a table where each new column is represented by a tab and each new row is indicated by a new line. I've managed to create a list for e ...

Using Vue.js along with vuex and axios allows for data retrieval only upon the second load

After creating a Vue.js app with vuex as a central store and using axios for basic API calls, I implemented the following store action: loadConstituencyByAreaCodeAndParliament({commit}, {parliament_id, area_code}) { axios.get('/cc-api/area-code/ ...

Having trouble connecting with Node.js and Express; encountering ERR_CONNECTION_REFUSED

I tried following this basic tutorial: After generating the files as instructed, I ran through all the steps but encountered an issue. Regardless of the browser I used, I kept getting "Unable to connect" in Firefox and "This webpage is not available ... E ...

Passing variable values from .post response to PHP: A guide

I'm currently working on integrating Geocode from the Google Maps API into my WordPress plugin within the wp-admin. I have created a custom post type that includes an input field for the address of a place, and I also have jQuery code set up to watch ...

What are the best options for storing small data in a React or Next.js project?

As I work on my personal portfolio using Next.JS, I've come to a point where I need to display multiple projects each with their own set of information like images, titles, and links. I'm wondering where would be the best place to store this data ...

Encountering [object, Object] while attempting to display JSON object retrieved from req.body in the console

While attempting to insert a product's details into my API's PostgreSQL database using Postman, I encountered an issue where the values of the specs key were displayed as [object Object] instead of showing the complete data. As a result, even in ...

Choose from the Angular enum options

I am working with an enum called LogLevel that looks like this: export enum LogLevel { DEBUG = 'DEBUG', INFO = 'INFO', WARNING = 'WARNING', ERROR = 'ERROR' } My goal is to create a dropdown select el ...

What is the process for including a new item in a JavaScript dictionary?

I'm currently learning JavaScript and I've encountered a challenge. I have a dictionary that I'd like to update whenever a button is clicked and the user enters some data in a prompt. However, for some reason, I am unable to successfully upd ...

Difficulties encountered while attempting to modify a class using Javascript

Recently, I've encountered an issue with my JavaScript where I am unable to keep a particular element's class changed. Despite attempting to change the class to "overlist", it only stays that way briefly before switching back to its original stat ...

Designing a menu header against a specific background color resulting in misalignment

I have been working on creating a menu header for my website. If you would like to take a look, here is the link to my jsfiddle page. Unfortunately, I am facing an issue where all my images and text should remain in that grey color scheme but somehow it& ...

Organize intricate JavaScript Arrays

Similar Question: How to sort an array of javascript objects? I'm in the process of transitioning some of my older ActionScript 2.0 code to JavaScript. While most things are running smoothly, I've hit a roadblock when trying to numerically s ...

Illumination causes surfaces to transform

In my simple scene, I have a ground and an interesting light source. However, when the light hits certain meshes, it creates some strange effects. The shadows are being cast correctly, but the other meshes affected by the light are showing unusual results. ...

How can I transfer checkbox data to another page utilizing ajax or javascript?

These are the checkboxes I am using and I want to pass the selected items' values to another page using ajax with javascript. I am looking to send the selected checkbox values through ajax to a different page... Your help would be greatly appreciate ...

When the back button on the browser is clicked, ensure that the customer is returned to the same position

What is my goal? I am looking to store the user's current position on the page so that when they navigate to another page and use the browser's "Back" button, they are taken back to that position. This behavior should only be triggered when the u ...