Forum

Getting Surface Flags in qrad3?

Discuss the construction of maps and the tools to create maps for 3D games.

Moderator: InsideQC Admins

Getting Surface Flags in qrad3?

Postby jitspoe » Tue Mar 03, 2015 3:33 am

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:

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?

Postby Spike » Tue Mar 03, 2015 4:16 am

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.
Spike
 
Posts: 2881
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: Getting Surface Flags in qrad3?

Postby jitspoe » Tue Mar 03, 2015 4:44 am

Ah-HAH! I see it.

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


Return to Mapping

Who is online

Users browsing this forum: No registered users and 1 guest