mirror of
https://github.com/TTimo/GtkRadiant.git
synced 2024-11-10 07:11:54 +00:00
- In SnapWeldVectorAccu() (in brush.c), raising error if any of the input
parameters are NULL (instead of just returning). SnapWeldVectorAccu() is going to be my next area of focus - much to be proofread there. - Proofreading and changing FixWindingAccu(). Changes include for example if a 3-pt winding is input, it always used to return valid. Now, it keeps collapsing close points until there is just one point left. These changes have not been tested yet. - There was a bug in the original FixWinding() where if a dup point was at the end of the winding, it didn't remove it properly. Fixed in FixWindingAccu() (original function untouched). - If any point is removed in FixWindingAccu(), the algorithm for removing points is run from the beginning. This makes things more consistent. So right now I have to test to see what happens if FixWindingAccu() returns a winding that has less than 3 points. This could cause bad things to happen such as segfault. I just don't know yet. git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/branches/Rambetter-math-fix-experiments@406 8a3a26a2-13c4-0310-b231-cf6edde360e5
This commit is contained in:
parent
c53833bfbd
commit
3a15b2a305
1 changed files with 51 additions and 20 deletions
|
@ -287,7 +287,8 @@ void SnapWeldVectorAccu(vec3_accu_t a, vec3_accu_t b, vec3_accu_t out)
|
||||||
int i;
|
int i;
|
||||||
vec_accu_t ai, bi, outi;
|
vec_accu_t ai, bi, outi;
|
||||||
|
|
||||||
if (a == NULL || b == NULL || out == NULL) return;
|
if (a == NULL || b == NULL || out == NULL)
|
||||||
|
Error("SnapWeldVectorAccu: NULL argument");
|
||||||
|
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
|
@ -366,40 +367,70 @@ qboolean FixWinding( winding_t *w )
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
FixWindingAccu()
|
||||||
|
removes degenerate edges from a winding
|
||||||
|
returns qtrue if the winding is valid
|
||||||
|
*/
|
||||||
qboolean FixWindingAccu(winding_accu_t *w)
|
qboolean FixWindingAccu(winding_accu_t *w)
|
||||||
{
|
{
|
||||||
// Serious doubts about this function. Will check it out later.
|
// TODO: Write regression test that chops tip off slim triangle tip.
|
||||||
// This is just a copy from the original for high res data types.
|
// TODO: Test to see what happens if our winding degenerates to less
|
||||||
// TODO: Examine this function with a fine-toothed comb.
|
// than 3 points.
|
||||||
|
|
||||||
|
// I still have serious doubts about this function. The caller isn't
|
||||||
|
// even using the return value.
|
||||||
|
|
||||||
qboolean valid = qtrue;
|
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
vec3_accu_t vec;
|
vec3_accu_t vec;
|
||||||
vec_accu_t dist;
|
vec_accu_t dist;
|
||||||
|
qboolean done, valid;
|
||||||
|
|
||||||
if (!w) return qfalse;
|
if (!w) return qfalse;
|
||||||
|
valid = qtrue;
|
||||||
|
|
||||||
for (i = 0; i < w->numpoints; i++)
|
while (qtrue)
|
||||||
{
|
{
|
||||||
if (w->numpoints == 3) return valid;
|
// NOTE: Original FixWinding() didn't remove points if the winding
|
||||||
|
// had 3 points. We may have to go back to doing that after we
|
||||||
j = (i + 1) % w->numpoints;
|
// understand more about what a winding with 2 or 1 points implies.
|
||||||
|
if (w->numpoints < 2) break; // Don't remove the only remaining point.
|
||||||
VectorSubtractAccu(w->p[i], w->p[j], vec);
|
done = qtrue;
|
||||||
dist = VectorLengthAccu(vec);
|
for (i = 0; i < w->numpoints; i++)
|
||||||
if (dist < DEGENERATE_EPSILON)
|
|
||||||
{
|
{
|
||||||
valid = qfalse;
|
j = (((i + 1) == w->numpoints) ? 0 : (i + 1));
|
||||||
SnapWeldVectorAccu(w->p[i], w->p[j], vec);
|
|
||||||
VectorCopyAccu(vec, w->p[i]);
|
VectorSubtractAccu(w->p[i], w->p[j], vec);
|
||||||
for (k = i + 2; k < w->numpoints; k++) {
|
dist = VectorLengthAccu(vec);
|
||||||
VectorCopyAccu(w->p[k], w->p[k - 1]);
|
if (dist < DEGENERATE_EPSILON)
|
||||||
|
{
|
||||||
|
valid = qfalse;
|
||||||
|
SnapWeldVectorAccu(w->p[i], w->p[j], vec);
|
||||||
|
VectorCopyAccu(vec, w->p[i]);
|
||||||
|
// NOTE: The new code initializes k to j + 1.
|
||||||
|
for (k = j + 1; k < w->numpoints; k++)
|
||||||
|
{
|
||||||
|
VectorCopyAccu(w->p[k], w->p[k - 1]);
|
||||||
|
}
|
||||||
|
w->numpoints--;
|
||||||
|
// The only way to finish off fixing the winding consistently and
|
||||||
|
// accurately is by fixing the winding all over again. For example,
|
||||||
|
// the point at index i and the point at index i-1 could now be
|
||||||
|
// less than the epsilon distance apart. There are too many special
|
||||||
|
// case problems we'd need to handle if we didn't start from the
|
||||||
|
// beginning.
|
||||||
|
done = qfalse;
|
||||||
|
break; // This will cause us to return to the "while" loop.
|
||||||
}
|
}
|
||||||
w->numpoints--;
|
|
||||||
}
|
}
|
||||||
|
if (done) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w->numpoints < 3) valid = qfalse;
|
if (w->numpoints < 3)
|
||||||
|
{
|
||||||
|
valid = qfalse;
|
||||||
|
Sys_FPrintf(SYS_VRB, "WARNING: winding degenerated to less than 3 points in FixWindingAccu\n");
|
||||||
|
}
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue