The unusual spinning behavior of child elements in three.js

My current project involves implementing an experimental version of a 2x2x2 Rubik's Cube. I have gathered insights from two previous posts that addressed issues related to attaching and detaching child objects in Three.js: Three.js: Proper way to add and remove child objects using THREE.SceneUtils.attach/detach functions and Three.js: Adding and Removing Children of Rotated Objects. By following these references, I have managed to rotate two faces independently with success.

However, when I try to replicate the same rotations through my code, I encounter unexpected results as the rotations are applied sequentially. This anomaly suggests that there might be inaccuracies in the transformations happening somewhere in the process. Despite thoroughly checking every matrix associated with the parent object, the issue persists after each rotation ends. Surprisingly, individual rotations work accurately, indicating that I managed to get about half of the steps right :). You can view a sample of the 2x2x2 cube here.

Here are snippets of the relevant code: --> For the event handler for rotating the right face

function rotateR()
{
    for(var i = 0; i < cubies.length; i++)
            if((pos(cubies[i]).x >= 53) && (pos(cubies[i]).x <= 55))
                active.push(cubies[i]);

        for(var i = 0; i < active.length; i++)
            console.log(active[i]);

        //reset pivot rotation
        pivot.rotation.set( 0, 0, 0 );
        pivot.updateMatrixWorld();

        //attach active[i] cubies to the pivot
        for (var i = 0; i < 4; i++)
            THREE.SceneUtils.attach(active[i], scene, pivot);   
        console.log("attached!");
        attachedR = true;
    }

In the render function:

if((pivot.rotation.x <= 1.580000000000001) && (attachedR === true))
{
            pivot.rotation.x += 0.02;
            console.log(pivot.rotation.x);
            if(pivot.rotation.x == 1.580000000000001)
            {
                attachedR = false;
                for(var i = 0; i < active.length; i++)
                    console.log(pos(active[i]).x + ", " + pos(active[i]).y + ", " + pos(active[i]).z);

                //Detach active[i] cubies from the parent pivot
                pivot.updateMatrixWorld();
                for(var i = 0; i < active.length; i++)
                {
                    active[i].updateWorldMatrix();
                    THREE.SceneUtils.detach(active[i], pivot, scene);
                }
            }
        }

The event handler and incremental animation functions for the Upper face follow the same pattern and reside in the same location within the code. The pos(cubies[i]) function provides the world coordinates of the mesh object. Where could I potentially be making errors in the rotational aspects of the cube faces? Any assistance would be greatly appreciated. Thank you.

Answer №1

One of the main issues identified was the active array never being emptied

Additionally, there is a significant amount of matrix updates happening, even when unnecessary

I've revamped your JavaScript code to now simply attach the cubes, perform the rotation, and then detach the cubes while resetting the rotation.

JavaScript

//Rotate Right face of cube
function rotateR()
{
    //Identify cubies within the right face of the cube and add them to active[i]
    for(var i = 0; i < cubies.length; i++) {
        var x = pos(cubies[i]).x; 
        if(x >= 54 && x <= 56)
            active.push(cubies[i]);
    }

    if (active.length != 4) alert ("active num wrong");
    
    //Attach active[i] cubies to the pivot
    for (var i = 0; i < 4; i++)
        THREE.SceneUtils.attach(active[i], scene, pivot);   
    attachedR = true;
}

//Rotate Upper face of the cube
function rotateU()
{
    //Find cubies that lie in the up face of the cube and store them in active[i]
    for(var i = 0; i < cubies.length; i++) {
        var position = pos(cubies[i]); 
        if(position.y >= 54 && position.y <= 56) {
            active.push(cubies[i]);
        }
    }

    if (active.length != 4) alert ("active num wrong");

    //Attach active[i] cubies to the pivot
    for (var i = 0; i < 4; i++)
        THREE.SceneUtils.attach(active[i], scene, pivot);
    attachedU = true;
}

function detachAndReset()
{
    for(var i = 0; i < active.length; i++)
    {
        THREE.SceneUtils.detach(active[i], pivot, scene);
    }
    active.length = 0;
    attachedR = false;
    attachedU = false;
    pivot.rotation.x = 0;
    pivot.rotation.y = 0;

}

//Get world position of cubies[i]
function pos(object)
{
    var position = new THREE.Vector3();
    position.setFromMatrixPosition( object.matrixWorld );
    return position;
}

function render()
{
    var endAnimation = false;

    //Rotate Right face of cube
    if(attachedR === true)
    {
        pivot.rotation.x += 0.02;
        if(pivot.rotation.x >= Math.PI / 2.0) {
            pivot.rotation.x = Math.PI / 2.0;
            endAnimation = true;
        }
    }

    //Rotate Upper face of cube
    if(attachedU === true)
    {
        pivot.rotation.y += 0.02;
        if(pivot.rotation.y >= Math.PI / 2.0) {
            pivot.rotation.y = Math.PI / 2.0;
            endAnimation = true;
        }
    } 

    renderer.render(scene, camera);
    if (endAnimation) {
        detachAndReset();
    }
}

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

Incorporating a Favicon into your NextJs App routing system

Encountering an issue with the new Next.js App Router. The head.js files have been removed, thus according to the documentation I need to implement metadata in layout.ts. My favicon file is named favicon.png. How should I specify it within the following c ...

Error with Ajax-bound selection (dropdown) - possibly due to an empty list in certain browsers

Upon taking over a project involving ASP.Net AJAX and JSON, I encountered an issue on a page that loads a large select (combo box) list of 1,430 entries. This list loads successfully on our main search page but produces an error in MicrosoftAjaxTemplates.d ...

Gauging Screen Size: A Comparison between Media Queries and JavaScript for Adjusting Div Position

I am currently facing an issue with the banner on my website. It contains a slider and has a position set to absolute. The problem arises when viewing it on smaller screens, as only the left side of the wide banner is visible. Initially, I tried using med ...

Decline the input according to the percentage

After experimenting with the script, I discovered that it did not perform as expected (even though it works on Google Webapp's script HTML form). My goal is to invalidate an input if the Downpayment is less than 30% or more than 100% of the Price, in ...

Add a style to every div except for the final one

I've attempted to add a unique style to all divs with the same class within a parent div, except for the last one. Strangely, my code doesn't seem to work as expected for this particular case. Can anyone spot what I might be overlooking? Right no ...

Executing MySQL queries synchronously in Node.js

When working with NodeJS and mysql2 to save data in a database, there are times when I need to perform database saves synchronously. An example of this is below: if(rent.client.id === 0){ //Save client connection.query('INSERT INTO clients (n ...

Aggregate the values of a key in an associative array and organize them by their respective key

I have a table set up like this: <table> <thead> <th>PRODUCT</th> <th>QUANTITY</th> <th>AREA</th> <th>PRICE</th> <th>TOTAL</th> <tr> &l ...

Refresh an iframe smoothly and without any visual distraction (using JavaScript)

Does anyone have a clever solution to dynamically refresh an iframe without the annoying flickering or flashing that usually occurs when the page reloads? Is it possible to incorporate a smooth blur-out and blur-in animation instead of the unappealing flic ...

Refresh the form fields using PHP_SELF after submission

How can I pass a calculated value to another form field using php_self to submit a form on the same page? The $title_insurance field is not getting populated, any suggestions on what might be causing this? <?php if(isset($_POST['submit'])) { ...

Obtain the URL value using jQuery and place it inside a <span> element

How can I insert a href value into the span tag like this? <p class="name"> <a download="adja-lo.pdf" title="adja-lo.pdf" href="http://localhost/MatrixDRSnews/apps/Matrix/server/php/files/adja-lo.pdf">adja-lo.pdf</a> </p> ...

The offspring of a React component

How can I select a specific div in children using React without passing it as a prop? I want to transform the code snippet from: <Pane label="Tab 1"> <div>This is my tab 1 contents!</div> </Pane> to: <Pane> <div&g ...

Why is DynamoDB still not deleting the item even though the promise returns successfully?

Using the DynamoDB DocumentClient, I attempted to delete items across multiple tables using Class: AWS.DynamoDB.DocumentClient A problem arose when I tried to delete items from multiple tables using promised.all(). The operation ran without deleting the i ...

Tips on incorporating an item into an array solely when a specific condition is met

Consider the following arrow function that creates an array: const myFunction = () => ["a", "b", "c"]; I am looking to modify this function to add another element if a specific argument is true. For example, I want it to look like this: const myFunc ...

What are the appropriate situations for utilizing getStaticPaths()?

Right now, an API call is being made in a main component and the fetched data is saved in a Singleton. This singleton data needs to be accessed by the getStaticPaths() function. However, due to the fact that getStaticPaths() pre-renders it, the singleton ...

Secondary camera in THREE.js rotates in sync with head rotation in virtual reality

Combining THREE.js and Aframe (in Exokit) has led me to develop a unique "selfie camera" component. However, I've encountered an unusual issue where the camera rotation is affected by head rotation when entering VR mode. Although I am aware of the cha ...

What is the method for performing a spelling check on every property within an array of Objects?

I'm working on a program that takes a user input as an argument and then searches for a similar match in an array of objects. The array of objects is retrieved from a database. When the user inputs a name, the search criteria should find objects with ...

Improving the display of events with fullcalendar using ajax requests

I have integrated the fullcalendar plugin from GitHub into my project. I am looking to implement a feature where I can retrieve more events from multiple server-side URLs through Ajax requests. Currently, the initial event retrieval is functioning proper ...

"Hey, getting an error stating 'require is not defined' while attempting to configure the .env file. Need some help here

I am currently working on setting up a .env file to securely store the credentials for my Firebase database within a vanilla JavaScript project. Despite following various tutorials and referencing the documentation for dotenv, I continue to encounter an er ...

The cloud function in Firebase was unable to connect to the dialogflow route

I am currently working on creating a chatbot using Dialogflow integrated with OpenAI in Firebase Cloud Function. However, I am facing an issue where I cannot access the /dialogflow endpoint and keep receiving the error message: "Cannot GET /dialogflow". My ...

Guidelines on populating a Vue array with data fetched from an Axios request

The v-breadcrumbs component is used to display data from the breadcrumbs array, which works seamlessly with static data. <v-row> <!-- Breadcrumbs --> <v-col class="d-flex"> <v-breadcrumbs :items="breadcrumbs"></v ...