Esempio n. 1
0
//===========================================================================
//
// 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
Esempio n. 2
0
/*	Saves all of the faces in the outside list to the bsp plane list
*/
static void SaveOutside( tree_t *tree, bool mirror )
{
	int		planenum;
	face_t	*f, *next, *newf;

	for( f = outside; f; f = next ) 
	{
		next = f->next;
		numcsgfaces++;
		planenum = f->planenum;

		if( mirror ) 
		{
			newf = NewFaceFromFace( f );
			newf->planeside = f->planeside ^ 1;	// reverse side
			newf->contents[0] = f->contents[1];
			newf->contents[1] = f->contents[0];
			newf->winding = ReverseWinding( f->winding );
			tree->validfaces[planenum] = MergeFaceToList_r( newf, tree->validfaces[planenum] );
		}

		tree->validfaces[planenum] = MergeFaceToList_r( f, tree->validfaces[planenum]);
		tree->validfaces[planenum] = FreeMergeListScraps( tree->validfaces[planenum] );
	}
}
Esempio n. 3
0
/*
=============
OutputPortal
=============
*/
void OutputPortal(portal_t *p, FILE *glview)
{
	winding_t *w;
	int       sides;

	sides = PortalVisibleSides(p);
	if (!sides)
	{
		return;
	}

	c_glfaces++;

	w = p->winding;

	if (sides == 2)       // back side
	{
		w = ReverseWinding(w);
	}

	OutputWinding(w, glview);

	if (sides == 2)
	{
		FreeWinding(w);
	}
}
Esempio n. 4
0
//===========================================================================
//
// 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
Esempio n. 5
0
File: bsp.c Progetto: otty/cake3
static void DrawPortal(portal_t * p, qboolean areaportal)
{
	winding_t      *w;
	int             sides;

	sides = PortalVisibleSides(p);
	if(!sides)
		return;

	w = p->winding;

	if(sides == 2)				// back side
		w = ReverseWinding(w);

	if(areaportal)
	{
		Draw_AuxWinding(w);
	}
	else
	{
		Draw_Winding(w);
	}

	if(sides == 2)
		FreeWinding(w);
}
Esempio n. 6
0
static face_t* FaceFromPortal (portal_t* p, bool pside)
{
	face_t* f;
	side_t* side = p->side;

	/* portal does not bridge different visible contents */
	if (!side)
		return nullptr;

	/* nodraw/caulk faces */
	if (side->surfaceFlags & SURF_NODRAW)
		return nullptr;

	f = AllocFace();

	f->texinfo = side->texinfo;
	f->planenum = (side->planenum & ~1) | pside;
	f->portal = p;

	if ((p->nodes[pside]->contentFlags & CONTENTS_WINDOW)
	 && VisibleContents(p->nodes[!pside]->contentFlags ^ p->nodes[pside]->contentFlags) == CONTENTS_WINDOW)
		return nullptr;	/* don't show insides of windows */

	/* do back-clipping */
	if (!config.nobackclip && mapplanes[f->planenum].normal[2] < -0.9) {
		/* this face is not visible from birds view - optimize away
		 * but only if it's not light emitting surface */
		const entity_t* e = &entities[side->brush->entitynum];
		if (!Q_streq(ValueForKey(e, "classname"), "func_rotating")) {
			if (!(curTile->texinfo[f->texinfo].surfaceFlags & SURF_LIGHT)) {
				/* e.g. water surfaces are removed if we set the surfaceFlags
				 * to SURF_NODRAW for this side */
				/*side->surfaceFlags |= SURF_NODRAW;*/
				return nullptr;
			}
		}
	}

	if (pside) {
		f->w = ReverseWinding(p->winding);
		f->contentFlags = p->nodes[1]->contentFlags;
	} else {
		f->w = CopyWinding(p->winding);
		f->contentFlags = p->nodes[0]->contentFlags;
	}
	return f;
}
Esempio n. 7
0
/*
=============
OutputPortal
=============
*/
void OutputPortal (portal_t *p, FileHandle_t glview)
{
	winding_t	*w;
	int		sides;

	sides = PortalVisibleSides (p);
	if (!sides)
		return;

	c_glfaces++;

	w = p->winding;

	if (sides == 2)		// back side
		w = ReverseWinding (w);

	OutputWinding (w, glview);

	if (sides == 2)
		FreeWinding(w);
}
Esempio n. 8
0
//===========================================================================
// 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;

	//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
Esempio n. 9
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
int AAS_StoreArea( tmp_area_t *tmparea ) {
	int side, edgenum, i;
	plane_t *plane;
	tmp_face_t *tmpface;
	aas_area_t *aasarea;
	aas_edge_t *edge;
	aas_face_t *aasface;
	aas_faceindex_t aasfacenum;
	vec3_t facecenter;
	winding_t *w;

	//when the area is merged go to the merged area
	//FIXME: this isn't necessary anymore because the tree
	//			is refreshed after area merging
	while ( tmparea->mergedarea ) tmparea = tmparea->mergedarea;
	//
	if ( tmparea->invalid ) {
		Error( "AAS_StoreArea: tried to store invalid area" );
	}
	//if there is an aas area already stored for this tmp area
	if ( tmparea->aasareanum ) {
		return -tmparea->aasareanum;
	}
	//
	if ( ( *aasworld ).numareas >= max_aas.max_areas ) {
		Error( "AAS_MAX_AREAS = %d", max_aas.max_areas );
	} //end if
	  //area zero is a dummy
	if ( ( *aasworld ).numareas == 0 ) {
		( *aasworld ).numareas = 1;
	}
	//create an area from this leaf
	aasarea = &( *aasworld ).areas[( *aasworld ).numareas];
	aasarea->areanum = ( *aasworld ).numareas;
	aasarea->numfaces = 0;
	aasarea->firstface = ( *aasworld ).faceindexsize;
	ClearBounds( aasarea->mins, aasarea->maxs );
	VectorClear( aasarea->center );
	//
//	Log_Write("tmparea %d became aasarea %d\r\n", tmparea->areanum, aasarea->areanum);
	//store the aas area number at the tmp area
	tmparea->aasareanum = aasarea->areanum;
	//
	for ( tmpface = tmparea->tmpfaces; tmpface; tmpface = tmpface->next[side] )
	{
		side = tmpface->frontarea != tmparea;
		//if there's an aas face created for the tmp face already
		if ( tmpface->aasfacenum ) {
			//we're at the back of the face so use a negative index
			aasfacenum = -tmpface->aasfacenum;
#ifdef DEBUG
			if ( tmpface->aasfacenum < 0 || tmpface->aasfacenum > max_aas.max_faces ) {
				Error( "AAS_CreateTree_r: face number out of range" );
			} //end if
#endif //DEBUG
			aasface = &( *aasworld ).faces[tmpface->aasfacenum];
			aasface->backarea = aasarea->areanum;
		} //end if
		else
		{
			plane = &mapplanes[tmpface->planenum ^ side];
			if ( side ) {
				w = tmpface->winding;
				tmpface->winding = ReverseWinding( tmpface->winding );
			} //end if
			if ( !AAS_GetFace( tmpface->winding, plane, 0, &aasfacenum ) ) {
				continue;
			}
			if ( side ) {
				FreeWinding( tmpface->winding );
				tmpface->winding = w;
			} //end if
			aasface = &( *aasworld ).faces[aasfacenum];
			aasface->frontarea = aasarea->areanum;
			aasface->backarea = 0;
			aasface->faceflags = tmpface->faceflags;
			//set the face number at the tmp face
			tmpface->aasfacenum = aasfacenum;
		} //end else
		  //add face points to the area bounds and
		  //calculate the face 'center'
		VectorClear( facecenter );
		for ( edgenum = 0; edgenum < aasface->numedges; edgenum++ )
		{
			edge = &( *aasworld ).edges[abs( ( *aasworld ).edgeindex[aasface->firstedge + edgenum] )];
			for ( i = 0; i < 2; i++ )
			{
				AddPointToBounds( ( *aasworld ).vertexes[edge->v[i]], aasarea->mins, aasarea->maxs );
				VectorAdd( ( *aasworld ).vertexes[edge->v[i]], facecenter, facecenter );
			} //end for
		} //end for
		VectorScale( facecenter, 1.0 / ( aasface->numedges * 2.0 ), facecenter );
		//add the face 'center' to the area 'center'
		VectorAdd( aasarea->center, facecenter, aasarea->center );
		//
		if ( ( *aasworld ).faceindexsize >= max_aas.max_faceindexsize ) {
			Error( "AAS_MAX_FACEINDEXSIZE = %d", max_aas.max_faceindexsize );
		} //end if
		( *aasworld ).faceindex[( *aasworld ).faceindexsize++] = aasfacenum;
		aasarea->numfaces++;
	} //end for
	  //if the area has no faces at all (return 0, = solid leaf)
	if ( !aasarea->numfaces ) {
		return 0;
	}
	//
	VectorScale( aasarea->center, 1.0 / aasarea->numfaces, aasarea->center );
	//Log_Write("area %d center %f %f %f\r\n", (*aasworld).numareas,
	//				aasarea->center[0], aasarea->center[1], aasarea->center[2]);
	//store the area settings
	AAS_StoreAreaSettings( tmparea->settings );
	//
	//Log_Write("tmp area %d became aas area %d\r\n", tmpareanum, aasarea->areanum);
	qprintf( "\r%6d", aasarea->areanum );
	//
	if ( ( *aasworld ).areasettings[aasarea->areanum].contents & AREACONTENTS_CLUSTERPORTAL ) {
		static int num;
		Log_Write( "***** area %d is a cluster portal %d\n", aasarea->areanum, num++ );
	} //end if
	  //
	( *aasworld ).numareas++;
	return -( ( *aasworld ).numareas - 1 );
} //end of the function AAS_StoreArea
Esempio n. 10
0
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};
//	vec3_t mins, maxs;
//	qboolean allowFreeIfSmall = 1;

//	VectorClear( mins );
//	VectorClear( maxs );

	//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 | CONTENTS_MONSTERCLIP ) ) {
				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
/*
		// RF, add this face to the bounds
		if (p->tmpface->faceflags & FACE_GROUND) {
			WindingBounds( p->winding, mins, maxs );
		}

		// RF, if this face has a solid at the other side, and it is not a GROUND, then we cannot free if its too small
		if (allowFreeIfSmall && (p->tmpface->faceflags & FACE_SOLID) && !(p->tmpface->faceflags & FACE_GROUND)) {
			// make sure it's not a ceiling
			if (!(DotProduct(cfg.phys_gravitydirection, mapplanes[p->tmpface->planenum].normal) > cfg.phys_maxsteepness)) {
				allowFreeIfSmall = 0;
			}
		}
*/
	} //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_DONOTENTER_LARGE ) {
		tmparea->contents |= AREACONTENTS_DONOTENTER_LARGE;
	}
	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;
	}
/*
	// RF, if we are using only ground areas, then ignore areas that arent grounded or attached to ladders, or underwater
	if (groundonly && !(areafaceflags & (FACE_GROUND|FACE_LADDER)) && !(tmparea->contents & (AREACONTENTS_WATER|AREACONTENTS_SLIME|AREACONTENTS_LAVA))) {
		numGroundOnlyFreed++;
		tmparea->invalid = true;
	}
*/
/*
	// RF, if this is a really small area, and it is surrounded by non-solid portals, then nuke it
	if (allowFreeIfSmall && !(areafaceflags & (FACE_LADDER)) && VectorDistance( mins, maxs ) < 32) {
		numTinyFreed++;
		tmparea->invalid = true;
	}
*/
	//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