Jump to content

InfiniteDistance


gwenael
 Share

Recommended Posts

In BABYLON.Mesh.prototype.computeWorldMatrix, there is the following line:

BABYLON.Matrix.TranslationToRef(this.position.x + camera.position.x, this.position.y + camera.position.y, this.position.z + camera.position.z, this._localTranslation);

This is done only if mesh.infiniteDistance is true.

 

For what I read in the code, position is relative to the parent and I think it's wrong to add mesh.position to camera.position since they are not expressed in the same space. Is it a hack or am I missing something?

Link to comment
Share on other sites

Now I'm confused about position.

 

I thought BABYLON.Mesh.prototype.position was relative to the parent (or world space if there is no parent) but I read BABYLON.Mesh.prototype.setLocalTranslation and I got confused.

 

According to this function and my understanding of it... position is set to the vector3 that we pass in local space and transformed by the world matrix, so position is expressed in world space (if I'm not wrong but I guess worldMatrix.setTranslation(BABYLON.Vector3.Zero()) will say the opposite). What happens in BABYLON.Mesh.prototype.computeWorldMatrix if the mesh has a parent?

BABYLON.Matrix.TranslationToRef(this.position.x, this.position.y, this.position.z, this._localTranslation);...this._localPivotScalingRotation.multiplyToRef(this._localTranslation, this._localWorld);var parentWorld = this.parent.getWorldMatrix();this._localWorld.multiplyToRef(parentWorld, this._worldMatrix);
Link to comment
Share on other sites

InfiniteDistance is mainly used by skyboxes. You can use it to always keep the distance between your skybox and your camera unchanged. So you can move without going through the sky :)

 

About setLocalTranslation, I'm not sure to understand but the meaning of this function is to allow to compute a translation (world) from a translation in the object space

Link to comment
Share on other sites

Thank you Deltakosh. I understood the purpose of InfiniteDistance, my concern is about the addition of mesh.position and camera.position. I do understand why you add one to the other one but I have the impression that they are not expressed in the same space so you may not add them following the same axis. I hope it's clearer.

 

About setLocalTranslation, that's the same issue. I thought mesh.position was expressed in local space and according to the body of BABYLON.Mesh.prototype.setLocalTranslation, I think you set mesh.position to a vector that is expressed in world space.

Link to comment
Share on other sites

If I have well understood, it means that a mesh which has the InfiniteDistance flag can't have a parent. That seems reasonable but maybe we could add a warning if it's not the case. Can a camera have a parent? I thought I read something about it.

Here BABYLON.Mesh.prototype.computeWorldMatrix how I would modify it (see comments for modifications) to take into account that the mesh and the camera could have a parent.

[...]// Translation/*if (this.infiniteDistance) {    var camera = this._scene.activeCamera;    BABYLON.Matrix.TranslationToRef(this.position.x + camera.position.x, this.position.y + camera.position.y, this.position.z + camera.position.z, this._localTranslation);} else {*/    BABYLON.Matrix.TranslationToRef(this.position.x, this.position.y, this.position.z, this._localTranslation);//}[...]// Parentif (this.parent && this.parent.getWorldMatrix && this.billboardMode === BABYLON.Mesh.BILLBOARDMODE_NONE) {    this._localPivotScalingRotation.multiplyToRef(this._localTranslation, this._localWorld);    var parentWorld = this.parent.getWorldMatrix();    this._localWorld.multiplyToRef(parentWorld, this._worldMatrix);} else {    this._localPivotScalingRotation.multiplyToRef(this._localTranslation, this._worldMatrix);}// added //if (this.infiniteDistance) {    var camera = this._scene.activeCamera;    var cameraPosition = camera.position;    var transform = new BABYLON.Matrix();    this._worldMatrix.invertToRef(transform);    transform = (camera.getWorldMatrix()).multiply(transform);        cameraPosition = BABYLON.Vector3.TransformCoordinates(cameraPosition, transform);    BABYLON.Matrix.TranslationToRef(this.position.x + cameraPosition.x, this.position.y + cameraPosition.y, this.position.z + cameraPosition.z, this._localTranslation);    // update matrices since this._localTranslation has been updated    // Parent    if (this.parent && this.parent.getWorldMatrix && this.billboardMode === BABYLON.Mesh.BILLBOARDMODE_NONE) {        this._localPivotScalingRotation.multiplyToRef(this._localTranslation, this._localWorld);        var parentWorld = this.parent.getWorldMatrix();        this._localWorld.multiplyToRef(parentWorld, this._worldMatrix);    } else {        this._localPivotScalingRotation.multiplyToRef(this._localTranslation, this._worldMatrix);    }}// end of modifications //// Bounding infothis._updateBoundingInfo();// Absolute positionthis._absolutePosition.copyFromFloats(this._worldMatrix.m[12], this._worldMatrix.m[13], this._worldMatrix.m[14]);return this._worldMatrix;

About setLocalTranslation, it's what I understood and yes you're clear, at least for me ;). What it's less clear for me it's why you set position to vector expressed in world space since in BABYLON.Mesh.prototype.computeWorldMatrix it seems that position is considered to be expressed in local space.

 

I wrote a jsfiddle that shows what could be a bug:

 

http://jsfiddle.net/gwenaelhagenmuller/wZcbZ/

 

I have a parent mesh and a child mesh and I apply setLocalTranslation to the child everytime one of the button is clicked (step of -0.1 along z axis). The button "setLocalTranslation" uses the current code of BabylonJS, the other button uses my modified code. With the current code, that's something weird: the child first moves down and then up. It doesn't happen with my modified code. The translation is along the z axis of the child.

 

I slightly modified BABYLON.Mesh.prototype.computeWorldMatrix to always compute this._localWorld:

this._localPivotScalingRotation.multiplyToRef(this._localTranslation, this._localWorld);    // Parentif (this.parent && this.parent.getWorldMatrix && this.billboardMode === BABYLON.Mesh.BILLBOARDMODE_NONE) {    this._localWorld.multiplyToRef(this.parent.getWorldMatrix(), this._worldMatrix);} else {    this._worldMatrix = this._localWorld;}

 

And I replaced BABYLON.Mesh.prototype.setLocalTranslation by:

BABYLON.Mesh.prototype.setLocalTranslation = function(vector3) {    this.computeWorldMatrix();    this.position = BABYLON.Vector3.TransformCoordinates(vector3, this._localWorld);};

Hopefully my maths are correct and didn't give you a headache.

Link to comment
Share on other sites

Of course I want to be a contributor :). I want to be able to say that this awesome 3d engine exists thanks to me... for small, little contributions I've made.

I will do the pull-request.

 

I understand why you want me to use TransformNormal, I did actually use TransformCoordinates to translate of vector3 the mesh along its axis but yeah, the function should then be named locallyTranslate instead of setLocalTranslation. For me vector3 is the translation to apply to the current position so if you pass BABYLON.Vector3.Zero() nothing happens whatever its position whereas setLocalTranslation(BABYLON.Vector3.Zero()) means for me it will be repositioned the mesh to its first position (its origin). I'm not sure I'm clear, sorry. And setLocalTranslation(new BABYLON.Vector3(1.0,0.0,0.0)) would always give the same result whereas locallyTranslate(new BABYLON.Vector3(1.0,0.0,0.0)) would move forward (along local x axis) the mesh and then can be used for an animation for example.

 

Here a jsfiddle that should be clearer than my sentences...

 

http://jsfiddle.net/gwenaelhagenmuller/35uFf/

 

About infiniteDistance, I think you're right to block its use when the mesh has a parent but you don't want to block the camera not to have a parent, do you? this.position and camera.position may not be expressed in the same space if the camera has a parent which has a world matrix different than the identity. 

Link to comment
Share on other sites

While I was committing before making a pull-request I had a second thought about setLocalTranslation. What do you try to do with it? I'm still confused about it. locallyTranslate is clear for me. We pass a translation vector to apply (move by 2 units along x axis for example) but I don't get the aim of setLocalTranslation.

 

setLocalTranslation sets the position (expressed in parent space) to the passed vector3 (expressed in local space) once this one has been converted to be expressed in parent space BUT since we use TransformNormal we consider that the origin of the converted vector3 is the origin of the parent space and then the mesh translates along a line which has the direction of vector3 and containing the origin of parent space instead of containg the previous origin of local space.

 

Here a new jsfiddle explaining my words:

 

http://jsfiddle.net/gwenaelhagenmuller/35uFf/15/

 

I placed the camera along the z-axis of the parent and I initially moved the child along the x-axis of the parent (child.position.x) so you can see the difference. First press "locallyTranslate" and then "setLocalTranslate". Press "locallyTranslate" again.

 

If you really want to set (but along the axis of the mesh) instead of adding like with locallyTranslate, we will have to store the initial position. setLocalTranslation will call locallyTranslate with the difference vector (vector3 - initiallyPosition)

Edited by gwenael
Link to comment
Share on other sites

setLocalTranslation is used to define the translation of the mesh but from the point of view of the mesh (let's imagine a car you want to drive, you will always have to simply call setLocalTranslation(vec3(0, x, 0)) where x is the distance you need. This will make the car going forward regardless its orientation

Link to comment
Share on other sites

I totally agree, locallyTranslate is more about adding a vector to the current location and to be able to define the local translation could also be useful, I'm just a little embarrassed with the fact that the initial position of the car is not taken into account like http://jsfiddle.net/gwenaelhagenmuller/35uFf/14/ reveals but to take it into account we would have to cache the initial position and you certainly don't want to do that and you are certainly ok with the fact it's not taken into account, so if it's ok for you it's ok for me :) and I would do the pull-request once I'm back from my vacations.

 

Thanks for your time like always.

Edited by gwenael
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...