How do I have my obj loaded properly centered at 0,0,0 and scaled?

Hi, guys!

I have been playing with Babylon.js for the last week or so and having so much fun!!

Though, I am having a trouble looking for my object every time I load a different one.

This example on Babylon PlayGround is somehow at the origin (0, 0, 0) and its scale is beautifully appropriate.

However, when I loaded an object that I downloaded from “sketchfab.com,” it is located way up in the Y axis. Of course, I can manually type in values for camera and target position and drag and zoom in/out to find objects that I load every time, but it is just so frustrating.

Here is what I did:

var createScene = function () {
  // This creates a basic Babylon Scene object (non-mesh)
  const scene = new BABYLON.Scene(engine);
  var camera = new BABYLON.ArcRotateCamera("camera", 2.372, 1, 0.5, BABYLON.Vector3.Zero(), scene);
  camera.upperRadiusLimit = 0.5;
  camera.lowerRadiusLimit = 0.25;
  camera.minZ = 0.01;
  // Attaches the camera to the canvas
  camera.attachControl(canvas, true);
  
  // This creates a light, aiming 0,1,0 - to the sky (non-mesh)
  const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 0, 0), scene);
  
  // Default intensity is 1. Let's dim the light a small amount
  light.intensity = 1;
  light.range = 10;
  
  var assetsManager = new BABYLON.AssetsManager(scene);
  var meshTask = assetsManager.addMeshTask("shoe task", "", "https://assets.babylonjs.com/meshes/", "shoe_variants.glb");
  // var meshTask = assetsManager.addMeshTask("shoe task", "", "./hoodie-v2/source/Hoodie/", "Hoodie.obj");
  meshTask.onSuccess = function (task) {
    task.loadedMeshes[0].position = BABYLON.Vector3.Zero();
  }
  
  assetsManager.onFinish = function (tasks) {
    engine.runRenderLoop(function () {
      scene.render();
    });
  };
  
  assetsManager.load();
  
  showAxis(900);
  
  return scene;
};

I tried BABYLON.Vector3.Zero(); so that hopefully, it is centered when I load it, but it is not working. Also, sometimes, the object is way too big.

Is there a way for me to load objects with properly centered with adequately scaled so it is fit right in the canvas?

Thank you so much!! I hope you guys enjoy coding with Babylon!!

Have a wonderful day!!

hi @DOEHOONLEE there is something about that mesh. I’m turning my computer off now, though. I would try loading it in the scene explorer to learn more what is going on. I can’t see it right now why it’s not working, but this code I’ve used in the past for scaling - maybe it helps a bit (you can also create a transform node and parent that to the meshes without parents, which is what I do):
Babylon.js Playground (babylonjs.com)

1 Like

The simplest way for all such models is to open it in some 3D editor like Blender, then set mesh origin as you need (one may add scaling to taste).

Hello there !

I’ve encountered some similar issues when trying to import .glb files I created with blender.

When you import a file, even if there is only one mesh in it, you’ll get an array of several meshes (called task.loadedMeshes in your case). I’m fairly new so I don’t exactly know why, but Babylon wraps your imported mesh as the child of a “_ root _” mesh.

There may even be several imbricated parents before you find your actual mesh, which is what’s happening in your playground. You can see you got 3 successive parents on your import :

And one of them has some transformations you might not want.
In your playground example for instance :

I think this structure after import is an artefact of the way your mesh was created and exported. I don’t know sketchfab, but I know in Blender I have to pay attention to edit the scale and the position of my mesh in ‘edit’ mode, to alter its geometry, and not in ‘object’ mode. Otherwise, this will create some offset transformations on the _ root _ mesh, leading to unexact scaling, or offcentered meshes.

I tried to put my imports in a separate async method, and setting its scaling to new BABYLON.Vector3(1, 1, 1), just in case. You can also set its parent to another mesh than the default _ root _ object, and then (not before) delete it using dispose().

That worked for me and I then had the same transforms in the Babylon scene as in my Blender software.

[EDIT] - Also this kinda is my first reply to a dev forum so if anything’s not clear or just sounds wrong about what I said, please tell me ! :slight_smile:

2 Likes

Thanks for that!

i personally remove the root mesh objects of all my loaded .glb files because I hate them as well. We need to do a democratic vote and send the results to Khronos Group because I simply cannot for the life of me even fathom even once good reason my. " _ root _" for every mesh … no thanks.

Nothing to do with the Khronos Group.

That sounds like a very nice and convenient way!! Thanks!! :slight_smile:

Woah~!! What a thorough explanation! Since I am new to Babylon, this seems very confusing for me at this moment though. Let me try your way and I’ll get back to you again. It might take some time xD

Big thank to you!!

1 Like

Some of the obj files I downloaded from sketchfab did not have root mesh and the arrays length were 1 only :frowning: Is this possible?

Yes. A single mesh is not uncommon for .obj files :slight_smile:

I see. I guess some free downloadable .obj are sometimes differently structured.

I never met this case, but I guess it is possible.
As JohnK said above, the _ root _ apparently has a purpose of handling some Babylon aspect.

I suppose in some cases this purpose is not needed (maybe the mesh is already in left hand mode) and thus the _ root _ node won’t be necessary. :man_shrugging:

haha , ok i get that , although I hate that as well. When I build a scene in blender and then use babylon I want all my objects transform properties to be the same and same axis system.

If i export y-up … an identity transform becomes -1 xscale and 90deg xRotation . So they are not the same as my scene. So i create a single root node that counters this transform , then i export normal axis from blender and add all imports into that root object.

I also then trash the __root__ object on import.

So now my babylon scene ( well inside the custom root node ) is the same as blender … same “root” objects names, same hierarchy for each , transform values the same , axis the same. life is now sweet again

I do know this is a horrible hack using a single custom root node but hey, to me , this seems a better solution than adding a __root__ to every imported object.

Approved. I can endorse this request. :grinning:

Here’s a function to center mesh content in a node:

1 Like

If you have an app where you don’t know which object will come in, and in what condition, or even which format it is, you could utilize boundingBox of the object.

Specifically, you would calculate bounding box from every mesh in the scene, and you will find the center point of the object/structure or whatever.

I already explained the process in some of the previous threads with playground example.

Hopefully it helps you out.

2 Likes

I believe that question has been answered (multiple times) and this old thread should have been closed.
I believe the answer from @nogalo is correct. There are variants of the same but the logic remains and is rather well explained in the linked post (my opinion).
May be someone from the Team would kindly close this topic. Mark the above as solution? cc @sebavan @carolhmj Thank you,

Thank you all for wonderful solutions!! :slight_smile:

I am not sure if I can close this thread.

No, you can’t… and neither can I. Only the Team can, so don’t worry about it :smiley:
Glad you found a solution to your problem and have a great day :sunglasses:

Edit: Oops. My apologies, didn’t realize this was your thread. So you did it. By marking it as a solution.
All good. Thanks for that :pray: