1 // Requries parts of the q3 tools source to compile
\r
3 // Written by: Brad Whitehead (whiteheb@gamerstv.net)
\r
6 #include "dialogs/dialogs-gtk.h"
\r
7 #include "DWinding.h"
\r
8 #include "bsploader.h"
\r
12 int leafbytes; //leafbytes = ((portalclusters+63)&~63)>>3;
\r
15 // added because int shift = 32; i = 0xFFFFFFFF >> shift;
\r
16 // then i = 0xFFFFFFFF, when it should = 0
\r
17 const unsigned long bitmasks[33] =
\r
20 0x00000001, 0x00000003, 0x00000007, 0x0000000F,
\r
21 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
\r
22 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
\r
23 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
\r
24 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
\r
25 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
\r
26 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
\r
27 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
\r
30 int bsp_leafnumfororigin(vec3_t origin)
\r
36 // TODO: check if origin is in the map??
\r
41 plane = &dplanes[node->planeNum];
\r
42 d = DotProduct (origin, plane->normal) - plane->dist;
\r
44 if ( node->children[0] < 0 )
\r
45 return -(node->children[0]+1);
\r
47 node = &dnodes[node->children[0]];
\r
49 if ( node->children[1] < 0 )
\r
50 return -(node->children[1]+1);
\r
52 node = &dnodes[node->children[1]];
\r
57 int bsp_leafnumforcluster(int cluster)
\r
62 for ( i = 0, l = dleafs; i < numleafs; i++, l++ )
\r
63 if ( l->cluster == cluster ) return(i);
\r
67 // leaf1 = origin leaf
\r
68 // leaf2 = leaf to test for
\r
69 /*int bsp_InPVS(int cluster1, int cluster2)
\r
71 vis_header *vheader;
\r
74 vheader = (vis_header *) visBytes;
\r
75 visdata = visBytes + VIS_HEADER_SIZE;
\r
77 return( *( visdata + ( cluster1 * vheader->leafbytes ) + (cluster2 / 8) ) & ( 1 << ( cluster2 % 8 ) ) );
\r
80 void bsp_setbitvectorlength( byte *v, int length_bits, int length_vector )
\r
86 *(v+i) = (byte) bitmasks[length_bits % 8];
\r
88 memset((v+i+1), 0, length_vector-i-1);
\r
92 void bsp_bitvectorsubtract(byte *first, byte *second, byte *out, int length)
\r
97 for ( i = 0; i < length; i++ )
\r
98 *(out+i) = *(first+i) & ~(*(second+i));
\r
101 int bsp_countclusters(byte *bitvector, int length)
\r
106 for ( i = 0; i < length; i++ )
\r
107 for ( j = 0; j < 8; j++ )
\r
108 if ( (*(bitvector+i) & (1 << j)) ) c++;
\r
112 int bsp_countclusters_mask(byte *bitvector, byte *maskvector, int length)
\r
117 for ( i = 0; i < length; i++ )
\r
118 for ( j = 0; j < 8; j++ )
\r
119 if ( (*(bitvector+i) & (1 << j)) && (*(maskvector+i) & (1 << j)) ) c++;
\r
123 void AddCluster(list<DWinding*> *pointlist, dleaf_t *cl, qboolean* repeatlist, vec3_t clr)
\r
127 int* leafsurf = &dleafsurfaces[cl->firstLeafSurface];
\r
128 for(int k = 0; k < cl->numLeafSurfaces; k++, leafsurf++)
\r
130 if(repeatlist[*leafsurf])
\r
133 dsurface_t* surf = &drawSurfaces[*leafsurf];
\r
134 if(surf->surfaceType != MST_PLANAR)
\r
137 qdrawVert_t* vert = &drawVerts[surf->firstVert];
\r
138 if(surf->firstVert + surf->numVerts > numDrawVerts)
\r
139 DoMessageBox("Warning", "Warning", MB_OK);
\r
141 w = new DWinding();
\r
142 w->AllocWinding(surf->numVerts);
\r
144 for (int l = 0; l < surf->numVerts; l++, vert++)
\r
146 (w->p[l])[0] = vert->xyz[0];
\r
147 (w->p[l])[1] = vert->xyz[1];
\r
148 (w->p[l])[2] = vert->xyz[2];
\r
150 w->clr[0] = clr[0];
\r
151 w->clr[1] = clr[1];
\r
152 w->clr[2] = clr[2];
\r
154 pointlist->push_back(w);
\r
156 repeatlist[*leafsurf] = true;
\r
165 list<DWinding*> *CreateTrace( dleaf_t *leaf, int c, vis_header *header, byte *visdata, byte *seen )
\r
168 int i, j, clusterNum;
\r
169 list<DWinding*> *pointlist = new list<DWinding*>;
\r
170 qboolean* repeatlist = new qboolean[numDrawSurfaces];
\r
173 vec3_t clrRnd[5] = {
\r
181 vec3_t clrGreen = {0.f, 1.f, 0.f};
\r
183 memset(repeatlist, 0, sizeof(qboolean)*numDrawSurfaces);
\r
185 vis = visdata + ( c * header->leafbytes );
\r
189 AddCluster(pointlist, &(dleafs[bsp_leafnumforcluster( c )]), repeatlist, clrGreen);
\r
191 for ( i = 0; i < header->leafbytes; i++ )
\r
193 for ( j = 0; j < 8; j++ )
\r
195 cl = &(dleafs[bsp_leafnumforcluster( clusterNum )]);
\r
197 if ( ( *(vis + i) & (1 << j) ) && (*(seen+i) & (1 << j)) && (leaf->area == cl->area))
\r
198 AddCluster(pointlist, cl, repeatlist, clrRnd[rand()%5]);
\r
212 setup for CreateTrace
\r
215 list<DWinding*> *TraceCluster (int leafnum)
\r
217 byte seen[(MAX_MAP_LEAFS/8) + 1];
\r
218 vis_header *vheader;
\r
222 vheader = (vis_header *) visBytes;
\r
223 visdata = visBytes + sizeof(vis_header);
\r
225 memset(seen, 0xFF, sizeof(seen));
\r
226 bsp_setbitvectorlength(seen, vheader->portalclusters, sizeof(seen));
\r
228 leaf = &(dleafs[leafnum]);
\r
230 return CreateTrace(leaf, leaf->cluster, vheader, visdata, seen);
\r
233 list<DWinding *>* BuildTrace(char* filename, vec3_t v_origin)
\r
235 if(!LoadBSPFile(filename))
\r
238 int leafnum = bsp_leafnumfororigin(v_origin);
\r
240 list<DWinding*> *pointlist = TraceCluster(leafnum);
\r