On the THREE.js Discourse forum one of the suggestions I saw concerning my animations going wacky at large distances from the origin was to just put the SkinnedMesh at the origin, then move the world around it instead of moving the SkinnedMesh through the world. The end result should be the same. This seemed like a reasonable suggestion (although it doesn’t really address the underlying issue) but implementation seemed like it would be a real pain. Well, circumstances sort of forced me to give this a shot and after some fiddling I figured out I could accomplish this with 4 lines. These two go at the beginning of my update loop:
scene.position.set(0, 0, 0);
This puts the scene itself at the origin, then tells THREE.js to update the transform matrices of the scene and all its children. At least, I think that’s what it does. Then at the end of the update loop:
This moves the scene away from the origin in the opposite direction the amount the player is away from the origin, so it puts the player at (0, 0, 0). It then moves the camera so that it is looking at the player’s new position at the origin.
That’s it. It’s that simple. Now my animations play smoothly and I didn’t really have to change much. The center of the world is still at (130560, 0, 130560) and the player and enemies can move around all in that space, but when it gets rendered the system sees everything as being centered around (0, 0, 0).
I’m still looking forward to a fix in THREE.js r94, but if this works I may keep it this way even after the fix. Eh, we’ll see.