📄 aas_create.c
字号:
//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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -