darkknight8 Posted August 27, 2018 Share Posted August 27, 2018 I have an existing scene with a group of meshes that represents a character. I want to attach a hat to the character. However, when I want to import the hat mesh into the scene with the character, it appears on top of the character like I expected but it's not attached to the character, which makes sense because it's a different mesh. What's the best approach to make the hat be part of the character mesh? Quote Link to comment Share on other sites More sharing options...
brianzinn Posted August 27, 2018 Share Posted August 27, 2018 Welcome to the forum!! You need to parent the hat to the character mesh. let characterMesh = .... let hatMesh = ... hatMesh.setParent(characterMesh); setParent() method will maintain the relative position and properties (ie: rotation, scaling) of the hat (unlike hatMesh.parent - characterMesh). Now when you move the character, the hat will move along with the character! Quote Link to comment Share on other sites More sharing options...
darkknight8 Posted August 27, 2018 Author Share Posted August 27, 2018 For some reason, it's not working. Here is my code so far: BABYLON.SceneLoader.Append("/assets/", "character.glb", scene, function (scene) { scene.createDefaultCameraOrLight(true); let characterMesh = scene.meshes; BABYLON.SceneLoader.ImportMesh(null, "/assets/", "hat.glb", scene, function (meshes, particleSystems, skeletons) { meshes.setParent(characterMesh); console.log(meshes.parent); }); }); What am I doing wrong here? Sorry, the code formatting tool is not working for some reason. Quote Link to comment Share on other sites More sharing options...
brianzinn Posted August 27, 2018 Share Posted August 27, 2018 meshes is an array, so you need to add one at a time. ie: BABYLON.SceneLoader.ImportMesh(null, "/assets/", "hat.glb", scene, function (meshes, articleSystems, skeletons) { meshes.forEach(m => m.setParent(characterMesh)); // console.log(meshes.parent); }); I haven't see hat.glb, but it might already have a root node, so you'd only need to set that one mesh - then it would be meshes[0].setParent(characterMesh), where 0 is the index of the root mesh. GameMonetize 1 Quote Link to comment Share on other sites More sharing options...
darkknight8 Posted August 27, 2018 Author Share Posted August 27, 2018 This works, but the hat appearance looks messed up, do you know what could be causing this? Is it the way that I am importing it? Quote Link to comment Share on other sites More sharing options...
Guest Posted August 27, 2018 Share Posted August 27, 2018 We may need to see it in the playground to help a bit more Quote Link to comment Share on other sites More sharing options...
darkknight8 Posted August 28, 2018 Author Share Posted August 28, 2018 @Deltakosh I can't make a full playground with it, since I can't release those mesh (though I can PM them to you if you need to see them ). But I have taken screenshots to show what I mean. The first screenshot shows the hat when you import it into the sandbox or you just import it regularly via append. The second picture shows what happens when you import it and attach it to the character's head. As you can see, the colors are way off and it happens to all the hat, not just this specific one. I am assuming it has to do with material issues. This is how the code looks: var delayCreateScene = function () { // create a basic BJS Scene object let scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color4(0, 0, 0, 1); BABYLON.SceneLoader.Append("/assets/", "character.glb", scene, function (scene) { scene.createDefaultCameraOrLight(true); scene.activeCamera.useFramingBehavior = true; // Forces our glTF file to face forward scene.activeCamera.alpha += Math.PI; scene.activeCamera.fov = 0.6; const framingBehavior = scene.activeCamera.getBehaviorByName("Framing"); framingBehavior.framingTime = 0; framingBehavior.elevationReturnTime = -1; const worldExtends = scene.getWorldExtends(); framingBehavior.zoomOnBoundingInfo(worldExtends.min, worldExtends.max); let characterMesh = scene.meshes; // here we have the character meshes (8 to be exact) ; BABYLON.SceneLoader.ImportMesh(null, "/assets/", "hat.glb", scene, function (meshes, particleSystems, skeletons) { for (let i = 1; i < meshes.length; i++) { meshes[i].setParent(characterMesh[0]); } }); window.addEventListener('resize', function () { engine.resize(); }); engine.runRenderLoop(function () { scene.render(); }); }); return scene; }; Quote Link to comment Share on other sites More sharing options...
brianzinn Posted August 28, 2018 Share Posted August 28, 2018 2 hours ago, darkknight8 said: what happens when you import it and attach it to the character's head I mentioned it earlier, but perhaps it didn't jump out. Probably each of those models already has a root element that the other meshes are already parented to. So, there is a mesh index and when you import the mesh, the other meshes are already have the .parent property set to that one (or another one in their hierarchy). So, if that is the case, you only need to setParent() from the root node of the hat (1 mesh) with the root node of the character. Really can't tell without the models themselves. It's rudimentary, but do a console.log on the meshes and check the parent properties - another option is to create a TransformNode and parent both root nodes to that. This won't work likely, but is a hint what you are after: for (let i = 0; i < meshes.length; i++) { // your loop starts at 1, but array index is 0's based if (!meshes[i].parent) { meshes[i].setParent(characterMesh[0]); } } Quote Link to comment Share on other sites More sharing options...
darkknight8 Posted August 28, 2018 Author Share Posted August 28, 2018 Yes, so the character mesh and the hat mesh both has their own parents. So if I understand you correctly, I should be doing this let hatMeshRoot = meshes[0] // the root mesh of the hat, the hat mesh has 2 nodes, the first is root let characterRoot = characterMesh[0] // character mesh has 9 nodes, the first is also root hatMeshRoot.setParent(characterRoot) Is this correct? Also, I want to point out that the code works great, the hat moves with the character as expected, but now the issue is the hat does not have its original texture. Do you know if this is a problem with parenting meshes or is this another issue altogether? I can PM the models to you if you want to take a look. Quote Link to comment Share on other sites More sharing options...
brianzinn Posted August 28, 2018 Share Posted August 28, 2018 Glad that we have made some progress and that the parenting is working out! Still not ready to celebrate though The only thing that I can think of right now is that the scaling or rotating is causing an issue with the texture. The actual code is here: https://github.com/BabylonJS/Babylon.js/blob/master/src/Mesh/babylon.transformNode.ts#L543 You can test if that is the case by instead of calling setParent() to directly set the parent property (the code in method linked above is not ran then? hatMeshRoot.parent = characterRoot You may need to adjust the hat position once you do that - the position will be in local space to character root (ie: hatMeshRoot.position.y += 1). Quote Link to comment Share on other sites More sharing options...
darkknight8 Posted August 28, 2018 Author Share Posted August 28, 2018 I am not scaling anything in this case. I also remove any rotation and the color is still strange. I wonder if it might be an import bug? I also realized the texture is messed up even before using the setParent method on the hat mesh. Quote Link to comment Share on other sites More sharing options...
brianzinn Posted August 28, 2018 Share Posted August 28, 2018 Try in the sandbox, if the textures don't load there then start a new question with details on the model format. Just drag'n'drop your model: https://sandbox.babylonjs.com/ edit: and I think there is a separate subforum for importing textures that will be more suitable... Quote Link to comment Share on other sites More sharing options...
dbawel Posted August 28, 2018 Share Posted August 28, 2018 Freeze all transforms before importing. Also, look at the pivot point and set in babylon.js if needed. Also, I rarely use materials and textures from external applications. I know many will disagree, but if you have problems with materials and textures from an exported application, why not simplify and forget about troubleshooting - unless you're not on a deadline and trying to work out a solid reliable pipeline. build your materials and textures in BJS, as there is far more flexibility. DB Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.