/*
===========================================================================
Copyright (C) 2000 - 2013, Raven Software, Inc.
Copyright (C) 2001 - 2013, Activision, Inc.
Copyright (C) 2013 - 2015, OpenJK contributors
This file is part of the OpenJK source code.
OpenJK is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
This program 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 this program; if not, see .
===========================================================================
*/
////////////////////////////////////////////////////////////////////////////////////////
// RAVEN STANDARD TEMPLATE LIBRARY
// (c) 2002 Activision
//
//
// Graph Region
// ------------
//
//
////////////////////////////////////////////////////////////////////////////////////////
#if !defined(RATL_GRAPH_REGION_INC)
#define RATL_GRAPH_REGION_INC
////////////////////////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////////////////////////
#if defined(RA_DEBUG_LINKING)
#pragma message("...including graph_region.h")
#endif
#if !defined(RAGL_COMMON_INC)
#include "ragl_common.h"
#endif
#if !defined(RAGL_GRAPH_VS_INC)
#include "graph_vs.h"
#endif
namespace ragl
{
////////////////////////////////////////////////////////////////////////////////////////
// The Graph Region Class
////////////////////////////////////////////////////////////////////////////////////////
template
class graph_region : public ratl::ratl_base
{
public:
////////////////////////////////////////////////////////////////////////////////////
// Capacity Enum
////////////////////////////////////////////////////////////////////////////////////
enum
{
NULL_REGION = -1,
NULL_EDGE = -1,
CAPACITY = MAXREGIONS
};
////////////////////////////////////////////////////////////////////////////////////
// Some Public Type Defines
////////////////////////////////////////////////////////////////////////////////////
typedef ragl::graph_vs TGraph;
typedef ratl::vector_vs TRegions;
typedef ratl::vector_vs TRegionEdge; // List Of All Edges Which Connect RegionA<->RegionB
typedef ratl::pool_vs TEdges; // Pool Of All RegionEdges
typedef ratl::grid2_vs TLinks; // Graph Of Links From Region To Region, Each Points To A RegionEdge
typedef ratl::bits_vs TClosed;
////////////////////////////////////////////////////////////////////////////////////
// Constructor
////////////////////////////////////////////////////////////////////////////////////
graph_region(TGraph& Graph) : mGraph(Graph)
{
clear();
}
~graph_region()
{
}
////////////////////////////////////////////////////////////////////////////////////
// Clear Out All Temp Data So We Can Recalculate Regions
////////////////////////////////////////////////////////////////////////////////////
void clear()
{
mRegions.resize(0, (int)NULL_REGION);
mRegions.resize(MAXNODES, (int)NULL_REGION);
mRegionCount = 0;
mReservedRegionCount = 0;
mLinks.init(NULL_EDGE);
for (int i=0; i= (MAXREGIONS-1) )
{//stop adding points, we're full, you MUST increase MAXREGIONS for this to work
return NULL_REGION;
}
mReservedRegionCount ++;
mRegionCount ++;
return (mRegionCount);
}
////////////////////////////////////////////////////////////////////////////////////
// assign_region
//
// Allows a user to pre-allocate a special region for a group of points
////////////////////////////////////////////////////////////////////////////////////
void assign_region(int NodeIndex, int RegionIndex)
{
mRegions[NodeIndex] = RegionIndex;
}
////////////////////////////////////////////////////////////////////////////////////
// Define Regions
//
// Scan through all the nodes (calling the depth first recursive traversal below),
// and mark regions of nodes which can traverse to one another without needing to check
// for valid edges.
//
////////////////////////////////////////////////////////////////////////////////////
bool find_regions(const typename TGraph::user& user)
{
int CurNodeIndex;
for (typename TGraph::TNodes::iterator i=mGraph.nodes_begin(); i!=mGraph.nodes_end(); i++)
{
CurNodeIndex = i.index();
if (mRegions[CurNodeIndex] == NULL_REGION)
{
assert(mRegionCount < (MAXREGIONS-1));
if (mRegionCount >= (MAXREGIONS-1) )
{//stop adding points, we're full, you MUST increase MAXREGIONS for this to work
return false;
}
mRegionCount ++; // Allocate The New Region
assign(CurNodeIndex, user); // Assign All Points To It
}
}
mRegionCount ++; // Size is actually 1 greater than the number of regions
return true;
}
////////////////////////////////////////////////////////////////////////////////////
// Search For All Possible Edges Which Connect Regions
//
// Once called, this class will have reference data for how to get from one region
// to another.
////////////////////////////////////////////////////////////////////////////////////
bool find_region_edges()
{
int RegionA;
int RegionB;
int RegionLink;
bool Success = true;
bool ReservedRegionLink;
for (int indexA=0; indexA0);
for (int j=0; j