CCGSubSurf_inline.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * ***** BEGIN GPL LICENSE BLOCK *****
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software Foundation,
  16. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. *
  18. * ***** END GPL LICENSE BLOCK *****
  19. */
  20. /** \file blender/blenkernel/intern/CCGSubSurf_inline.h
  21. * \ingroup bke
  22. */
  23. #ifndef __CCGSUBSURF_INLINE_H__
  24. #define __CCGSUBSURF_INLINE_H__
  25. BLI_INLINE int ccg_gridsize(int level)
  26. {
  27. BLI_assert(level > 0);
  28. BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1);
  29. return (1 << (level - 1)) + 1;
  30. }
  31. BLI_INLINE int ccg_edgesize(int level)
  32. {
  33. BLI_assert(level > 0);
  34. BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1);
  35. return 1 + (1 << level);
  36. }
  37. BLI_INLINE int ccg_spacing(int high_level, int low_level)
  38. {
  39. BLI_assert(high_level > 0 && low_level > 0);
  40. BLI_assert(high_level >= low_level);
  41. BLI_assert((high_level - low_level) <= CCGSUBSURF_LEVEL_MAX);
  42. return 1 << (high_level - low_level);
  43. }
  44. BLI_INLINE int ccg_edgebase(int level)
  45. {
  46. BLI_assert(level > 0);
  47. BLI_assert(level <= CCGSUBSURF_LEVEL_MAX + 1);
  48. return level + (1 << level) - 1;
  49. }
  50. /* **** */
  51. BLI_INLINE byte *VERT_getLevelData(CCGVert *v)
  52. {
  53. return (byte *)(&(v)[1]);
  54. }
  55. BLI_INLINE byte *EDGE_getLevelData(CCGEdge *e)
  56. {
  57. return (byte *)(&(e)[1]);
  58. }
  59. BLI_INLINE CCGVert **FACE_getVerts(CCGFace *f)
  60. {
  61. return (CCGVert **)(&f[1]);
  62. }
  63. BLI_INLINE CCGEdge **FACE_getEdges(CCGFace *f)
  64. {
  65. return (CCGEdge **)(&(FACE_getVerts(f)[f->numVerts]));
  66. }
  67. BLI_INLINE byte *FACE_getCenterData(CCGFace *f)
  68. {
  69. return (byte *)(&(FACE_getEdges(f)[(f)->numVerts]));
  70. }
  71. /* **** */
  72. BLI_INLINE void *ccg_vert_getCo(CCGVert *v, int lvl, int dataSize)
  73. {
  74. return &VERT_getLevelData(v)[lvl * dataSize];
  75. }
  76. BLI_INLINE float *ccg_vert_getNo(CCGVert *v,
  77. int lvl,
  78. int dataSize,
  79. int normalDataOffset)
  80. {
  81. return (float *) &VERT_getLevelData(v)[lvl * dataSize + normalDataOffset];
  82. }
  83. BLI_INLINE void *ccg_edge_getCo(CCGEdge *e, int lvl, int x, int dataSize)
  84. {
  85. int levelBase = ccg_edgebase(lvl);
  86. return &EDGE_getLevelData(e)[dataSize * (levelBase + x)];
  87. }
  88. BLI_INLINE float *ccg_edge_getNo(CCGEdge *e,
  89. int lvl,
  90. int x,
  91. int dataSize,
  92. int normalDataOffset)
  93. {
  94. int levelBase = ccg_edgebase(lvl);
  95. return (float *) &EDGE_getLevelData(e)[dataSize * (levelBase + x) + normalDataOffset];
  96. }
  97. BLI_INLINE void *ccg_face_getIECo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize)
  98. {
  99. int maxGridSize = ccg_gridsize(levels);
  100. int spacing = ccg_spacing(levels, lvl);
  101. byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
  102. return &gridBase[dataSize * x * spacing];
  103. }
  104. BLI_INLINE void *ccg_face_getIENo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize, int normalDataOffset)
  105. {
  106. int maxGridSize = ccg_gridsize(levels);
  107. int spacing = ccg_spacing(levels, lvl);
  108. byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
  109. return &gridBase[dataSize * x * spacing + normalDataOffset];
  110. }
  111. BLI_INLINE void *ccg_face_getIFCo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize)
  112. {
  113. int maxGridSize = ccg_gridsize(levels);
  114. int spacing = ccg_spacing(levels, lvl);
  115. byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
  116. return &gridBase[dataSize * (maxGridSize + (y * maxGridSize + x) * spacing)];
  117. }
  118. BLI_INLINE float *ccg_face_getIFNo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset)
  119. {
  120. int maxGridSize = ccg_gridsize(levels);
  121. int spacing = ccg_spacing(levels, lvl);
  122. byte *gridBase = FACE_getCenterData(f) + dataSize * (1 + S * (maxGridSize + maxGridSize * maxGridSize));
  123. return (float *) &gridBase[dataSize * (maxGridSize + (y * maxGridSize + x) * spacing) + normalDataOffset];
  124. }
  125. BLI_INLINE int ccg_face_getVertIndex(CCGFace *f, CCGVert *v)
  126. {
  127. int i;
  128. for (i = 0; i < f->numVerts; i++)
  129. if (FACE_getVerts(f)[i] == v)
  130. return i;
  131. return -1;
  132. }
  133. BLI_INLINE int ccg_face_getEdgeIndex(CCGFace *f, CCGEdge *e)
  134. {
  135. int i;
  136. for (i = 0; i < f->numVerts; i++)
  137. if (FACE_getEdges(f)[i] == e)
  138. return i;
  139. return -1;
  140. }
  141. BLI_INLINE void *ccg_face_getIFCoEdge(CCGFace *f, CCGEdge *e, int f_ed_idx, int lvl, int eX, int eY, int levels, int dataSize)
  142. {
  143. int maxGridSize = ccg_gridsize(levels);
  144. int spacing = ccg_spacing(levels, lvl);
  145. int x, y, cx, cy;
  146. BLI_assert(f_ed_idx == ccg_face_getEdgeIndex(f, e));
  147. eX = eX * spacing;
  148. eY = eY * spacing;
  149. if (e->v0 != FACE_getVerts(f)[f_ed_idx]) {
  150. eX = (maxGridSize * 2 - 1) - 1 - eX;
  151. }
  152. y = maxGridSize - 1 - eX;
  153. x = maxGridSize - 1 - eY;
  154. if (x < 0) {
  155. f_ed_idx = (f_ed_idx + f->numVerts - 1) % f->numVerts;
  156. cx = y;
  157. cy = -x;
  158. }
  159. else if (y < 0) {
  160. f_ed_idx = (f_ed_idx + 1) % f->numVerts;
  161. cx = -y;
  162. cy = x;
  163. }
  164. else {
  165. cx = x;
  166. cy = y;
  167. }
  168. return ccg_face_getIFCo(f, levels, f_ed_idx, cx, cy, levels, dataSize);
  169. }
  170. BLI_INLINE void Normalize(float no[3])
  171. {
  172. const float length = sqrtf(no[0] * no[0] + no[1] * no[1] + no[2] * no[2]);
  173. if (length > EPSILON) {
  174. const float length_inv = 1.0f / length;
  175. no[0] *= length_inv;
  176. no[1] *= length_inv;
  177. no[2] *= length_inv;
  178. }
  179. else {
  180. NormZero(no);
  181. }
  182. }
  183. /* Data layers mathematics. */
  184. BLI_INLINE int VertDataEqual(const float a[], const float b[], const CCGSubSurf *ss)
  185. {
  186. int i;
  187. for (i = 0; i < ss->meshIFC.numLayers; i++) {
  188. if (a[i] != b[i])
  189. return 0;
  190. }
  191. return 1;
  192. }
  193. BLI_INLINE void VertDataZero(float v[], const CCGSubSurf *ss)
  194. {
  195. memset(v, 0, sizeof(float) * ss->meshIFC.numLayers);
  196. }
  197. BLI_INLINE void VertDataCopy(float dst[], const float src[], const CCGSubSurf *ss)
  198. {
  199. int i;
  200. for (i = 0; i < ss->meshIFC.numLayers; i++)
  201. dst[i] = src[i];
  202. }
  203. BLI_INLINE void VertDataAdd(float a[], const float b[], const CCGSubSurf *ss)
  204. {
  205. int i;
  206. for (i = 0; i < ss->meshIFC.numLayers; i++)
  207. a[i] += b[i];
  208. }
  209. BLI_INLINE void VertDataSub(float a[], const float b[], const CCGSubSurf *ss)
  210. {
  211. int i;
  212. for (i = 0; i < ss->meshIFC.numLayers; i++)
  213. a[i] -= b[i];
  214. }
  215. BLI_INLINE void VertDataMulN(float v[], float f, const CCGSubSurf *ss)
  216. {
  217. int i;
  218. for (i = 0; i < ss->meshIFC.numLayers; i++)
  219. v[i] *= f;
  220. }
  221. BLI_INLINE void VertDataAvg4(float v[],
  222. const float a[], const float b[],
  223. const float c[], const float d[],
  224. const CCGSubSurf *ss)
  225. {
  226. int i;
  227. for (i = 0; i < ss->meshIFC.numLayers; i++)
  228. v[i] = (a[i] + b[i] + c[i] + d[i]) * 0.25f;
  229. }
  230. #endif /* __CCGSUBSURF_INLINE_H__ */