How can I incorporate various Mixamo animations onto an FBX model in Three.js without skins?

I'm working on developing a game that features an animated character with various animations sourced from Mixamo. The goal is to have the character's animation change dynamically based on user interactions within the game, such as Walking, Running, or Idle. Here's how I am currently loading the FBX model (without animations):

loader.load('Assets/Animations/Main.fbx', function(object){
    object.traverse(function (child){
        if (child.isMesh) {
           child.castShadow = true;
           child.receiveShadow = true;
           child.frustumCulled = false;
        }
   });

   object.rotation.x = Math.PI / 2
   object.position.x = 11;
   scene.add(object);
});

Additionally, I have separate files for animations that do not include skin:

Idle.fbx
Walking.fbx
Running.fbx

The end goal is to achieve something similar to the examples shown here or here. However, both of these references present challenges; one relies on a model with multiple animations attached (while my model has three animations without skin), and the other is written in TypeScript instead of JavaScript.

Being relatively new to 3D modeling, I'm unsure about how to attach all the skinless animations to the main fbx model. Is there a way to combine these animations into a single model using Blender, or can this be achieved directly in three.js?

I would greatly appreciate any guidance or assistance with this. Thank you!


EDIT:

In response to @GuyNachshon's suggestions, should I approach it like this?

First, load the model without animations (yourMesh) and establish an AnimationMixer:

var mixer;

loader.load('Assets/Animations/Main.fbx', function(object){
    object.traverse(function (child){
        if (child.isMesh) {
           child.castShadow = true;
           child.receiveShadow = true;
           child.frustumCulled = false;
        }
   });

   mixer = new THREE.AnimationMixer(object);
   object.rotation.x = Math.PI / 2
   object.position.x = 11;
   scene.add(object);
});

Next, load the three animation files without skin and add them to an animationsArray. (Not entirely certain if this is the correct method of loading animations...):

loader.load('Assets/Animations/Idle.fbx', function(object){
    object.traverse(function (child){
        if (child.isMesh) {
           child.castShadow = true;
           child.receiveShadow = true;
           child.frustumCulled = false;
        }
   });

   object.rotation.x = Math.PI / 2
   object.position.x = 11;

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

loader.load('Assets/Animations/Walking.fbx', function(object){
    object.traverse(function (child){
        if (child.isMesh) {
           child.castShadow = true;
           child.receiveShadow = true;
           child.frustumCulled = false;
        }
   });

   object.rotation.x = Math.PI / 2
   object.position.x = 11;

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

loader.load('Assets/Animations/Running.fbx', function(object){
    object.traverse(function (child){
        if (child.isMesh) {
           child.castShadow = true;
           child.receiveShadow = true;
           child.frustumCulled = false;
        }
   });

   object.rotation.x = Math.PI / 2
   object.position.x = 11;

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

Once all assets are loaded, initiate the actions:

let actions = mixer.clipAction(animationsArray).play();

And then follow up with:

actions.play();

Will this line trigger the playback of the first animation within animationsArray?

Answer №1

To implement the animations in your project, you will first need to create an AnimationMixer. This allows for smoother animation transitions and control.

Assuming you have set up your scene and added a mesh, the next step is to initialize the animation mixer:

let mixer = new THREE.AnimationMixer(yourMesh);

After initializing the mixer, you can add animations using clipActions:

let actions = mixer.clipAction(animationsArray).play();

To play the animations, call the play method on the actions:

actions.play();

For a better understanding of how to utilize the AnimationMixer, refer to the documentation provided above.


Edit - Addressing your recent edit

If you want to specify which animation should play, there are various methods available. Here's an example from the official documentation:

const mixer = new THREE.AnimationMixer(mesh);
const clips = mesh.animations;

// Update the mixer on each frame
function update() {
    mixer.update(deltaSeconds);
}

// Play a specific animation
const clip = THREE.AnimationClip.findByName(clips, 'dance');
const action = mixer.clipAction(clip);
action.play();

// Play all animations
clips.forEach(function (clip) {
    mixer.clipAction(clip).play();
});

If you're struggling with organizing your code structure, here's a general example demonstrating how to attach animations to an FBX model and manage them:

let mixer = THREE.AnimationMixer;
let modelReady = false;
const animationActions = THREE.AnimationAction;
let activeAction = THREE.AnimationAction;
let lastAction = THREE.AnimationAction;
const fbxLoader = new FBXLoader();

Once everything is initialized, proceed to load the necessary components:

// Code snippet truncated for brevity

Define the animations and actions:

// Code snippet truncated for brevity

Let the animations begin!

// Code snippet truncated for brevity

Putting it all together:

// Import necessary modules and components
import * as THREE from 'three';
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader';

// Define variables and functions for managing animations
// Code snippet truncated for brevity

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 in three.js: Undefined property 'center' cannot be read

I am currently attempting to import an OBJ file on a server using node.js and three.js, but I am encountering an error after parsing the file. Below is the code snippet that showcases how I am importing the geometry: var loader = new THREE.OBJLoader() ...

Screen the $http request information prior to transmission

Angular has a built-in feature that removes properties with a prefix of $$ from request data or params objects. I want to filter out my own UI-specific properties that I don't want to send to the server, but I don't want to rely on using $$. Is ...

The sequence in which three.js resources are loaded

In my project, I am dealing with loading a 3D model using THREE.LoadingManager along with several textures. However, a recurring issue I face is that when I open the page with a cleared cache, the model loads without textures. I am able to see the textures ...

Unable to display images using jquery

Just getting started. I'm attempting to load images from a folder. The HTML and JavaScript files are located in the same directory as the images, yet I am still unable to load them. $(function() { $('#main').append('<img src="plus. ...

Difficulty retrieving information using AngularJS service post selection of item

Currently, I am working on a project involving an AngularJS application. While using the service testPanelService, I encountered a problem where selecting an item from a list correctly logs the details of the selected item. However, when attempting to fetc ...

Challenges with synchronizing Highcharts horizontally

I have been working on implementing synchronized charts in my application by using the example code provided by Highcharts here. My layout consists of columns created with the Materialize framework, and I placed the charts side by side in a row. However, I ...

Interactive form featuring text fields and dropdown menus

Is it possible to create a form with the ability to add new rows consisting of SELECT and INPUT elements? Although my current code allows for this, I am facing an issue where no variable from the SELECT element is posted when the form is submitted. This i ...

Update the positioning of the element to center instead of the default top left origin using jQuery

I am facing an issue with positioning a marker inside a triangle, which is represented by a simple div, as shown in the image below: https://i.stack.imgur.com/0Q7Lm.png The marker needs to be placed exactly at the centroid of the triangle. However, it see ...

notifications failing to load properly on my rails application

I have created a rails application where users can comment on specific tasks. Whenever a new comment is posted on a task, all the users following that project should receive a notification. However, I am facing an issue where my ajax notifications are not ...

Challenges with splitting asynchronous code in NPM modules

Earlier, I posted a query on Stack Overflow I have recently established a local package within the main app's package.json: "contact-page": "file:local_modules/contact-page" The package.jsonmain and scripts sections for the contact module are confi ...

Unlocking Secret Data with External JavaScript

Currently, I am focusing on validating user input, specifically the name to ensure it is at least 6 characters long. Although I plan to implement more validation, I am facing an issue with error display. When the JavaScript code is embedded within the HTML ...

When using $http in AngularJS, an error may occur when it

I ran a test on my PHP code independently and obtained the following output: {"tabId":1,"tabName":"Main","uId":"1"}{"tabId":2,"tabName":"Photography","uId":"1"} However, my AngularJS application is unable to receive the callback and is throwing an error ...

Looking for assistance with finding a specific value in Firestore?

As I venture into using firestore for the first time, I'm in the process of creating a registration page with vue. One crucial step before adding a new user to the database is to validate if the provided username already exists. If it does not exist, ...

Discovering the overlap between two arrays using Node.js

Question: Simplest code for array intersection in JavaScript In the development of my app using Mongodb and Nodejs, I am working with a 'students' collection that includes an array listing all the courses (course IDs) a specific student has ta ...

What does my HTML code show in the console log for the AJAX data?

Need some help with transferring data using an ajax request. Trying to send the input field contents, but getting unwanted html code in output of console.log("ok" + data), while console.log("ok" + formData) gives the desired value. In my Django view, the ...

The steps to properly load "child.vue" into the correct position within "parent.vue" are as follows

Currently I am developing a single page web application using Vue.js. This app consists of 4 "page.vue" files, each with a right and left child .vue component nested inside. For instance, the Page1.vue file is structured as follows (omitting style and scr ...

Real-time Data Stream and Navigation Bar Location

Utilizing the EventSource API, I am pulling data from a MySQL database and showcasing it on a website. Everything is running smoothly as planned, but my goal is to exhibit the data in a fixed height div, with the scrollbar constantly positioned at the bott ...

The setState function in React updates the value, however, when a form is submitted, it captures and

Encountering a problem with a modified field value not remaining on the form after submission. Working on a form where users can upload images. The image URL returned by the hosting service is saved in a state variable using this.setState({ im ...

Having trouble getting a form to submit to a Rails server using AJAX in IE11 with jQuery

Currently, I'm attempting to transfer data from a form to a Rails server using AJAX. The form consists of two text inputs and one file input. Below is the code for my submit event handler: $("form").on("submit", function(event) { event.preventDefa ...

issues with jasmine angularjs tests exhibiting erratic outcomes

During the execution of my unit tests, I often encounter a scenario where some random test(s) fail for a specific controller without any apparent reason. The error messages typically look like this: Expected spy exec to have been called with [ Object({}) ...