diff options
author | tma <tma@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-10-29 23:13:09 +0000 |
---|---|---|
committer | tma <tma@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-10-29 23:13:09 +0000 |
commit | ce25a7def5dc658d78c06016494b90972f1cf973 (patch) | |
tree | ba01dacc114803beafb50a02ce7b01d13302e7ad /code/bspc/aas_create.c | |
parent | cb1d870b05814322bc2ebd26a111eb792e186f33 (diff) | |
download | ioquake3-aero-ce25a7def5dc658d78c06016494b90972f1cf973.tar.gz ioquake3-aero-ce25a7def5dc658d78c06016494b90972f1cf973.zip |
* General decrufting:
* Removed Q3_STATIC and associated defines
* Removed MAC_STATIC
* Replaced __LCC__ with Q3_VM
* Removed bspc and splines directories
git-svn-id: svn://svn.icculus.org/quake3/trunk@201 edf5b092-35ff-0310-97b2-ce42778d08ea
Diffstat (limited to 'code/bspc/aas_create.c')
-rw-r--r-- | code/bspc/aas_create.c | 1142 |
1 files changed, 0 insertions, 1142 deletions
diff --git a/code/bspc/aas_create.c b/code/bspc/aas_create.c deleted file mode 100644 index 6eea740..0000000 --- a/code/bspc/aas_create.c +++ /dev/null @@ -1,1142 +0,0 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Quake III Arena source code; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ - -#include "qbsp.h" -#include "../botlib/aasfile.h" -#include "aas_create.h" -#include "aas_store.h" -#include "aas_gsubdiv.h" -#include "aas_facemerging.h" -#include "aas_areamerging.h" -#include "aas_edgemelting.h" -#include "aas_prunenodes.h" -#include "aas_cfg.h" -#include "../qcommon/surfaceflags.h" - -//#define AW_DEBUG -//#define L_DEBUG - -#define AREAONFACESIDE(face, area) (face->frontarea != area) - -tmp_aas_t tmpaasworld; - -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_InitTmpAAS(void) -{ - //tmp faces - tmpaasworld.numfaces = 0; - tmpaasworld.facenum = 0; - tmpaasworld.faces = NULL; - //tmp convex areas - tmpaasworld.numareas = 0; - tmpaasworld.areanum = 0; - tmpaasworld.areas = NULL; - //tmp nodes - tmpaasworld.numnodes = 0; - tmpaasworld.nodes = NULL; - // - tmpaasworld.nodebuffer = NULL; -} //end of the function AAS_InitTmpAAS -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_FreeTmpAAS(void) -{ - tmp_face_t *f, *nextf; - tmp_area_t *a, *nexta; - tmp_nodebuf_t *nb, *nextnb; - - //free all the faces - for (f = tmpaasworld.faces; f; f = nextf) - { - nextf = f->l_next; - if (f->winding) FreeWinding(f->winding); - FreeMemory(f); - } //end if - //free all tmp areas - for (a = tmpaasworld.areas; a; a = nexta) - { - nexta = a->l_next; - if (a->settings) FreeMemory(a->settings); - FreeMemory(a); - } //end for - //free all the tmp nodes - for (nb = tmpaasworld.nodebuffer; nb; nb = nextnb) - { - nextnb = nb->next; - FreeMemory(nb); - } //end for -} //end of the function AAS_FreeTmpAAS -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -tmp_face_t *AAS_AllocTmpFace(void) -{ - tmp_face_t *tmpface; - - tmpface = (tmp_face_t *) GetClearedMemory(sizeof(tmp_face_t)); - tmpface->num = tmpaasworld.facenum++; - tmpface->l_prev = NULL; - tmpface->l_next = tmpaasworld.faces; - if (tmpaasworld.faces) tmpaasworld.faces->l_prev = tmpface; - tmpaasworld.faces = tmpface; - tmpaasworld.numfaces++; - return tmpface; -} //end of the function AAS_AllocTmpFace -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_FreeTmpFace(tmp_face_t *tmpface) -{ - if (tmpface->l_next) tmpface->l_next->l_prev = tmpface->l_prev; - if (tmpface->l_prev) tmpface->l_prev->l_next = tmpface->l_next; - else tmpaasworld.faces = tmpface->l_next; - //free the winding - if (tmpface->winding) FreeWinding(tmpface->winding); - //free the face - FreeMemory(tmpface); - tmpaasworld.numfaces--; -} //end of the function AAS_FreeTmpFace -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -tmp_area_t *AAS_AllocTmpArea(void) -{ - tmp_area_t *tmparea; - - tmparea = (tmp_area_t *) GetClearedMemory(sizeof(tmp_area_t)); - tmparea->areanum = tmpaasworld.areanum++; - tmparea->l_prev = NULL; - tmparea->l_next = tmpaasworld.areas; - if (tmpaasworld.areas) tmpaasworld.areas->l_prev = tmparea; - tmpaasworld.areas = tmparea; - tmpaasworld.numareas++; - return tmparea; -} //end of the function AAS_AllocTmpArea -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_FreeTmpArea(tmp_area_t *tmparea) -{ - if (tmparea->l_next) tmparea->l_next->l_prev = tmparea->l_prev; - if (tmparea->l_prev) tmparea->l_prev->l_next = tmparea->l_next; - else tmpaasworld.areas = tmparea->l_next; - if (tmparea->settings) FreeMemory(tmparea->settings); - FreeMemory(tmparea); - tmpaasworld.numareas--; -} //end of the function AAS_FreeTmpArea -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -tmp_node_t *AAS_AllocTmpNode(void) -{ - tmp_nodebuf_t *nodebuf; - - if (!tmpaasworld.nodebuffer || - tmpaasworld.nodebuffer->numnodes >= NODEBUF_SIZE) - { - nodebuf = (tmp_nodebuf_t *) GetClearedMemory(sizeof(tmp_nodebuf_t)); - nodebuf->next = tmpaasworld.nodebuffer; - nodebuf->numnodes = 0; - tmpaasworld.nodebuffer = nodebuf; - } //end if - tmpaasworld.numnodes++; - return &tmpaasworld.nodebuffer->nodes[tmpaasworld.nodebuffer->numnodes++]; -} //end of the function AAS_AllocTmpNode -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_FreeTmpNode(tmp_node_t *tmpnode) -{ - tmpaasworld.numnodes--; -} //end of the function AAS_FreeTmpNode -//=========================================================================== -// returns true if the face is a gap from the given side -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -int AAS_GapFace(tmp_face_t *tmpface, int side) -{ - vec3_t invgravity; - - //if the face is a solid or ground face it can't be a gap - if (tmpface->faceflags & (FACE_GROUND | FACE_SOLID)) return 0; - - VectorCopy(cfg.phys_gravitydirection, invgravity); - VectorInverse(invgravity); - - return (DotProduct(invgravity, mapplanes[tmpface->planenum ^ side].normal) > cfg.phys_maxsteepness); -} //end of the function AAS_GapFace -//=========================================================================== -// returns true if the face is a ground face -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -int AAS_GroundFace(tmp_face_t *tmpface) -{ - vec3_t invgravity; - - //must be a solid face - if (!(tmpface->faceflags & FACE_SOLID)) return 0; - - VectorCopy(cfg.phys_gravitydirection, invgravity); - VectorInverse(invgravity); - - return (DotProduct(invgravity, mapplanes[tmpface->planenum].normal) > cfg.phys_maxsteepness); -} //end of the function AAS_GroundFace -//=========================================================================== -// adds the side of a face to an area -// -// side : 0 = front side -// 1 = back side -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_AddFaceSideToArea(tmp_face_t *tmpface, int side, tmp_area_t *tmparea) -{ - int tmpfaceside; - - if (side) - { - if (tmpface->backarea) Error("AAS_AddFaceSideToArea: already a back area\n"); - } //end if - else - { - if (tmpface->frontarea) Error("AAS_AddFaceSideToArea: already a front area\n"); - } //end else - - if (side) tmpface->backarea = tmparea; - else tmpface->frontarea = tmparea; - - if (tmparea->tmpfaces) - { - tmpfaceside = tmparea->tmpfaces->frontarea != tmparea; - tmparea->tmpfaces->prev[tmpfaceside] = tmpface; - } //end if - tmpface->next[side] = tmparea->tmpfaces; - tmpface->prev[side] = NULL; - tmparea->tmpfaces = tmpface; -} //end of the function AAS_AddFaceSideToArea -//=========================================================================== -// remove (a side of) a face from an area -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_RemoveFaceFromArea(tmp_face_t *tmpface, tmp_area_t *tmparea) -{ - int side, prevside, nextside; - - if (tmpface->frontarea != tmparea && - tmpface->backarea != tmparea) - { - Error("AAS_RemoveFaceFromArea: face not part of the area"); - } //end if - side = tmpface->frontarea != tmparea; - if (tmpface->prev[side]) - { - prevside = tmpface->prev[side]->frontarea != tmparea; - tmpface->prev[side]->next[prevside] = tmpface->next[side]; - } //end if - else - { - tmparea->tmpfaces = tmpface->next[side]; - } //end else - if (tmpface->next[side]) - { - nextside = tmpface->next[side]->frontarea != tmparea; - tmpface->next[side]->prev[nextside] = tmpface->prev[side]; - } //end if - //remove the area number from the face depending on the side - if (side) tmpface->backarea = NULL; - else tmpface->frontarea = NULL; - tmpface->prev[side] = NULL; - tmpface->next[side] = NULL; -} //end of the function AAS_RemoveFaceFromArea -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_CheckArea(tmp_area_t *tmparea) -{ - int side; - tmp_face_t *face; - plane_t *plane; - vec3_t wcenter, acenter = {0, 0, 0}; - vec3_t normal; - float n, dist; - - if (tmparea->invalid) Log_Print("AAS_CheckArea: invalid area\n"); - for (n = 0, face = tmparea->tmpfaces; face; face = face->next[side]) - { - //side of the face the area is on - side = face->frontarea != tmparea; - WindingCenter(face->winding, wcenter); - VectorAdd(acenter, wcenter, acenter); - n++; - } //end for - n = 1 / n; - VectorScale(acenter, n, acenter); - for (face = tmparea->tmpfaces; face; face = face->next[side]) - { - //side of the face the area is on - side = face->frontarea != tmparea; - -#ifdef L_DEBUG - if (WindingError(face->winding)) - { - Log_Write("AAS_CheckArea: area %d face %d: %s\r\n", tmparea->areanum, - face->num, WindingErrorString()); - } //end if -#endif L_DEBUG - - plane = &mapplanes[face->planenum ^ side]; - - if (DotProduct(plane->normal, acenter) - plane->dist < 0) - { - Log_Print("AAS_CheckArea: area %d face %d is flipped\n", tmparea->areanum, face->num); - Log_Print("AAS_CheckArea: area %d center is %f %f %f\n", tmparea->areanum, acenter[0], acenter[1], acenter[2]); - } //end if - //check if the winding plane is the same as the face plane - WindingPlane(face->winding, normal, &dist); - plane = &mapplanes[face->planenum]; -#ifdef L_DEBUG - if (fabs(dist - plane->dist) > 0.4 || - fabs(normal[0] - plane->normal[0]) > 0.0001 || - fabs(normal[1] - plane->normal[1]) > 0.0001 || - fabs(normal[2] - plane->normal[2]) > 0.0001) - { - Log_Write("AAS_CheckArea: area %d face %d winding plane unequal to face plane\r\n", - tmparea->areanum, face->num); - } //end if -#endif L_DEBUG - } //end for -} //end of the function AAS_CheckArea -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_CheckFaceWindingPlane(tmp_face_t *face) -{ - float dist, sign1, sign2; - vec3_t normal; - plane_t *plane; - winding_t *w; - - //check if the winding plane is the same as the face plane - WindingPlane(face->winding, normal, &dist); - plane = &mapplanes[face->planenum]; - // - sign1 = DotProduct(plane->normal, normal); - // - if (fabs(dist - plane->dist) > 0.4 || - fabs(normal[0] - plane->normal[0]) > 0.0001 || - fabs(normal[1] - plane->normal[1]) > 0.0001 || - fabs(normal[2] - plane->normal[2]) > 0.0001) - { - VectorInverse(normal); - dist = -dist; - if (fabs(dist - plane->dist) > 0.4 || - fabs(normal[0] - plane->normal[0]) > 0.0001 || - fabs(normal[1] - plane->normal[1]) > 0.0001 || - fabs(normal[2] - plane->normal[2]) > 0.0001) - { - Log_Write("AAS_CheckFaceWindingPlane: face %d winding plane unequal to face plane\r\n", - face->num); - // - sign2 = DotProduct(plane->normal, normal); - if ((sign1 < 0 && sign2 > 0) || - (sign1 > 0 && sign2 < 0)) - { - Log_Write("AAS_CheckFaceWindingPlane: face %d winding reversed\r\n", - face->num); - w = face->winding; - face->winding = ReverseWinding(w); - FreeWinding(w); - } //end if - } //end if - else - { - Log_Write("AAS_CheckFaceWindingPlane: face %d winding reversed\r\n", - face->num); - w = face->winding; - face->winding = ReverseWinding(w); - FreeWinding(w); - } //end else - } //end if -} //end of the function AAS_CheckFaceWindingPlane -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_CheckAreaWindingPlanes(void) -{ - int side; - tmp_area_t *tmparea; - tmp_face_t *face; - - Log_Write("AAS_CheckAreaWindingPlanes:\r\n"); - for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next) - { - if (tmparea->invalid) continue; - for (face = tmparea->tmpfaces; face; face = face->next[side]) - { - side = face->frontarea != tmparea; - AAS_CheckFaceWindingPlane(face); - } //end for - } //end for -} //end of the function AAS_CheckAreaWindingPlanes -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_FlipAreaFaces(tmp_area_t *tmparea) -{ - int side; - tmp_face_t *face; - plane_t *plane; - vec3_t wcenter, acenter = {0, 0, 0}; - //winding_t *w; - float n; - - for (n = 0, face = tmparea->tmpfaces; face; face = face->next[side]) - { - if (!face->frontarea) Error("face %d has no front area\n", face->num); - //side of the face the area is on - side = face->frontarea != tmparea; - WindingCenter(face->winding, wcenter); - VectorAdd(acenter, wcenter, acenter); - n++; - } //end for - n = 1 / n; - VectorScale(acenter, n, acenter); - for (face = tmparea->tmpfaces; face; face = face->next[side]) - { - //side of the face the area is on - side = face->frontarea != tmparea; - - plane = &mapplanes[face->planenum ^ side]; - - if (DotProduct(plane->normal, acenter) - plane->dist < 0) - { - Log_Print("area %d face %d flipped: front area %d, back area %d\n", tmparea->areanum, face->num, - face->frontarea ? face->frontarea->areanum : 0, - face->backarea ? face->backarea->areanum : 0); - /* - face->planenum = face->planenum ^ 1; - w = face->winding; - face->winding = ReverseWinding(w); - FreeWinding(w); - */ - } //end if -#ifdef L_DEBUG - { - float dist; - vec3_t normal; - - //check if the winding plane is the same as the face plane - WindingPlane(face->winding, normal, &dist); - plane = &mapplanes[face->planenum]; - if (fabs(dist - plane->dist) > 0.4 || - fabs(normal[0] - plane->normal[0]) > 0.0001 || - fabs(normal[1] - plane->normal[1]) > 0.0001 || - fabs(normal[2] - plane->normal[2]) > 0.0001) - { - Log_Write("area %d face %d winding plane unequal to face plane\r\n", - tmparea->areanum, face->num); - } //end if - } -#endif - } //end for -} //end of the function AAS_FlipAreaFaces -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_RemoveAreaFaceColinearPoints(void) -{ - int side; - tmp_face_t *face; - tmp_area_t *tmparea; - - //FIXME: loop over the faces instead of area->faces - for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next) - { - for (face = tmparea->tmpfaces; face; face = face->next[side]) - { - side = face->frontarea != tmparea; - RemoveColinearPoints(face->winding); -// RemoveEqualPoints(face->winding, 0.1); - } //end for - } //end for -} //end of the function AAS_RemoveAreaFaceColinearPoints -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_RemoveTinyFaces(void) -{ - int side, num; - tmp_face_t *face, *nextface; - tmp_area_t *tmparea; - - //FIXME: loop over the faces instead of area->faces - Log_Write("AAS_RemoveTinyFaces\r\n"); - num = 0; - for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next) - { - for (face = tmparea->tmpfaces; face; face = nextface) - { - side = face->frontarea != tmparea; - nextface = face->next[side]; - // - if (WindingArea(face->winding) < 1) - { - if (face->frontarea) AAS_RemoveFaceFromArea(face, face->frontarea); - if (face->backarea) AAS_RemoveFaceFromArea(face, face->backarea); - AAS_FreeTmpFace(face); - //Log_Write("area %d face %d is tiny\r\n", tmparea->areanum, face->num); - num++; - } //end if - } //end for - } //end for - Log_Write("%d tiny faces removed\r\n", num); -} //end of the function AAS_RemoveTinyFaces -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_CreateAreaSettings(void) -{ - int i, flags, side, numgrounded, numladderareas, numliquidareas; - tmp_face_t *face; - tmp_area_t *tmparea; - - numgrounded = 0; - numladderareas = 0; - numliquidareas = 0; - Log_Write("AAS_CreateAreaSettings\r\n"); - i = 0; - qprintf("%6d areas provided with settings", i); - for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next) - { - //if the area is invalid there no need to create settings for it - if (tmparea->invalid) continue; - - tmparea->settings = (tmp_areasettings_t *) GetClearedMemory(sizeof(tmp_areasettings_t)); - tmparea->settings->contents = tmparea->contents; - tmparea->settings->modelnum = tmparea->modelnum; - flags = 0; - for (face = tmparea->tmpfaces; face; face = face->next[side]) - { - side = face->frontarea != tmparea; - flags |= face->faceflags; - } //end for - tmparea->settings->areaflags = 0; - if (flags & FACE_GROUND) - { - tmparea->settings->areaflags |= AREA_GROUNDED; - numgrounded++; - } //end if - if (flags & FACE_LADDER) - { - tmparea->settings->areaflags |= AREA_LADDER; - numladderareas++; - } //end if - if (tmparea->contents & (AREACONTENTS_WATER | - AREACONTENTS_SLIME | - AREACONTENTS_LAVA)) - { - tmparea->settings->areaflags |= AREA_LIQUID; - numliquidareas++; - } //end if - //presence type of the area - tmparea->settings->presencetype = tmparea->presencetype; - // - qprintf("\r%6d", ++i); - } //end for - qprintf("\n"); -#ifdef AASINFO - Log_Print("%6d grounded areas\n", numgrounded); - Log_Print("%6d ladder areas\n", numladderareas); - Log_Print("%6d liquid areas\n", numliquidareas); -#endif //AASINFO -} //end of the function AAS_CreateAreaSettings -//=========================================================================== -// create a tmp AAS area from a leaf node -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -tmp_node_t *AAS_CreateArea(node_t *node) -{ - int pside; - int areafaceflags; - portal_t *p; - tmp_face_t *tmpface; - tmp_area_t *tmparea; - tmp_node_t *tmpnode; - vec3_t up = {0, 0, 1}; - - //create an area from this leaf - tmparea = AAS_AllocTmpArea(); - tmparea->tmpfaces = NULL; - //clear the area face flags - areafaceflags = 0; - //make aas faces from the portals - for (p = node->portals; p; p = p->next[pside]) - { - pside = (p->nodes[1] == node); - //don't create faces from very small portals -// if (WindingArea(p->winding) < 1) continue; - //if there's already a face created for this portal - if (p->tmpface) - { - //add the back side of the face to the area - AAS_AddFaceSideToArea(p->tmpface, 1, tmparea); - } //end if - else - { - tmpface = AAS_AllocTmpFace(); - //set the face pointer at the portal so we can see from - //the portal there's a face created for it - p->tmpface = tmpface; - //FIXME: test this change - //tmpface->planenum = (p->planenum & ~1) | pside; - tmpface->planenum = p->planenum ^ pside; - if (pside) tmpface->winding = ReverseWinding(p->winding); - else tmpface->winding = CopyWinding(p->winding); -#ifdef L_DEBUG - // - AAS_CheckFaceWindingPlane(tmpface); -#endif //L_DEBUG - //if there's solid at the other side of the portal - if (p->nodes[!pside]->contents & (CONTENTS_SOLID | CONTENTS_PLAYERCLIP)) - { - tmpface->faceflags |= FACE_SOLID; - } //end if - //else there is no solid at the other side and if there - //is a liquid at this side - else if (node->contents & (CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA)) - { - tmpface->faceflags |= FACE_LIQUID; - //if there's no liquid at the other side - if (!(p->nodes[!pside]->contents & (CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA))) - { - tmpface->faceflags |= FACE_LIQUIDSURFACE; - } //end if - } //end else - //if there's ladder contents at other side of the portal - if ((p->nodes[pside]->contents & CONTENTS_LADDER) || - (p->nodes[!pside]->contents & CONTENTS_LADDER)) - { - - //NOTE: doesn't have to be solid at the other side because - // when standing one can use a crouch area (which is not solid) - // as a ladder - // imagine a ladder one can walk underthrough, - // under the ladder against the ladder is a crouch area - // the (vertical) sides of this crouch area area also used as - // ladder sides when standing (not crouched) - tmpface->faceflags |= FACE_LADDER; - } //end if - //if it is possible to stand on the face - if (AAS_GroundFace(tmpface)) - { - tmpface->faceflags |= FACE_GROUND; - } //end if - // - areafaceflags |= tmpface->faceflags; - //no aas face number yet (zero is a dummy in the aasworld faces) - tmpface->aasfacenum = 0; - //add the front side of the face to the area - AAS_AddFaceSideToArea(tmpface, 0, tmparea); - } //end else - } //end for - qprintf("\r%6d", tmparea->areanum); - //presence type in the area - tmparea->presencetype = ~node->expansionbboxes & cfg.allpresencetypes; - // - tmparea->contents = 0; - if (node->contents & CONTENTS_CLUSTERPORTAL) tmparea->contents |= AREACONTENTS_CLUSTERPORTAL; - if (node->contents & CONTENTS_MOVER) tmparea->contents |= AREACONTENTS_MOVER; - if (node->contents & CONTENTS_TELEPORTER) tmparea->contents |= AREACONTENTS_TELEPORTER; - if (node->contents & CONTENTS_JUMPPAD) tmparea->contents |= AREACONTENTS_JUMPPAD; - if (node->contents & CONTENTS_DONOTENTER) tmparea->contents |= AREACONTENTS_DONOTENTER; - if (node->contents & CONTENTS_WATER) tmparea->contents |= AREACONTENTS_WATER; - if (node->contents & CONTENTS_LAVA) tmparea->contents |= AREACONTENTS_LAVA; - if (node->contents & CONTENTS_SLIME) tmparea->contents |= AREACONTENTS_SLIME; - if (node->contents & CONTENTS_NOTTEAM1) tmparea->contents |= AREACONTENTS_NOTTEAM1; - if (node->contents & CONTENTS_NOTTEAM2) tmparea->contents |= AREACONTENTS_NOTTEAM2; - - //store the bsp model that's inside this node - tmparea->modelnum = node->modelnum; - //sorta check for flipped area faces (remove??) - AAS_FlipAreaFaces(tmparea); - //check if the area is ok (remove??) - AAS_CheckArea(tmparea); - // - tmpnode = AAS_AllocTmpNode(); - tmpnode->planenum = 0; - tmpnode->children[0] = 0; - tmpnode->children[1] = 0; - tmpnode->tmparea = tmparea; - // - return tmpnode; -} //end of the function AAS_CreateArea -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -tmp_node_t *AAS_CreateAreas_r(node_t *node) -{ - tmp_node_t *tmpnode; - - //recurse down to leafs - if (node->planenum != PLANENUM_LEAF) - { - //the first tmp node is a dummy - tmpnode = AAS_AllocTmpNode(); - tmpnode->planenum = node->planenum; - tmpnode->children[0] = AAS_CreateAreas_r(node->children[0]); - tmpnode->children[1] = AAS_CreateAreas_r(node->children[1]); - return tmpnode; - } //end if - //areas won't be created for solid leafs - if (node->contents & CONTENTS_SOLID) - { - //just return zero for a solid leaf (in tmp AAS NULL is a solid leaf) - return NULL; - } //end if - - return AAS_CreateArea(node); -} //end of the function AAS_CreateAreas_r -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_CreateAreas(node_t *node) -{ - Log_Write("AAS_CreateAreas\r\n"); - qprintf("%6d areas created", 0); - tmpaasworld.nodes = AAS_CreateAreas_r(node); - qprintf("\n"); - Log_Write("%6d areas created\r\n", tmpaasworld.numareas); -} //end of the function AAS_CreateAreas -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_PrintNumGroundFaces(void) -{ - tmp_face_t *tmpface; - int numgroundfaces = 0; - - for (tmpface = tmpaasworld.faces; tmpface; tmpface = tmpface->l_next) - { - if (tmpface->faceflags & FACE_GROUND) - { - numgroundfaces++; - } //end if - } //end for - qprintf("%6d ground faces\n", numgroundfaces); -} //end of the function AAS_PrintNumGroundFaces -//=========================================================================== -// checks the number of shared faces between the given two areas -// since areas are convex they should only have ONE shared face -// however due to crappy face merging there are sometimes several -// shared faces -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_CheckAreaSharedFaces(tmp_area_t *tmparea1, tmp_area_t *tmparea2) -{ - int numsharedfaces, side; - tmp_face_t *face1, *sharedface; - - if (tmparea1->invalid || tmparea2->invalid) return; - - sharedface = NULL; - numsharedfaces = 0; - for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side]) - { - side = face1->frontarea != tmparea1; - if (face1->backarea == tmparea2 || face1->frontarea == tmparea2) - { - sharedface = face1; - numsharedfaces++; - } //end if - } //end if - if (!sharedface) return; - //the areas should only have one shared face - if (numsharedfaces > 1) - { - Log_Write("---- tmp area %d and %d have %d shared faces\r\n", - tmparea1->areanum, tmparea2->areanum, numsharedfaces); - for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side]) - { - side = face1->frontarea != tmparea1; - if (face1->backarea == tmparea2 || face1->frontarea == tmparea2) - { - Log_Write("face %d, planenum = %d, face->frontarea = %d face->backarea = %d\r\n", - face1->num, face1->planenum, face1->frontarea->areanum, face1->backarea->areanum); - } //end if - } //end if - } //end if -} //end of the function AAS_CheckAreaSharedFaces -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_CheckSharedFaces(void) -{ - tmp_area_t *tmparea1, *tmparea2; - - for (tmparea1 = tmpaasworld.areas; tmparea1; tmparea1 = tmparea1->l_next) - { - for (tmparea2 = tmpaasworld.areas; tmparea2; tmparea2 = tmparea2->l_next) - { - if (tmparea1 == tmparea2) continue; - AAS_CheckAreaSharedFaces(tmparea1, tmparea2); - } //end for - } //end for -} //end of the function AAS_CheckSharedFaces -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_FlipFace(tmp_face_t *face) -{ - tmp_area_t *frontarea, *backarea; - winding_t *w; - - frontarea = face->frontarea; - backarea = face->backarea; - //must have an area at both sides before flipping is allowed - if (!frontarea || !backarea) return; - //flip the face winding - w = face->winding; - face->winding = ReverseWinding(w); - FreeWinding(w); - //flip the face plane - face->planenum ^= 1; - //flip the face areas - AAS_RemoveFaceFromArea(face, frontarea); - AAS_RemoveFaceFromArea(face, backarea); - AAS_AddFaceSideToArea(face, 1, frontarea); - AAS_AddFaceSideToArea(face, 0, backarea); -} //end of the function AAS_FlipFace -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -/* -void AAS_FlipAreaSharedFaces(tmp_area_t *tmparea1, tmp_area_t *tmparea2) -{ - int numsharedfaces, side, area1facing, area2facing; - tmp_face_t *face1, *sharedface; - - if (tmparea1->invalid || tmparea2->invalid) return; - - sharedface = NULL; - numsharedfaces = 0; - area1facing = 0; //number of shared faces facing towards area 1 - area2facing = 0; //number of shared faces facing towards area 2 - for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side]) - { - side = face1->frontarea != tmparea1; - if (face1->backarea == tmparea2 || face1->frontarea == tmparea2) - { - sharedface = face1; - numsharedfaces++; - if (face1->frontarea == tmparea1) area1facing++; - else area2facing++; - } //end if - } //end if - if (!sharedface) return; - //if there's only one shared face - if (numsharedfaces <= 1) return; - //if all the shared faces are facing to the same area - if (numsharedfaces == area1facing || numsharedfaces == area2facing) return; - // - do - { - for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side]) - { - side = face1->frontarea != tmparea1; - if (face1->backarea == tmparea2 || face1->frontarea == tmparea2) - { - if (face1->frontarea != tmparea1) - { - AAS_FlipFace(face1); - break; - } //end if - } //end if - } //end for - } while(face1); -} //end of the function AAS_FlipAreaSharedFaces -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_FlipSharedFaces(void) -{ - int i; - tmp_area_t *tmparea1, *tmparea2; - - i = 0; - qprintf("%6d areas checked for shared face flipping", i); - for (tmparea1 = tmpaasworld.areas; tmparea1; tmparea1 = tmparea1->l_next) - { - if (tmparea1->invalid) continue; - for (tmparea2 = tmpaasworld.areas; tmparea2; tmparea2 = tmparea2->l_next) - { - if (tmparea2->invalid) continue; - if (tmparea1 == tmparea2) continue; - AAS_FlipAreaSharedFaces(tmparea1, tmparea2); - } //end for - qprintf("\r%6d", ++i); - } //end for - Log_Print("\r%6d areas checked for shared face flipping\n", i); -} //end of the function AAS_FlipSharedFaces -*/ -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_FlipSharedFaces(void) -{ - int i, side1, side2; - tmp_area_t *tmparea1; - tmp_face_t *face1, *face2; - - i = 0; - qprintf("%6d areas checked for shared face flipping", i); - for (tmparea1 = tmpaasworld.areas; tmparea1; tmparea1 = tmparea1->l_next) - { - if (tmparea1->invalid) continue; - for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side1]) - { - side1 = face1->frontarea != tmparea1; - if (!face1->frontarea || !face1->backarea) continue; - // - for (face2 = face1->next[side1]; face2; face2 = face2->next[side2]) - { - side2 = face2->frontarea != tmparea1; - if (!face2->frontarea || !face2->backarea) continue; - // - if (face1->frontarea == face2->backarea && - face1->backarea == face2->frontarea) - { - AAS_FlipFace(face2); - } //end if - //recheck side - side2 = face2->frontarea != tmparea1; - } //end for - } //end for - qprintf("\r%6d", ++i); - } //end for - qprintf("\n"); - Log_Write("%6d areas checked for shared face flipping\r\n", i); -} //end of the function AAS_FlipSharedFaces -//=========================================================================== -// creates an .AAS file with the given name -// a MAP should be loaded before calling this -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_Create(char *aasfile) -{ - entity_t *e; - tree_t *tree; - double start_time; - - //for a possible leak file - strcpy(source, aasfile); - StripExtension(source); - //the time started - start_time = I_FloatTime(); - //set the default number of threads (depends on number of processors) - ThreadSetDefault(); - //set the global entity number to the world model - entity_num = 0; - //the world entity - e = &entities[entity_num]; - //process the whole world - tree = ProcessWorldBrushes(e->firstbrush, e->firstbrush + e->numbrushes); - //if the conversion is cancelled - if (cancelconversion) - { - Tree_Free(tree); - return; - } //end if - //display BSP tree creation time - Log_Print("BSP tree created in %5.0f seconds\n", I_FloatTime() - start_time); - //prune the bsp tree - Tree_PruneNodes(tree->headnode); - //if the conversion is cancelled - if (cancelconversion) - { - Tree_Free(tree); - return; - } //end if - //create the tree portals - MakeTreePortals(tree); - //if the conversion is cancelled - if (cancelconversion) - { - Tree_Free(tree); - return; - } //end if - //Marks all nodes that can be reached by entites - if (FloodEntities(tree)) - { - //fill out nodes that can't be reached - FillOutside(tree->headnode); - } //end if - else - { - LeakFile(tree); - Error("**** leaked ****\n"); - return; - } //end else - //create AAS from the BSP tree - //========================================== - //initialize tmp aas - AAS_InitTmpAAS(); - //create the convex areas from the leaves - AAS_CreateAreas(tree->headnode); - //free the BSP tree because it isn't used anymore - if (freetree) Tree_Free(tree); - //try to merge area faces - AAS_MergeAreaFaces(); - //do gravitational subdivision - AAS_GravitationalSubdivision(); - //merge faces if possible - AAS_MergeAreaFaces(); - AAS_RemoveAreaFaceColinearPoints(); - //merge areas if possible - AAS_MergeAreas(); - //NOTE: prune nodes directly after area merging - AAS_PruneNodes(); - //flip shared faces so they are all facing to the same area - AAS_FlipSharedFaces(); - AAS_RemoveAreaFaceColinearPoints(); - //merge faces if possible - AAS_MergeAreaFaces(); - //merge area faces in the same plane - AAS_MergeAreaPlaneFaces(); - //do ladder subdivision - AAS_LadderSubdivision(); - //FIXME: melting is buggy - AAS_MeltAreaFaceWindings(); - //remove tiny faces - AAS_RemoveTinyFaces(); - //create area settings - AAS_CreateAreaSettings(); - //check if the winding plane is equal to the face plane - //AAS_CheckAreaWindingPlanes(); - // - //AAS_CheckSharedFaces(); - //========================================== - //if the conversion is cancelled - if (cancelconversion) - { - Tree_Free(tree); - AAS_FreeTmpAAS(); - return; - } //end if - //store the created AAS stuff in the AAS file format and write the file - AAS_StoreFile(aasfile); - //free the temporary AAS memory - AAS_FreeTmpAAS(); - //display creation time - Log_Print("\nAAS created in %5.0f seconds\n", I_FloatTime() - start_time); -} //end of the function AAS_Create |