mirror of
https://github.com/UberGames/GtkRadiant.git
synced 2024-11-10 06:31:41 +00:00
This is in branch Rambetter-math-fix-experiments.
- Added lengthy comment to describe the choice of smallestEpsilonAllowed in polylib.c for the new 64 bit chopping code. I think that this comment will allow us to make sure that we have the correct choice of epsilon. - Tweaked comments around VEC_SMALLEST_EPSILON_AROUND_ONE and VEC_ACCU_SMALLEST_EPSILON_AROUND_ONE (actually renamed them). git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/branches/Rambetter-math-fix-experiments@383 8a3a26a2-13c4-0310-b231-cf6edde360e5
This commit is contained in:
parent
56e74492bc
commit
adf336fec1
2 changed files with 22 additions and 11 deletions
|
@ -38,12 +38,12 @@ typedef vec_t vec3_t[3];
|
|||
typedef vec_t vec5_t[5];
|
||||
typedef vec_t vec4_t[4];
|
||||
|
||||
// Smallest positive value such that 1.0 + VEC_SMALLEST_EPSILON != 1.0
|
||||
// In the case of 32 bits (which is the case), it's 0.00000011921.
|
||||
// Smallest positive value such that 1.0 + VEC_SMALLEST_EPSILON_AROUND_ONE != 1.0.
|
||||
// In the case of 32 bits (which is likely the case), it's 0.00000011921.
|
||||
// Don't forget that your epsilons should depend on the possible range of values,
|
||||
// because for example 1000.0 + VEC_SMALLEST_EPSILON will almost certainly be
|
||||
// equal to 1000.0.
|
||||
#define VEC_SMALLEST_EPSILON FLT_EPSILON
|
||||
// because for example adding VEC_SMALLEST_EPSILON_AROUND_ONE to 1024.0 will almost
|
||||
// certainly not change its value.
|
||||
#define VEC_SMALLEST_EPSILON_AROUND_ONE FLT_EPSILON
|
||||
|
||||
#define SIDE_FRONT 0
|
||||
#define SIDE_ON 2
|
||||
|
@ -316,12 +316,12 @@ vec_t ray_intersect_triangle(const ray_t *ray, qboolean bCullBack, const vec3_t
|
|||
typedef double vec_accu_t;
|
||||
typedef vec_accu_t vec3_accu_t[3];
|
||||
|
||||
// Smallest positive value such that 1.0 + VEC_ACCU_SMALLEST_EPSILON != 1.0
|
||||
// In the case of 64 bits (which is the case), it's 0.00000000000000022204.
|
||||
// Smallest positive value such that 1.0 + VEC_ACCU_SMALLEST_EPSILON_AROUND_ONE != 1.0.
|
||||
// In the case of 64 bits (which is likely the case), it's 0.00000000000000022204.
|
||||
// Don't forget that your epsilons should depend on the possible range of values,
|
||||
// because for example 1000.0 + VEC_ACCU_SMALLEST_EPSILON will almost certainly
|
||||
// be equal to 1000.0.
|
||||
#define VEC_ACCU_SMALLEST_EPSILON DBL_EPSILON
|
||||
// because for example adding VEC_ACCU_SMALLEST_EPSILON_AROUND_ONE to 1024.0 will almost
|
||||
// certainly not change its value.
|
||||
#define VEC_ACCU_SMALLEST_EPSILON_AROUND_ONE DBL_EPSILON
|
||||
|
||||
// TODO: I have a feeling it may be safer to break these function out into actual functions
|
||||
// in order to avoid accidental loss of precision. For example, say you call
|
||||
|
|
|
@ -632,7 +632,18 @@ void ChopWindingInPlaceAccu(winding_accu_t **inout, vec3_t normal, vec_t dist, v
|
|||
// want the resolution of vec_accu_t to have a large resolution around the epsilon.
|
||||
// Some of that leftover resolution even goes away after we scale to points far away.
|
||||
|
||||
static const vec_accu_t smallestEpsilonAllowed = ((vec_accu_t) VEC_SMALLEST_EPSILON) * 0.5;
|
||||
// Here is a further discussion regarding the choice of smallestEpsilonAllowed.
|
||||
// In the 32 float world (we can assume vec_t is that), the "epsilon around 1.0" is
|
||||
// 0.00000011921. In the 64 bit float world (we can assume vec_accu_t is that), the
|
||||
// "epsilon around 1.0" is 0.00000000000000022204. (By the way these two epsilons
|
||||
// are defined as VEC_SMALLEST_EPSILON_AROUND_ONE VEC_ACCU_SMALLEST_EPSILON_AROUND_ONE
|
||||
// respectively.) If you divide the first by the second, you get approximately
|
||||
// 536,885,246. Dividing that number by 200,000 (a typical base winding coordinate)
|
||||
// gives 2684. So in other words, if our smallestEpsilonAllowed was chosen as exactly
|
||||
// VEC_SMALLEST_EPSILON_AROUND_ONE, you would be guaranteed at least 2000 "ticks" in
|
||||
// 64-bit land inside of the epsilon for all numbers we're dealing with.
|
||||
|
||||
static const vec_accu_t smallestEpsilonAllowed = ((vec_accu_t) VEC_SMALLEST_EPSILON_AROUND_ONE) * 0.5;
|
||||
if (crudeEpsilon < smallestEpsilonAllowed) fineEpsilon = smallestEpsilonAllowed;
|
||||
else fineEpsilon = (vec_accu_t) crudeEpsilon;
|
||||
|
||||
|
|
Loading…
Reference in a new issue