mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-14 17:01:22 +00:00
Split up separator finding and winding clipping.
Interesting, it makes very little (maybe faster) difference to find all the separators for levels 3 and 4. This might be due to the higher levels using most of the planes to fully clip source away. Anyway, it makes the code a little clearer (one function, one task).
This commit is contained in:
parent
f80ae52828
commit
46d41ad9ac
1 changed files with 52 additions and 54 deletions
|
@ -87,37 +87,30 @@ delete_separator (threaddata_t *thread, sep_t *sep)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_separators (threaddata_t *thread, pstack_t *stack)
|
free_separators (threaddata_t *thread, sep_t *sep_list)
|
||||||
{
|
{
|
||||||
int i;
|
while (sep_list) {
|
||||||
|
sep_t *sep = sep_list;
|
||||||
for (i = 2; i > 0; i--) {
|
sep_list = sep->next;
|
||||||
while (stack->separators[i - 1]) {
|
|
||||||
sep_t *sep = stack->separators[i - 1];
|
|
||||||
stack->separators[i - 1] = sep->next;
|
|
||||||
delete_separator (thread, sep);
|
delete_separator (thread, sep);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ClipToSeparators
|
Find the planes separating source from pass. The planes form a double
|
||||||
|
pyramid with source as the base (ie, source's edges will all be in one
|
||||||
|
plane each) and the vertex of the pyramid is between source and pass.
|
||||||
|
Edges from pass may or may not be in a plane, but each vertex will be in
|
||||||
|
at least one plane.
|
||||||
|
|
||||||
Source, pass, and target are an ordering of portals.
|
If flip is false, the planes will be such that the space enclosed by the
|
||||||
|
planes and on the pass side of the vertex are on the front sides of the
|
||||||
Generates seperating planes candidates by taking two points from source and
|
planes. If flip is true, then the space on the source side of the vertex
|
||||||
one point from pass, and clips target by them.
|
and enclosed by the planes is on the front side of the planes.
|
||||||
|
|
||||||
If target is totally clipped away, that portal can not be seen through.
|
|
||||||
|
|
||||||
Normal clip keeps target on the same side as pass, which is correct if the
|
|
||||||
order goes source, pass, target. If the order goes pass, source, target
|
|
||||||
then test should be odd.
|
|
||||||
*/
|
*/
|
||||||
static winding_t *
|
static sep_t *
|
||||||
ClipToSeparators (threaddata_t *thread, pstack_t *stack,
|
FindSeparators (threaddata_t *thread, winding_t *source, winding_t *pass,
|
||||||
winding_t *source, winding_t *pass, winding_t *target,
|
int flip)
|
||||||
int test)
|
|
||||||
{
|
{
|
||||||
float d;
|
float d;
|
||||||
int i, j, k, l;
|
int i, j, k, l;
|
||||||
|
@ -127,15 +120,8 @@ ClipToSeparators (threaddata_t *thread, pstack_t *stack,
|
||||||
vec3_t v1, v2;
|
vec3_t v1, v2;
|
||||||
vec_t length;
|
vec_t length;
|
||||||
|
|
||||||
if (test < 2 && stack->separators[test]) {
|
sep_t *separators = 0;
|
||||||
sep_t *sep;
|
|
||||||
|
|
||||||
for (sep = stack->separators[test]; target && sep; sep = sep->next) {
|
|
||||||
target = ClipWinding (target, &sep->plane, false);
|
|
||||||
}
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
// check all combinations
|
|
||||||
for (i = 0; i < source->numpoints; i++) {
|
for (i = 0; i < source->numpoints; i++) {
|
||||||
l = (i + 1) % source->numpoints;
|
l = (i + 1) % source->numpoints;
|
||||||
VectorSubtract (source->points[l], source->points[i], v1);
|
VectorSubtract (source->points[l], source->points[i], v1);
|
||||||
|
@ -211,26 +197,29 @@ ClipToSeparators (threaddata_t *thread, pstack_t *stack,
|
||||||
}
|
}
|
||||||
|
|
||||||
// flip the normal if we want the back side
|
// flip the normal if we want the back side
|
||||||
if (test & 1) {
|
if (flip) {
|
||||||
VectorNegate (plane.normal, plane.normal);
|
VectorNegate (plane.normal, plane.normal);
|
||||||
plane.dist = -plane.dist;
|
plane.dist = -plane.dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clip target by the seperating plane. If target is null, then
|
|
||||||
// we're pre-caching the rest of the separators
|
|
||||||
if (target)
|
|
||||||
target = ClipWinding (target, &plane, false);
|
|
||||||
if (test < 2) {
|
|
||||||
sep_t *sep = new_separator (thread);
|
sep_t *sep = new_separator (thread);
|
||||||
sep->plane = plane;
|
sep->plane = plane;
|
||||||
sep->next = stack->separators[test];
|
sep->next = separators;
|
||||||
stack->separators[test] = sep;
|
separators = sep;
|
||||||
} else if (!target) {
|
|
||||||
return NULL; // target is not visible
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return separators;
|
||||||
|
}
|
||||||
|
|
||||||
|
static winding_t *
|
||||||
|
ClipToSeparators (const sep_t *separators, winding_t *target)
|
||||||
|
{
|
||||||
|
const sep_t *sep;
|
||||||
|
|
||||||
|
for (sep = separators; target && sep; sep = sep->next) {
|
||||||
|
target = ClipWinding (target, &sep->plane, false);
|
||||||
|
}
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,8 +351,10 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
|
||||||
// pointing from the edges of source passing though the corners of
|
// pointing from the edges of source passing though the corners of
|
||||||
// pass
|
// pass
|
||||||
winding_t *old = target;
|
winding_t *old = target;
|
||||||
target = ClipToSeparators (thread, &stack, source, prevstack->pass,
|
if (!stack.separators[0])
|
||||||
target, 0);
|
stack.separators[0] = FindSeparators (thread, source,
|
||||||
|
prevstack->pass, 0);
|
||||||
|
target = ClipToSeparators (stack.separators[0], target);
|
||||||
if (!target) {
|
if (!target) {
|
||||||
thread->stats.targetclipped++;
|
thread->stats.targetclipped++;
|
||||||
FreeWinding (source);
|
FreeWinding (source);
|
||||||
|
@ -381,8 +372,10 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
|
||||||
// triangles rotated 60 (or 180) degrees relative to each other,
|
// triangles rotated 60 (or 180) degrees relative to each other,
|
||||||
// parallel and in line, target will wind up being a hexagon.
|
// parallel and in line, target will wind up being a hexagon.
|
||||||
winding_t *old = target;
|
winding_t *old = target;
|
||||||
target = ClipToSeparators (thread, &stack, prevstack->pass, source,
|
if (!stack.separators[1])
|
||||||
target, 1);
|
stack.separators[1] = FindSeparators (thread, prevstack->pass,
|
||||||
|
source, 1);
|
||||||
|
target = ClipToSeparators (stack.separators[1], target);
|
||||||
if (!target) {
|
if (!target) {
|
||||||
thread->stats.targetclipped++;
|
thread->stats.targetclipped++;
|
||||||
FreeWinding (source);
|
FreeWinding (source);
|
||||||
|
@ -397,8 +390,10 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
|
||||||
// the trimmed target
|
// the trimmed target
|
||||||
if (options.level > 2) {
|
if (options.level > 2) {
|
||||||
winding_t *old = source;
|
winding_t *old = source;
|
||||||
source = ClipToSeparators (thread, &stack, target, prevstack->pass,
|
sep_t *sep;
|
||||||
source, 2);
|
sep = FindSeparators (thread, target, prevstack->pass, 0);
|
||||||
|
source = ClipToSeparators (sep, source);
|
||||||
|
free_separators (thread, sep);
|
||||||
if (!source) {
|
if (!source) {
|
||||||
thread->stats.sourceclipped++;
|
thread->stats.sourceclipped++;
|
||||||
FreeWinding (target);
|
FreeWinding (target);
|
||||||
|
@ -410,8 +405,10 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
|
||||||
|
|
||||||
if (options.level > 3) {
|
if (options.level > 3) {
|
||||||
winding_t *old = source;
|
winding_t *old = source;
|
||||||
source = ClipToSeparators (thread, &stack, prevstack->pass, target,
|
sep_t *sep;
|
||||||
source, 3);
|
sep = FindSeparators (thread, prevstack->pass, target, 1);
|
||||||
|
source = ClipToSeparators (sep, source);
|
||||||
|
free_separators (thread, sep);
|
||||||
if (!source) {
|
if (!source) {
|
||||||
thread->stats.sourceclipped++;
|
thread->stats.sourceclipped++;
|
||||||
FreeWinding (target);
|
FreeWinding (target);
|
||||||
|
@ -432,7 +429,8 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
|
||||||
FreeWinding (source);
|
FreeWinding (source);
|
||||||
FreeWinding (target);
|
FreeWinding (target);
|
||||||
}
|
}
|
||||||
free_separators (thread, &stack);
|
free_separators (thread, stack.separators[1]);
|
||||||
|
free_separators (thread, stack.separators[0]);
|
||||||
|
|
||||||
LOCK;
|
LOCK;
|
||||||
set_delete (stack.mightsee);
|
set_delete (stack.mightsee);
|
||||||
|
|
Loading…
Reference in a new issue