BitBucket.h
上传用户:ghyvgy
上传日期:2009-05-26
资源大小:547k
文件大小:10k
源码类别:

其他游戏

开发平台:

Python

  1. /*
  2. s_p_oneil@hotmail.com
  3. Copyright (c) 2000, Sean O'Neil
  4. All rights reserved.
  5. Redistribution and use in source and binary forms, with or without
  6. modification, are permitted provided that the following conditions are met:
  7. * Redistributions of source code must retain the above copyright notice,
  8.   this list of conditions and the following disclaimer.
  9. * Redistributions in binary form must reproduce the above copyright notice,
  10.   this list of conditions and the following disclaimer in the documentation
  11.   and/or other materials provided with the distribution.
  12. * Neither the name of this project nor the names of its contributors
  13.   may be used to endorse or promote products derived from this software
  14.   without specific prior written permission.
  15. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  19. LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  20. CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  21. SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25. POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include "Impostor.h"
  28. #define NUM_BYTES(nBits) (nBits>>3)
  29. #define NUM_WORDS(nBits) (nBits>>4)
  30. #define NUM_DWORDS(nBits) (nBits>>5)
  31. #define NUM_QWORDS(nBits) (nBits>>6)
  32. #define BIT_BYTES(nBit) (7 - (nBit & 7))
  33. #define BIT_WORDS(nBit) (15 - (nBit & 15))
  34. #define BIT_DWORDS(nBit) (31 - (nBit & 31))
  35. #define MASK_BYTES(nBit) (1 << BIT_BYTES(nBit))
  36. #define MASK_WORDS(nBit) (1 << BIT_WORDS(nBit))
  37. #define MASK_DWORDS(nBit) (1 << BIT_DWORDS(nBit))
  38. class CBitBucket
  39. {
  40. protected:
  41. unsigned long m_nBits;
  42. unsigned long *m_pBucket;
  43. public:
  44. // Constructors and copy methods
  45. CBitBucket() { m_pBucket = NULL; }
  46. CBitBucket(unsigned long nBits) { m_pBucket = NULL; Init(nBits); }
  47. CBitBucket(const CBitBucket &b) { m_pBucket = NULL; *this = b; }
  48. ~CBitBucket() { Cleanup(); }
  49. void operator=(const CBitBucket &b)
  50. {
  51. Init(b.m_nBits);
  52. for(unsigned long i=0; i<NUM_DWORDS(m_nBits); i++)
  53. m_pBucket[i] = b.m_pBucket[i];
  54. }
  55. // Init and cleanup methods
  56. void Init(unsigned long nBits)
  57. {
  58. Cleanup();
  59. m_nBits = nBits;
  60. m_pBucket = new unsigned long[NUM_DWORDS(m_nBits)];
  61. }
  62. void Cleanup()
  63. {
  64. if(m_pBucket)
  65. {
  66. delete m_pBucket;
  67. m_pBucket = NULL;
  68. }
  69. }
  70. // Direct bit access methods
  71. operator unsigned long *() { return (unsigned long *)m_pBucket; }
  72. operator unsigned short *() { return (unsigned short *)m_pBucket; }
  73. operator unsigned char *() { return (unsigned char *)m_pBucket; }
  74. bool operator[](int n) { return GetBit(n); }
  75. bool operator()(int n) { return GetBit(n); }
  76. bool GetBit(int n) { return ((unsigned long)n >= m_nBits) ? false : (m_pBucket[NUM_DWORDS(n)] & MASK_DWORDS(n)) != 0; }
  77. void SetBit(int n) { m_pBucket[NUM_DWORDS(n)] |= MASK_DWORDS(n); }
  78. void ClearBit(int n) { m_pBucket[NUM_DWORDS(n)] &= ~MASK_DWORDS(n); }
  79. void FlipBit(int n) { m_pBucket[NUM_DWORDS(n)] ^= MASK_DWORDS(n); }
  80. unsigned long GetBitCount() { return m_nBits; }
  81. unsigned long GetByteCount() { return NUM_BYTES(m_nBits); }
  82. unsigned long GetWordCount() { return NUM_WORDS(m_nBits); }
  83. unsigned long GetDWordCount() { return NUM_DWORDS(m_nBits); }
  84. // Bitwise arithmetic operators (with a fixed DWORD)
  85. CBitBucket operator&(unsigned long n)
  86. {
  87. CBitBucket bRet(m_nBits);
  88. for(unsigned long i=0; i<NUM_DWORDS(m_nBits); i++)
  89. bRet.m_pBucket[i] = m_pBucket[i] & n;
  90. return bRet;
  91. }
  92. CBitBucket operator|(unsigned long n)
  93. {
  94. CBitBucket bRet(m_nBits);
  95. for(unsigned long i=0; i<NUM_DWORDS(m_nBits); i++)
  96. bRet.m_pBucket[i] = m_pBucket[i] | n;
  97. return bRet;
  98. }
  99. CBitBucket operator^(unsigned long n)
  100. {
  101. CBitBucket bRet(m_nBits);
  102. for(unsigned long i=0; i<NUM_DWORDS(m_nBits); i++)
  103. bRet.m_pBucket[i] = m_pBucket[i] ^ n;
  104. return bRet;
  105. }
  106. void operator&=(unsigned long n)
  107. {
  108. for(unsigned long i=0; i<NUM_DWORDS(m_nBits); i++)
  109. m_pBucket[i] &= n;
  110. }
  111. void operator|=(unsigned long n)
  112. {
  113. for(unsigned long i=0; i<NUM_DWORDS(m_nBits); i++)
  114. m_pBucket[i] |= n;
  115. }
  116. void operator^=(unsigned long n)
  117. {
  118. for(unsigned long i=0; i<NUM_DWORDS(m_nBits); i++)
  119. m_pBucket[i] ^= n;
  120. }
  121. // Bitwise arithmetic operators (with a CBitBucket object)
  122. CBitBucket operator&(CBitBucket b)
  123. {
  124. CBitBucket bRet(m_nBits);
  125. for(unsigned long i=0; i<NUM_DWORDS(m_nBits); i++)
  126. bRet.m_pBucket[i] = m_pBucket[i] & b.m_pBucket[i];
  127. return bRet;
  128. }
  129. CBitBucket operator|(CBitBucket b)
  130. {
  131. CBitBucket bRet(m_nBits);
  132. for(unsigned long i=0; i<NUM_DWORDS(m_nBits); i++)
  133. bRet.m_pBucket[i] = m_pBucket[i] | b.m_pBucket[i];
  134. return bRet;
  135. }
  136. CBitBucket operator^(CBitBucket b)
  137. {
  138. CBitBucket bRet(m_nBits);
  139. for(unsigned long i=0; i<NUM_DWORDS(m_nBits); i++)
  140. bRet.m_pBucket[i] = m_pBucket[i] ^ b.m_pBucket[i];
  141. return bRet;
  142. }
  143. void operator&=(CBitBucket b)
  144. {
  145. for(unsigned long i=0; i<NUM_DWORDS(m_nBits); i++)
  146. m_pBucket[i] &= b.m_pBucket[i];
  147. }
  148. void operator|=(CBitBucket b)
  149. {
  150. for(unsigned long i=0; i<NUM_DWORDS(m_nBits); i++)
  151. m_pBucket[i] |= b.m_pBucket[i];
  152. }
  153. void operator^=(CBitBucket b)
  154. {
  155. for(unsigned long i=0; i<NUM_DWORDS(m_nBits); i++)
  156. m_pBucket[i] ^= b.m_pBucket[i];
  157. }
  158. // Shifting and rotating functions and operators (n must be between 0 and 31)
  159. CBitBucket ShiftLeft(int n, unsigned long nEdge=0)
  160. {
  161. CBitBucket bRet;
  162. int nOff = 32-n;
  163. for(unsigned long i=0; i<NUM_DWORDS(m_nBits)-1; i++)
  164. bRet.m_pBucket[i] = (m_pBucket[i]<<n) | (m_pBucket[i+1]>>nOff);
  165. bRet.m_pBucket[i] = (m_pBucket[i]<<n) | nEdge;
  166. return bRet;
  167. }
  168. CBitBucket ShiftRight(int n, unsigned long nEdge=0)
  169. {
  170. CBitBucket bRet;
  171. int nOff = 32-n;
  172. for(unsigned long i=NUM_DWORDS(m_nBits)-1; i>0; i--)
  173. bRet.m_pBucket[i] = (m_pBucket[i]>>n) | (m_pBucket[i-1]<<nOff);
  174. bRet.m_pBucket[i] = (m_pBucket[i]>>n) | nEdge;
  175. return bRet;
  176. }
  177. CBitBucket RotateLeft(int n) { return ShiftLeft(n, m_pBucket[0] >> (32-n)); }
  178. CBitBucket RotateRight(int n) { return ShiftRight(n, m_pBucket[NUM_DWORDS(m_nBits)-1] << (32-n)); }
  179. CBitBucket operator<<(int n) { return ShiftLeft(n); }
  180. CBitBucket operator>>(int n) { return ShiftRight(n); }
  181. void Fill()
  182. {
  183. for(unsigned long i=0; i < NUM_WORDS(m_nBits); i++)
  184. ((unsigned short *)m_pBucket)[i] = 0xFFFF;
  185. }
  186. };
  187. /*
  188. ** Problem!!!
  189. ** Unable to quickly shift in x, y, and z for quick bit manipulation.
  190. ** If you create classes hardcoded in dimensions of 8, 16, or 32, quick hardcoded
  191. ** shifts would be possible by shifting bits, bytes, words, or dwords.
  192. **
  193. ** For clouds, there is still going to be a problem of moving between parent cells.
  194. ** This will be a problem both for interpolating/updating cells and moving due to wind.
  195. */
  196. class C3DBitBucket : public CBitBucket
  197. {
  198. protected:
  199. unsigned long nx, ny, nz;
  200. public:
  201. // Constructors and copy methods
  202. C3DBitBucket() : CBitBucket() {}
  203. C3DBitBucket(unsigned long x, unsigned long y, unsigned long z)
  204. {
  205. Init(x, y, z);
  206. }
  207. C3DBitBucket(const C3DBitBucket &b)
  208. {
  209. *this = b;
  210. }
  211. void operator=(const C3DBitBucket &b)
  212. {
  213. nx = b.nx;
  214. ny = b.ny;
  215. nz = b.nz;
  216. CBitBucket::operator=(b);
  217. }
  218. void Init(unsigned long x, unsigned long y, unsigned long z)
  219. {
  220. nx = x;
  221. ny = y;
  222. nz = z;
  223. CBitBucket::Init(x*y*z);
  224. }
  225. bool operator()(int x, int y, int z){ return GetBit(x, y, z); }
  226. int GetBitPos(int x, int y, int z)
  227. {
  228. if((unsigned long)x >= nx || (unsigned long)y >= ny || (unsigned long)z >= nz)
  229. return -1;
  230. return ((z * ny + y) * nx) + x;
  231. }
  232. bool GetBit(int x, int y, int z) { return CBitBucket::GetBit(GetBitPos(x, y, z)); }
  233. void SetBit(int x, int y, int z) { CBitBucket::SetBit(GetBitPos(x, y, z)); }
  234. void ClearBit(int x, int y, int z) { CBitBucket::ClearBit(GetBitPos(x, y, z)); }
  235. void FlipBit(int x, int y, int z) { CBitBucket::FlipBit(GetBitPos(x, y, z)); }
  236. void NoiseFill(int nSeed)
  237. {
  238. CFractal fr(3, nSeed, 0.5f, 2.0f);
  239. srand(nSeed);
  240. for(unsigned long x=0; x < nx; x++)
  241. for(unsigned long y=0; y < ny; y++)
  242. for(unsigned long z=0; z < nz; z++)
  243. {
  244. float f[3] = {(float)x/32, (float)y/32, (float)z/16};
  245. float fNoise = fr.fBm(f, 8.0f);
  246. if(fNoise > 0.25f)
  247. SetBit(x, y, z);
  248. else
  249. ClearBit(x, y, z);
  250. }
  251. }
  252. };
  253. class CCloudCell
  254. {
  255. public:
  256. unsigned char m_cDensity, m_cBrightness;
  257. };
  258. class CCloudBlock : public CImpostor
  259. {
  260. protected:
  261. unsigned short nx, ny, nz;
  262. CCloudCell *m_pGrid;
  263. public:
  264. CCloudBlock()
  265. {
  266. m_pGrid = NULL;
  267. }
  268. void Cleanup()
  269. {
  270. if(m_pGrid)
  271. {
  272. delete m_pGrid;
  273. m_pGrid = NULL;
  274. }
  275. }
  276. void Init(unsigned short x, unsigned short y, unsigned short z)
  277. {
  278. Cleanup();
  279. nx = x;
  280. ny = y;
  281. nz = z;
  282. m_vDimension = CVector((x+3)*0.5f, (y+3)*0.5f, (z+3)*0.5f);
  283. m_pGrid = new CCloudCell[nx*ny*nz];
  284. }
  285. int GetCellPos(unsigned short x, unsigned short y, unsigned short z)
  286. {
  287. if(x >= nx || y >= ny || z >= nz)
  288. return -1;
  289. return ((z * ny + y) * nx) + x;
  290. }
  291. CCloudCell *GetCloudCell(unsigned short x, unsigned short y, unsigned short z)
  292. {
  293. int nPos = GetCellPos(x, y, z);
  294. if(nPos < 0)
  295. return NULL;
  296. return &m_pGrid[nPos];
  297. }
  298. void NoiseFill(int nSeed);
  299. void Light(CVector &vLight);
  300. void Draw(C3DObject *pCamera, float fHalfSize, bool bImpostor=false);
  301. };