gwenael Posted December 23, 2013 Share Posted December 23, 2013 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? Quote Link to comment Share on other sites More sharing options...
gwenael Posted December 23, 2013 Author Share Posted December 23, 2013 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); Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted December 24, 2013 Share Posted December 24, 2013 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 Quote Link to comment Share on other sites More sharing options...
gwenael Posted December 24, 2013 Author Share Posted December 24, 2013 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. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted December 25, 2013 Share Posted December 25, 2013 For InfiniteDistance, you have to consider that the position is expressed in world space (like the camera position)For setLocalTranslation, the function's parameter is expressed in local space and transform to world space Not sure I'm clear Quote Link to comment Share on other sites More sharing options...
gwenael Posted December 26, 2013 Author Share Posted December 26, 2013 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. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted December 26, 2013 Share Posted December 26, 2013 For setLocalTranslation, you are absolutely right:) Do you mind to make a pull request on Github?? (so you will be rewarded as contributor^^) About infiniteDIstance, I have to take time to think about your update:) (I'm travelling right now far from my computer) Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted December 27, 2013 Share Posted December 27, 2013 After thinking about infiniteDistance, I think I would block its use when the mesh has a parent because in this case this is a non senseAbout setLocalTranslation we should use TransformNormal instead of TransformCoordinates because _localWorld contains previous translation Quote Link to comment Share on other sites More sharing options...
gwenael Posted December 27, 2013 Author Share Posted December 27, 2013 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. Quote Link to comment Share on other sites More sharing options...
gwenael Posted December 27, 2013 Author Share Posted December 27, 2013 For me both methods could be useful but I feel like setLocalTranslation should be renamed setLocalPosition. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted December 27, 2013 Share Posted December 27, 2013 Agree for creating both also agree to make infiniteDistance works with a parentedCamera ( i will fix that point for the next release) Quote Link to comment Share on other sites More sharing options...
gwenael Posted December 27, 2013 Author Share Posted December 27, 2013 (edited) 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 January 10, 2014 by gwenael Quote Link to comment Share on other sites More sharing options...
gwenael Posted December 27, 2013 Author Share Posted December 27, 2013 Be careful, do not be as dumb as I was, the lines are effectively parallel. That's the projection which gives the impression they are not. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted December 27, 2013 Share Posted December 27, 2013 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 Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted December 27, 2013 Share Posted December 27, 2013 locallyTranslate is more about adding a vector to the current location, don't you think ? I must agree that this one is more useful but we need also to be able to define (not add) the local translation Quote Link to comment Share on other sites More sharing options...
gwenael Posted December 28, 2013 Author Share Posted December 28, 2013 (edited) 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 January 10, 2014 by gwenael Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted December 29, 2013 Share Posted December 29, 2013 excellent thank you very much! Quote Link to comment Share on other sites More sharing options...
gwenael Posted January 2, 2014 Author Share Posted January 2, 2014 https://github.com/BabylonJS/Babylon.js/pull/116 GameMonetize 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.