Search Unity

Double Precision Vector3

Discussion in 'Scripting' started by kohlditz, Jul 16, 2013.

  1. kohlditz

    kohlditz

    Joined:
    May 21, 2013
    Posts:
    6
    Hello,

    I'm making a space game and needed higher precision than Vector3 to represent the vasty nothingness of space so decompiled Unity Vector3, Vector2 and Mathf and converted them to double precision. Most methods were relatively straightforward to convert (they were converting floats to doubles internally to do the math). There's a few cases where the method called an internal Unity function, in those cases I've wrapped the original function.

    I checked with Unity if it was okay to distribute this and they said it was, so if you need higher precision you can grab the files from here:

    https://github.com/kohlditz/vector3d
     
  2. chubbspet

    chubbspet

    Joined:
    Feb 18, 2010
    Posts:
    1,220
    thanks! I might need this for an upcoming simulation project
     
  3. Supershandy

    Supershandy

    Joined:
    Jul 18, 2012
    Posts:
    25
    How do I go about incorperating these files into unity?

    Also, does it circumvent the float precision problem in the inspector?
     
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,209
    Make new scripts in Unity, then copy and paste.

    No, since these are custom structs and therefore can't be used in the inspector.

    --Eric
     
  5. Supershandy

    Supershandy

    Joined:
    Jul 18, 2012
    Posts:
    25
    Do they need to be added to an empty gameobject or can they just be referenced in mono?
     
  6. nicoreda

    nicoreda

    Joined:
    Sep 12, 2012
    Posts:
    3
    Hey, this is a very big interessing script.
    But now, I don't know where I need to add the script. I've tested in camera (also tried the moving part), and it say "Can't add script behaviour Vector3d. The script needs to derive from MonoBehaviour !". So, I guess it's because of "using System". But what now ? :s. Thanks in advance. :=)
     
  7. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,209
    You don't attach the script to anything, you just have it in your project.

    --Eric
     
  8. nicoreda

    nicoreda

    Joined:
    Sep 12, 2012
    Posts:
    3
  9. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,209
    There aren't any changes; it doesn't affect the way Unity works at all. It's a custom struct.

    --Eric
     
  10. nicoreda

    nicoreda

    Joined:
    Sep 12, 2012
    Posts:
    3
    Ah okay thanks. I understand now. (Sorry, I'm french. :3)
    And now I see Vector3d I didn't see it before, I know now.
     
  11. strich

    strich

    Joined:
    Aug 14, 2012
    Posts:
    288
    Thanks for making that publicly available. However I'm curious - How do you plan to get around the problem of physics precision in your game?
     
  12. Marionette

    Marionette

    Joined:
    Feb 3, 2013
    Posts:
    349
    curious: what's the point? (if you'll excuse the pun ;)

    won't the resulting calcs be cast back to float in the bowels of the engine anyway? until UT uses doubles internally, this will always be an issue AFAIK..
     
  13. DSebJ

    DSebJ

    Joined:
    Mar 30, 2013
    Posts:
    101
    Awesome, thank you.

    Do you have a suggestion on approach for implementation? I.e. Referencing the double precision coordinates to the float precision that Unity Supports? So when getting to x, switch to a local precision?
     
  14. Aldeminor

    Aldeminor

    Joined:
    May 3, 2014
    Posts:
    2
    Man, you're great! Double math it is what I need! Now I'm learning Unity and C# (very basicaly, started few days ago), but far away I have planning to create space sim. It will help me a lot, I hope :)
     
  15. Weltista

    Weltista

    Joined:
    May 6, 2014
    Posts:
    9
    Same here, thanks a bunch! Should help with the space sim greatly. :)

    Cheers!
     
  16. Weltista

    Weltista

    Joined:
    May 6, 2014
    Posts:
    9
    Just one more thing though. What about rotations? Quaternion doesn't seem to be working with doubles, while conversing from double to float just to make a rotation wit Q. doesn't sound great either. Any thoughts?
     
    JoeStrout likes this.
  17. looki666

    looki666

    Joined:
    Sep 5, 2013
    Posts:
    79
    So I just need to replace Vector3 , with Vector3d ? Could you post some example scene ? ( Even simple moving Cube )

    Sorry , I am graphics designer , not programmer .
     
  18. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,209
    It's really only of use to programmers. You can't just replace Vector3 with Vector3d since everything in Unity itself uses Vector3 and that can't be changed. Only your own code can use Vector3d.

    --Eric
     
  19. TheSniperFan

    TheSniperFan

    Joined:
    Jul 18, 2013
    Posts:
    686
    One example would be giving your GameObjects something like a "dpTransform" which stores the position with double precision.
    Now, instead of manipulating the transform directly, you would always manipulate the dpTransform which, after it gets manipulated, updates the transform.
    That way you'd prevent data-loss when something happens very far away. Sure, the engine would still give you problems, but your logic would stay reliable. The dpTransform would store where the GameObject is supposed to be.

    Example situation where this would come handy:
    Simulation very far away: Move GameObject x 10 cm to the right.
    Problem: You're so far away that movement happens in 1 m jumps.
    Solution: Whenever the player moves too far away from the center of the map, everything is moved so that the player is at the center again. Say you go forward, when going over a "border" everything is moved backwards so the stuff behind you looses precision, while the stuff in front you has its precision increased. How can this work? Our dpTransform stores the accurate data which is used to restore the transforms.
    If there was no dpTransform we wouldn't have been able to store the information that the GameObject is now 10 cm more to the right.
     
    HolyGhostFire and Zionmoose like this.
  20. maximus9600

    maximus9600

    Joined:
    Jun 9, 2014
    Posts:
    12
    In my case,i have a transform.position for a game object.I am not able to use transform.position as it supports only Vecotr3 due to which i get an error.How do i rectify this?
     
  21. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,209
    You don't; Unity only uses single-precision floats for Vector3 and this can't be changed. Transform.position only uses Vector3 and that can't be changed either. There seems to be some repeated confusion in this thread: the double-precision Vector3 is a custom struct and can't just be plugged into Unity as a substitute for the standard Vector3. See TheSniperFan's post for an example of how you might actually use it.

    --Eric
     
  22. LethalHax

    LethalHax

    Joined:
    Jul 16, 2014
    Posts:
    2
    If only I could actually replace the original vector3 with this...

    I'm struggling with precision errors for my f16 sim.
    I have the camera inside the cockpit, but when I fly a few thousand meters, it starts shaking like hell due to precision errors :(
     
  23. DSebJ

    DSebJ

    Joined:
    Mar 30, 2013
    Posts:
    101
  24. jcarrion

    jcarrion

    Joined:
    Sep 10, 2012
    Posts:
    49
    Im afraid you need to write your own Vector3D (double) physics engine .

    It is not that difficult , thou but in order to get any decent framerate it needs to be coded natively on the target platform. It took us best part of a year !
    Indeed , our physics plugin enables physics on Float , doubles , or even quad_precision. In www.space-simulator.com
    we do have actual planetary distances with a sub-milimeter accuracy . and running decently on iOS :)
     
  25. Marionette

    Marionette

    Joined:
    Feb 3, 2013
    Posts:
    349
    In my opinion, there seems to be a lot of misunderstandings in this thread. Just as with any physical medium, you will always be limited to what that that medium can actually represent, be it printers, monitors or unity3d.

    You might be able to minimize float creep, but you will never be able to get rid of it completely because as soon as you go to set a position or check a boundary or work with audio with your nice precise calculations, your double will get downcast to a float, losing whatever precision you gained.

    If unity3d used doubles natively internally, you'd ultimately still have issues since the other physical limitations would eventually kick in. IE: how floating points are handled by the different OS's, platforms, processors, graphics cards, monitors, DSP's etc etc.

    Cast this to a float:
    0.56622885888511233135576443

    For graphics, it will ultimately come down to rounding rules since the smallest unit of measure will be a single pixel, which is an int. You can't draw 0.52245654 of a pixel. It's either on to some value or off to a value. And even if you COULD get the card to take it, the monitor would never be able to display it properly, at least not with today's technology. Sure, there are lots of hacks and approximations, AA is one of them. Trilinear, bilinear filters are examples of others.

    Now, that all said, WOULD using doubles internally increase precision? Sure. It would lessen the float creep considerably, but even with doubles, you eventually end up at the same spot, if you'll excuse the pun.

    Just to drive the point home (ha!), Google how floats are stored, represented and processed just in the different languages, C++ vs .net.
     
  26. Noctys

    Noctys

    Joined:
    Aug 23, 2013
    Posts:
    23
    Thanks for this - I was about to write my one (didn't think about decompiling it) so you saved me a ton of time. I also added this in to the bottom, fimple code, but could save others that don't know about casting some time.

    public static implicit operator Vector3d(Vector3 v)
    {
    return new Vector3d(v.x, v.y, v.z);
    }

    I didn't read everything, so maybe you covered this - but people have been questioning the value of this - You don't need precision for display, but you do need it for calculations.

    For example I am using it to calculate real world gravitational rotations of planets around a sun using relativity, - then during LateUpdate I move the model to correspond a point that is 10% of the actual value (models are also not to scale). You can't do this with a float because the outer-solar system is to vast - a double can easily do this and with much more precision.
     
  27. Noctys

    Noctys

    Joined:
    Aug 23, 2013
    Posts:
    23
    Also, the const values at the top of Mathd should be updated to double point precision:

    public const double PI = 3.14159265358979;
    public const double Infinity = double.PositiveInfinity;
    public const double NegativeInfinity = double.NegativeInfinity;
    public const double Deg2Rad = Mathd.PI / 180.0;
    public const double Rad2Deg = 180.0 / Mathd.PI;
    public const double Epsilon = double.Epsilon;

    the kEpsilon value at the top of the Vector2/3d should probably be updated too but I am not sure what those values would be.
     
  28. Snownebula

    Snownebula

    Joined:
    Nov 29, 2013
    Posts:
    174
    Could someone make an example project showing how to use this. It would be very helpful, thanks.
     
  29. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,470
    no example project is needed, this isnt replacing the Vector3 unity already has. Its just a Vector3 stuct with double precision. You can use this if you need your own logic to run in double precision, just remember it will need to be cast down to float precision when used with unity.

    It mirrors the usage of the build in Vector3 and Vector2, just using Vector3d and Vector2D, and MathD instead of MathF.

    Also a lot of what is on the Mathd class overlaps the float math stuff that is already part of .net in System.Math
     
  30. Simon-O

    Simon-O

    Joined:
    Jan 22, 2014
    Posts:
    34
    Fantastic effort, thanks. Mental thumbs up for the explicit conversions
     
  31. Medusa-Zenovka

    Medusa-Zenovka

    Joined:
    Oct 1, 2014
    Posts:
    24
    This whole system is tricky to program with floating point ect., but for huge open worlds it works pretty well. If you are using Unitys pathfinding system you might be better off making a scaled down version of your map so your AI finds its way across the map, but use a custom local avoidence instead. All the Physics you need is some collision check and raycasting system using doubles.
    At least thats how I implemented it.
     
  32. HolyGhostFire

    HolyGhostFire

    Joined:
    Dec 15, 2017
    Posts:
    1
    @sniperfan Great post! So would the dpTransform actually do the moving of the object to double precision when the object is in front of the camera, or would it send the double-precision location to somewhere else and that would do the moving? If the latter case is true, then wouldn't you lose the double-precision when trying to update the transform's position? I'm sorry if these are stupid questions, I guess I'm not used to using anything but Vector3s and transform.position to move an object.
     
  33. kohlditz

    kohlditz

    Joined:
    May 21, 2013
    Posts:
    6
    Necropost here;

    This was built to handle an internal model of world state, so this is purely for data structures internal to the world state.

    The mirroring of vector3 etc is for convenience, the expectation is you manipulate the model at double precision; and then can easily cast to single precision to generate the scene to render.

    Some of the functions are dodgy because a) I didn't need them, b) I didn't understand the math well enough and c) c# is not a language I particularly know or use

    This is just a decompile of the unity library with some cleanup, it's in the public domain so use how you see fit.

    And to echo some comments above, for it to be useful; you'd typically use a floating origin and then scale things to a sensible size so you can leverage the z-buffer.

    For an example of what this is attempting to solve see these youtube videos.

    a)

    Two moons orbiting Jupiter at scale using single precision floats. Notice the jitter.

    b)

    Basically the same scene with double precision, the orbits are much smoother.

    c)

    Technique ported to Unity, all objects are represented at 1:1 scale internally
     
  34. cosmochristo

    cosmochristo

    Joined:
    Sep 24, 2018
    Posts:
    31
    Thanks for posting this kohlditz. I would like to do something like this and modify to use continuous floating origin so I can make some comparisons (accuracy and performance).
     
unityunity