Using Three JS: Import an OBJ file, move it to the center of the scene, and rotate around it

I am trying to figure out how to load an OBJ file and translate its coordinates to the world origin (0,0,0) in order to make orbit controls function smoothly without using Pivot points.

My goal is to automatically translate random OBJ objects with different geometries/center points to the scene origin. I need a flexible solution that can work for any model, not just a hardcoded translate for a specific one.

This seems like a common scenario in Three JS (basic 3D object viewer), but surprisingly I haven't been able to find a definitive solution on Stack Overflow.

Many of the older answers I've come across use deprecated functions, so I'm hoping for a fresh answer even if there are similar solutions already available.

Some things I've experimented with:

  1. The code snippet below helps fit the object nicely within the camera view, but it doesn't completely solve the translation/orbiting issue.

    // Fit camera to object
    var bBox = new THREE.Box3().setFromObject(scene);
    var height = bBox.size().y;
    var dist = height / (2 * Math.tan(camera.fov * Math.PI / 360));
    var pos = scene.position;
    
    // Adjust position so object isn't too close or far
    camera.position.set(pos.x, pos.y, dist * 0.5); 
    camera.lookAt(pos);
    
  2. I've read about using geometry.center() to translate an object's coordinates back to the origin, but the old THREE.GeometryUtils.center has been replaced by geometry.center() and I keep encountering errors when attempting to implement it.

  3. Since geometry is now replaced by bufferGeometry when loading OBJs, I'm struggling to convert bufferGeometry into geometry to utilize the center() function. Do I need to place this in a loop within the object traversal > child loop? It all feels overly complex.

    geometry = new THREE.Geometry().fromBufferGeometry( child.geometry );
    

My current code simply involves an OBJLoader:

      var objLoader = new THREE.OBJLoader();
      objLoader.setPath('assets/');
      objLoader.load('BasketballNet_Skull.obj', function (object) {

            object.traverse( function ( child ) {

                if ( child instanceof THREE.Mesh ) {

                   child.material = material;

                }

        } );
       scene.add(object);
});

(By the way, this is my first time posting a question on Stack Overflow, so please excuse any formatting or beginner mistakes)

Answer №1

Why not use the object.geometry.center() method here?

var objLoader = new THREE.OBJLoader();
      objLoader.setPath('assets/');
      objLoader.load('BasketballNet_Skull.obj', function (object) {


            object.traverse( function ( child ) {

                if ( child instanceof THREE.Mesh ) {

                   child.material = material;
                   child.geometry.center();

                }

        } );
       scene.add(object);

Answer №2

After working through this, I've managed to make progress by utilizing some key functions from Meshviewer Master, an older Three JS object viewer. https://github.com/ideesculture/meshviewer I want to give full credit to Gautier Michelin for providing this valuable code https://github.com/gautiermichelin

Once the OBJ is loaded, there are three important steps to take:

1. Generating a Bounding Box based on the OBJ

    boundingbox = new THREE.BoundingBoxHelper(object, 0xff0000);

    boundingbox.update();

    sceneRadiusForCamera = Math.max(
        boundingbox.box.max.y - boundingbox.box.min.y,
        boundingbox.box.max.z - boundingbox.box.min.z,
        boundingbox.box.max.x - boundingbox.box.min.x
    )/2 * (1 + Math.sqrt(5)) ; // golden number to enhance display

2. Setting up the Camera according to the bounding box / scene radius

function showFront() {
if (objectCopy !== undefined) objectCopy.rotation.z =  0;
    controls.reset();
    camera.position.z = 0;
    camera.position.y = 0;
    camera.position.x = sceneRadiusForCamera;
    camera.lookAt(scene.position);
}

(the mesh viewer code also features functions for viewing left, top, etc)

3. Adjusting the position of the OBJ to the scene origin In any centering task, positioning involves dividing the width and height by 2

function resetObjectPosition(){
    boundingbox.update();

    size.x = boundingbox.box.max.x - boundingbox.box.min.x;
    size.y = boundingbox.box.max.y - boundingbox.box.min.y;
    size.z = boundingbox.box.max.z - boundingbox.box.min.z;

    // Repositioning object
    objectCopy.position.x = -boundingbox.box.min.x - size.x/2;
    objectCopy.position.y = -boundingbox.box.min.y - size.y/2;
    objectCopy.position.z = -boundingbox.box.min.z - size.z/2;
    boundingbox.update();
    if (objectCopy !== undefined) objectCopy.rotation.z =  0;

} 

Answer №3

Based on what you've mentioned, it seems like you're looking to have objects added to the scene appear at the center of the camera view. One common approach to achieving this is by incorporating camera controls into your scene, such as THREE.OrbitControls, and setting the target for the camera as the object you wish to focus on. By doing so, the desired object will be centered in the view, with the camera's rotation and movement being oriented around that specific object.

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

AngularJS $injector.unpr Error: Understanding and Resolving Common Dependency Injection

As a beginner in AngularJS JavaScript, I have recently started learning and practicing with some small sample programs. However, when attempting this particular code snippet, I encountered an error that I need help resolving. <body ng-app="myApp"> ...

Ways to consistently press a particular button every single second

The code on the webpage looks like this: <div id="content"> <div class="container-fluid"> Slots <p>The current jackpot is 23220!<p/> <p>You lose.</p> <form method=post action=/game ...

Converting JSON objects into datetime: A step-by-step guide

I am looking for a way to display JSON data in a Kendo chart. Below is the code I have: <head> <meta charset="utf-8"/> <title>Kendo UI Snippet</title> <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019 ...

Utilizing a function as a value in React state (setState) compared to defining state with constructor in a class and utilizing a state object

Can someone help me understand the concept of state in React better? I'm confused about the differences between these two implementations: This: class Todo extends ... { constructor (){ super() this.state = { ... } } } And This: class Todo extend ...

Is there a way to input the Sno data into the database in ascending order?

function table_insert(lease_ids){ var lease_id=lease_ids+1; var table = document.getElementById('table_data123'), rows = table.getElementsByTagName('tr'), i, j, cells, customerId; for (i = 0, j = rows.le ...

Obtaining essential data while facing a redirect situation

I need to extract the og data from a specific URL: https://www.reddit.com/r/DunderMifflin/comments/6x62mz/just_michael_pouring_sugar_into_a_diet_coke/ Currently, I am using open-graph-scraper for this task. However, the issue I'm facing is that it i ...

Conceal and reveal feature for multiple dynamic identifiers simultaneously

After submitting the form, I am dynamically creating buttons. <template name="workflow"> {{#each newaction}} <div class="btn-box" > {{> actioncardsubcontent}} <button type="button" class="cancelsub" >New Action</button&g ...

When testing the Next.js App locally, the APIs function properly. However, issues arise when attempting to deploy the app

Having trouble deploying my NextJS App APIs to Netlify. Everything runs smoothly locally, but I keep encountering this error when trying to deploy. https://i.sstatic.net/C8FUv.png ...

Using ObjectIDs in MongoDB may be successful, however, it may not function properly in Mongoose

The desired effect is successfully achieved by the first code snippet shown below: //in mongodb console: db.collection.update({"username":"name"}, {$pull : { "task" : { "_id" : ObjectId("55280205702c316b6d79c89c")}}}) However, the second code snippet wri ...

The Runtime Error encountered in NEXTJS: TypeError - Unable to iterate over 'games' as it is not

Attempting to create my inaugural website that showcases data from an API sans a tutorial. Does it seem like I may have overlooked something? I've successfully fetched the API and confirmed in the console log that the necessary data is present. Howev ...

Error message from Angular development server: Channel is reporting an error in handling the response. The UNK/SW_UNREACHABLE options

After recently installing a new Angular app, I encountered an issue while running 'ng serve'. The application initially loads without any problems, but after a few seconds, I started seeing a strange error in the console. Channel: Error in handle ...

Guide on creating an Iframe in HTML with JavaScript

Can someone help me troubleshoot why the following code isn't working to write an iframe into HTML using JavaScript? <html> <body> <script> document.write("<iframe width="560" height="315" src="https://www.youtube.com/embed/9Ow8 ...

Bidirectional updates in AngularJS with CSS styling

On the backend, certain HTML elements store their position and size persistently and retrieve them when the page loads. These elements can be dragged and resized by users, with any updates needing to be saved on the backend for consistency across sessions. ...

I'm looking to integrate Jest in my React project with npm. How can I achieve

I've developed my application with create react app and npm. While reviewing the official documentation for jest at https://jestjs.io/docs/tutorial-react, I noticed that they only provide information on testing CRA apps using yarn. Does this suggest t ...

Dynamic links with Node Acl

Utilizing the npm module Acl to establish an ACL system has been my current focus. You can check out the homepage of this module at: https://github.com/OptimalBits/node_acl. While the documentation provides straightforward examples for granting role acces ...

Tips for simulating or monitoring a function call from a separate file

Within my codebase, there is a function that is triggered upon submission. After the payload has been posted, I aim to execute a function located in a distinct file named showResponseMessage: Contact.js import { onValueChangeHandler, showResponseMessage, ...

Error: Unable to access the 'length' property of an undefined value | Solving the challenge of finding the shortest word within a string | Codewars Problem

I'm currently working on a function to find the shortest word in a given string of words. Issue: I encountered the error below TypeError: Cannot read property 'length' of undefined at findShort at Test.describe._ at /runner/fra ...

Executing a npm script (script.js) with custom arguments - a step-by-step guide

I'm considering creating a setup similar to lodash custom builds. Basically, I want to allow users to input a command like: lodash category=collection,function This would create a custom module with the specified category. I've been looking in ...

Changing the visual appearance of an alert in JavaScript and HTML

My knowledge in JavaScript is limited, but I have a script that retrieves a query from a Python service to a Mongodb database. The query is returned in the following format: [{CHAIN: "STREET ELM, ELMER", CODE: "1234"}, {CHAIN: "STREET LM, LMAO", CODE: ...

Begin counting when a particular div element is visible on the screen

I have a plugins.init.js file that contains a try-catch block which runs on page load. I am looking for a way to execute this code only once when the div with the class counter-value comes into view. Is there a method to achieve this? try { const count ...