How to set a Euler object from a plain JSON object/

My virtual world receives position updates for the other players in the world from my server. I then have to take the update and reposition the avatar for the remote player to keep the worlds in sync. Therefore, I am sending position and rotation values “over the wire”.

The problem I’m having is that if I try to use the object’s rotation.set() function using the values in the received object, it doesn’t work and the object disappears off the screen:

        // This does NOT work.
        self.threeJsAvatar.rotation.set(newRotation._x, newRotation._y, newRotation._z, newRotation._order);


However, If I use the received object's values to create a **new** `Euler` object, and then set the object's `rotation` from that, it works fine:
```js
        // This WORKS.
        const reusableEulerObj = new THREE.Euler(newRotation._x, newRotation._y, newRotation._z, newRotation._order);

        self.threeJsAvatar.rotation.set(reusableEulerObj.x, reusableEulerObj.y, reusableEulerObj.z);

But, that means I’m creating tons of new Euler objects over time and I was told to avoid that and to reuse a module scope object instead. Apparently the Euler object constructor is doing something I need to emulate or use a different approach that avoid this problem altogether.

How can I update the object’s rotation using the private variables that got sent "over the wire in the form of a plain JSON object, without creating a new Euler object,? Or is there a better way to do this overall?

Those really should be the same thing, I don’t think three.js is doing anything tricky here.

Are you able to print the state of the Euler before/after an update both ways to compare?

Like:

const { x, y, z, order } = object.rotation;
console.log({x, y, z, order});

The only difference I’m seeing is that the order argument isn’t getting passed in the last line of code in your example. If the order were something other than the default (XYZ) then that would make a difference.

It’s also a bit of a red flag to me that the API sends “private” values prefixed with underscores… public/private visibility usually is not a thing that exists in API responses.

1 Like

Not here. That’s just the contents of a raw Euler object, not a security hole. I just didn’t bother creating a temporary object and copy over the xyz fields just to facilitate a simple rename of the internal field values. The Euler object doesn’t have public xyz fields for some reason like the THREE.Vector3 object does.

I’ll trace and inspect as you suggest and see if anything turns up. What I think is weird is that when I set the reusable Euler object in the first approach, I can no longer see the object in the scene at all. What kind of a rotation value could cause that extreme behavior?

It has x/y/z but they are getters/setters rather than properties. So you can still access euler.x or a THREE.Euler instance.

What kind of a rotation value could cause that extreme behavior?

NaN, for example. But really any difference vs. the other code sample.

1 Like