//=====================================================================================
//	FreePortal
//=====================================================================================
geBoolean FreePortal(GBSP_Portal *Portal)
{
	if (!Portal->Poly)
	{
		GHook.Error("FreePortal:  Portal with NULL Poly.\n");
		return GE_FALSE;
	}

	FreePoly(Portal->Poly);

	geRam_Free(Portal);

	return GE_TRUE;
}
Exemple #2
0
//================================================================================
//	FreeAllVisData
//================================================================================
void FreeAllVisData(void)
{

	int32		i;

	if (LeafVisBits)
		geRam_Free(LeafVisBits);
	LeafVisBits = NULL;

	GFXVisData = NULL;
	NumGFXVisData = 0;

	if (VisPortals)
	{
		for (i=0; i< NumVisPortals; i++)
		{
			FreePoly(VisPortals[i].Poly);

			if (VisPortals[i].FinalVisBits)
				geRam_Free(VisPortals[i].FinalVisBits);

			if (VisPortals[i].VisBits)
				geRam_Free(VisPortals[i].VisBits);
		}

		geRam_Free(VisPortals);
	}

	if (VisSortedPortals)
		geRam_Free(VisSortedPortals);
	if (PortalSeen)
		geRam_Free(PortalSeen);
	if (VisLeafs)
		geRam_Free(VisLeafs);

	VisPortals = NULL;
	VisSortedPortals = NULL;
	PortalSeen = NULL;
	VisLeafs = NULL;

	FreeGBSPFile();		// Free rest of GBSP GFX data
}
//=====================================================================================
//	PartitionPortals_r
//=====================================================================================
geBoolean PartitionPortals_r(GBSP_Node *Node)
{
	GBSP_Poly		*NewPoly, *FPoly, *BPoly;
	GBSP_Plane		*pPlane, *pPlane2;
	GBSP_Portal		*Portal, *NewPortal, *Next;
	GBSP_Node		*Front, *Back, *OtherNode;
	int32			Side;

	CalcNodeBoundsFromPortals(Node);

	if (Node->PlaneNum == PLANENUM_LEAF)
		return GE_TRUE;

	if (VisPortals && Node->Detail)			// We can stop at detail seperators for the vis tree
		return GE_TRUE;

	//if (!InitializeNodePortal(Node))
	//	return GE_FALSE;
	//if (!DistributeNodePortalsToChildren(Node))
	//	return GE_FALSE;

	Front = Node->Children[0];
	Back = Node->Children[1];

	pPlane = &Planes[Node->PlaneNum];

	// Create a new portal
	if (!CreatePolyOnNode (Node, &NewPoly))
	{
		GHook.Error("PartitionPortals_r:  CreatePolyOnNode failed.\n");
		return GE_FALSE;
	}

	// Clip it against all other portals attached to this node
	for (Portal = Node->Portals; Portal && NewPoly; Portal = Portal->Next[Side])
	{
		if (Portal->Nodes[0] == Node)
			Side = 0;
		else if (Portal->Nodes[1] == Node)
			Side = 1;
		else
		{
			GHook.Error("PartitionPortals_r:  Portal does not look at either node.\n");
			return GE_FALSE;
		}

		pPlane2 = &Planes[Portal->PlaneNum];

		if (!ClipPolyEpsilon(NewPoly, 0.001f, pPlane2, Side, &NewPoly))
		{
			GHook.Error("PartitionPortals_r:  There was an error clipping the poly.\n");
			return GE_FALSE;
		}

		if (!NewPoly)
		{
			GHook.Printf("PartitionPortals_r:  Portal was cut away.\n");
			break;
		}
	}
	
	if (NewPoly && PolyIsTiny (NewPoly))
	{
		FreePoly(NewPoly);
		NewPoly = NULL;
	}

	if (NewPoly)
	{
		NewPortal = AllocPortal();
		if (!NewPortal)
		{
			GHook.Error("PartitionPortals_r:  Out of memory for portal.\n");
			return GE_FALSE;
		}
		NewPortal->Poly = NewPoly;
		NewPortal->PlaneNum = Node->PlaneNum;
		NewPortal->OnNode = Node;

		if (!CheckPortal(NewPortal))
		{
			GHook.Error("PartiionPortals_r:  Check Portal failed.\n");
			return GE_FALSE;
		}
		else
			AddPortalToNodes(NewPortal, Front, Back);

	}
	
	// Partition all portals by this node
	for (Portal = Node->Portals; Portal; Portal = Next)
	{
		if (Portal->Nodes[0] == Node)
			Side = 0;
		else if (Portal->Nodes[1] == Node)
			Side = 1;
		else
		{
			GHook.Error("PartitionPortals_r:  Portal does not look at either node.\n");
			return GE_FALSE;
		}

		Next = Portal->Next[Side];
		
		// Remember the node on the back side
		OtherNode = Portal->Nodes[!Side];
		RemovePortalFromNode(Portal, Portal->Nodes[0]);
		RemovePortalFromNode(Portal, Portal->Nodes[1]);

		if (!SplitPolyEpsilon(Portal->Poly, 0.001f, pPlane, &FPoly, &BPoly, GE_FALSE))
		{
			GHook.Error("PartitionPortals_r:  Could not split portal.\n");
			return GE_FALSE;
		}
		
		if (FPoly && PolyIsTiny(FPoly))
		{
			FreePoly(FPoly);
			FPoly = NULL;
		}

		if (BPoly && PolyIsTiny(BPoly))
		{
			FreePoly(BPoly);
			BPoly = NULL;
		}
		
		if (!FPoly && !BPoly)
			continue;
		
		if (!FPoly)
		{
			Portal->Poly = BPoly;
			if (Side)
				AddPortalToNodes(Portal, OtherNode, Back);
			else
				AddPortalToNodes(Portal, Back, OtherNode);
			continue;
		}

		if (!BPoly)
		{
			Portal->Poly = FPoly;
			if (Side)
				AddPortalToNodes(Portal, OtherNode, Front);
			else
				AddPortalToNodes(Portal, Front, OtherNode);
			continue;
		}

		// Portal was split
		NewPortal = AllocPortal();
		if (!NewPortal)
		{
			GHook.Error("PartitionPortals_r:  Out of memory for portal.\n");
			return GE_FALSE;
		}
		Portal->Poly = FPoly;
		*NewPortal = *Portal;
		NewPortal->Poly = BPoly;
		
		if (Side)
		{
			AddPortalToNodes(Portal, OtherNode, Front);
			AddPortalToNodes(NewPortal, OtherNode, Back);
		}
		else
		{
			AddPortalToNodes(Portal, Front, OtherNode);
			AddPortalToNodes(NewPortal, Back, OtherNode);
		}
	}

	if (Node->Portals != NULL)
	{
		GHook.Printf("*WARNING* PartitionPortals_r:  Portals still on node after distribution...\n");
	}
	
	if (!PartitionPortals_r(Front))
		return GE_FALSE;

	if (!PartitionPortals_r(Back))
		return GE_FALSE;

	return GE_TRUE;
}
Exemple #4
0
//=======================================================================================
//	LoadPortalFile
//=======================================================================================
geBoolean LoadPortalFile(char *FileName)
{
	int32		LeafFrom, LeafTo;
	VIS_Portal	*pPortal;
	VIS_Leaf	*pLeaf;
	GBSP_Poly	*pPoly;
	int32		i, NumVerts;
	char		TAG[13];
	geVFile		*f;

	pPoly = NULL;

	// open the file
	f = geVFile_OpenNewSystem(NULL, GE_VFILE_TYPE_DOS, FileName, NULL, GE_VFILE_OPEN_READONLY);

	if (!f)		// opps
	{
		GHook.Error("LoadPortalFile:  Could not open %s for reading.\n", FileName);
		goto ExitWithError;
	}
	
	// 
	//	Check the TAG
	//
	if (geVFile_Read(f, TAG, sizeof(char) * 12) != GE_TRUE)
	{
		GHook.Error("LoadPortalFile:  Error reading portal file TAG.\n");
		goto ExitWithError;
	}

	if (strncmp(TAG, "GBSP_PRTFILE", 12))
	{
		GHook.Error("LoadPortalFile:  %s is not a GBSP Portal file.\n", FileName);
		goto ExitWithError;
	}

	//
	//	Get the number of portals
	//
	if (geVFile_Read(f, &NumVisPortals, sizeof(int32)) != GE_TRUE)
	{
		GHook.Error("LoadPortalFile:  Error reading NumVisPortals.\n");
		goto ExitWithError;
	}

	if (NumVisPortals >= MAX_TEMP_PORTALS)
	{
		GHook.Error("LoadPortalFile:  Max portals for temp buffers.\n");
		goto ExitWithError;
	}
	
	VisPortals = GE_RAM_ALLOCATE_ARRAY(VIS_Portal,NumVisPortals);
	
	if (!VisPortals)
	{
		GHook.Error("LoadPortalFile:  Out of memory for VisPortals.\n");
		goto ExitWithError;
	}
	
	memset(VisPortals, 0, sizeof(VIS_Portal)*NumVisPortals);

	VisSortedPortals = GE_RAM_ALLOCATE_ARRAY(pVIS_Portal,NumVisPortals);
	
	if (!VisSortedPortals)
	{
		GHook.Error("LoadPortalFile:  Out of memory for VisSortedPortals.\n");
		goto ExitWithError;
	}

	//
	//	Get the number of leafs
	//
	if (geVFile_Read(f, &NumVisLeafs, sizeof(int32)) != GE_TRUE)
	{
		GHook.Error("LoadPortalFile:  Error reading NumVisLeafs.\n");
		goto ExitWithError;
	}

	if (NumVisLeafs > NumGFXLeafs)
		goto ExitWithError;
	
	VisLeafs = GE_RAM_ALLOCATE_ARRAY(VIS_Leaf,NumVisLeafs);
	if (!VisLeafs)
	{
		GHook.Error("LoadPortalFile:  Out of memory for VisLeafs.\n");
		goto ExitWithError;
	}

	memset(VisLeafs, 0, sizeof(VIS_Leaf)*NumVisLeafs);
	
	//
	//	Load in the portals
	//
	for (i=0; i< NumVisPortals; i++)
	{
		if (geVFile_Read(f, &NumVerts, sizeof(int32)) != GE_TRUE)
		{
			GHook.Error("LoadPortalFile:  Error reading NumVerts.\n");
			goto ExitWithError;
		}

		pPoly = AllocPoly(NumVerts);

		if (!pPoly)
			goto ExitWithError;

		if (geVFile_Read(f, pPoly->Verts, sizeof(geVec3d) * NumVerts) != GE_TRUE)
		{
			GHook.Error("LoadPortalFile:  Error reading portal vertices.\n");
			goto ExitWithError;
		}
		
		if (geVFile_Read(f, &LeafFrom, sizeof(int32)) != GE_TRUE)
		{
			GHook.Error("LoadPortalFile:  Error reading portal LeafFrom.\n");
			goto ExitWithError;
		}
		
		if (geVFile_Read(f, &LeafTo, sizeof(int32)) != GE_TRUE)
		{
			GHook.Error("LoadPortalFile:  Error reading portal LeafTo.\n");
			goto ExitWithError;
		}

		if (LeafFrom >= NumVisLeafs || LeafFrom < 0)
		{
			GHook.Error("LoadPortalFile:  Invalid LeafFrom: %i.\n", LeafFrom);
			goto ExitWithError;
		}

		if (LeafTo >= NumVisLeafs || LeafTo < 0)
		{
			GHook.Error("LoadPortalFile:  Invalid LeafTo: %i.\n", LeafTo);
			goto ExitWithError;
		}

		pLeaf = &VisLeafs[LeafFrom];
		pPortal = &VisPortals[i];

		pPortal->Poly = pPoly;
		pPortal->Leaf = LeafTo;
		PlaneFromVerts(pPoly->Verts, &pPortal->Plane);
		
		pPortal->Next = pLeaf->Portals;
		pLeaf->Portals = pPortal;

		CalcPortalInfo(pPortal);
	}
	
	NumVisLeafBytes = ((NumVisLeafs+63)&~63) >> 3;
	NumVisPortalBytes = ((NumVisPortals+63)&~63) >> 3;

	NumVisPortalLongs = NumVisPortalBytes/sizeof(uint32);
	NumVisLeafLongs = NumVisLeafBytes/sizeof(uint32);

	geVFile_Close(f);

	return GE_TRUE;

	// ==== ERROR ===
	ExitWithError:
	{
		if (f)
			geVFile_Close(f);

		if (VisPortals)
			geRam_Free(VisPortals);
		if (VisSortedPortals)
			geRam_Free(VisSortedPortals);
		if (VisLeafs)
			geRam_Free(VisLeafs);

		if (pPoly)
			FreePoly(pPoly);

		VisPortals = NULL;
		VisSortedPortals = NULL;
		VisLeafs = NULL;
		pPoly = NULL;

		return GE_FALSE;
	}
}