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