int TestLine_r( int node, vec3_t start, vec3_t stop ){ tnode_t *tnode; float front, back; vec3_t mid; float frac; int side; int r; 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 ) { return TestLine_r( tnode->children[0], start, stop ); } if ( front < ON_EPSILON && back < ON_EPSILON ) { 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; } return TestLine_r( tnode->children[!side], mid, stop ); }
/* ============== TestPatchToFace Sets vis bits for all patches in the face ============== */ void TestPatchToFace (unsigned patchnum, int facenum, int head, unsigned bitpos) { patch_t *patch = &patches[patchnum]; patch_t *patch2 = face_patches[facenum]; // if emitter is behind that face plane, skip all patches if ( patch2 && DotProduct(patch->origin, patch2->normal) > PatchPlaneDist(patch2)+1.01 ) { // we need to do a real test for ( ; patch2 ; patch2 = patch2->next) { unsigned m = patch2 - patches; // check vis between patch and patch2 // if bit has not already been set // && v2 is not behind light plane // && v2 is visible from v1 if ( m > patchnum && DotProduct (patch2->origin, patch->normal) > PatchPlaneDist(patch)+1.01 && TestLine_r (head, patch->origin, patch2->origin) == CONTENTS_EMPTY ) { // patchnum can see patch m int bitset = bitpos+m; vismatrix[ bitset>>3 ] |= 1 << (bitset&7); } } }
int TestLine_color (int node, vec3_t start, vec3_t stop, vec3_t occluded) { occluded[0] = occluded[1] = occluded[2] = 1.0; if (doing_texcheck) return TestLine_r_texcheck (node, 0, start, stop, start, stop, occluded); else return TestLine_r (node, start, stop); }
int TestLine (vec3_t start, vec3_t stop) { vec3_t occluded; occluded[0] = occluded[1] = occluded[2] = 1.0; if (doing_texcheck) return TestLine_r_texcheck (0, 0, start, stop, start, stop, occluded); else return TestLine_r (0, start, stop); }
//without texture checking int TestLine_r (int node, vec3_t set_start, vec3_t stop) { tnode_t *tnode; float front, back; vec3_t mid, _start; vec_t *start; float frac; int side; int r; start = set_start; re_test: r = 0; if (node & (1<<31)) { if ((r = node & ~(1<<31)) != CONTENTS_WINDOW) { return r; } return 0; } 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; } if (front < ON_EPSILON && back < ON_EPSILON) { node = tnode->children[1]; goto re_test; } 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; if ((r = TestLine_r (tnode->children[side], start, mid))) return r; node = tnode->children[!side]; start = _start; start[0] = mid[0]; start[1] = mid[1]; start[2] = mid[2]; goto re_test; }
int TestLine (vec3_t start, vec3_t stop) { return TestLine_r (0, start, stop); }