Jump to content

Mesh translates in world space incorrectly when pivot set


JohnK
 Share

Recommended Posts

The problem

Create a box

box1.jpg.a9a70eb1b828609dfaef3f8179e299e5.jpgfig 1

Use

box.setPivotMatrix(BABYLON.Matrix.Translation(-0.5, 0.5, 0.5));

To set the pivot at the lower right front corner (shown by small grey sphere).

box2.jpg.ed11f243828a9df941f4345d97cc82f1.jpg fig 2

Position the box at (2, 0, 0) and note that it is the pivot that is positioned at (2, 0, 0).

box.position = new BABYLON.Vector3(2, 0, 0);

box3.jpg.1dffef80226553475cf4d5b488de3c9c.jpgfig 3

Delete box.position and replace with

box.translate(BABYLON.Axis.X, 2, BABYLON.Space.LOCAL);

As you would expect since the local and world axes are in alignment you get the same result.

box3.jpg.1dffef80226553475cf4d5b488de3c9c.jpgfig 4

Now replace LOCAL with WORLD

box.translate(BABYLON.Axis.X, 2, BABYLON.Space.WORLD);

Since local and world axes are in alignment and translate is a vector displacement and the displacement is the same then you would expect the box to be at the same position. However it is not as is seen below.

box4.jpg.ffe0567c8ee01355b2a15ed21a593e12.jpgfig 5

Probable Issue

Getting the position of the box for fig 2 it is at (0, 0, 0) ie the position of the pivot, the absolutePosition for the box in fig 2 is (-0.5, 0.5, 0.5) the position of the box's center in world space.

So a translation in either local or world space would give the boxes position as (2, 0, 0) and its absolute position as (1.5, 0.5, 0.5) which it is for fig 3 using position and for fig 4 for translate in local space.

However translation in world space gives a position of (1.5, 0.5, 0.5) and an absolutePosition of (1, 1, 1) = (1.5, 0.5, 0.5) + (-0.5, 0.5, 0.5) . It is out by the pivot vector.

Tracking down translate in Mesh/babylon.abstractMesh.ts

public translate(axis: Vector3, distance: number, space?: Space): AbstractMesh {
  var displacementVector = axis.scale(distance);
  if (!space || (space as any) === Space.LOCAL) {
     var tempV3 = this.getPositionExpressedInLocalSpace().add(displacementVector);
     this.setPositionWithLocalVector(tempV3);
  }
  else {
     this.setAbsolutePosition(this.getAbsolutePosition().add(displacementVector));
  }
  return this;
}

where for Space.WORLD there is a call to 'setAbsolutePosition' the code for which is

public setAbsolutePosition(absolutePosition: Vector3): AbstractMesh {
  if (!absolutePosition) {
     return;
  }
  var absolutePositionX;
  var absolutePositionY;
  var absolutePositionZ;
  if (absolutePosition.x === undefined) {
     if (arguments.length < 3) {
       return;
     }
     absolutePositionX = arguments[0];
     absolutePositionY = arguments[1];
     absolutePositionZ = arguments[2];
   }
   else {
     absolutePositionX = absolutePosition.x;
     absolutePositionY = absolutePosition.y;
     absolutePositionZ = absolutePosition.z;
   }
   if (this.parent) {
      var invertParentWorldMatrix = this.parent.getWorldMatrix().clone();
      invertParentWorldMatrix.invert();
      var worldPosition = new Vector3(absolutePositionX, absolutePositionY, absolutePositionZ);
      this.position = Vector3.TransformCoordinates(worldPosition, invertParentWorldMatrix);
   } else {
       this.position.x = absolutePositionX;
       this.position.y = absolutePositionY;
       this.position.z = absolutePositionZ;
   }
   return this;
}

which takes into account a parent but not a pivot. Also it sets the absolutePosition by setting only the position. However as is seen above when using a pivot, like for the parent case, position and absolute position are different by the pivot vector.

Possible Solution

Would be very nervous of suggesting changes to 'setAbsolutePosition' as I would not know what else it might affect.

So suggest the following change to translate - 'add(this.getPivotPoint())'  - but am not submitting a PR since I am not absolutely certain this is the correct way to go. Have tried it locally and it gives me what I expect but do not know whether it affects anything else and will wait until better BJS minds than mine check it out.

public translate(axis: Vector3, distance: number, space?: Space): AbstractMesh {
  var displacementVector = axis.scale(distance);
  if (!space || (space as any) === Space.LOCAL) {
     var tempV3 = this.getPositionExpressedInLocalSpace().add(displacementVector);
     this.setPositionWithLocalVector(tempV3);
  }
  else {
     this.setAbsolutePosition(this.getAbsolutePosition().add(displacementVector).add(this.getPivotPoint()));
  }
  return this;
}

 

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...