Discrepancies in rounding calculations between three.js on Chrome and Firefox

In my three JS scene, I have a plane positioned and rotated in a certain way. When I send a raycast towards this plane and project an object onto it, everything works perfectly fine in chromium but gets turned upside down in firefox.

This discrepancy is causing significant issues for me, and it seems to be related to a rounding error when the mesh updates the matrix.

To illustrate the problem, consider the following example:

const test = new THREE.Mesh(new THREE.PlaneGeometry(), new THREE.MeshBasicMaterial());
test.position.copy(new THREE.Vector3(-0.0800582263098657,0,-0.003907569688712309))
test.rotation.copy(new THREE.Euler(-1.5707963267948966,0,0, "XYZ"))
test.updateMatrix()
const asString = `[${test.matrix.elements.join(",")}]`
const chromeString = "[1,0,0,0,0,2.220446049250313e-16,-1,0,0,1,2.220446049250313e-16,0,-0.0800582263098657,0,-0.003907569688712309,1]"
console.log(`
${asString}
${chromeString}
${asString === chromeString ? "equal" : "not equal"}
`)

When running this code, you'll see that the output is equal for chromium but not for firefox. The difference lies in the sign change of the fifth element, which may seem small due to the 'e-16' value, but it causes the projection to flip in firefox.

I've experimented with manually setting the matrix to match the result in chromium (disabling matrixAutoUpdate), and that resolved the issue in firefox. Therefore, I believe the root cause lies within this calculation.

My question is: Is there a way to ensure consistent calculations across browsers by sacrificing some precision? I'm willing to make adjustments to achieve uniform behavior.

Answer №1

After much effort, I was able to come up with a solution that may not be the most efficient or elegant.

function adjustMatrixPrecisionOnObject(object: THREE.Object3D) {
    const update = object.updateMatrix;
    object.updateMatrix = function updateMatrix() {
        const precision = 10000000
        const round = (num) => Math.round(num * precision) / precision;
        this.position.setX(round(this.position.x));
        this.position.setY(round(this.position.y));
        this.position.setZ(round(this.position.z));
        this.rotation.set(
            round(this.rotation.x),
            round(this.rotation.y),
            round(this.rotation.z),
            this.rotation.order
        )
        update.call(this, {});
    }
}

When using this method with my object, the values are rounded to ensure compatibility with both V8 and SpiderMonkey. While it gets the job done, there may be a more optimal solution waiting to be discovered.

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

Encountering an issue with the date pipe in Angular that prevents

I'm trying to incorporate a date pipe in my AngularJS and Firebase project to display the creation date of a post. However, I am facing an issue where the date does not appear when testing it. Below is my create Post function: createPost() { con ...

X-ray Picker failing to retrieve a value

I am currently using the most recent version of the x-ray npm module in the code snippet below. Despite my expectations, the Meta and Metatags elements remain empty when I print out obj. Can anyone help me identify what I might be missing? var Xray = req ...

Having difficulty encapsulating three.js rendered particles within a single div

I'm facing an issue where the particles generated by my three.js project are not contained within a specific div or html element as intended. Instead of staying within the designated boundaries, the particles are spreading across the entire DOM witho ...

`an error occurs when trying to loop through an object and add a key``

I'm currently facing an issue with adding a key to an object through looping. Here is the code snippet: function checkResult(want, reference) { const keys = Object.keys(reference); for(let i=0; i<Object.keys(reference).length; i++){ console ...

Can Javascript be used to open a new window, send POST parameters to it, and pass the request as application/json?

I have a browser client application built with JavaScript that manages a large amount of state data. Sometimes, this data needs to be organized into a structured object and sent to a new window for further processing. Currently, I am using a solution wher ...

Tips on implementing a script injected through the JS console to update form data in an Angular webpage and ensure that the changes are successfully saved

I am currently working on enhancing an existing electron app integrated with Angular. The main goal is to inject a script once the application is loaded in order to add a hotkey for efficiency. This hotkey should automatically click an edit button, input s ...

What is the best way to eliminate a count from an array when a button is deselected using JavaScript?

Whenever a button is selected, the value appears on the console.log as expected when using an array. To enhance this functionality, I also need to find a way to remove the value from the console when the button is deselected. var totalWishlist = []; $( ...

Creating cutting-edge Hololens apps with WebGL and Three.js

My current project involves a WebGL application that I created using JavaScript and ThreeJS. While I was able to incorporate WebVR to create an immersive environment, I believe that my app could truly shine in mixed-reality/AR. From what I have observed, H ...

Dynamic css property implementation in Vue list rendering

I am currently working on creating a carousel-style list of items similar to the iOS native date/time pickers, where the list can be shifted both upwards and downwards. The positioning of each item is determined by the `top` property from a model, which i ...

What is the best way to retrieve a value from a JSON object using AngularJS?

Using nodeJS, the server sends a JSON object to the controller: data = { "question": "theQuestion", "answer": "theAnswer" }; res.json(data); In the controller, I attempt to manipulate the variable as follows: data = QA.get(); $scope.q = data[que ...

Is it advisable to subscribe to the entire database upon startup in Meteor?

Creating a Meteor app for the internal use of a company, I have designed it to track people and enable managers to assign tasks to various employees. Given the small size of the data being utilized, I anticipate that the database will not grow significantl ...

The jQuery menu is malfunctioning in Internet Explorer due to the Document Mode being set to Quirks

I am encountering an issue where the below code is not functioning properly in Internet Explorer's document mode quirks. Each time I hover over the submenu, its length doubles unexpectedly. Can someone please provide assistance with this matter? < ...

nodemon is launching an endless number of .node-xmlhttprequest-sync files

I am facing a strange issue with my app that imports a module containing a promise. Everything runs smoothly when I start the app using "node app.js" However, if I use "nodemon" to launch it, it constantly creates files with names like .node-xmlhttpreque ...

Utilizing JQuery for real-time total updates

When a new div is created by clicking a button, I want to dynamically maintain an order system where the first div is labeled as 1 of 1, then as more divs are added it should change to 1 of 2, and so on. If a div is deleted, the numbering should reset back ...

Guide to locating and substituting two integer values within a string using JavaScript

Given a string such as: "Total duration: 5 days and 10 hours", where there are always two integers in the order of days and then hours. If I need to update the old string based on calculations using fields and other values, what is the most efficient meth ...

What could be the reason for the issue `injection "store" not found` showing up when attempting to call `this.store.commit()`?

I am currently working on storing values with VueX, specifically using Vuex 4.0 instead of the older version 3.0. While attempting to commit a value, I encountered an issue as follows: ... this.$store.commit("changerusername", u) ... To addres ...

Automatically update div content using AJAX in a different approach

In my situation, I am facing a unique challenge compared to other queries. I have a div element with the following code <div id="ondiv"><?php ?></div> Within this PHP section are details of people who are currently online. Ideally, when ...

Adding a list without a specific order into a paragraph with the help of jQuery

Working on a client-side class, I am in the process of changing an XHR request and getElementById function to a jQuery ajax request along with jQuery document manipulation. The task at hand is to display descriptions of items available from "Rob's Roc ...

Striving to implement a dynamic dropdown menu using React's <select> element and rendering users from an array as selectable options

I am currently working on a project to develop an application that allows users to be added to a MongoDb database and have their names displayed in a dropdown menu. While creating the form, I encountered two issues - one related to the closing tag error a ...

I am experiencing difficulties in accessing the DOM

I have implemented jQuery $.ajax to dynamically load data into table rows as shown below: <table id='row-data'> <tr><td>1001</td></tr> <tr><td>1322</td></tr> <tr><td>15 ...