Get clean EulerAngles

Hello,
I have a small issue with the eulerAngles, that I cannot figure out how to solve without rewriting existing code.

I have a script, which requires some rotational values between 0 – 360 and I thought I can simply feed it with the output from the getEulerAngles() function and clamp it to stay between 0/360 instead of -360/360. But then I run into the issue, that the output of the eulerAngle function does some weird voodoo of swapping the rotational values around. Like discussed here:

The problem is that the script works only with the x & y axes and expects z to stay at zero all the time.
Therefore the orientation isnt matching anymore, if the euler angle function returns angles with z on 180 for example.

Is there any way how to get the angles in a way like the entity rotation values in the editor without these swaps in-between?

Greetings,

Martin

It’s difficult because the rotation is represented as a quaternion and converting it to euler angles returns values between -180 and 180.

In this case, a workaround is to have an Vec3 attribute in the/a script to store the euler angles you want in the editor or any value so you can do the processing you need on it as well as storing it as euler angles without the axis flip. The downside is that you don’t see the object rotate in the editor.

1 Like

Yeah, I noticed its slightly more difficult, than I initially thought.

The idea to use a separate script as workaround is not bad, this way I won’t need to rewrite my existing code. Tough it’s also not too convenient to attach an additional script to each of my target entities. Just to manually assign some proper rotational values to them…

It slightly bothers me, that I cannot come up with a proper conversion. I mean it works in one direction, so it should also work the other way around x)

Quaternion rotation to Euler is always a bit of an issue due to the multiple possible rotations that represent the same thing. Basically what a Quaternion is, is a rotation around an axis. In the case “weird voodoo” happens, it’s because the math has flipped the direction of that axis.

I use this to get a rotation around a known axis:

var vo = new pc.Vec3()
function orthogonal(v) {

    var x = Math.abs(v.x)
    var y = Math.abs(v.y)
    var z = Math.abs(v.z)
    var other = x < y
        ? ( x < z
            ? pc.Vec3.RIGHT
            : pc.Vec3.FORWARD )
        : ( y < z
            ? pc.Vec3.UP
            : pc.Vec3.FORWARD )
    return vo.cross(v, other)
}

var v1 = new pc.Vec3()
var v2 = new pc.Vec3()
var v3 = new pc.Vec3()
pc.Quat.prototype.twist = function(axis) {
    var orth = orthogonal(axis)
    var transformed = this.transformVector(orth, v2)
    var flattened = v1.copy(transformed).sub(v3.copy(axis).scale(transformed.dot(axis))).normalize()
    var angle = Math.acos(orth.dot(flattened)) * pc.math.RAD_TO_DEG
    return v1.set(this.x, this.y, this.z).dot(axis) > 0 ? -angle : angle
}

You can call it with pc.Vec3.UP/LEFT/FORWARD etc.

2 Likes

You can group select all the entities and then add a script and/or modify data all in one go.

Yeah sure, it’s not that the editor isn’t convenient to work with :wink:

I just wanted to avoid that in the first place, as it’s an additional step in the workflow. Nether less I found a solution, which works out and isn’t adding to much extra complexity to the setup. I went with the additional script now, but added a load of further options to it. If I need that why not take use of the additional possibilities :stuck_out_tongue:

Found a simple workaround for that as well. I attached an event listener to the attribute change of the script, which toggles a separate camera, to show me its position in the play view. It’s not updating its rotating in the editor, but that’s convenient enough to quickly setup the rotational values.

@whydoidoit Thanks fort hat sinppet.