levels.c

Go to the documentation of this file.
00001 
00005 /*
00006 Copyright (C) 1997-2001 Id Software, Inc.
00007 
00008 This program is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU General Public License
00010 as published by the Free Software Foundation; either version 2
00011 of the License, or (at your option) any later version.
00012 
00013 This program is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016 
00017 See the GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00023 */
00024 
00025 #include "bsp.h"
00026 
00027 
00028 const vec3_t v_epsilon = { 1, 1, 1 };
00029 int brush_start, brush_end;
00030 
00031 vec3_t worldMins, worldMaxs;
00032 
00033 static int oldmodels, oldleafs, oldleafbrushes, oldplanes, oldvertexes, oldnormals, oldnodes, oldtexinfo, oldfaces, oldedges, oldsurfedges;
00034 
00035 void PushInfo (void)
00036 {
00037     oldmodels = curTile->nummodels;
00038     oldleafs = curTile->numleafs;
00039     oldleafbrushes = curTile->numleafbrushes;
00040     oldplanes = curTile->numplanes;
00041     oldvertexes = curTile->numvertexes;
00042     oldnormals = curTile->numnormals;
00043     oldnodes = curTile->numnodes;
00044     oldtexinfo = curTile->numtexinfo;
00045     oldfaces = curTile->numfaces;
00046     oldedges = curTile->numedges;
00047     oldsurfedges = curTile->numsurfedges;
00048 }
00049 
00050 void PopInfo (void)
00051 {
00052     curTile->nummodels = oldmodels;
00053     curTile->numleafs = oldleafs;
00054     curTile->numleafbrushes = oldleafbrushes;
00055     curTile->numplanes = oldplanes;
00056     curTile->numvertexes = oldvertexes;
00057     curTile->numnormals = oldnormals;
00058     curTile->numnodes = oldnodes;
00059     curTile->numtexinfo = oldtexinfo;
00060     curTile->numfaces = oldfaces;
00061     curTile->numedges = oldedges;
00062     curTile->numsurfedges = oldsurfedges;
00063 }
00064 
00069 static int32_t BuildNodeChildren (const int n[3])
00070 {
00071     int32_t node = LEAFNODE;
00072     int i;
00073 
00074     for (i = 0; i < 3; i++) {
00075         dBspNode_t *newnode;
00076         vec3_t newmins, newmaxs, addvec;
00077 
00078         if (n[i] == LEAFNODE)
00079             continue;
00080 
00081         if (node == LEAFNODE) {
00082             /* store the valid node */
00083             node = n[i];
00084 
00085             ClearBounds(newmins, newmaxs);
00086             VectorCopy(curTile->nodes[node].mins, addvec);
00087             AddPointToBounds(addvec, newmins, newmaxs);
00088             VectorCopy(curTile->nodes[node].maxs, addvec);
00089             AddPointToBounds(addvec, newmins, newmaxs);
00090         } else {
00091             /* add a new "special" dnode and store it */
00092             newnode = &curTile->nodes[curTile->numnodes];
00093             curTile->numnodes++;
00094 
00095             newnode->planenum = PLANENUM_LEAF;
00096             newnode->children[0] = node;
00097             newnode->children[1] = n[i];
00098             newnode->firstface = 0;
00099             newnode->numfaces = 0;
00100 
00101             ClearBounds(newmins, newmaxs);
00102             VectorCopy(curTile->nodes[node].mins, addvec);
00103             AddPointToBounds(addvec, newmins, newmaxs);
00104             VectorCopy(curTile->nodes[node].maxs, addvec);
00105             AddPointToBounds(addvec, newmins, newmaxs);
00106             VectorCopy(curTile->nodes[n[i]].mins, addvec);
00107             AddPointToBounds(addvec, newmins, newmaxs);
00108             VectorCopy(curTile->nodes[n[i]].maxs, addvec);
00109             AddPointToBounds(addvec, newmins, newmaxs);
00110             VectorCopy(newmins, newnode->mins);
00111             VectorCopy(newmaxs, newnode->maxs);
00112 
00113             node = curTile->numnodes - 1;
00114         }
00115 
00116         AddPointToBounds(newmins, worldMins, worldMaxs);
00117         AddPointToBounds(newmaxs, worldMins, worldMaxs);
00118 
00119         Verb_Printf(VERB_DUMP, "BuildNodeChildren: node=%i (%i %i %i) (%i %i %i)\n", node,
00120             curTile->nodes[node].mins[0], curTile->nodes[node].mins[1], curTile->nodes[node].mins[2], curTile->nodes[node].maxs[0], curTile->nodes[node].maxs[1], curTile->nodes[node].maxs[2]);
00121     }
00122 
00123     /* return the last stored node */
00124     return node;
00125 }
00126 
00127 #define SPLIT_BRUSH_SIZE 256
00128 
00133 static int32_t ConstructLevelNodes_r (const int levelnum, const vec3_t cmins, const vec3_t cmaxs)
00134 {
00135     bspbrush_t *list;
00136     tree_t *tree;
00137     vec3_t diff, bmins, bmaxs;
00138     int32_t nn[3];
00139     node_t *node;
00140 
00141     /* calculate bounds, stop if no brushes are available */
00142     if (!MapBrushesBounds(brush_start, brush_end, levelnum, cmins, cmaxs, bmins, bmaxs))
00143         return LEAFNODE;
00144 
00145     Verb_Printf(VERB_DUMP, "ConstructLevelNodes_r: lv=%i (%f %f %f) (%f %f %f)\n", levelnum,
00146         cmins[0], cmins[1], cmins[2], cmaxs[0], cmaxs[1], cmaxs[2]);
00147 
00148     VectorSubtract(bmaxs, bmins, diff);
00149 
00150 /*  Com_Printf("(%i): %i %i: (%i %i) (%i %i) -> (%i %i) (%i %i)\n", levelnum, (int)diff[0], (int)diff[1],
00151         (int)cmins[0], (int)cmins[1], (int)cmaxs[0], (int)cmaxs[1],
00152         (int)bmins[0], (int)bmins[1], (int)bmaxs[0], (int)bmaxs[1]); */
00153 
00154     if (diff[0] > SPLIT_BRUSH_SIZE || diff[1] > SPLIT_BRUSH_SIZE) {
00155         /* continue subdivision */
00156         /* split the remaining hull at the middle of the longer axis */
00157         vec3_t nmins, nmaxs;
00158         int n;
00159 
00160         if (diff[1] > diff[0])
00161             n = 1;
00162         else
00163             n = 0;
00164 
00165         VectorCopy(bmins, nmins);
00166         VectorCopy(bmaxs, nmaxs);
00167 
00168         nmaxs[n] -= diff[n] / 2;
00169 /*      Com_Printf("  (%i %i) (%i %i)\n", (int)nmins[0], (int)nmins[1], (int)nmaxs[0], (int)nmaxs[1]); */
00170         nn[0] = ConstructLevelNodes_r(levelnum, nmins, nmaxs);
00171 
00172         nmins[n] += diff[n] / 2;
00173         nmaxs[n] += diff[n] / 2;
00174 /*      Com_Printf("    (%i %i) (%i %i)\n", (int)nmins[0], (int)nmins[1], (int)nmaxs[0], (int)nmaxs[1]); */
00175         nn[1] = ConstructLevelNodes_r(levelnum, nmins, nmaxs);
00176     } else {
00177         /* no children */
00178         nn[0] = LEAFNODE;
00179         nn[1] = LEAFNODE;
00180     }
00181 
00182     /* add v_epsilon to avoid clipping errors */
00183     VectorSubtract(bmins, v_epsilon, bmins);
00184     VectorAdd(bmaxs, v_epsilon, bmaxs);
00185 
00186     /* Call BeginModel only to initialize brush pointers */
00187     BeginModel(entity_num);
00188 
00189     list = MakeBspBrushList(brush_start, brush_end, levelnum, bmins, bmaxs);
00190     if (!list) {
00191         nn[2] = LEAFNODE;
00192         return BuildNodeChildren(nn);
00193     }
00194 
00195     if (!config.nocsg)
00196         list = ChopBrushes(list);
00197 
00198     /* begin model creation now */
00199     tree = BrushBSP(list, bmins, bmaxs);
00200     MakeTreePortals(tree);
00201     MarkVisibleSides(tree, brush_start, brush_end);
00202     MakeFaces(tree->headnode);
00203     FixTjuncs(tree->headnode);
00204 
00205     if (!config.noprune)
00206         PruneNodes(tree->headnode);
00207 
00208     /* correct bounds */
00209     node = tree->headnode;
00210     VectorAdd(bmins, v_epsilon, node->mins);
00211     VectorSubtract(bmaxs, v_epsilon, node->maxs);
00212 
00213     /* finish model */
00214     nn[2] = WriteBSP(tree->headnode);
00215     FreeTree(tree);
00216 
00217     /* Store created nodes */
00218     return BuildNodeChildren(nn);
00219 }
00220 
00221 
00233 void ProcessLevel (unsigned int levelnum)
00234 {
00235     vec3_t mins, maxs;
00236     dBspModel_t *dm;
00237 
00238     /* oversizing the blocks guarantees that all the boundaries will also get nodes. */
00239     /* get maxs */
00240     mins[0] = (config.block_xl) * 512.0 + 1.0;
00241     mins[1] = (config.block_yl) * 512.0 + 1.0;
00242     mins[2] = -MAX_WORLD_WIDTH + 1.0;
00243 
00244     maxs[0] = (config.block_xh + 1.0) * 512.0 - 1.0;
00245     maxs[1] = (config.block_yh + 1.0) * 512.0 - 1.0f;
00246     maxs[2] = MAX_WORLD_WIDTH - 1.0;
00247 
00248     Verb_Printf(VERB_EXTRA, "Process levelnum %i (curTile->nummodels: %i)\n", levelnum, curTile->nummodels);
00249     /* Com_Printf("Process levelnum %i (curTile->nummodels: %i)\n", levelnum, curTile->nummodels); */
00250 
00252     dm = &curTile->models[levelnum];
00253     memset(dm, 0, sizeof(*dm));
00254 
00256     /* back copy backup brush sides structure */
00257     /* to reset all the changed values (especialy "finished") */
00258     memcpy(mapbrushes, mapbrushes + nummapbrushes, sizeof(mapbrush_t) * nummapbrushes);
00259 
00260     /* Store face number for later use */
00261     dm->firstface = curTile->numfaces;
00262     dm->headnode = ConstructLevelNodes_r(levelnum, mins, maxs);
00263     /* This here replaces the calls to EndModel */
00264     dm->numfaces = curTile->numfaces - dm->firstface;
00265 
00266 /*  if (!dm->numfaces)
00267         Com_Printf("level: %i -> %i : f %i\n", levelnum, dm->headnode, dm->numfaces);
00268 */
00269 }

Generated by  doxygen 1.6.2