Assigning the matrixWorld attribute to an object in three.js

I'm working with a 4x4 transformation matrix in Octave that encodes rotation and position data. After confirming that this matrix represents a valid transformation, I want to use it to set the matrixWorld property of a three.js Object3D object. This involves setting the position and rotation of the object based on the transformation matrix.

Based on information from the three.js documentation and various discussions online, it seems that setting nameOfObject.matrixAutoUpdate to false is crucial. However, despite trying different approaches to set nameOfObject.matrixWorld, the object still renders at the origin with no rotation.

Here are the methods I've attempted within an update method before calling render():

// Creating a three.js matrix
var tempMatrix = new THREE.Matrix4();
tempMatrix.fromArray(arrayContainingTransformationMatrix);

// Values are correctly set
console.log(tempMatrix.elements);

// The following approaches were tried individually

// First approach (unsuccessful)
nameOfObject.matrixAutoUpdate = false;
nameOfObject.matrixWorld.copy(tempMatrix);

// Second approach (also unsuccessful)
// Based on a related SO question
nameOfObject.matrixAutoUpdate = false;
nameOfObject.matrix.copy(tempMatrix);
nameOfObject.updateMatrixWorld(true);

// Third approach (also unsuccessful)
nameOfObject.matrixAutoUpdate = false;
nameOfObject.matrixWorld.fromArray(arrayContainingTransformationMatrix);

// Regardless of the approach, the console shows correct values
console.log(sphere1.matrixWorld.elements);

Some additional points to consider:

  • I understand that setting matrixAutoUpdate to false may not need to be repeated in every iteration, but I have done so as a precaution.
  • Modifying nameOfObject.position based on the fourth column of the transformation matrix results in the expected position change, ruling out a rendering issue.
  • While it's advised not to call updateMatrix() when manually adjusting the matrix, information on the implications of updateMatrixWorld() is less abundant.

Any advice on this matter would be greatly appreciated. If needed, I will delve into the source code, but I believe there might be a simple solution I am overlooking in my use of three.js.

Answer №1

At the present moment, I have successfully obtained the desired outcome by adjusting the object's matrix property (which represents the local transform in relation to the object's parent). Given that the object's parent is scene, the following code snippet functions as intended:

scene.add(nameOfObject);

// Utilizing this transformation matrix (a translation of two units along the x-axis):
// 1 0 0 2
// 0 1 0 0
// 0 0 1 0
// 0 0 0 1

// Column-major rendition of the transformation
var tempArrayCM = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 0, 1];
// As per the documentation, Matrix4.fromArray() employs column-major format

// Row-major rendition of the transformation
var matrixT = new THREE.Matrix4();
matrixT.set(1, 0, 0, 2, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
// As per the documentation, Matrix4.set() employs row-major format

nameOfObject.matrixAutoUpdate = false;

nameOfObject.matrix.fromArray(tempArrayCM); // This functions as expected

//nameOfObject.matrix.copy(matrixT); // This also functions as expected

//nameOfObject.matrixWorld.fromArray(tempArrayCM); // Does not have any effect

//nameOfObject.matrixWorld.copy(matrixT); // Does not have any effect

It appears that setting matrixWorld does not yield the desired results. This may not pose an issue when the object is a child of scene, but complications can arise if the object is a descendant of a child of scene and there is a need to set its global position independently from its parent (edit: it seems that the attach and detach methods from SceneUtils could facilitate this, albeit indirectly).

I will refrain from marking this as the definitive solution since it is essentially a workaround that is applicable only when the object's parent is scene.

On a side note: I find it slightly peculiar that Matrix4.set() utilizes row-major order while Matrix4.fromArray() and Matrix4.elements utilize column-major order.

Answer №2

Examining the source code.

updateMatrix: function () {
        this.matrix.compose( this.position, this.quaternion, this.scale );
        this.matrixWorldNeedsUpdate = true;
    },

Upon closer inspection, it becomes evident that the matrix of an Object3D is constructed using its position, quaternion, and scale properties.

Therefore, instead of directly setting the matrix, it may be more convenient to manipulate the individual components that make up the matrix.

For instance, the following code snippet repositions the scene to center it within a specified range and scales it accordingly.

    let xrange = xmax-xmin, yrange = ymax-ymin, zrange = zmax-zmin;
    let range = (xrange+yrange+zrange)/3;
    scene.scale.set(2/range,2/range,2/range);
    scene.position.set( -(xmax+xmin)/2, -(ymax+ymin)/2, -(zmax+zmin)/2); 
    seene.updateMatrix();

Answer №3

Typically, the matrixWorld of an object is updated using the methods outlined below:

    let object = new THREE.Object3D();
    let matrixWorld = new THREE.Matrix4();
    // By decomposing the matrixWorld, we can update the object's position, rotation, and scale.
    matrixWorld.decompose(object.position, object.rotation, object.scale);

These recommendations are provided in the official documentation for the Three.js library.

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

"Error encountered when attempting to call the requestFocus() method on a Java applet from JavaScript

I'm encountering an issue with calling the requestFocus() method in JavaScript. Uncaught TypeError: Object #<HTMLAppletElement> has no method 'requestFocus' Below is my JavaScript code within the <head> tags: function onLoad() ...

Improve the translation animation on an element containing numerous child nodes

Looking for ways to enhance the smoothness of the transition in the "infinity list" animation. While it's just a demo at the moment, the real app will have various elements emerging from each "pin". The main performance bottleneck seems to stem from t ...

Learn how to use the Firebase Adapter for Next Auth to easily sign in using your email and password

I am currently using next-auth along with a Firebase adapter for authentication, but I am uncertain about the correct way to sign in users. I do not want to utilize my Google account for signing in; instead, I have user accounts within a Firebase project a ...

Discovering the technique to interact with obscured objects through a haze of PointsMaterial in three.js

Is there a property that allows objects behind a fog of multiple points to be clickable? I want to be able to click on objects even when they are obscured by the fog. Below is the code I am using to create and animate the fog: const loadFogEffect = () =&g ...

What is the best way to utilize this resulting value as an input?

I am trying to generate a random number using math.random and use that value in the following script: let bday = Math.floor( Math.random() * (30 - 1 + 1) + 1 ); await test.page.select('select[name="day_select"]',bday); However, I am ...

What is the best way to implement custom serialization for Date types in JSON.stringify()?

class MyClass { myString: string; myDate: Date; } function foo() { const myClassArray: MyClass[] = .... return JSON.stringify(myClassArray); // or expressApp.status(200).json(myClassArray); } foo will generate a JSON string with the date format o ...

Examining the process through which an element attains focus

Scenario I am working on a Backbone application that has an event listener set up for focus events on a textarea. Since Backbone relies on jQuery events, my main concern revolves around jQuery focus events. Inquiry Is there a method to determine how an e ...

Tips on ensuring Angular calls you back once the view is ready

My issue arises when I update a dropdown list on one of my pages and need to trigger a refresh method on this dropdown upon updating the items. Unfortunately, I am unsure how to capture an event for this specific scenario. It seems like enlisting Angular ...

"Turn a blind eye to Restangular's setRequestInterceptor just this

When setting up my application, I utilize Restangular.setRequestInterceptor() to trigger a function that displays a loading screen whenever a request is made with Restangular. Yet, there is a specific section in my application where I do not want this fun ...

Steps to implement jQuery after executing the command "npm install jquery"

Greetings! I recently utilized npm install jquery to add jQuery to my project. However, I noticed that it was downloaded into node_modules\jquery along with some unnecessary files. My goal is to only move node_modules\jquery\dist\jquer ...

Discover how to access all of the response headers from an HTTP request in Angular

Currently, I am utilizing HttpClient to make a request for a `json` file. My intention is to have the file cached using `ETag`, however, this feature does not seem to be functioning as expected. Upon investigation, it appears that the absence of sending of ...

Leveraging Three.js Raycaster for a seamless PDF download functionality

Is there a way to trigger a PDF download when clicking on a 3D object in a Three.js scene? Below is an example of how I have set up the Raycaster: var raycaster; var mouse = { x: 0, y: 0 }; init(); function init() { raycaster = new THREE.Raycaster() ...

What could be causing my Express API registration route to fail when attempting to POST?

Currently, I'm in the process of developing a compact authentication system for a practice project that I've undertaken. As part of this endeavor, I am sending POST requests via Postman to my Express server located at http://localhost:4000/api/re ...

Unexpected behavior encountered with Angular module dependency injection

Having some difficulty managing dependencies for my node app. Here's the current structure: app.js var app = angular.module('myApp', ['myController', 'myFactory', 'rzModule', 'chart.js', 'myServ ...

Sending dynamic data through AJAX to a CodeIgniter controller is a common task that allows for seamless

Can anyone help me with retrieving data from a looping form in CodeIgniter? The form works fine, but I'm struggling to fetch the looping data in the controller. Here's my view (form): <form action="#" id="ap_data"> <div class="table-r ...

Troubleshooting Variable Issues in PHP and JavaScript

On my PHP page, I have a while loop where I am retrieving the following... print $divLeft.strip_tags($row->twitterUser)."?size=normal\"/><br \/>".$row->twitterUser.$divRight."<a href='javascript:void(0);' id=&apos ...

Problem arises when a recursive function call is nested within a request in an asynchronous setting

Currently, I am working on the task of finding a specific document path by providing its name as an argument. In the fetch_doc_path function, I am making two get requests to retrieve a JSON file containing information about all files. Subsequently, I recur ...

Using Vue.js to apply different CSS classes based on multiple conditions

Is there a way to highlight rows in a table based on specific conditions? For example, when the fine is greater than zero (fine > 0) or the due date is later than today. The current code works well for highlighting rows where issue.fine is greater than ...

Submit a data array using formData through axios

I am planning to send array data using formData. The backend is set up to accept the data array separated by a dash ; For example, if I were to use Postman and input the form-data like this: id_barang : 122;288;383 (sending 3 values of id with dashes ;) W ...

Verify whether all the elements within a specific div are distinct by utilizing jQuery

I need to create a select box that, when an option is chosen, generates a certain number of textboxes within a div. Currently, there are three fields: display_name[], user_name[], and user_password[] The code for this functionality is as follows: <se ...