Go to the
documentation of this file.
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #pragma once
00017
00018 #include "IParticleContainer.h"
00019 #include "..\ifnpub.h"
00020 #include "..\bitarray.h"
00021
00022 class OrbazTrueBlock;
00023
00024
00025
00026 #define PARTICLECHANNELTRUEFALSEITERATOR_INTERFACE Interface_ID(0x91cd191c, 0x1eb34500)
00027 #define GetParticleChannelTrueFalseIteratorInterface(obj) ((IParticleChannelTrueFalseIterator*)obj->GetInterface(PARTICLECHANNELTRUEFALSEITERATOR_INTERFACE))
00028
00029
00030 class IParticleChannelTrueFalseIterator : public FPMixinInterface
00031 {
00032 public:
00033
00034
00035
00036 virtual int GetFirstTrue(void) = 0;
00037
00038 virtual int GetFirstTrue(int& localIndex) = 0;
00039
00040
00041
00042 virtual int GetNextTrue(void) = 0;
00043
00044 virtual int GetNextTrue(int& localIndex) const = 0;
00045
00046
00047 virtual int GetTrueCount(void) = 0;
00048
00049 virtual int GetTrueIndex(int i) const = 0;
00050
00051
00052 virtual int GetTrueBlockCount(void) = 0;
00053
00054 virtual const OrbazTrueBlock& GetTrueBlock(int i) const = 0;
00055
00056 FPInterfaceDesc* GetDesc() { return GetDescByID(PARTICLECHANNELTRUEFALSEITERATOR_INTERFACE); }
00057 };
00058
00059 class OrbazTrueEnumerator : public BitArrayCallback
00060 {
00061 public:
00062 OrbazTrueEnumerator(int*& iterIndices)
00063 : m_iterIndices(iterIndices)
00064 , m_index(0)
00065 {
00066 }
00067
00068 void proc(int n)
00069 {
00070 m_iterIndices[m_index++] = n;
00071 }
00072 OrbazTrueEnumerator& operator=(const OrbazTrueEnumerator& rhs)
00073 {
00074 if (this != & rhs)
00075 {
00076 m_iterIndices = rhs.m_iterIndices;
00077 m_index = rhs.m_index;
00078 }
00079 return *this;
00080 }
00081 private:
00082 int*& m_iterIndices;
00083 int m_index;
00084 };
00085
00086 class OrbazTrueBlock : public MaxHeapOperators
00087 {
00088 public:
00089 OrbazTrueBlock()
00090 : m_majorIndex(0)
00091 , m_blockIndices(0)
00092 {
00093 }
00094 OrbazTrueBlock(const OrbazTrueBlock& block)
00095 : m_majorIndex(block.m_majorIndex)
00096 , m_blockIndices(block.m_blockIndices)
00097 {
00098 }
00099 OrbazTrueBlock(int majorIndex, DWORD32 blockIndices)
00100 : m_majorIndex(majorIndex)
00101 , m_blockIndices(blockIndices)
00102 {
00103 }
00104
00105 inline int GetMajorIndex(void) const { return m_majorIndex; }
00106 inline void SetMajorIndex(int index) { m_majorIndex = index; }
00107 void AddBlockIndex(int index) { m_blockIndices |= (1<<(index&kBitsPerDWORDMask)); }
00108
00109
00110 int NumberSet(void) const
00111 {
00112 static NumberBitsSetInUChar nbc;
00113 int numSet = 0;
00114 uchar* miniBlocks = (uchar*)(&m_blockIndices);
00115 for(int i=0; i<4; ++i)
00116 numSet += nbc.getNumBitsSet(miniBlocks[i]);
00117 return numSet;
00118 }
00119
00120
00121 static int SetAllTrueBlocks(int particleCount, OrbazTrueBlock*& trueBlocks)
00122 {
00123 if (trueBlocks != NULL)
00124 {
00125 delete [] trueBlocks;
00126 trueBlocks = NULL;
00127 }
00128
00129 int numTrueBlocks = particleCount>>5;
00130 bool incompleteEndBlock = (particleCount%kBitsPerDWORD != 0);
00131 int numCompleteBlocks = numTrueBlocks;
00132 if (incompleteEndBlock)
00133 ++numTrueBlocks;
00134 trueBlocks = new OrbazTrueBlock[numTrueBlocks];
00135 int i=0;
00136 for(; i<numCompleteBlocks; ++i)
00137 trueBlocks[i] = OrbazTrueBlock(i<<5, 0xFFFFFFFF);
00138 if (incompleteEndBlock)
00139 for(int j=i<<5; j<particleCount; ++j)
00140 trueBlocks[i].AddBlockIndex(j);
00141 return numTrueBlocks;
00142 }
00143
00144 static int GetMaxNumTrueBlocks(int particleCount)
00145 {
00146 int numTrueBlocks = particleCount >> 5;
00147 if (particleCount % kBitsPerDWORD != 0)
00148 ++numTrueBlocks;
00149 return numTrueBlocks;
00150 }
00151
00152 static int OptimizeMemoryUsage(int numBlocksSet, int numBlocksAllocated, OrbazTrueBlock*& trueBlocks)
00153 {
00154 if (numBlocksSet != numBlocksAllocated)
00155 {
00156 OrbazTrueBlock* temp = new OrbazTrueBlock[numBlocksSet];
00157 memcpy(temp, trueBlocks, sizeof(OrbazTrueBlock)*numBlocksSet);
00158 delete [] trueBlocks;
00159 trueBlocks = temp;
00160 }
00161 return numBlocksSet;
00162 }
00163
00164 protected:
00165 int m_majorIndex;
00166 DWORD32 m_blockIndices;
00167
00168 private:
00169 static const int kBitsPerDWORDMask = 31;
00170 static const int kBitsPerDWORD = 32;
00171
00172 class NumberBitsSetInUChar : public MaxHeapOperators
00173 {
00174 public:
00175 NumberBitsSetInUChar()
00176 {
00177 m_numBits[0] = 0;
00178 for(int i=0, j=1, index=1; i<8; ++i, j<<1)
00179 {
00180 int lowIndex = index-j;
00181 for(int k=0; k<j; ++k)
00182 {
00183 m_numBits[index++] = m_numBits[lowIndex++] + 1;
00184 }
00185 }
00186 }
00187
00188 inline uchar getNumBitsSet(uchar n)
00189 {
00190 return m_numBits[n];
00191 }
00192
00193 private:
00194 uchar m_numBits[256];
00195 };
00196 };
00197
00198 class OrbazTrueBlockIterator : public OrbazTrueBlock
00199 {
00200 public:
00201 OrbazTrueBlockIterator(const OrbazTrueBlock& block)
00202 : OrbazTrueBlock(block)
00203 , m_iter(0)
00204 , m_mask(1)
00205 {
00206 }
00207
00208
00209
00210 int GetNextTrue(void)
00211 {
00212 for(; m_iter < kBitsPerDWORD; ++m_iter, m_mask<<=1)
00213 {
00214 if (m_mask & m_blockIndices)
00215 {
00216 m_mask <<= 1;
00217 return (m_majorIndex + (m_iter++));
00218 }
00219 }
00220 return -1;
00221 }
00222
00223 static const int kBitsPerDWORD = 32;
00224
00225 private:
00226 OrbazTrueBlockIterator(void)
00227 : OrbazTrueBlock()
00228 , m_iter(0)
00229 , m_mask(1)
00230 {}
00231
00232 int m_iter;
00233 int m_mask;
00234 };
00235
00236 class OrbazTrueBlockEnumerator : public BitArrayCallback
00237 {
00238 public:
00239 OrbazTrueBlockEnumerator(OrbazTrueBlock*& trueBlocks)
00240 : m_trueBlocks(trueBlocks)
00241 , m_blockIndex(-1)
00242 {
00243 }
00244
00245 void proc(int n)
00246 {
00247 int curMajorIndex = n & kMajorIndexMask;
00248 if (m_blockIndex >= 0)
00249 {
00250 if (m_trueBlocks[m_blockIndex].GetMajorIndex() != curMajorIndex)
00251 {
00252 m_trueBlocks[++m_blockIndex].SetMajorIndex(curMajorIndex);
00253 }
00254 }
00255 else
00256 {
00257 m_blockIndex = 0;
00258 m_trueBlocks[0].SetMajorIndex(curMajorIndex);
00259 }
00260 m_trueBlocks[m_blockIndex].AddBlockIndex(n);
00261 }
00262
00263 inline int NumBlocksSet(void) { return m_blockIndex+1; }
00264 OrbazTrueBlockEnumerator& operator=(const OrbazTrueBlockEnumerator& rhs)
00265 {
00266 if (this != &rhs)
00267 {
00268 m_trueBlocks = rhs.m_trueBlocks;
00269 m_blockIndex = rhs.m_blockIndex;
00270 }
00271 return *this;
00272 }
00273 private:
00274 OrbazTrueBlock*& m_trueBlocks;
00275 int m_blockIndex;
00276 static const DWORD kMajorIndexMask = 0xFFFFFFE0;
00277 };
00278
00279