mirror of
https://github.com/UberGames/GtkRadiant.git
synced 2025-02-23 20:31:33 +00:00
This is in branch Rambetter-math-fix-experiments.
- Adding a bunch of *Accu() functions: * SnapWeldVectorAccu() in brush.c (needs major proofread). * FixWindingAccu() in brush.c (needs major proofread). * CopyWindingAccuToNormal() in polylib.c. * VectorLengthAccu() in mathlib.c. * Q_rintAccu() in mathlib.h. * FreeWindingAccu() declaration in polylib.h (was missing). - Adding a #ifdef's for EXPERIMENTAL_HIGH_PRECISION_MATH_Q3MAP2_FIXES. It's turned on now. Testing brush winding formation. This code compiles on Linux, I have no idea if it works. About to test a little, then going to bed. git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/branches/Rambetter-math-fix-experiments@384 8a3a26a2-13c4-0310-b231-cf6edde360e5
This commit is contained in:
parent
adf336fec1
commit
f32b2b3712
5 changed files with 114 additions and 0 deletions
|
@ -335,6 +335,9 @@ typedef vec_accu_t vec3_accu_t[3];
|
|||
#define VectorCopyAccu(a, b) ((b)[0] = (a)[0], (b)[1] = (a)[1], (b)[2] = (a)[2])
|
||||
#define VectorScaleAccu(a, b, c) ((c)[0] = (b) * (a)[0], (c)[1] = (b) * (a)[1], (c)[2] = (b) * (a)[2])
|
||||
#define CrossProductAccu(a, b, c) ((c)[0] = (a)[1] * (b)[2] - (a)[2] * (b)[1], (c)[1] = (a)[2] * (b)[0] - (a)[0] * (b)[2], (c)[2] = (a)[0] * (b)[1] - (a)[1] * (b)[0])
|
||||
#define Q_rintAccu(in) ((vec_accu_t) floor(in + 0.5))
|
||||
|
||||
vec_accu_t VectorLengthAccu(vec3_accu_t v);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -63,6 +63,11 @@ vec_t VectorLength(vec3_t v)
|
|||
return length;
|
||||
}
|
||||
|
||||
vec_accu_t VectorLengthAccu(vec3_accu_t v)
|
||||
{
|
||||
return (vec_accu_t) sqrt((v[0] * v[0]) + (v[1] * v[1]) + (v[2] * v[2]));
|
||||
}
|
||||
|
||||
qboolean VectorCompare (vec3_t v1, vec3_t v2)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -459,6 +459,28 @@ winding_t *CopyWinding (winding_t *w)
|
|||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CopyWindingAccuToNormal
|
||||
==================
|
||||
*/
|
||||
winding_t *CopyWindingAccuToNormal(winding_accu_t *w)
|
||||
{
|
||||
int i;
|
||||
winding_t *c;
|
||||
|
||||
c = AllocWinding(w->numpoints);
|
||||
c->numpoints = w->numpoints;
|
||||
for (i = 0; i < c->numpoints; i++)
|
||||
{
|
||||
// TODO: Add VectorCopyAccuToNormal() to mathlib.h.
|
||||
c->p[i][0] = (vec_t) w->p[i][0];
|
||||
c->p[i][1] = (vec_t) w->p[i][1];
|
||||
c->p[i][2] = (vec_t) w->p[i][2];
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
ReverseWinding
|
||||
|
|
|
@ -70,3 +70,5 @@ typedef struct
|
|||
|
||||
winding_accu_t *BaseWindingForPlaneAccu(vec3_t normal, vec_t dist);
|
||||
void ChopWindingInPlaceAccu(winding_accu_t **w, vec3_t normal, vec_t dist, vec_t epsilon);
|
||||
winding_t *CopyWindingAccuToNormal(winding_accu_t *w);
|
||||
void FreeWindingAccu(winding_accu_t *w);
|
||||
|
|
|
@ -277,6 +277,34 @@ void SnapWeldVector( vec3_t a, vec3_t b, vec3_t out )
|
|||
}
|
||||
}
|
||||
|
||||
void SnapWeldVectorAccu(vec3_accu_t a, vec3_accu_t b, vec3_accu_t out)
|
||||
{
|
||||
// I have very serious concerns about this function.
|
||||
// This is a first pass where I just copy the original SnapWeldVector()
|
||||
// and make sure it works with the higher resolution data types.
|
||||
// TODO: Examine this function with a fine-toothed comb.
|
||||
|
||||
int i;
|
||||
vec_accu_t ai, bi, outi;
|
||||
|
||||
if (a == NULL || b == NULL || out == NULL) return;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
ai = Q_rintAccu(a[i]);
|
||||
bi = Q_rintAccu(a[i]); // Note, it's using a[i]. This is from legacy code.
|
||||
|
||||
if (ai == a[i]) out[i] = a[i];
|
||||
else if (bi == b[i]) out[i] = b[i];
|
||||
|
||||
else if (fabs(ai - a[i]) < fabs(bi < b[i])) out[i] = a[i];
|
||||
else out[i] = b[i];
|
||||
|
||||
outi = Q_rintAccu(out[i]);
|
||||
if (fabs(outi - out[i]) <= SNAP_EPSILON) out[i] = outi;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
@ -338,11 +366,44 @@ qboolean FixWinding( winding_t *w )
|
|||
return valid;
|
||||
}
|
||||
|
||||
qboolean FixWindingAccu(winding_accu_t *w)
|
||||
{
|
||||
// Serious doubts about this function. Will check it out later.
|
||||
// This is just a copy from the original for high res data types.
|
||||
// TODO: Examine this function with a fine-toothed comb.
|
||||
|
||||
qboolean valid = qtrue;
|
||||
int i, j, k;
|
||||
vec3_accu_t vec;
|
||||
vec_accu_t dist;
|
||||
|
||||
if (!w) return qfalse;
|
||||
|
||||
for (i = 0; i < w->numpoints; i++)
|
||||
{
|
||||
if (w->numpoints == 3) return valid;
|
||||
|
||||
j = (i + 1) % w->numpoints;
|
||||
|
||||
VectorSubtractAccu(w->p[i], w->p[j], vec);
|
||||
dist = VectorLengthAccu(vec);
|
||||
if (dist < DEGENERATE_EPSILON)
|
||||
{
|
||||
valid = qfalse;
|
||||
SnapWeldVectorAccu(w->p[i], w->p[j], vec);
|
||||
VectorCopyAccu(vec, w->p[i]);
|
||||
for (k = i + 2; k < w->numpoints; k++) {
|
||||
VectorCopyAccu(w->p[k], w->p[k - 1]);
|
||||
}
|
||||
w->numpoints--;
|
||||
}
|
||||
}
|
||||
|
||||
if (w->numpoints < 3) valid = qfalse;
|
||||
return valid;
|
||||
}
|
||||
|
||||
#define EXPERIMENTAL_HIGH_PRECISION_MATH_Q3MAP2_FIXES 1
|
||||
|
||||
/*
|
||||
CreateBrushWindings()
|
||||
|
@ -353,7 +414,11 @@ returns false if the brush doesn't enclose a valid volume
|
|||
qboolean CreateBrushWindings( brush_t *brush )
|
||||
{
|
||||
int i, j;
|
||||
#ifdef EXPERIMENTAL_HIGH_PRECISION_MATH_Q3MAP2_FIXES
|
||||
winding_accu_t *w;
|
||||
#else
|
||||
winding_t *w;
|
||||
#endif
|
||||
side_t *side;
|
||||
plane_t *plane;
|
||||
|
||||
|
@ -366,7 +431,11 @@ qboolean CreateBrushWindings( brush_t *brush )
|
|||
plane = &mapplanes[ side->planenum ];
|
||||
|
||||
/* make huge winding */
|
||||
#ifdef EXPERIMENTAL_HIGH_PRECISION_MATH_Q3MAP2_FIXES
|
||||
w = BaseWindingForPlaneAccu(plane->normal, plane->dist);
|
||||
#else
|
||||
w = BaseWindingForPlane( plane->normal, plane->dist );
|
||||
#endif
|
||||
|
||||
/* walk the list of brush sides */
|
||||
for( j = 0; j < brush->numsides && w != NULL; j++ )
|
||||
|
@ -378,14 +447,27 @@ qboolean CreateBrushWindings( brush_t *brush )
|
|||
if( brush->sides[ j ].bevel )
|
||||
continue;
|
||||
plane = &mapplanes[ brush->sides[ j ].planenum ^ 1 ];
|
||||
#ifdef EXPERIMENTAL_HIGH_PRECISION_MATH_Q3MAP2_FIXES
|
||||
ChopWindingInPlaceAccu(&w, plane->normal, plane->dist, 0);
|
||||
#else
|
||||
ChopWindingInPlace( &w, plane->normal, plane->dist, 0 ); // CLIP_EPSILON );
|
||||
#endif
|
||||
|
||||
/* ydnar: fix broken windings that would generate trifans */
|
||||
#ifdef EXPERIMENTAL_HIGH_PRECISION_MATH_Q3MAP2_FIXES
|
||||
FixWindingAccu(w);
|
||||
#else
|
||||
FixWinding( w );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* set side winding */
|
||||
#ifdef EXPERIMENTAL_HIGH_PRECISION_MATH_Q3MAP2_FIXES
|
||||
side->winding = CopyWindingAccuToNormal(w);
|
||||
FreeWindingAccu(w);
|
||||
#else
|
||||
side->winding = w;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* find brush bounds */
|
||||
|
|
Loading…
Reference in a new issue