aboutsummaryrefslogtreecommitdiffstats
path: root/code/bspc/aas_create.c
diff options
context:
space:
mode:
Diffstat (limited to 'code/bspc/aas_create.c')
-rw-r--r--code/bspc/aas_create.c1142
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