AR-js-org / AR.js

Image tracking, Location Based AR, Marker tracking. All on the Web.
MIT License
5.3k stars 909 forks source link

[feature request] Implement floating origin on geolocation ar #499

Open marcusx2 opened 1 year ago

marcusx2 commented 1 year ago

What is the current behavior?

Currently, the world position of entities(and the camera) when using ARJS' aframe geolocation AR can have values on the millionth scale. From my tests, it can vary between(more or less) -20million to 20million. The problem with this is for other frameworks that wants to use ARJS solely to retrieve the position information for placement and have floating point precision problems. Take a look at this issue. It's exactly what I'm facing. I successfully managed to use ARJS' geolocation (aframe version) to position objects in another framework such as PlayCanvas, but I am running into this problem.

Ideally, I'd like a feature where the camera's world position stays at (0, 0, 0), and there's a threshold property that when met, centers the camera to 0, 0, 0 again and repositions the entities around it. See this short video (from this plugin, consider that the avatar shown is the camera and everything around are the aframe entities. What moves are the entities around the camera, not the camera itself) which showcases exactly what I'm looking for. Example camera's position is (20000000, 0, 0) and entity is (20000001, 0, 0), camera becomes (0, 0, 0) and entity (1, 0, 0). The distance stays the same but now the values are small and avoid the floating point precision problem.

I am currently implementing this floating point origin to fix the issue I'm having, but I think it would be nice if this feature was available out of the box for ARJS' geolocation AR so that it can be easily used by other game frameworks that have problems with floating point precisions (which seems to be literally every other game framework except aframe lol).

Other useful resources

https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@7.1/manual/Camera-Relative-Rendering.html https://www.youtube.com/watch?v=qIxifMcvYTs https://manuel-rauber.com/2022/04/06/floating-origin-in-unity/ https://www.reddit.com/r/Unity3D/comments/ijwfec/the_further_you_are_from_000_the_messier_stuff/ https://www.alanzucconi.com/2020/08/03/floating-point-arithmetic/

@nickw1 what do you think?

nickw1 commented 1 year ago

@marcusx2 I see what you mean. As it happens the older location-based components (not new-location-based) to set the world origin to be the original GPS position, but this was removed for simplicity.

However, in the light of what you have said, I can add it back to new-location-based, so that the world origin is the initial position and the objects have coordinates relative to the initial GPS position.

I am slightly concerned about updating the world coordinates of the objects, though, as this may impact performance particularly if you have large numbers of objects. Perhaps that can be added in as an optional feature?

So, for the next release I will optionally restore the original behaviour, i.e. world origin is the initial GPS position. To avoid breaking existing code, however, it will not be the default, it will require a flag to be passed in.

marcusx2 commented 1 year ago

Hello @nickw1 , thank you for your reply.

So, for the next release I will optionally restore the original behaviour, i.e. world origin is the initial GPS position. To avoid breaking existing code, however, it will not be the default, it will require a flag to be passed in.

This would certainly help a lot and fix most cases. It would only break if the user started using ARJS too distant from the entities anyways. On this case the world position of the camera would end up on gigantic values as the user finally arrives at the locations and the problem would happen again.

I am slightly concerned about updating the world coordinates of the objects, though, as this may impact performance particularly if you have large numbers of objects. Perhaps that can be added in as an optional feature?

As an optional feature it would be great, I don't mind. Like I said, having an optional threshold to reset the camera to world origin and the other entities to correct relative world position would be great! (e.g. threshold is 5000, which means world position is 5000 on either axis). Of course if an entity relative to the camera is on a distance bigger than the threshold, it wouldn't even show up! Will you implement floating origin as well?

marcusx2 commented 1 year ago

Maps service has this feature too.

marcusx2 commented 1 year ago

So, for the next release I will optionally restore the original behaviour, i.e. world origin is the initial GPS position. To avoid breaking existing code, however, it will not be the default, it will require a flag to be passed in.

@nickw1 is this change hard to do, can you guide me through it? If you can send me the modified version with just this change I'd greatly appreciate it. If it's not something trivial then never mind, I can wait until next release. Thanks!

nickw1 commented 1 year ago

@marcusx2 it's actually quite easy but I haven't had the time this week. I will do it as soon as I can.

marcusx2 commented 1 year ago

Hopefully a movefloatingorigin method can also make it to a next release together with world-origin-as-original-GPS-position. In this case the camera could also have a distance property which is the distance from the world origin. The method doesn't have to be called automatically and you could let the user make the decision of calling it or not. So for example, every time the gps position event fires, I check the distance of the camera from the origin, and if I regard it as far enough I call the movefloatingorigin method myself.

nickw1 commented 1 year ago

OK what I think I'll do is implement #498, #499 and #502 for the next release (bugfix release 3.4.4), keeping this as an optional for the moment (but will probably make it the default in 3.5). Your other issues are a little more complex, and perhaps less critical, so will leave these to a later release.

marcusx2 commented 1 year ago

OK what I think I'll do is implement #498, #499 and #502 for the next release (bugfix release 3.4.4), keeping this as an optional for the moment (but will probably make it the default in 3.5). Your other issues are a little more complex, and perhaps less critical, so will leave these to a later release.

I think you mean you will implement initial gps position at world origin for the next release, but not the floating origin(movefloatingorigin method) which is this issue. It's because implementing initial gps position at world origin is the first step.

I'd say #498 is the most critical, then comes the rest.

Ok I understand. Thank you very much, looking forward to the next bugfix release!

nickw1 commented 1 year ago

Sorry, no I also meant the floating origin as well. I will however leave #501 for now. (Actually #500 should be easy to fix too, so add that in as well).

nickw1 commented 1 year ago

508 allows the initial GPS position to be used as the world origin.

The floating origin however will require a rewrite of part of the code so I'm proposing postponing it for the 3.5 release, and at that point, introducing a breaking change of making the initial GPS position the world origin by default.

marcusx2 commented 1 year ago

bump

marcusx2 commented 5 months ago

bump