00001 #include <math.h>
00002 #include <assert.h>
00003
00004 #include "ControlPointContainer.h"
00005
00006
00007 using namespace VRS;
00008
00009 namespace random_racer
00010 {
00011
00012 ControlPointContainer::ControlPointContainer(
00013 unsigned int p_numControlPoints, unsigned int p_blocksize,
00014 SO<Callback1<std::vector<Vector>* > > p_genPointCallback,
00015 int p_minY, int p_maxY)
00016 {
00017 assert( p_minY < p_maxY );
00018
00019 m_callback = p_genPointCallback;
00020 m_blocksize = p_blocksize;
00021 m_numControlPoints = p_numControlPoints;
00022 m_minY = p_minY;
00023 m_maxY = p_maxY;
00024 m_absHeight = calculateAbsHeight(m_minY, m_maxY);
00025 }
00026
00027 ControlPointContainer::~ControlPointContainer()
00028 {
00029 }
00030
00031 int
00032 ControlPointContainer::mapToKey(double p_value)
00033 {
00034 return int(floor(p_value/m_blocksize));
00035 }
00036
00037 int
00038 ControlPointContainer::getOffset(int p_key)
00039 {
00040 return p_key*(int)m_blocksize;
00041 }
00042
00043 unsigned char
00044 ControlPointContainer::mapToHashMapHeight(double p_height)
00045 {
00046 return (unsigned char)(round(p_height * 254.0));
00047 }
00048
00049 double
00050 ControlPointContainer::mapHeightBack(unsigned char p_height)
00051 {
00052 if(m_calcMinus)
00053 {
00054 return ((double)p_height/254.0 * (double)m_absHeight) -
00055 (double)abs(m_minY);
00056 }
00057 else
00058 {
00059 return ((double)p_height/254.0 * (double)m_absHeight) +
00060 (double)abs(m_minY);
00061 }
00062 }
00063
00064 unsigned int
00065 ControlPointContainer::calculateAbsHeight(int p_minHeight, int p_maxHeight)
00066 {
00067 if(p_minHeight <= 0 && p_maxHeight > 0)
00068 {
00069 m_calcMinus = true;
00070 return (p_maxHeight + abs(p_minHeight));
00071 }
00072 if(p_minHeight > 0 && p_maxHeight > 0)
00073 {
00074 m_calcMinus = false;
00075 return (p_maxHeight - p_minHeight);
00076 }
00077 if(p_minHeight < 0 && p_maxHeight < 0)
00078 {
00079 m_calcMinus = true;
00080 return (p_maxHeight + abs(p_minHeight));
00081 }
00082 else
00083 return 0;
00084 }
00085
00086 void
00087 ControlPointContainer::getFourBlocks(double p_valueX, double p_valueZ,
00088 int* p_blockList)
00089 {
00090 int roundedX = (int)round(p_valueX/m_blocksize);
00091 int roundedZ = (int)round(p_valueZ/m_blocksize);
00092
00093 p_blockList[0] = roundedX;
00094 p_blockList[1] = roundedZ;
00095 p_blockList[2] = roundedX-1;
00096 p_blockList[3] = roundedZ-1;
00097 p_blockList[4] = roundedX-1;
00098 p_blockList[5] = roundedZ;
00099 p_blockList[6] = roundedX;
00100 p_blockList[7] = roundedZ-1;
00101 }
00102
00103 void
00104 ControlPointContainer::generateBlock(int p_valueX, int p_valueZ)
00105 {
00106 m_genPointCache.clear();
00107
00108 m_callback->callback(&m_genPointCache);
00109
00110 std::vector<unsigned char>* tempBlock;
00111 tempBlock = new std::vector<unsigned char>( (m_numControlPoints *
00112 m_numControlPoints), 255);
00113
00114 for( std::vector<Vector>::iterator i = m_genPointCache.begin(); i !=
00115 m_genPointCache.end(); i++)
00116 {
00117 if((*i)[0] >= 0 && (*i)[0] <= m_numControlPoints &&
00118 (*i)[1] >= 0 && (*i)[1] <= 1 &&
00119 (*i)[2] >= 0 && (*i)[2] <= m_numControlPoints)
00120 {
00121 (*tempBlock)[mapsIndex((*i)[0], (*i)[2])] =
00122 mapToHashMapHeight((*i)[1]);
00123 }
00124 }
00125
00126 (*(m_hashMap[p_valueX]))[p_valueZ] = tempBlock;
00127 }
00128
00129 unsigned int
00130 ControlPointContainer::mapsIndexBackToX(unsigned int p_index)
00131 {
00132 return unsigned(floor(p_index/m_numControlPoints));
00133 }
00134
00135 unsigned int
00136 ControlPointContainer::mapsIndexBackToZ(unsigned int p_index,
00137 unsigned int p_valueX)
00138 {
00139 return p_index - (p_valueX*m_numControlPoints);
00140 }
00141
00142 }