/* =========================================================================== 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 // // // Grid // ---- // There are two versions of the Grid class. Simply, they apply a discreet function // mapping from a n dimensional space to a linear aray. // // // // // // // NOTES: // // // //////////////////////////////////////////////////////////////////////////////////////// #if !defined(RATL_GRID_VS_INC) #define RATL_GRID_VS_INC //////////////////////////////////////////////////////////////////////////////////////// // Includes //////////////////////////////////////////////////////////////////////////////////////// #if !defined(RATL_COMMON_INC) #include "ratl_common.h" #endif #if !defined(RATL_ARRAY_VS) #include "array_vs.h" #endif namespace ratl { //////////////////////////////////////////////////////////////////////////////////////// // The 2D Grid Class //////////////////////////////////////////////////////////////////////////////////////// template class grid2_vs : public ratl_base { public: //////////////////////////////////////////////////////////////////////////////////// // Constructor //////////////////////////////////////////////////////////////////////////////////// grid2_vs() { clear(); } enum { RANGE_NULL = 12345, }; //////////////////////////////////////////////////////////////////////////////////// // Assignment Operator //////////////////////////////////////////////////////////////////////////////////// grid2_vs& operator=(const grid2_vs& other) { mData = other.mData; for (int i=0; i<2; i++) { mSize[i] = other.mSize[i]; mMins[i] = other.mMins[i]; mMaxs[i] = other.mMaxs[i]; mScale[i] = other.mScale[i]; } return (*this); } void set_size(int xSize, int ySize) { if (xSize=0 && y>=0 && x=0 && yint>=0 && xint=0 && yint>=0 && xintmMaxs[i] || mMaxs[i]==RANGE_NULL) { mMaxs[i] = point[i]; } } assert(mSize[0]>0 && mSize[1]>0); mScale[0] = ((mMaxs[0] - mMins[0])/mSize[0]); mScale[1] = ((mMaxs[1] - mMins[1])/mSize[1]); } //////////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////////// void truncate_position_to_bounds(float& xReal, float& yReal) { if (xReal(mMaxs[0]-1.0f)) { xReal = mMaxs[0]-1.0f; } if (yReal(mMaxs[1]-1.0f)) { yReal = mMaxs[1]-1.0f; } } //////////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////////// void get_cell_position(int x, int y, float& xReal, float& yReal) { // assert(mScale[0]!=0.0f && mScale[1]!=0.0f); xReal = (x * mScale[0]) + mMins[0] + (mScale[0] * 0.5f); yReal = (y * mScale[1]) + mMins[1] + (mScale[1] * 0.5f); } void get_cell_upperleft(int x, int y, float& xReal, float& yReal) { // assert(mScale[0]!=0.0f && mScale[1]!=0.0f); xReal = (x * mScale[0]) + mMins[0]; yReal = (y * mScale[1]) + mMins[1]; } void get_cell_lowerright(int x, int y, float& xReal, float& yReal) { // assert(mScale[0]!=0.0f && mScale[1]!=0.0f); xReal = (x * mScale[0]) + mMins[0] + (mScale[0]); yReal = (y * mScale[1]) + mMins[1] + (mScale[1]); } void scale_by_largest_axis(float& dist) { assert(mScale[0]!=0.0f && mScale[1]!=0.0f); if (mScale[0]>mScale[1]) { dist /= mScale[0]; } else { dist /= mScale[1]; } } //////////////////////////////////////////////////////////////////////////////////// // Data //////////////////////////////////////////////////////////////////////////////////// private: array_vs mData; int mSize[2]; float mMins[2]; float mMaxs[2]; float mScale[2]; public: //////////////////////////////////////////////////////////////////////////////////// // Raw Get - For The Iterator Dereference Function //////////////////////////////////////////////////////////////////////////////////// T& rawGet(int Loc) { assert(Loc>=0 && LocrawGet(mLoc));} // Inc Operator //-------------- void operator++(int) {mLoc++;} // Row & Col Offsets //------------------- void offsetRows(int num) {mLoc += (YSIZE_MAX*num);} void offsetCols(int num) {mLoc += (num);} // Return True If On Frist Column Of A Row //----------------------------------------- bool onColZero() { return (mLoc%XSIZE_MAX)==0; } // Evaluate The XY Position Of This Iterator //------------------------------------------- void position(int& X, int& Y) { Y = mLoc / XSIZE_MAX; X = mLoc - (Y*XSIZE_MAX); } private: int mLoc; grid2_vs* mOwner; }; //////////////////////////////////////////////////////////////////////////////////// // Iterator Begin //////////////////////////////////////////////////////////////////////////////////// iterator begin(int x=0, int y=0) { assert(x>=0 && y>=0 && x Bounds[i]) { mMaxs[i] = Bounds[i]; } mLoc[i] = mMins[i]; } } // Assignment Operator //--------------------- void operator= (const riterator &t) { mOwner = t.mOwner; for (int i=0; i<2; i++) { mMins[i] = t.mMins[i]; mMaxs[i] = t.mMaxs[i]; mLoc[i] = t.mLoc[i]; } } // Equality & Inequality Operators //--------------------------------- bool operator!=(const riterator &t) { return (mLoc[0]!=t.mLoc[0] || mLoc[1]!=t.mLoc[1]); } bool operator==(const riterator &t) { return (mLoc[0]==t.mLoc[0] && mLoc[1]==t.mLoc[1]); } // Dereference Operator //---------------------- T& operator* () { return (mOwner->get(mLoc[0], mLoc[1])); } // Inc Operator //-------------- void operator++(int) { if (mLoc[1] <= mMaxs[1]) { mLoc[0]++; if (mLoc[0]>(mMaxs[0])) { mLoc[0] = mMins[0]; mLoc[1]++; } } } bool at_end() { return (mLoc[1]>mMaxs[1]); } // Return True If On Frist Column Of A Row //----------------------------------------- bool onColZero() { return (mLoc[0]==mMins[0]); } // Evaluate The XY Position Of This Iterator //------------------------------------------- void position(int& X, int& Y) { Y = mLoc[1]; X = mLoc[0]; } private: int mMins[2]; int mMaxs[2]; int mLoc[2]; grid2_vs* mOwner; }; //////////////////////////////////////////////////////////////////////////////////// // Ranged Iterator Begin (x and y are the center of the range) //////////////////////////////////////////////////////////////////////////////////// riterator rangeBegin(int range, int x, int y) { assert(x>=0 && y>=0 && x=0 && y>=0 && x