Weird problem positioning meshes loaded from a gltf

I’m using a GLTF for the first time, and something weird is happening:
https://playground.babylonjs.com/#C0RGLQ#2

I’m trying to create an interactive data viz where you can see how many calories, etc are in your burger/sandwich as you add or remove parts of the sandwich. When you choose to add/remove a part, I need to recalculate the y for for the stack of sandwich parts you’ve chosen so you don’t, for ex, end up w big blank spaces in your sandwich if you remove several toppings. This should be pretty straightforward: loop through the stack of chosen sandwich parts, with y = the y of the last part + the last part’s height.

When I first tried it, the parts ended up all over the place. So, I used the inspector to move the parts to where they should be if all the parts had been chosen, then stored each part’s y in an array called list:

var list = [-0.15, -0.19, -0.24, -0.385, -0.514, -0.424, -0.454, -0.237, -0.286];

The y’s should get bigger. And yet first they get smaller, then the last few get bigger. ???

As a sanity check, I positioned the top bun at y=0, then created two spheres at y=0 and y=0.5.

I re-read the docs and googled gltf and position, and couldn’t figure out what’s going wrong. For ex, I wondered if the meshes were using local rather than world axes, but the doc says:

Position places the pilot with reference to the world axes using a vector (x, y, z)

Any idea what’s going on?

Also, if it turns out there’s an issue with the gltf/glb, which I found on remix, what’s the easiest free tool to look at & tweak it?

Thanks!
Anders

The position property is definitely local. You should use absolutePosition for world position.

https://playground.babylonjs.com/#C0RGLQ#3

I think that quote you got from the babylon 101 tutorial is taken out of context. The “world axes” there is referring to an object and not world space.

1 Like

Thanks, @bghgary! Glad it turned out to be an easy fix.

Anders

1 Like

@Anders I am pleased that @bghgary solved the issue you were having, however there is a point of clarification I would like to make about his reply.

The “world axes” do refer to the axes of the “world space”. He is correct that the quote is taken out of context since position places an object relative to its current frame of reference which may change with its context. The statement about the pilot’s position is in the context of “Following its creation the pilot…” When a mesh is created its frame of reference is the world axes.

When importing a mesh, as in your case, the exporting software may have changed the frame of reference, for example by setting a parent or pivot, and so as you found position may not behave as you expect if you do not realise this.

The Inspector in your playground shows that your node_id meshes have a parent ‘root’ which itself has a parent ‘root
image

Many people find weird things happening when importing a mesh and often parenting is the root cause :slightly_smiling_face:

3 Likes

@bghgary @JohnK turns out I was prematurely optimistic last night. This morning, when I started playing around with the code, I realized there’s a problem.

Here’s a slightly modified version of your solution, which uses absolutePosition:
https://playground.babylonjs.com/#C0RGLQ#7

If absolutePosition was working, the top burger bun, which has a Y of 0, should be at the same height as the teal sphere; it’s not.

So, I changed the y value of the last few burger parts to 0, and I added a log statement in this version:

console.log("\n", sandwich[i].name, “: y is”, y);

Here’s the result:
Bottom Bun : y is -0.15
Hamburger : y is -0.19
Cheddar Cheese : y is -0.24
Lettuce : y is -0.385
Red Onion : y is -0.514
Tomato : y is 0
Pickle : y is 0
Ketchup : y is 0
Mustard : y is 0

if absolutePosition was working, we should see a bunch of the sandwich’s parts roughly at the same position. But it looks like nothing has moved.

So I created an example where I commented out the code moving the burger parts:
https://playground.babylonjs.com/#C0RGLQ#5

As you can see, it looks identical.

In other words, it looks like absolutePosition isn’t doing anything; all we are seeing is the position of the original burger parts. :frowning:

Or am I misinterpreting what I’m seeing?

Sorry, my mistake. To set the absolutePosition, call setAbsolutePosition instead of what I did.

https://playground.babylonjs.com/#C0RGLQ#9

1 Like

But since the tomato, pickle, catchup, and mustard all have a Y of 0, shouldn’t they be located in the same position? If you look at the Console, you can see that their y is getting set to 0, and yet they are all spread apart – and significantly higher than that Teal sphere, which also has a y of 0.

In this case, the meshes are offset in the vertex positions.

You can see this with the inspector:

Maybe use a pivot matrix?

1 Like

You beat me to it. I just worked that out! You can see in this PG https://playground.babylonjs.com/#C0RGLQ#10 that all objects have the same position and absolutePosition and so the relative spacing is because of the values of their vertices.

EDIT PG added

2 Likes

I read a bit about pivot matrixes, and… maybe I need to change my strategy. :slight_smile:

Here’s my goal: I’m trying to put together a handful of proof of concept examples of how you could train, say, a business analyst who was an Excel power user how to do creative data visualizations using BabylonJS. If it weren’t for the issue with the meshes being offset in the vertex positions, the code would be relatively straightforward; I could see training the power user up to the point – starting with simpler examples – where they’d be comfortably using it. But if they also have to understand pivot matrixes, it’s going to get too complicated & intimidating. Seems like fixing the glft is a better way to go.

Are there any free tools you’d recommend that would let me easily tweek the glft so there’s no offset? Or should I give up on this glft and find another?

Thanks!
Anders

Here is a possible solution but you need to give it more testing https://playground.babylonjs.com/#C0RGLQ#11

Line 28 uses the boundingBox to obtain the absolute position of each item ignoring the vertex positions
(If you want an accurate height line 29 will give it to you)

Items you want to use are listed in the parts array line 31

EDIT Almost forgot I have changed the order of items in the sandwich array to match the order they are displayed on screen (otherwise the yPositions are in the wrong order)

Line 39 increments the y displacement for missing items (it will be negative)

This y displacement is added to the next item that is used.

3 Likes

That looks like a promising direction! Thanks, @JohnK! I’ll go play w it for a day or so.

An alternative would be to use the y displacements for each mesh to reset the positions in the vertex buffer
That way you you could use the position property of each item to set their placement.

1 Like

If you go down the path of baking the positions back into the mesh, you can then re-export it as a glTF and then not have to deal with the vertex position offset anymore.

2 Likes