What I am proposing here is to rebase the overarching client-side coordinate system in Vircadia to 48 bit integers, rather than the current 32-bit IEEE floats. Only client-side, though.
Note: This is NOT a proposition to change the graphics system to integer/fixed-point
(that would be an awfully big job of no benefit in the context of currently common GPU hardware!)
Also note: I would be able to put some time (several hours per week, indefinitely) into working on these ideas myself (ie, I’m not asking others to do it for me), but would only be interested in doing so if the community feels it is a worthwhile direction for Vircadia! Also keeping in mind that I am not a professionally-trained programmer - I’m self taught, mostly in C on micro-controller-class devices. I am happy to try to learn as I go, but would require some support via answering of probably-stupid questions in the forums!
So this is primarily intended a question on if it is worthwhile (to the community) for me to pursue this idea. Details below are provided for clarity, and for opportunity for others to point out any flaws in my idea (and any mistaken assumptions I have made in formulating it!).
The current Vircadia system has an object-placement coordinate system based on 32-bit IEEE floating-point numbers. Though in theory, this allows a server-administrator to choose world-extent vs object-placement-resolution, at present it seems to be fixed to a 1mm granularity and 16km extent for practical purposes, in the user-side UI at least.
I am proposing an alternative in-world coordinate system (predominantly expressed client-side) using 48-bit integers with a fixed granularity of 10μm* (ie: 1 unit = 10μm).
*Declaration of conflict-of-interest: I have chosen the 10μm value for entirely personal reasons. Specifically, it is a usefully-fine-grained value occurring at a ‘sweet-spot’ intersecting the base-10 metric system closely enough (97.6%) with my own preferred measurement units (base-8 multiples of the plank-length) that I can fiddle the UI to use either base+unit just by adding/subtracting zeros from the numbers displayed/input in a marginally-modified UI!
This would give a coordinate system with an extent of 2.8 million!! km. Rather large, being big enough to very comfortably fit a Jovian-moon-system-sized ‘world’ inside its bounds! (
64-bit would get you out to solar-system scale, which could be an option, but keeping those high 16-bits reserved can potentially help with keeping integer/fixed-point maths within the range of a 64-bit CPU register while calculations are in-flight!
Also, to mash up Arthur C. Clarke and Bill Gates* “All the worlds of Jupiter ought to be enough for anyone!”
*To be fair on Mr Gates, in context his statement should be more like: 640k ought to be enough for anyone using MS-DOS for anything it could reasonably be expected to be used for.!
To properly utilise this additional coordinate space, a server would have to supply the client with the following additional data about itself:
1) Base scale - an indicator of the ‘unit’ size of the server.
At present the scale of a Vircadia appears to be assumed fixed at 1mm object placement resolution across an approximately 16km extent, per axis (before resolution granularity starts to noticeably suffer the effects of floating-point-format non-linearity).
Instead, I suggest the server should be able to specify its preferred optimal FP range explicitly to the client, so the server-operator can choose to reduce the maximum extent to gain higher object placement-resolution or vice-versa, and the client UI can set its input limits accordingly (it is, I believe, mainly a UI issue, as the nature of floats already allow this to be done as long as the user manually avoids exceeding the preferred bounds - this mostly just makes it explicit it in the UI presented to the user).
Personal note: I originally was going to suggest switching server-coordinates to 32-bit integers to better use a smaller fixed resolution over a greater extent, but after typing out my ideas on that realised that being able to actually choose the trade-off in extent-vs-resolution is sort of what IEEE floating point is all about in the first place, so why not use the existing format’s strength!
2) Origin offset - a 32-bit-per-axis offset in 48-bit coordinate space (added to the 32 MSB of the 48-bit coordinates of the server’s objects to get absolute location in 48-bit space).
This allows multiple servers to inhabit the same coordinate space seamlessly, with the avatar moving between them simply by changing location in 48-bit integer space.
It is assumed the client is tracking which objects in its 48-bit space are being served from which server and unioning them in its local scene-graph.
Note that the server placement-resolution provided will be about 0.66m, or 2ft (10um*2^16), which allows fairly fine-grained placement of server-origins (for example, it is sufficiently fine for fitting an apartment-sized ‘world’ into a level of a sky-scraper-shell with other ‘apartment-servers’ filling other levels of the same shell; or being able to place 1/4-acre housing blocks along a non-strait road. ie, not forcing a Second-Life-style fixed-sized-grid-layout to such worlds).
Rather than each server individually advising its ‘origin offset’, it might be more efficient and secure to for any server sharing physical space with others to send a link to a new type of server (and a null-type address if not space-sharing)…
3) Federation Server
An additional server type would handle federated sets of worlds, one server per federation, managing the origins and bounds of all its contained worlds.
Note that this is not one central server for all federated worlds, but one server per federated set, of which there could be any number. We are not centralising here at a general level, only between server-operators that want to share a space, with as many shared spaces as desired. A user would still ‘teleport’ between individual federations, but now can move spatially between servers within a federation sharing a single coordinate system.
Notes for consideration:
Spatially-overlapping servers probably don’t need to be aware of each other except in special cases.
Avatars will need to interact with multiple servers where objects of said servers are occupying the same space.
Would OR-ing collision boundaries between multiple space-concurrent* servers (ie, a collision on any server blocks the avatar) be manageable? … Probably reasonable to no expect more than 4 concurrently geographically-overlapping servers: eg: over-world, sub-world, local-world, closest-local-neighbour at the extreme.
Server-controlled physics-controlled objects would be bounded by their server spatial extent (probably mostly a good thing as it stops inadvertent - or deliberate - object-spamming between non-overlapping servers - ie: I can’t stuff my physical-neighbours’ space full of tribbles hosted from my own server!)
A special object type/attribute for NPCs, Vehicles and such, that explicitly forces multi-server physics interaction might be enough to cover cases where generic inter-server physical interaction is useful/desired, so cases where this extra load is present are explicitly set up, with the lighter-weight no-interaction being default for most objects. Servers could also explicitly handle inter-server-object interaction via custom back-end programming, with an appropriate API, where the general explicitly-via-physics interaction described is not sufficient.
The client-side object-location calculation would likely go something like…
_For each axis (X,Y,Z)
__Convert object location float32 to int64 (normalised via server_base_scale to 10um units)
__Add (32-bit_server_origin_offset << 16)
__Subtract current 48-bit-space avatar location
__Convert back to float32 for graphics subsystem (assuming things far away from avatar won’t miss any loss in precision from this conversion - or are far-clipped out anyway)
A bit of extra work there, but the avatar-location-subtract, at least, is presumably already happening somewhere in he graphics stack.
Also, this calculation is just needed once per object in the scene-graph - calculations on all sub-vertexes, etc. shouldn’t need to change, just use the above final float32 origin result instead of the raw server-origin-relative one they presently use. That is to say, I wouldn’t expect this to noticeably impact performance as it is a relatively tiny part of the entire graphics pipeline.
- Sole world
- A lone-world server would just set its origin_offset to zero and carry on indistinguishable from present.
- Building complex
- A macro-server would supply the shell of the building, (and possibly enforce server-boundaries within - extra coding presumably required).
- Individual apartment-servers are slotted into appropriate cavities within the building shell and serve internal walls, furniture, etc. to any avatar within this cavity.
- Optionally, a apartment-server might serve a low-poly, low-frame-rate, version of its contents to anyone observing it from outside (eg, through the windows).
- Note that the building-server and apartment-servers are identical from a codebase and functionality perspective: they just have different scale and origin settings.
- A town-server supplies a terrain and some public amenities such as roads/pathways, etc.
- House-servers occupy designated housing blocks and provide the contents of them (high-poly if on the block, or a low-poly shell if viewing from outside)
- Additional servers may supply parks, chunks of forested areas, etc. high/low poly, as per housing blocks.
- For visual continuity, the town-server might also cache a home-server’s low-poly building which it can substitute in if it detects home-server has gone offline.
- Note that, again, the township-server and house-servers only differ in scale and origin settings.
- A country-server hosts multiple of the above town-servers which in turn host house servers, and possibly also a few apartment servers in the capital!
- Additional servers supply forests, deserts, fields, lakes, etc. between towns.
- The country-server also supplies a programatically-generated terrain for all the above to sit over, and the default sky for them to sit under.
- Some apartment-servers are providing multi-sub-server orbital-space-station-shaped structures high overhead.
- Yep, nothing special about the different ‘levels’ of server here, only scale and origin settings.
- All the way down! As far as you care to go. Well, down to 0.66m, anyway!