Getting Surface Flags in qrad3?
Moderator: InsideQC Admins
3 posts
• Page 1 of 1
Getting Surface Flags in qrad3?
So I'm basically rewriting the sun light feature in qrad3, and I need to do a trace that will return true if it hits sky. I'm running into a bit of an issue, though. For some reason, I can't seem to get to the brushes with the trace.
Original trace:
My modified version, which tries to collide against the actual brushes (Using CM_TraceToLeaf/CM_ClipBoxToBrush from the engine code as reference):
(Pardon the sloppy WIP code).
Problem I'm running into is that leaf->numleafbrushes is always 0. I never actually get into that loop where it checks against all the brushes.
Most leaf nodes are either 0x80000000 or 0x80000001.
There ARE leaves that have brushes, but I never seem to be hitting them. I'm not sure what I'm doing wrong. Probably something stupid. Any ideas?
Original trace:
- Code: Select all
int TestLine_r (int node, vec3_t set_start, vec3_t stop)
{
tnode_t *tnode;
float front, back;
vec3_t mid, start;
float frac;
int side;
int r;
start[0] = set_start[0];
start[1] = set_start[1];
start[2] = set_start[2];
re_test:
if (node & (1<<31))
{
return node & ~(1<<31); // leaf node
}
tnode = &tnodes[node];
switch (tnode->type)
{
case PLANE_X:
front = start[0] - tnode->dist;
back = stop[0] - tnode->dist;
break;
case PLANE_Y:
front = start[1] - tnode->dist;
back = stop[1] - tnode->dist;
break;
case PLANE_Z:
front = start[2] - tnode->dist;
back = stop[2] - tnode->dist;
break;
default:
front = (start[0]*tnode->normal[0] + start[1]*tnode->normal[1] + start[2]*tnode->normal[2]) - tnode->dist;
back = (stop[0]*tnode->normal[0] + stop[1]*tnode->normal[1] + stop[2]*tnode->normal[2]) - tnode->dist;
break;
}
if (front >= -ON_EPSILON && back >= -ON_EPSILON)
{
node = tnode->children[0];
goto re_test;
// return TestLine_r (tnode->children[0], start, stop);
}
if (front < ON_EPSILON && back < ON_EPSILON)
{
node = tnode->children[1];
goto re_test;
// return TestLine_r (tnode->children[1], start, stop);
}
side = front < 0;
frac = front / (front-back);
mid[0] = start[0] + (stop[0] - start[0])*frac;
mid[1] = start[1] + (stop[1] - start[1])*frac;
mid[2] = start[2] + (stop[2] - start[2])*frac;
r = TestLine_r (tnode->children[side], start, mid);
if (r)
return r;
node = tnode->children[!side];
start[0] = mid[0];
start[1] = mid[1];
start[2] = mid[2];
goto re_test;
// return TestLine_r (tnode->children[!side], mid, stop);
}
My modified version, which tries to collide against the actual brushes (Using CM_TraceToLeaf/CM_ClipBoxToBrush from the engine code as reference):
- Code: Select all
// jit - mostly copied from TestLine_r.
static int TraceToSky_r (vec3_t scale, int node, const vec3_t start_in, const vec3_t stop)
{
tnode_t *tnode;
float front, back;
vec3_t mid, start;
float frac;
int side;
int r;
start[0] = start_in[0];
start[1] = start_in[1];
start[2] = start_in[2];
re_test:
// Nodes < 0 (highest bit set) are leaf nodes.
if (node & (1<<31))
{
int leafnum = node & ~(1<<31); // leaf node
if (leafnum)
{
int k;
int brushnum;
dleaf_t *leaf;
dbrush_t *b;
int brushtestret;
//leaf = &map_leafs[leafnum];
leaf = dleafs + leafnum;
// trace line against all brushes in the leaf
for (k = 0; k < leaf->numleafbrushes; ++k)
{
//brushnum = map_leafbrushes[leaf->firstleafbrush + k];
brushnum = dleafbrushes[leaf->firstleafbrush + k];
//b = &map_brushes[brushnum];
b = dbrushes + brushnum;
//if (b->checkcount == checkcount)
// continue; // already checked this brush in another leaf
//b->checkcount = checkcount;
//if (!(b->contents & trace_contents))
// continue;
brushtestret = TraceToSkyBrushTest(scale, start, stop, b);
if (brushtestret != 0)
return brushtestret;
}
}
return 0;
}
// todo: seems the conditional checks here would probably be slower than just doing the math -- test that theory.
tnode = &tnodes[node];
switch (tnode->type)
{
case PLANE_X:
front = start[0] - tnode->dist;
back = stop[0] - tnode->dist;
break;
case PLANE_Y:
front = start[1] - tnode->dist;
back = stop[1] - tnode->dist;
break;
case PLANE_Z:
front = start[2] - tnode->dist;
back = stop[2] - tnode->dist;
break;
default:
front = (start[0]*tnode->normal[0] + start[1]*tnode->normal[1] + start[2]*tnode->normal[2]) - tnode->dist;
back = (stop[0]*tnode->normal[0] + stop[1]*tnode->normal[1] + stop[2]*tnode->normal[2]) - tnode->dist;
break;
}
if (front >= -ON_EPSILON && back >= -ON_EPSILON)
{
node = tnode->children[0];
goto re_test;
// return TestLine_r (tnode->children[0], start, stop);
}
if (front < ON_EPSILON && back < ON_EPSILON)
{
node = tnode->children[1];
goto re_test;
// return TestLine_r (tnode->children[1], start, stop);
}
side = front < 0;
frac = front / (front-back);
mid[0] = start[0] + (stop[0] - start[0])*frac;
mid[1] = start[1] + (stop[1] - start[1])*frac;
mid[2] = start[2] + (stop[2] - start[2])*frac;
r = TraceToSky_r(scale, tnode->children[side], start, mid);
if (r)
return r;
node = tnode->children[!side];
start[0] = mid[0];
start[1] = mid[1];
start[2] = mid[2];
goto re_test;
}
(Pardon the sloppy WIP code).
Problem I'm running into is that leaf->numleafbrushes is always 0. I never actually get into that loop where it checks against all the brushes.
Most leaf nodes are either 0x80000000 or 0x80000001.
There ARE leaves that have brushes, but I never seem to be hitting them. I'm not sure what I'm doing wrong. Probably something stupid. Any ideas?
- jitspoe
- Posts: 217
- Joined: Mon Jan 17, 2005 5:27 am
Re: Getting Surface Flags in qrad3?
TestLine returns contents values, not leaf numbers.
MakeTnode stores the leaf's contents into the tnode's parent, so you'll need to either modify the tnodes or just directly use the dnodes+dplanes
that's why your code deals with bits instead of using the if(node<0)leafnum=(-1-node); conversion that is native to the bsp format.
MakeTnode stores the leaf's contents into the tnode's parent, so you'll need to either modify the tnodes or just directly use the dnodes+dplanes
that's why your code deals with bits instead of using the if(node<0)leafnum=(-1-node); conversion that is native to the bsp format.
- Spike
- Posts: 2892
- Joined: Fri Nov 05, 2004 3:12 am
- Location: UK
Re: Getting Surface Flags in qrad3?
Ah-HAH! I see it.
Thanks a bunch!
- Code: Select all
if (node->children[i] < 0)
{
t->children[i] = (dleafs[-node->children[i] - 1].contents & CONTENTS_SOLID) | (1<<31);
}
else
{
t->children[i] = tnode_p - tnodes;
MakeTnode (node->children[i]);
}
Thanks a bunch!
- jitspoe
- Posts: 217
- Joined: Mon Jan 17, 2005 5:27 am
3 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 1 guest