Flomotion Posted September 13, 2015 Share Posted September 13, 2015 Hi all, I'm importing my camera position and rotation from a .max export to .Babylon. And I make the camera fly from 1 camera point to the other.But in some cases the camera rotation rotates like 270 degrees to get to the end rotation. I've set up the angles in this playground. http://www.babylonjs-playground.com/#W27OD How can I calculate the difference in angle between 2 vectors and convert 1 of them to make sure that the shortest route will be taken? thanks To clarify: Quote Link to comment Share on other sites More sharing options...
dimumurray Posted September 14, 2015 Share Posted September 14, 2015 You can use the Dot Product to find the shortest angle between the vectors. Let A be the vector defined by the dark blue colored arrow and let B be the vector defined by the cyan colored arrow. The Dot Product of two vectors can be calculated using any of two equations.One equation states that the Dot Product of 2 vectors is the product of the magnitude of the vectors times the cosine of the shortest angle (theta) between them, written as:A . B = ||A|| ||B|| cos(theta) The other equation finds the dot product by taking the product of the x and y components of the two vectors and adding them together, written as:A . B = AxBx + AyBy These equations are equivalent so you can solve for theta using:AxBx + AyBy = ||A|| ||B|| cos(theta) However you can simplify things a great deal by normalizing the two vectors so that their magnitudes are of unit length. Once normalized the magnitudes of A and B are both 1. So you end up with.An = normalize( A )Bn = normalize( B )And from that you get:AnxBnx + AnyBny = cos(theta) and theta can be found using:theta = arccos(AnxBnx + AnyBny)There is still one problem though. Theta is just the raw angle of rotation, a scalar value. It doesn't tell you whether you should be doing clockwise rotation or counter-clockwise rotation from A to B. To figure that out you'll have to use the 2D version of the Cross-Product (aka Wedge Product). To find the 2D Cross-Product of vector A and B use the following equation:A X B = AxBy - AyBx Now what you want to know is if the result of the above gives you a +ve or -ve value. If +ve you have clockwise rotation, if -ve you have counter-clockwise rotation. Once you know that you can make theta -ve or leave it as +ve. Ahiru and zeke_chan 2 Quote Link to comment Share on other sites More sharing options...
Flomotion Posted September 14, 2015 Author Share Posted September 14, 2015 wow.. thanks.I was afraid it wouldn't be a very simple thing. But.. I should be able to write it down in code. If I manage to get it right I'll post it here. I just noticed that I see no z-value in the equation. Does it mean that this calculation is only for 2D vectors? Quote Link to comment Share on other sites More sharing options...
dimumurray Posted September 14, 2015 Share Posted September 14, 2015 I assumed this was a 2D question. These concepts can be applied to 3D (Babylon's Vector3 class has the requisite methods to cover both dot and cross products), but you'd be far better off using quaternions (Babylon's Quaternion class should cover your needs). If you go the Quaternion route you'll still need to find the angle using the dot product. You'll need the cross produlct as well, but to determine the axis of rotation. In 3D the cross-product of 2 vectors gives you a vector that is perpendicular to both vector (which can then serve as the axis of rotation common to both). You can use the Vector3's cross product method to calculate that vector and then pass that vector and the angle to the method Quaternion::RotationAxis(angle, axis) to get the Quaternion. Then you can use the slerp method on it to smoothly animate the camera. Best part is that you don't have to worry about clockwise and counter-clockwise rotation (as in the 2D case). That comes built in once your calculate the axis of rotation. Quote Link to comment Share on other sites More sharing options...
Flomotion Posted September 14, 2015 Author Share Posted September 14, 2015 Thanks for your answer. Would you mind giving a small example?I might be able to pull it of with your description. But for now it sounds very complicated to me.Hope I'm not overasking.:-)Floris Quote Link to comment Share on other sites More sharing options...
adam Posted September 14, 2015 Share Posted September 14, 2015 It's easier to ease a rotation of this type with quaternions, but since bablyon cameras don't have a rotationQuaternion property I first rotated a box mesh and then copied it to the camera. http://www.babylonjs-playground.com/#W27OD#2 Quote Link to comment Share on other sites More sharing options...
Flomotion Posted September 14, 2015 Author Share Posted September 14, 2015 Hi Adam,thanks for your reply. And clever to use the box for the rotationQuaternion.The rotation seems to be taking the short route. But the starting and ending viewpoint is different from my example.I noticed that you had shifted the value's in the fromRotation and toRotation.But changing it to my original value's unfortunately didn't fix it.(though hard to see.. with only clouds ;-) I'll try to do what Dimumurray suggested with your method. Quote Link to comment Share on other sites More sharing options...
adam Posted September 14, 2015 Share Posted September 14, 2015 It does look like there is an issue with my proposed solution. I can't make the camera ease to the left using a negative value: http://www.babylonjs-playground.com/#W27OD#3 Quote Link to comment Share on other sites More sharing options...
dimumurray Posted September 14, 2015 Share Posted September 14, 2015 I don't have any implementation for you but here's a decent series of videos that cover the theory behind how Quaternions work. Math For Game Developers - QuaternionsOnce you get that under you belt you should be able to look at the Babylon.js APIs and figure out how best to solve the problem. Better yet you'll have a solid grasp of quaternions and when to apply them. Quote Link to comment Share on other sites More sharing options...
adam Posted September 14, 2015 Share Posted September 14, 2015 [DELETED] Quote Link to comment Share on other sites More sharing options...
fenomas Posted September 15, 2015 Share Posted September 15, 2015 It does look like there is an issue with my proposed solution. I can't make the camera ease to the left using a negative value: http://www.babylonjs-playground.com/#W27OD#3 I'm no quaternion expert but it looks to me like Babylon's quaternion.toEulerAngles() is buggy:BABYLON.Quaternion.RotationYawPitchRoll( 0, 0.1, 0 ).toEulerAngles()t {x: 0, y: 0.09999999999999945, z: 0}BABYLON.Quaternion.RotationYawPitchRoll( 0, -0.1, 0 ).toEulerAngles()t {x: 3.141592653589793, y: 0.09999999999999945, z: -3.141592653589793}For your demo, if you avoid conversions by parenting the camera to the mesh with the rotation quaternion, it should work:http://www.babylonjs-playground.com/#W27OD#6 adam 1 Quote Link to comment Share on other sites More sharing options...
fenomas Posted September 15, 2015 Share Posted September 15, 2015 Actually I think I was wrong about toEulerAngles being buggy. I'm not sure what's wrong here. Quote Link to comment Share on other sites More sharing options...
jerome Posted September 15, 2015 Share Posted September 15, 2015 if you are in 3D and you know the initial direction and the final wanted one, you can get the rotation from the initial to the final with : RotationFromAxis() Quote Link to comment Share on other sites More sharing options...
Flomotion Posted September 15, 2015 Author Share Posted September 15, 2015 I'm affraid none of the solutions work yet. I'd like to be able to do it with imported camera's.But many thanks for the suggestions. Maybe after taking the course Dimumuray suggested I'll be able to create something. Going to watch it now :-) Quote Link to comment Share on other sites More sharing options...
Flomotion Posted September 15, 2015 Author Share Posted September 15, 2015 well.. it seems my problem was easy to fix.. I feel a bit stupid.I just checked for every axis:if (Math.abs(fromRotation.x-toRotation.x)> Math.PI) { if ((fromRotation.x-toRotation.x)>0) { fromRotation.x = fromRotation.x-Math.PI*2; } else { fromRotation.x = fromRotation.x+Math.PI*2; } } But finding out about the math for game developers is very nice.Thanks for all your replies! Quote Link to comment Share on other sites More sharing options...
MinsuKim Posted July 20, 2018 Share Posted July 20, 2018 On 2015. 9. 15. at 오전 2시 28분, adam said: 이 타입의 회전을 쿼터니언으로 쉽게하는 것이 쉽지만, bablyon 카메라에는 rotationQuaternion 속성이 없으므로 먼저 상자 메쉬를 회전시킨 다음 카메라로 복사합니다. http://www.babylonjs-playground.com/#W27OD#2 i find my Issue! 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.