Awesome! The viewer will also be translating the entire content closer to the world origin soon as part of one of the next updates.
However I’ll also be trying the idea for a solution I mentioned in my previous response just out of curiosity. I just need to make a bit of time for it
So I’ve looked into the matter found the problem(s) and fixed them
There are two issues in the current implementation:
Our current RTE implementation is very much large-range biased when it comes to emulating the double precision vertex positions. We encoded double precision values as two separate floats. When you normally do this, there are multiple ways in which you can encode them, depending if you want a higher range, or a higher precision. It’s impossible to have both the highest range and the highest precision at the same time. You can however give up range in favor of precision, and vice-versa. Our current RTE implementation is highly in favor of range currently. Much to highly actually… This makes precision suffer greatly, and that’s why you got that poor quality mesh as a result
The second issue is less complicated, and it’s to do with how three.js stores the vertex position values in it’s buffer attributes. It casts them down to float before we get a change to do the high/low split, meaning we’re currently splitting float values, which again hurts precision. Complementary to this, three’s implementation for computing the vertex normals, use the position buffer attribute content as the source for generating them. Since the buffer attribute is already casted down to float, the normals also get messed up by default, but that’s an easy fix, since we can compute the normals ourselves using the double vertex positions
Regarding the first issue, I’m thinking of having a dynamic rage/precision encoding depending on the world size. We will add this feature in one of the next releases. Regarding the second issue, we’ll simply compute the normals ourselves and make sure we split the double value, not the casted down one.