Object3D pivot/axis position

How one can calculate object’s “pivot” position (in object local coordinates) and orientation (in world coordinates)?

Here is an example:

https://ibb.co/ss2dwFF

  • on the screenshot one can see an object (group) and the editor shows “pivot/helper axes” of the object - it’s from the threejs editor webpage

So it’s possible to get this information - but i can’t figure it out. Let’s imagine, i would like to have the pivot point located in another “corner” of the object (i.e. move it to the “left” corner).

Questions:

  1. How can i programmatically get this information from the object3d itself?
    1.1 how to get position of the pivot/helper relative to the object (i.e. on the screenshot its at the lower right from vertex of the object bounding box)
  2. How can i programmatically change the pivot position - for instance would like to have the pivot point located at the center of the lower z plane of the object’s bounding box

Right now i have a workaround - i do not get this information instead i make a “wrapper” object and position (center) internal object accordingly. It “simulates” change in pivot point position. It works well but modification of the “pivot” point seems more elegant.

  1. Three doesn’t implement an idea of pivot. The pivot you’ve described is just the position of the object. To get that world-space position you can do:
const position = new Three.Vector3();
object.getWorldPosition(position); // NOTE Now `position` will give you the world-space position of the object / pivot

And in local-space, that’s just object.position.


i would like to have the pivot point located in another “corner” of the object

  1. Place the object inside an empty Group, position it locally within the group, then rotate it within that group (basically treat that group as the actual object.)

  2. Alternatively, if you’re more into math than nested transformations - you can also rotateOnAxis.

1 Like

Thanks,
however, how threejs web editor knows where to draw the axes on object? Found a similar thread:

but it does not answer my question.
Any more hints?

As above - they are always drawn at object’s world-space position (which is equivalent to object’s local (0.0, 0.0, 0.0) position.) The location of that (0.0, 0.0, 0.0) point depends on the model itself - if you import the model in Blender and select it, this point will be marked with an orange dot:

(Here and here to be more precise.)

fXA1C

(You can modify that point in Blender by pressing Tab, and moving the vertices around - that way you’ll shift the pivoting point into the opposite direction.)

thanks a lot, now it makes more sense. I slowly start to understand.

so maybe last little experiment with sketchup and three js to fully understand what is going on:

  1. made a box in sketchup, by default gizmo/pivot/axes is on the “left” corner

  2. exported it as dae and imported into threejs editor. Gizmo is presented in the “left” corner, same as in sketchup

  3. edited object’s axes in sketchup. Moved the gizmo/axes/pivot to the “right” corner

  4. exported it as dae and imported into threejs editor. Gizmo is presented in the “right” corner, same as in sketchup

  5. selected each object in three js (one with “left” gizmo, another with “right” gizmo) and exported one by one as object (json)

  6. made a diff of resulting json files

Results:

  1. threejs is fully aware of where is the “gizmo/handle/pivot/axes” - so it knows where is the objects (0,0,0) in the world coordinates (as mjurczyk noticed)
  2. the difference between these two objects, with only “gizmo/axes/pivot” changed:
    2.1 object’s matrix property index 13 is changed (26.4647534 changed into 65.8348321,22)
    2.2 geometry’s vertices positions are changed (seem to be translated by -39 which is a difference between 26 and 64)

So it seems that “origin/pivot” is just object’s (0,0,0) as you said and when it’s modified (it was moved along the “red” axis) it results in object’s matrix position changed (geometry is translated).

Do I understand correctly?

  1. Sorry but the statement stays - there’s no gizmo / pivot, so three can’t be aware of it. There’s just object position - and the geometry is constructed around that position :sweat_smile: (so if a geometry vertex in the Mesh is at position (20, 20, 20) and position of the Mesh is (4, 4, 4), then the position of that vertex will be (24, 24, 24).)
  2. This behaviour depends exclusively on the a) software you use to create the model, b) exporter you use to export model from that software, c) output file format. Exporters may (or may not) choose to center the object in it’s “centre of gravity” before exporting, making the model look exactly the same regardless of where you’d move it before exporting. I can vouch only for Blender that it does not do so.

Long story short - imo there’s no value in trying to understand this. Personally I’d just write code that loads a model, calculates it’s bounding box, and then centres the model so that (0, 0, 0) will always mean centre of gravity for the given model. That way you’ll be able to load models with all kinds of random transformations and be sure that they’ll be aligned in the same, uniform way.

2 Likes

There code for achieve this centering.

object3D.traverse((child) => {
          const bbox = new Box3().setFromObject(child);
          const vec = new Vector3();
          bbox.getCenter(vec);
          if (child instanceof Mesh) {
            const material = child.material as MeshPhongMaterial;
            child.position.set(vec.x, vec.y, vec.z);
            if (child.geometry) {
              child.geometry.translate(-vec.x, -vec.y, -vec.z);
            }
            
          } else {
            child.position.set(vec.x, vec.y, vec.z);
            child.traverse((child) => {
              if (child instanceof Mesh) {
                child.geometry.translate(-vec.x, -vec.y, -vec.z);
              }
            });
            child.position.set(0, 0, 0);
          }
        });
1 Like