1 // Requries parts of the q3 tools source to compile
3 // Written by: Brad Whitehead (whiteheb@gamerstv.net)
6 #include "dialogs/dialogs-gtk.h"
14 int leafbytes; //leafbytes = ((portalclusters+63)&~63)>>3;
17 // added because int shift = 32; i = 0xFFFFFFFF >> shift;
18 // then i = 0xFFFFFFFF, when it should = 0
19 const unsigned long bitmasks[33] =
22 0x00000001, 0x00000003, 0x00000007, 0x0000000F,
23 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
24 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
25 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
26 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
27 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
28 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
29 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
32 int bsp_leafnumfororigin( vec3_t origin ){
37 // TODO: check if origin is in the map??
42 plane = &dplanes[node->planeNum];
43 d = DotProduct( origin, plane->normal ) - plane->dist;
45 if ( node->children[0] < 0 ) {
46 return -( node->children[0] + 1 );
49 node = &dnodes[node->children[0]];
53 if ( node->children[1] < 0 ) {
54 return -( node->children[1] + 1 );
57 node = &dnodes[node->children[1]];
63 int bsp_leafnumforcluster( int cluster ){
67 for ( i = 0, l = dleafs; i < numleafs; i++, l++ )
68 if ( l->cluster == cluster ) {
74 // leaf1 = origin leaf
75 // leaf2 = leaf to test for
76 /*int bsp_InPVS(int cluster1, int cluster2)
81 vheader = (vis_header *) visBytes;
82 visdata = visBytes + VIS_HEADER_SIZE;
84 return( *( visdata + ( cluster1 * vheader->leafbytes ) + (cluster2 / 8) ) & ( 1 << ( cluster2 % 8 ) ) );
87 void bsp_setbitvectorlength( byte *v, int length_bits, int length_vector ){
92 *( v + i ) = (byte) bitmasks[length_bits % 8];
94 memset( ( v + i + 1 ), 0, length_vector - i - 1 );
98 void bsp_bitvectorsubtract( byte *first, byte *second, byte *out, int length ){
102 for ( i = 0; i < length; i++ )
103 *( out + i ) = *( first + i ) & ~( *( second + i ) );
106 int bsp_countclusters( byte *bitvector, int length ){
110 for ( i = 0; i < length; i++ )
111 for ( j = 0; j < 8; j++ )
112 if ( ( *( bitvector + i ) & ( 1 << j ) ) ) {
118 int bsp_countclusters_mask( byte *bitvector, byte *maskvector, int length ){
122 for ( i = 0; i < length; i++ )
123 for ( j = 0; j < 8; j++ )
124 if ( ( *( bitvector + i ) & ( 1 << j ) ) && ( *( maskvector + i ) & ( 1 << j ) ) ) {
130 void AddCluster( std::list<DWinding*> *pointlist, dleaf_t *cl, bool* repeatlist, vec3_t clr ){
133 int* leafsurf = &dleafsurfaces[cl->firstLeafSurface];
134 for ( int k = 0; k < cl->numLeafSurfaces; k++, leafsurf++ )
136 if ( repeatlist[*leafsurf] ) {
140 dsurface_t* surf = &drawSurfaces[*leafsurf];
141 if ( surf->surfaceType != MST_PLANAR ) {
145 qdrawVert_t* vert = &drawVerts[surf->firstVert];
146 if ( surf->firstVert + surf->numVerts > numDrawVerts ) {
147 DoMessageBox( "Warning", "Warning", eMB_OK );
151 w->AllocWinding( surf->numVerts );
153 for ( int l = 0; l < surf->numVerts; l++, vert++ )
155 ( w->p[l] )[0] = vert->xyz[0];
156 ( w->p[l] )[1] = vert->xyz[1];
157 ( w->p[l] )[2] = vert->xyz[2];
163 pointlist->push_back( w );
165 repeatlist[*leafsurf] = true;
174 std::list<DWinding*> *CreateTrace( dleaf_t *leaf, int c, vis_header *header, byte *visdata, byte *seen ){
176 int i, j, clusterNum;
177 std::list<DWinding*> *pointlist = new std::list<DWinding*>;
178 bool* repeatlist = new bool[numDrawSurfaces];
189 vec3_t clrGreen = {0.f, 1.f, 0.f};
191 memset( repeatlist, 0, sizeof( bool ) * numDrawSurfaces );
193 vis = visdata + ( c * header->leafbytes );
197 AddCluster( pointlist, &( dleafs[bsp_leafnumforcluster( c )] ), repeatlist, clrGreen );
199 for ( i = 0; i < header->leafbytes; i++ )
201 for ( j = 0; j < 8; j++ )
203 cl = &( dleafs[bsp_leafnumforcluster( clusterNum )] );
205 if ( ( *( vis + i ) & ( 1 << j ) ) && ( *( seen + i ) & ( 1 << j ) ) && ( leaf->area == cl->area ) ) {
206 AddCluster( pointlist, cl, repeatlist, clrRnd[rand() % 5] );
221 setup for CreateTrace
224 std::list<DWinding*> *TraceCluster( int leafnum ){
225 byte seen[( MAX_MAP_LEAFS / 8 ) + 1];
230 vheader = (vis_header *) visBytes;
231 visdata = visBytes + sizeof( vis_header );
233 memset( seen, 0xFF, sizeof( seen ) );
234 bsp_setbitvectorlength( seen, vheader->portalclusters, sizeof( seen ) );
236 leaf = &( dleafs[leafnum] );
238 return CreateTrace( leaf, leaf->cluster, vheader, visdata, seen );
241 std::list<DWinding *>* BuildTrace( char* filename, vec3_t v_origin ){
242 if ( !LoadBSPFile( filename ) ) {
246 int leafnum = bsp_leafnumfororigin( v_origin );
248 std::list<DWinding*> *pointlist = TraceCluster( leafnum );