/* =========================================================================== 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