|
Miha003, Newbie
Posted: 29 September 2012 10:57 AM Total Posts: 26
I know this is basic stuff, but I need someone to explain it to me.
Asume I have a mesh in space (x,y,z) position. I want to rotate it around its local axis. Individual rotation works fine (around a single axis) but when combining (for example rotate around z and y axis) it doesn’t work as expected.
I know where is the problem: rotation around local z axis changes the local coordinate system, the y axis will not point up/vertically anymore, therefore when the rotation around y axis come…the rotation is messed up.
I DON’T know how to resolve this problem in away3d.
First I have tried :
mesh.rotationX += rotX;
mesh.rotationY += rotY;
mesh.rotationZ += rotZ;
It doesn’t work because of the problem I have described above.
Then I have tried:
var mat : Matrix3D = _currShip.transform;
var matDecompose: Vector.<Vector3D> =mat.decompose();
var rotMatrix : Vector3D = matDecompose[1];
rotMatrix.x += _currShipRotX* MathConsts.DEGREES_TO_RADIANS;
rotMatrix.y += _currShipRotY* MathConsts.DEGREES_TO_RADIANS;
rotMatrix.z += _currShipRotZ* MathConsts.DEGREES_TO_RADIANS;
mat.recompose(matDecompose);
_currShip.transform = mat;
Suprisingly this code produces the same effect as the code from my 1st attempt.
Although in the decompose method’s comment it says “The rotations occur consecutively and do not change the axis of each other”
. I understand this as when applying a rotation around Z, the local axis used for rotating around Y is not affected.
Then I have tried reading 1000 forums on the net. Nobody gives a precise example. They all give hints about use quaternion, or this or that.
Can anybody help me?
Thanks in advance!
|
|
Miha003, Newbie
Posted: 30 September 2012 05:56 AM Total Posts: 26
[ # 2 ]
Thanks Fabrice for the hint.
I did this:
var quat :Quaternion = new Quaternion();
quat.fromEulerAngles( _currShipRotX* MathConsts.DEGREES_TO_RADIANS, _currShipRotY MathConsts.DEGREES_TO_RADIANS, _currShipRotZ* MathConsts.DEGREES_TO_RADIANS);
var rotVector : Vector3D = quat.rotatePoint(_currShip.position);
_currShip.rotateTo(rotVector.x,rotVector.y,rotVector.z);
But it doesn’t work.
What am I doing wrong?
|
Sandro, Newbie
Posted: 30 September 2012 07:01 AM Total Posts: 10
[ # 3 ]
For free rotation without locks try something like
public var matrix:Matrix3D;
matrix = object.transform.clone(); matrix.appendRotation(rotY, object.upVector, matrix.position); matrix.appendRotation(rotX, object.rightVector, matrix.position); matrix.appendRotation(rotZ, object.forwardVector, matrix.position); object.transform = matrix;
|
Miha003, Newbie
Posted: 30 September 2012 07:12 AM Total Posts: 26
[ # 4 ]
Just tried your solution, but I get the same results as in my initial attempts.
Please read what I have written in my initial post.
|
Sandro, Newbie
Posted: 30 September 2012 07:23 AM Total Posts: 10
[ # 5 ]
but when combining (for example rotate around z and y axis) it doesn’t work as expected
It is not clear what you expect. We have to keep the vertical orientation of the object?
|
Miha003, Newbie
Posted: 30 September 2012 07:27 AM Total Posts: 26
[ # 6 ]
“rotation around local z axis changes the local coordinate system, the y axis will not point up/vertically anymore, therefore when the rotation around y axis come…the rotation is messed up.”
In other words: Rotate the object around z axis, then rotate around y axis => the object will look if it have been rotated around x axis as well.
Here is another explanation: I have an aircraft flying along z axis, my camera is right behind him. When I rotate the aircraft around z and y axis , I would expect that the nose and tail of the aircraft don’t change their position on y axis. But they do…as if the aircraft would rotate also around x axis.
I hope it is more clear now.
|
Sandro, Newbie
Posted: 30 September 2012 07:40 AM Total Posts: 10
[ # 7 ]
Yes, now it is clear what is expected.
I suggest to put an object into a container. Container rotate only on the Y-axis (vertical), the object rotate only on the local Z-axis (forward).
|
Miha003, Newbie
Posted: 30 September 2012 08:22 AM Total Posts: 26
[ # 8 ]
Interesting solution, just tried it and it works!
Thanks a lot.
But still, it is strange that for such a basic problem I have to do these workarounds. I have read many formus, but nobody gives the complete solution so that a beginner like me can easily understand. It is either very complicated, or maybe it is to much to write, or maybe it is secret lol.
I would be very curious to see how those quaternions would resolve this in away3d, but my attempts failed. So I will stick to your solution for now.
Thank you Sandro!
|
Sandro, Newbie
Posted: 30 September 2012 08:41 AM Total Posts: 10
[ # 9 ]
You can also in matrix.appendRotation specify the global axis (upVec).
public var matrix:Matrix3D; public var upVec:Vector3D = new Vector3D(0,1,0);
matrix = object.transform.clone(); matrix.appendRotation(rotY, upVec, matrix.position); matrix.appendRotation(rotX, object.rightVector, matrix.position); matrix.appendRotation(rotZ, object.forwardVector, matrix.position); object.transform = matrix;
|
Miha003, Newbie
Posted: 30 September 2012 08:49 AM Total Posts: 26
[ # 10 ]
Sandro you saved the day
Now that is an excelent solution.
So I guess the key was to use upVec and not object.upVec.
Thank you very much!
|
Miha003, Newbie
Posted: 02 October 2012 01:49 PM Total Posts: 26
[ # 11 ]
Playing around with my new rotating ship (thank you Sandro for making it happen) I noticed the following problem: ship starts from 0,0,0 rotation, I rotate to left….then right…then left again then right again a couple of times.
Then I try to bring the ship back to 0,0,0 rotation, but that is not possible anymore. The rotation around x axis is messed up. I see in traces something like 10,0,0 degrees.
The more I continue rotating left and right, when trying to bring the ship back to original rotation(0,0,0)...those 10 degres increases.
Its like the rotation is losing precision or something.
Basically I am alternatively pressing and holding ‘A’ and ‘D’ keys.
On each frame my ship should rotate 2 degress (to left or right).
Here is my code:
private function onEnterFrame(event : Event) : void {
var matrix : Matrix3D = _currShip.transform.clone();
matrix.appendRotation(-currRotZ, UP_VECTOR,matrix.position);
matrix.appendRotation(currRotX, _currShip.rightVector,matrix.position);
matrix.appendRotation(currRotZ, _currShip.forwardVector,matrix.position);
_currShip.transform = matrix;
}
private function onKeyDown(event : KeyboardEvent) : void {
switch (event.keyCode) {
case Keyboard.SHIFT:
break;
case Keyboard.A:
_currShipRotZ = 2;
break;
case Keyboard.D:
_currShipRotZ = -2;
break;
case Keyboard.W:
_currShipRotX = 2;
break;
case Keyboard.S:
_currShipRotX = -2;
break;
}
}
private function onKeyUp(event : KeyboardEvent) : void {
switch (event.keyCode) {
case Keyboard.SHIFT:
break;
case Keyboard.A:
case Keyboard.D:
_currShipRotZ = 0;
break;
case Keyboard.W:
case Keyboard.S:
_currShipRotX = 0;
break;
}
}
|