[ODE] Accuracy / FPU stuff

Martin C. Martin martin at metahuman.org
Tue Jul 8 05:22:01 2003


Pierre,

Thanks for explaining all this in so much detail!  Can I talk you into
adding it to the ODE wiki?  Adding things to the wiki really does seem to
cut down questions on this list, so I assume people are reading it...

- Martin

Pierre Terdiman wrote:
> 
> >    Is there some good reason for this, or is this just that OPCODE uses
> > single internally and doesn't have a switch (i.e., will OPCODE break if
> > I make it "use double and memory use be damned"?)
> 
> Let's make it clear....
> 
> There are two different issues here :
> 
> 1) Using "float" instead of "double", mainly OPCODE vs ODE :
> 
> OPCODE really doesn't need double precision :
> 
> - if you're using quantized trees, nodes don't even contain a single
> floating-point value. So you won't "damn the memory use" by using "double".
> 
> - if you're using non-quantized trees, nodes contain floating-point values
> for bounding boxes. However those are only bounding boxes which are *not*
> supposed to be accurate in the first place. Using "double" here will indeed
> increase memory usage, *and be totally, definitely useless*.
> 
> - the actual client mesh is *not* stored in OPCODE's structures, I'm only
> using indices to get those back. So I don't really care how you store your
> meshes (floats or doubles) as far as computations are concerned. The only
> thing that needs fixing if your meshes are stored in "double", is the
> MeshInterface, because it expects float pointers in return. This is probably
> where all the problems are coming from : if you cast your double-precision
> points to float in OPCODE's callbacks for example, it obviously won't work,
> and collisions won't be detected indeed.
> 
> Using callbacks, a possible fix would be to convert each requested triangle
> to floats on-the-fly, and return pointers to the converted triangle to
> OPCODE. As long as you don't use multiple threads doing simultaneous
> collision queries, it should work fine.
> 
> Now I seriously doubt you need double-precision meshes. In particular,
> they're probably single-precision to begin with, out of your favorite
> modeling package (3DSMAX, etc). So you should keep them single-precision,
> use OPCODE's pointers (possibly with a stride), and convert the floats to
> doubles for ODE's computations, if needed. But even this is probably dubious
> : doubles are useful in big and intensive matrix computations, but that's
> about it. My own rigid body code uses plain floats all the way without
> troubles, for example.
> 
> I'm also using D3D, which brings up the second issue :
> 
> 2) the *internal* FPU accuracy and D3D's D3DCREATE_FPU_PRESERVE
> 
> The nature of your floating-point values ("float" or "double") is only half
> the story. Using "float" for example, you still have multiple choices
> regarding the *internal* FPU precision. This is controlled by the FPU
> control word, and can't be accessed / modified through C.
> 
> The D3D flag only changes this internal accuracy as far as I know. They
> don't use "double" inside, that would be ridiculous, especially since :
> 
> - you only store 32-bits floats in your vertex buffer anyway
> - the hardware certainly doesn't have two code paths for two different
> pipelines, it would be twice as much gates for nothing !
> 
> I believe this flag only changes only very few things, and mainly related to
> the software rendering mode. There have been a number of threads about this
> on the DXML in the past.
> 
> Now I've seen cases where *internal* FPU precision was modified by D3D init
> *even* with that flag on. It might also change the FPU rounding mode, which
> is a problem when you compile with /QIfist on VC++ 6 (for fast float-to-int
> conversions).
> 
> On top of this, D3D *isn't* the only thing changing the FPU settings
> silently. A classical other example is LoadLibrary.
> 
> In summary, assuming the FPU is correctly setup is a recipe for disaster.
> (Never assume anything, as always)
> 
> What I do then is very simple :
> - initialize D3D the normal way, without the FPU flag
> - explicitely reset the FPU control word to what I want, each frame (it's
> very cheap, no problem)
> 
> For what it's worth, my rigid body simulation uses "floats" all the way with
> the smallest internal accuracy, and renders the scene with D3D or GL just
> fine.
> 
> Pierre
> 
> _______________________________________________
> ODE mailing list
> ODE@q12.org
> http://q12.org/mailman/listinfo/ode