Improperly aligned rotation using tween.js and three.js

Utilizing three.js and tween.js, my goal is to develop a Rubik's cube made up of 27 small cubes grouped together for rotation by +Math.PI/2 or -Math.PI/2. To ensure smooth rotation, I am implementing the tween library.

The specific issue I encounter is that if a face undergoes multiple rotations (more than 10), it becomes noticeably misaligned. Despite numerous attempts, I am unable to identify the solution for fixing this problem (view visual image of the issue).

Below is the function responsible for rotating the objects in the sample provided:

function rotate( ii ) {
    // Create a temporary object to group multiple objects together for rotation
    var rotationGroup = new THREE.Object3D();
    scene.add(rotationGroup);
    THREE.SceneUtils.attach( box[ ii ], scene, rotationGroup );
    rotationGroup.updateMatrixWorld();

    // Check for any active animations, and stop the function if so
    if( TWEEN.getAll().length > 0 )
        return;

    // Create the animation tween object
    var tween;
    var duration = 300;
    var radiants = Math.PI/2;
    tween = new TWEEN.Tween( rotationGroup.rotation ).to( { z: radiants }, duration );
    tween.easing( TWEEN.Easing.Quadratic.InOut );
    tween.onComplete(
        function() {
            THREE.SceneUtils.detach( box[ ii ], rotationGroup, scene );
            box[ii].updateMatrixWorld();
            scene.remove(rotationGroup);
        }
    );

    // Start the animation
    tween.start();
}

I am currently unable to create a functioning snippet on Stack Overflow, so I have included some code below replicating the issue within the example scenario provided:

var camera, scene, renderer;
var canvas;

var cameraControls;
var clock = new THREE.Clock();

var box = [];

// Additional functions and setup omitted for brevity

function rotate( ii ) {

    var rotationGroup = new THREE.Object3D();
    scene.add(rotationGroup);
    THREE.SceneUtils.attach( box[ ii ], scene, rotationGroup );
    rotationGroup.updateMatrixWorld();

    if( TWEEN.getAll().length > 0 )
        return;
    var tween;
    var duration = 300;
    var radiants = Math.PI/2;

    tween = new TWEEN.Tween( rotationGroup.rotation ).to( { z: radiants }, duration );

    tween.easing( TWEEN.Easing.Quadratic.InOut );
    tween.onComplete(
        function() {
            THREE.SceneUtils.detach( box[ ii ], rotationGroup, scene );
            box[ii].updateMatrixWorld();
            scene.remove(rotationGroup);
        }
    );

    tween.start();
}

// Additional scene setup and cube creation code

Logging the rotation values of rotationGroup and box[ii] to the console reveals a slight discrepancy in their rotations, with the Object3D rotation introducing a minor error on the fourth decimal digit.

Answer №1

I made some alterations to the anonymous function that runs after the tween finishes, incorporating code to verify the rotation and set the correct rotation value (credit to @WestLangley for identifying the solution).

 function() {
     THREE.SceneUtils.detach( box[ ii ], rotationGroup, scene );
     box[ii].updateMatrixWorld();
     scene.remove(rotationGroup);

     // Verify the rotation value and adjust accordingly
     var check = Math.floor( box[ii].rotation.z );
     if( check==1 )
         box[ii].rotation.z = Math.PI/2;
     else if( check==3 )
         box[ii].rotation.z = Math.PI;
     else if( check==-2 )
         box[ii].rotation.z = -Math.PI/2;
     else
         box[ii].rotation.z = 0;
 }

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

Locate the next element with the same class using jQuery across the entire document

I'm working with the following HTML: <section class="slide current"></section> <section> <div class="slide"></div> <div class="slide"></div> </section> <section class="slide"></section> ...

The initial render of children elements in React Google Maps Api may not display properly

I am struggling to incorporate the Google Maps API into my app. Everything works smoothly until I try to display a Marker at the initial rendering of the map. The Marker does not show up, but if I add another Marker after the rendering is complete, then it ...

When I try to use the mongoose find() function, I am receiving a Promise status of <Pending>

I recently developed a function to retrieve the list of all products stored in MongoDB using mongoose. However, when trying to log this information, I am unexpectedly getting a Promise instead. Below is the relevant code snippet: router.get('/', ...

`I am facing issues with class binding in Vue 3 when using SwiperJS`

Currently, I am working with Vue 3 along with swiperjs. I have encountered a problem related to the v-bind:class behavior in my project. The issue arises when transitioning to the second slide, where the !h-auto class does not get applied as expected. St ...

Display a specific section of an image as the background in a div, with the image scaled and positioned perfectly

Utilizing a 1900 x 1080 image within a div as the background <!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8" /> <style> html,body { height:100%; } #imageHolder{ ...

Optimizing File Transfers and Streaming Using Next.js and CDN Integration

As I work on developing a download system for large files on my website using Next.js and hosting the files on a CDN, I face the challenge of downloading multiple files from the CDN, creating a zip archive, and sending it to the client. Currently, I have i ...

Module fails to load in the proper sequence

As a .NET developer who is relatively new to modern client-side web applications, I am currently working on developing an Angular2 charting application using Chart.js. The modules are being loaded with SystemJS. Below is the content of my systemjs.config. ...

insert a new field into the database within Prisma while ensuring existing table data remains untouched

I have been working with the Prisma ORM and I currently have some data in my table. This is how my model looks: model User { id Int @default(autoincrement()) @id username String @db.VarChar(100) @unique } model Post { id Int @id @defa ...

The initial click may not gather all the information, but the subsequent click will capture all necessary data

Issue with button logging on second click instead of first, skipping object iteration function. I attempted using promises and async await on functions to solve this issue, but without success. // Button Code const btn = document.querySelector("button") ...

Learn how to effectively transfer data from $.getjson to PHP, specifically through the use of Laravel's @foreach loop

$.getJSON( 'http://localhost/media_books/index.php/new_books.json?provider_id=1&limit=99&offset=1') .done(function( json ) { $(tar).closest('.accordion').children('div').text(json); }); I have successfully obtaine ...

Tips for making WebDriver pause until Sencha AJAX request finishes

While testing a page with Selenium WebDriver, I encountered an issue related to the Sencha JavaScript library being used on the underlying page. The problem arises when I input a value into a field and an AJAX call is made to validate that field. If the va ...

Issue with validation of radio buttons in an AngularJS form

Currently, I'm in the process of building a web application that involves 4 radio buttons. My main focus now is on validating these radio buttons to ensure that none are checked by default. In the scenario where the user tries to submit the form witho ...

Camera rotation governing trajectory rotation

Currently, I've been experimenting with a space simulator demo using three.js and flightcontrols.js (a built-in example in three.js). If you'd like to check out the demo, you can view it here: The control system is straightforward - the mouse c ...

fresh map from Google: Coordinates LatLng may not be a number, but my hunch tells me it is

Seeking Assistance with this Issue - For example, the initial location data appears as: "Object Lat: -36.768498 Lng: 174.75895" However, an error is indicating that the latitude is not recognized as a number. Rather than making adjustments without clea ...

having trouble adjusting the width of the buefy modal

Currently, I am working with vuejs alongside bulma and buefy. Specifically, I am utilizing the buefy modal feature and attempting to customize the modal width by utilizing its 'width' property. Thus far, I have attempted specifying the width in t ...

Are 'const' and 'let' interchangeable in Typescript?

Exploring AngularJS 2 and Typescript led me to create something using these technologies as a way to grasp the basics of Typescript. Through various sources, I delved into modules, Typescript concepts, with one particularly interesting topic discussing the ...

Does Material-UI MenuItem pass arguments to the onClick handler function?

I am currently working with a search.js file and a search-date.js file. Within the search.js file, there is a container called SearchDate which I render. However, I'm puzzled by the behavior of the MenuItem component when it is clicked. The function ...

What is the proper way to combine two arrays containing objects together?

I am faced with the challenge of merging arrays and objects. Here is an example array I am working with: [ { name: "test", sub: { name: "asdf", sub: {} } }, { name: "models", sub: {} } ] ...

Steps for automatically retrying a failed expect statement in Jest

In my React application, I am utilizing Jest for performing unit testing. One aspect of my application involves a Material UI date picker with next and previous buttons. The selected date is displayed in the browser URL. Each time the user clicks on the ne ...

Include a fresh attribute in the Interface

How can I include a boolean property isPhotoSelected: boolean = false; in an API interface that I cannot modify? The current interface looks like this: export interface LibraryItem { id: string; photoURL: string; thumbnailURL: string; fi ...