00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <geomipmap/MipMapPatchIndex.h>
00022 #include <common/DefinesAssert.h>
00023 #include <limits.h>
00024 #include <vector>
00025
00026 MipMapPatchIndex::MipMapPatchIndex() :
00027 indices_(0), size_(0), bufferOffSet_(-1),
00028 minIndex_(INT_MAX), maxIndex_(0)
00029 {
00030 }
00031
00032 MipMapPatchIndex::~MipMapPatchIndex()
00033 {
00034 delete [] indices_;
00035 }
00036
00037 void MipMapPatchIndex::generate(int size, int totalsize, int skip, unsigned int border, unsigned int totallods)
00038 {
00039
00040 unsigned int borderLeft = (border & BorderLeft) >> 0;
00041 unsigned int borderRight = (border & BorderRight) >> 3;
00042 unsigned int borderTop = (border & BorderTop) >> 6;
00043 unsigned int borderBottom= (border & BorderBottom)>> 9;
00044
00045 if (borderLeft > totallods ||
00046 borderRight > totallods ||
00047 borderTop > totallods ||
00048 borderBottom > totallods)
00049 {
00050
00051
00052 return;
00053 }
00054
00055 int borderLeftSkip = skip * (1 << borderLeft);
00056 int borderRightSkip = skip * (1 << borderRight);
00057 int borderTopSkip = skip * (1 << borderTop);
00058 int borderBottomSkip = skip * (1 << borderBottom);
00059
00060 if (border != 0 &&
00061 (borderLeftSkip > size ||
00062 borderRightSkip > size ||
00063 borderTopSkip > size ||
00064 borderBottomSkip > size))
00065 {
00066
00067
00068 return;
00069 }
00070
00071
00072
00073 std::vector<unsigned short> indices;
00074 int j=0;
00075 for (int y=0; y<size; y+=skip)
00076 {
00077 for (int x=0; x<=size; x+=skip)
00078 {
00079 int i = 0;
00080
00081
00082 bool up = (y % (2 * skip) == 0);
00083 if (up)
00084 {
00085 i = (size - x + y * (size + 1));
00086 }
00087 else
00088 {
00089 i = (x + y * (size + 1));
00090 }
00091
00092
00093 indices.push_back(i);
00094 indices.push_back(i + (size + 1) * skip);
00095
00096
00097 if (x == size && (y != (size - skip)))
00098 {
00099 indices.push_back(i + (size + 1) * skip);
00100 }
00101 }
00102 }
00103
00104
00105
00106
00107
00108 unsigned short *mappingIndices = new unsigned short[(size + 1) * (size + 1)];
00109 unsigned short *currentMappingIndex = mappingIndices;
00110 unsigned short currentMappingCount = 0;
00111 unsigned short lastGoodXTop, lastGoodXBottom, lastGoodYLeft, lastGoodYRight;
00112 for (int y=0; y<=size; y+=1)
00113 {
00114
00115 if (y % borderLeftSkip == 0) lastGoodYLeft = currentMappingCount;
00116 if (y % borderRightSkip == 0) lastGoodYRight = currentMappingCount;
00117
00118 for (int x=0; x<=size; x+=1, currentMappingIndex++, currentMappingCount++)
00119 {
00120
00121 if (x % borderTopSkip == 0) lastGoodXTop = currentMappingCount;
00122 else if (x % borderTopSkip == 1) lastGoodXTop += borderTopSkip;
00123 if (x % borderBottomSkip == 0) lastGoodXBottom = currentMappingCount;
00124
00125
00126 *currentMappingIndex = currentMappingCount;
00127
00128
00129
00130 if (((border & BorderLeft) > 0) && x == 0)
00131 {
00132 *currentMappingIndex = lastGoodYLeft;
00133 }
00134 if (((border & BorderRight) > 0) && x == size)
00135 {
00136 *currentMappingIndex = lastGoodYRight + size;
00137 }
00138 if (((border & BorderBottom) > 0) && y == 0)
00139 {
00140 *currentMappingIndex = lastGoodXBottom;
00141 }
00142 if (((border & BorderTop) > 0) && y == size)
00143 {
00144 *currentMappingIndex = lastGoodXTop;
00145 }
00146 }
00147 currentMappingCount += totalsize - size;
00148 }
00149
00150
00151 size_ = (int) indices.size();
00152 if (!indices_) indices_ = new unsigned short[size_];
00153 for (int i=0; i<size_; i++)
00154 {
00155 int j = indices[i];
00156 DIALOG_ASSERT(!(j <0 || j > (size + 1) * (size + 1)));
00157 int k = mappingIndices[j];
00158 indices_[i] = k;
00159 if (k > maxIndex_) maxIndex_ = k;
00160 else if (k < minIndex_) minIndex_ = k;
00161 }
00162 delete [] mappingIndices;
00163 }