I think 'setLocalEulerAngles' z-axis is strange


#1

Hi.
First of all, you guys are always getting help Thank you.

This is my simple code

Hello.prototype.initialize = function() {
    var initAngle = this.entity.getLocalEulerAngles();
    console.log(initAngle);
    
    // Case 1 : It's works!
    // this.entity.setLocalEulerAngles(initAngle.x, initAngle.y + 90, initAngle.z);
    // console.log(this.entity.getLocalEulerAngles());
   
    // Case 2 : It's works!
    // this.entity.setLocalEulerAngles(initAngle.x + 20, initAngle.y, initAngle.z);
    // console.log(this.entity.getLocalEulerAngles());
    
    // Case 3 : Is world z axis?? 
    // this.entity.setLocalEulerAngles(initAngle.x, initAngle.y, initAngle.z + 20);
    // console.log(this.entity.getLocalEulerAngles());
};

uncomment in order.
Default: {x: 0, y: 0, z: 0}
PNG

Case 1:.setLocalEulerAngles(initAngle.x, initAngle.y + 90, initAngle.z)
{x: 0, y: 90, z: 0}
1
Case 2:setLocalEulerAngles(initAngle.x + 20, initAngle.y, initAngle.z)
{x: 20, y: 90, z: 0}
2
Case 3:setLocalEulerAngles(initAngle.x, initAngle.y, initAngle.z + 20)
{x: 2.248991783197472e-15, y: 90, z: 0} …??? (Z is still 0)
3
My prediction is that the box should lean forward, When run case 3 ,but it is not.
Case 3 rotates like world z-axis…

Here is my project
https://playcanvas.com/editor/project/626119

If this is a gimbal-lock, how can i avoid?


#2

It’s not so much broken but more of a nuance of the engine.

this.entity.getLocalEulerAngles() returns a reference to the pc.Vec3 for the euler angles.

This means that when you change the local angles of the entity, (eg case 1) you are also changing the value of initAngle as it’s a reference.

Change it from

    var initAngle = this.entity.getLocalEulerAngles();

to

    var initAngle = this.entity.getLocalEulerAngles().clone();

And you now have a copy of the starting euler angles to work with.


#3

Thanks yaustar :slight_smile:

I have another question about rotate

I want to rotate object and return to the original state regardless of the order.
But there is something weird.

var q = new pc.Quat();
    this.entity.setLocalRotation(q);
    this.entity.setRotation(q);

    //Default Case    
    this.entity.rotate(0, 0, 20); //z
    this.entity.rotate(0, 20, 0); //y
      
    //Case 1 : It's works!
    // this.entity.rotate(0, -20, 0); //y
    // this.entity.rotate(0, 0, -20); //z

    //Case 2 : It's works!
    //this.entity.rotate(0, -20, -20); //z        

    //Case 3 : ???
    this.entity.rotate(0, 0, -20); //z    
    this.entity.rotate(0, -20, 0); //y

default:


Case 1: Return to original perfectly!

Case 3: ???

Is there any way to return to the same state as the Default case, regardless of the order?

Actually, Now I’m making three slider(x,y,z) axis, but it is very difficult…
Because of ordering
4

Move the y-axis and the z-axis.
for back to original, Move the y-axis and the z-axis
it doesn’t return to its original state, Only same when Move the z-axis and the y-axis


#4

The order of rotations matter. To go back to the original, you have to reverse the order. ie:

var q = new pc.Quat();
    this.entity.setLocalRotation(q);
    this.entity.setRotation(q);

    //Default Case    
    this.entity.rotate(0, 0, 20); //z
    this.entity.rotate(0, 20, 0); //y
      
    //Case 1 : It's works!
    // this.entity.rotate(0, -20, 0); //y
    // this.entity.rotate(0, 0, -20); //z

    //Case 2 : It's works!
    //this.entity.rotate(0, -20, -20); //z        

    //Case 3 : ???
    this.entity.rotate(0, -20, 0); //y
    this.entity.rotate(0, 0, -20); //z    

For the slider, you are best off storing the euler angles in the script and setting the rotation of the entity rather than applying deltas.


#5

For the slider, there’s something weird going on.

In this time, I’m using the World space.

https://playcanvas.com/editor/scene/776822

If you control the x- and y-axes, they move on the same axis. It’s even a world space! Not local!