☑ setEulerAngles followed by translateLocal resulting in NaN location - bug or am I doing something wrong?

Hi all,

First time poster here and only a few hours into working with PlayCanvas and I’ve gotten stuck. I am trying to reflect my entity off the edges of the screen - ie: come in at 45 degrees, hit the wall edge, and bounce back at the angle a ball would.

For some reason when I’m very close to the wall and I try to bounce off I get a NaN location and my entity disappears. I’d be very grateful if anyone would take a look, and if you don’t know why it could be doing this perhaps I should submit a bug report?

Here’s my code and the relevant console output:

console.log("Pre rotate Z: " + this.entity.getPosition().z);

slugRot = this.entity.getEulerAngles();
angDiff = 90 - slugRot.y;
this.entity.setEulerAngles(slugRot.x, 180 + (90 - slugRot.y), slugRot.z);
console.log("Post rotate Z: " + this.entity.getPosition().z);
        
this.entity.translateLocal(0,0,-0.05);
console.log("Post translate Z: " + this.entity.getPosition().z);

Console output:

Pre rotate Z: -3.7720694541931152
Post rotate Z: -3.7720694541931152
Post translate Z: NaN

You can also try the game here: http://playcanv.as/p/GFG49WF2/

Arrow keys to move, and spacebar to jump. The weirdest part is that you can jump from far away and the reflection works perfectly, but if you go very close (so the slug’s center cube is almost touching the top border) and jump and it will always cause the problem.

It’s difficult to tell without the whole source, could you share the project itself? Meanwhile, I see if I can reproduce locally.

I’ve managed to find your project and forked here to see if I can find out what is causing your NaN.
https://playcanvas.com/project/440414/overview/translate-local-issue

Turns out that you were setting the scale of the entity to 0 on one of the axis which causes the calculation of Eular angles to go wrong as it causes a division by 0 error (NaN). (See below for the engine code.

        getEulerAngles: (function () {
            var scale = new pc.Vec3();

            return function (eulers) {
                var x, y, z, sx, sy, sz, m, halfPi;

                eulers = (eulers === undefined) ? new pc.Vec3() : eulers;

                this.getScale(scale);
                sx = scale.x;
                sy = scale.y;
                sz = scale.z;

                m = this.data;

                y = Math.asin(-m[2] / sx);
                halfPi = Math.PI * 0.5;

                if (y < halfPi) {
                    if (y > -halfPi) {
                        x = Math.atan2(m[6] / sy, m[10] / sz);
                        z = Math.atan2(m[1] / sx, m[0] / sx);
                    } else {
                        // Not a unique solution
                        z = 0;
                        x = -Math.atan2(m[4] / sy, m[5] / sy);
                    }
                } else {
                    // Not a unique solution
                    z = 0;
                    x = Math.atan2(m[4] / sy, m[5] / sy);
                }

                return eulers.set(x, y, z).scale(pc.math.RAD_TO_DEG);
            };

The solution for this case is to either keep track of the rotation yourself in code (which is what we do in the Orbit Camera sample) or don’t set the local scale to 0 which is what I did in Slug.js with math.clamp.

Wow thank you so much Steven, I will watch out for it next time.