What is the best way to attach a Child mesh to a Parent mesh?

I am facing an issue with loading a facial mesh and separate eye mesh into three.js from Blender. The face is set as the parent and eyes as the child in Blender. How can I accomplish this task successfully?

Additionally, there seems to be a problem with loading textures, as only one can be loaded at a time. Can someone provide assistance with resolving this issue? Thank you.

var loader = new THREE.JSONLoader();        
        loader.load( "./three/models/JSON/Blender/DM_Face.json", addModelToScene );           //function( geometry, material ) {
      //loader.load( "./three/models/JSON/Blender/DM_Eye.json", addModelToScene );

    //var materials = [material1, material2];
    //var meshFaceMaterial = new THREE.MeshFaceMaterial( materials );

function addModelToScene( geometry, materials ) { //sphereGeometry1, sphereMaterial1 ) {            
    var material = new THREE.MeshPhongMaterial({morphTargets: true, map: THREE.ImageUtils.loadTexture('./three/models/JSON/Blender/DM.fbm/RyEddie_face_1001.jpg')});    
var Mouth = new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture('./three/models/JSON/Blender/DM.fbm/RyEddie_mouth_1005.jpg')});

        mesh = new THREE.Mesh( geometry, material, Mouth )          
        mesh.scale.set( 17, 13, 13 );
        mesh.position.x = 0;            //Position (x = nach rechts+ links-)  
        mesh.position.y = -17;          //Position (y = nach oben +, unten-)
        mesh.position.z = 0;            //Position (z = nach vorne +, hinten-)          
        scene.add( mesh )   

    //var sphereMaterial1 = new THREE.MeshPhongMaterial( {map: THREE.ImageUtils.loadTexture('./three/models/JSON/Blender/DM.fbm/RyEddie_eyes01_1007.jpg')});
            //sphareMesh1 = new THREE.Mesh( sphereGeometry1, sphereMaterial1 )
            //sphareMesh1.scale.set( 30, 30, 30 );
        //sphareMesh1.position.x = 0;       //Position (x = nach rechts+ links-)  
        //sphareMesh1.position.y = 0;       //Position (y = nach oben +, unten-)
        //sphareMesh1.position.z = 0;       //Position (z = nach vorne +, hinten-)              
        //scene.add( sphareMesh1 );         


            mixer = new THREE.AnimationMixer( mesh );
            var clip = THREE.AnimationClip.CreateFromMorphTargetSequence( 'test', geometry.morphTargets, 30 );
        mixer.clipAction( clip ).setDuration( 6 ).play();

        };

The JSON file specifies the texture materials as follows:

"materials":[{      
        "depthTest":true,
        "transparent":false,
        "depthWrite":true,
        "colorSpecular":[0.5,0.5,0.5],
        "DbgName":"Face",
        "wireframe":false,
        "visible":true,
        "DbgIndex":5,
        "DbgColor":61166,
        "doubleSided":false,
        "specularCoef":103,
        "colorEmissive":[0,0,0],
        "opacity":1,
        "colorDiffuse":[0.8,0.8,0.8],
        "shading":"phong",
        "blending":1
      },{
        "depthTest":true,
        "transparent":true,
        "depthWrite":true,
        "DbgName":"Eyelashes",
        "wireframe":false,
        "visible":true,
        "DbgIndex":0,
        "DbgColor":15658734,
        "doubleSided":false,
        "colorEmissive":[0,0,0],
        "opacity":0,
        "colorDiffuse":[0.0414118,0.0379608,0.0310588],
        "shading":"lambert",
        "blending":1
     },{
        "depthTest":true,
        "transparent":true,
        "depthWrite":true,
        "colorSpecular":[0.5,0.5,0.5],
        "DbgName":"EyeMoisture",
        "wireframe":false,
        "visible":true,
        "DbgIndex":14,
        "DbgColor":15658734,
        "doubleSided":false,
        "specularCoef":103,
        "colorEmissive":[0,0,0],
        "opacity":0,
        "colorDiffuse":[0.8,0.8,0.8],
        "shading":"phong",
        "blending":1
      },{
        "depthTest":true,
        "transparent":false,
        "depthWrite":true,
        "colorSpecular":[0.5,0.5,0.5],
        "DbgName":"Torso",
        "wireframe":false,
        "visible":true,
        "DbgIndex":9,
        "DbgColor":15658734,
        "doubleSided":false,
        "specularCoef":103,
        "colorEmissive":[0,0,0],
        "opacity":1,
        "colorDiffuse":[0.8,0.8,0.8],
        "shading":"phong",
        "blending":1
     },{

Answer №1

Instead of directly parenting one mesh to another, it is recommended to utilize the concept of Groups to avoid rendering issues.

https://example.com/docs/#api/objects/Group

Below is a simplified code snippet for your reference:

var parent = new THREE.Group();
loader.load("model1.json", function(geometry, materials){
  var childMesh1 = new THREE.Mesh(geometry, material);
  parent.add(childMesh1);
});
loader.load("model2.json", function(geometry, materials){
  var childMesh2 = new THREE.Mesh(geometry, material);
  parent.add(childMesh2);
});
scene.add(parent);

(Side Note: The Mesh constructor only requires two parameters. docs)

By manipulating the parent, both childMesh1 and childMesh2 will be affected. This includes position, rotation, scale, and skew transformations that will propagate to all meshes within the parent.

You can also nest multiple Groups to establish a hierarchy within your model, although this topic can be further explored in separate discussions.

three.js version r87

Answer №2

@TheJim01, this is the current state of affairs.

let loader = new THREE.JSONLoader();
// let loader = new THREE.ObjectLoader();
  // loader.load( "./three/models/JSON/Blender/Face.json", addModelToScene ); 

let head = new THREE.Group();
loader.load("./three/models/JSON/Blender/Face.json", function(geometry, materials){
let material = new THREE.MeshPhongMaterial({morphTargets: true, map: THREE.ImageUtils.loadTexture('./three/models/JSON/Blender/DM.fbm/RyEddie_face_1001.jpg')});
let mesh = new THREE.Mesh(geometry, material);
head.add(mesh);
});

loader.load("./three/models/JSON/Blender/Eyes.json", function(geometry, materials){
let material = new THREE.MeshPhongMaterial({morphTargets: true, map: THREE.ImageUtils.loadTexture('./three/models/JSON/Blender/DM.fbm/eyes_1001.jpg')});
let mesh = new THREE.Mesh(geometry, material);
head.add(mesh);
});

function addModelToScene(geometry, materials) {

mesh = new THREE.Mesh(geometry, material)
mesh.scale.set(13, 13, 13);
mesh.position.x = 0;
mesh.position.y = -25;
mesh.position.z = 0;
scene.add(mesh);

mixer = new THREE.AnimationMixer(mesh);

let clip = THREE.AnimationClip.CreateFromMorphTargetSequence('test', geometry.morphTargets, 30);

mixer.clipAction(clip).setDuration(6);
let action = mixer.clipAction(clip);

Play.onclick = function Play() {
action.play();
}
Stop.onclick = function Stop() {
action.stop();
}

};

Answer №3

@TheJim01 Indeed, the model Face is now visible but the eyes are still missing and the animation has halted. I made some modifications as follows. It's intriguing that removing the texture prevents the face from displaying. Does it have something to do with the textures?

let loader = new THREE.JSONLoader();

let headModel = new THREE.Group();
loader.load("./three/models/JSON/Blender/Face.json", function(geometry, materials){
let material = new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture('./three/models/JSON/Blender/DM.fbm/face_1001.jpg')});
let mesh = new THREE.Mesh(geometry, material);
mesh.scale.set( 13, 13, 13 );
mesh.position.x = 0;
...  
});

scene.add(headModel);


function addModelToScene( geometry, materials ) {
morphTargets: true

mixer = new THREE.AnimationMixer(mesh, headModel);

var clip = THREE.AnimationClip.CreateFromMorphTargetSequence('gallop', geometry.morphTargets, 30);

mixer.clipAction(clip).setDuration(6);
var action = mixer.clipAction(clip);

Play.onclick = function Play() {
action.play();
}
Stop.onclick = function Stop() {
action.stop();
}

};

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

Increase the object name in localStorage to save information entered in input fields

For testing purposes only - do not use for production. I am experimenting with storing data from 3 different input fields (text and numbers) in localStorage. My goal is to have the values increment every time the form is submitted. However, I am encounte ...

Object.assign changes the original array object in place

I am facing a challenge while attempting to modify the value of a specific index in my state, specifically the property post_comments. The issue lies in the fact that even though I am only modifying a copy of the state, the actual state is also being alter ...

When working with a barcode font in Chrome, using style.fontFamily may not be effective, but utilizing className can achieve the desired result

Take a look at this HTML snippet: <style> .barcode { font-family: 'BC C39 3 to 1 Medium'; } </style> <div><span id='spn'>1234567</span></div> This code will apply a barcode font style: <script> ...

Experiencing difficulty creating a realistic typing effect with JavaScript that would accurately simulate typing errors

I condensed everything into a single HTML file for easier testing of this specific section. The objective is to initially type Wx, then delete the x, pause for a second, and finally type elcome. Currently, the output is Wlcome. I have attempted various m ...

The value of req.cookies is returning as undefined, even though cookies have been

I integrated the cookie-parser module into my express app. When a user requests the root page, I use res.cookie(name, value) to set a random number on the cookie, which is working correctly (I verified this in my browser console). However, when I attempt t ...

Verify whether the form inputs are necessary or optional when utilizing a specific directive

Hello, I am trying to determine if all the necessary fields are filled out in a form using jQuery only. I have attempted this: $('#form').find('input, select, textarea').each(function(){ if(!$(this).prop(&apo ...

Exploring the functionality of Angular.js through QUnit testing

Is it possible to integrate angular.mock.inject() with QUnit instead of Jasmine? In the provided code snippet, angular.mock.dump is defined, but unfortunately angular.mock.inject remains undefined. <!DOCTYPE html> <html ng-app="mymodule"> & ...

What could be the reason behind the login button not triggering the console message display?

I've decided to delve into web server development on my own and have been tweaking a GitHub repository for ExpressJS with Typescript that I stumbled upon. My initial goal is simple - just to have something displayed on the console when I click the log ...

Tips for uploading an input file using ajax method instead of a form

I have a dynamic table that sends all input text to my database using ajax. Here is the code I have implemented so far: <script language="javascript" type="text/javascript"> var i = 2; // This variable always points to the last row function test( ...

React.js error: Uncaught TypeError: Cannot read property 'map' of null

Hey there, I'm currently working on creating a MERN Stack web app following this tutorial: https://youtu.be/aibtHnbeuio. I'm fairly new to the stack and could really use some help fixing this issue... Error Encountered: TypeError: Cannot read p ...

Angular Swiper Integration: Maintaining Scope Inside Configuration Callback

Trying to grasp the concept of working with callbacks to maintain scope can be a bit tricky, as I've been experiencing. Specifically, I've been struggling with a callback in the Swiper library for Angular, where I am unable to keep my desired sco ...

The AngularJS asynchronous directive in isolation is malfunctioning

I need to pass an object retrieved from the database to a child directive. Sending data synchronously works fine, but when I fetch the data asynchronously from a remote server, the directive is triggered before the results are received. Here is the contro ...

What is the best way to create an Office Script autofill feature that automatically fills to the last row in Excel?

Having trouble setting up an Excel script to autofill a column only down to the final row of data, without extending further. Each table I use this script on has a different number of rows, so hardcoding the row range is not helpful. Is there a way to make ...

A JavaScript promise that triggers the "then" function right away

As I work on developing a single-page app, JavaScript promises have become a critical component. In specific scenarios, I require the "then" method to execute synchronously if the promise is already resolved. To address this need, I have created a custom p ...

Concatenate a variable string with the JSON object key

I am currently working on a request with a JSON Object structure similar to the following: let formData = { name: classifierName, fire_positive_examples: { value: decodedPositiveExample, options: { filename: 'posit ...

Injecting a full browser-screen DIV into the body of the webpage

Recently, I was tasked with developing a script that could be utilized on any website. As a test, I decided to use the Google search results page. My goal is simple - to have a full-screen semi-transparent div displayed on any site for cookie notification ...

Can Node support setting the ECMAScript version?

After some research, I discovered that Node utilizes Chrome's V8 JavaScript engine. If you're interested in learning more about ES6 support, check out this link as well as this one. Additionally, there is a command for viewing V8 options when usi ...

The request included an unsupported media type of "text/plain;charset=UTF-8". This caused an error in the NextJS API when interacting with Django Rest Framework

Currently diving into the world of web development, I am endeavoring to construct a website utilizing NextJS and Django Rest Framework. While NextJS effectively proxies API endpoints for retrieving data, I find myself grappling with making it work for a PO ...

Experiencing ERR_TOO_MANY_REDIRECTS while using Next.js with Vercel and a Custom Domain through Cloudflare

I'm having trouble getting my Next.js project set up on Vercel with a custom domain managed through Cloudflare. Despite configuring the DNS and SSL settings correctly, I keep seeing a net::ERR_TOO_MANY_REDIRECTS error when trying to access my site at ...

Why is the image not disappearing even after using JavaScript to do so?

I'm having an issue with my JavaScript code that is supposed to make an image disappear when the data-slide-to attribute is equal to 1. However, the image remains visible even though the code seems correct. Can anyone help me understand why it's ...