surfaces.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. #include "bsp5.h"
  2. // SubdivideFace
  3. // InitHash
  4. // HashVec
  5. // GetVertex
  6. // GetEdge
  7. // MakeFaceEdges
  8. static int subdivides;
  9. /* a surface has all of the faces that could be drawn on a given plane
  10. the outside filling stage can remove some of them so a better bsp can be generated */
  11. // =====================================================================================
  12. // SubdivideFace
  13. // If the face is >256 in either texture direction, carve a valid sized
  14. // piece off and insert the remainder in the next link
  15. // =====================================================================================
  16. void SubdivideFace(face_t* f, face_t** prevptr)
  17. {
  18. vec_t mins, maxs;
  19. vec_t v;
  20. int axis;
  21. int i;
  22. dplane_t plane;
  23. face_t* front;
  24. face_t* back;
  25. face_t* next;
  26. texinfo_t* tex;
  27. vec3_t temp;
  28. // special (non-surface cached) faces don't need subdivision
  29. tex = &g_texinfo[f->texturenum];
  30. if (tex->flags & TEX_SPECIAL)
  31. {
  32. return;
  33. }
  34. if (f->facestyle == face_hint)
  35. {
  36. return;
  37. }
  38. if (f->facestyle == face_skip)
  39. {
  40. return;
  41. }
  42. #ifdef ZHLT_NULLTEX // AJM
  43. if (f->facestyle == face_null)
  44. return; // ideally these should have their tex_special flag set, so its here jic
  45. #endif
  46. //SILENCER: Not yet implemented - just altered copypasta here
  47. /*if (f->facestyle == face_blocklight)
  48. return;*/
  49. for (axis = 0; axis < 2; axis++)
  50. {
  51. while (1)
  52. {
  53. mins = 999999;
  54. maxs = -999999;
  55. for (i = 0; i < f->numpoints; i++)
  56. {
  57. v = DotProduct(f->pts[i], tex->vecs[axis]);
  58. if (v < mins)
  59. {
  60. mins = v;
  61. }
  62. if (v > maxs)
  63. {
  64. maxs = v;
  65. }
  66. }
  67. if ((maxs - mins) <= g_subdivide_size)
  68. {
  69. break;
  70. }
  71. // split it
  72. subdivides++;
  73. VectorCopy(tex->vecs[axis], temp);
  74. v = VectorNormalize(temp);
  75. VectorCopy(temp, plane.normal);
  76. plane.dist = (mins + g_subdivide_size - 16) / v;
  77. next = f->next;
  78. SplitFace(f, &plane, &front, &back);
  79. if (!front || !back)
  80. {
  81. Developer(DEVELOPER_LEVEL_SPAM, "SubdivideFace: didn't split the %d-sided polygon @(%.0f,%.0f,%.0f)",
  82. f->numpoints, f->pts[0][0], f->pts[0][1], f->pts[0][2]);
  83. break;
  84. }
  85. *prevptr = back;
  86. back->next = front;
  87. front->next = next;
  88. f = back;
  89. }
  90. }
  91. }
  92. //===========================================================================
  93. typedef struct hashvert_s
  94. {
  95. struct hashvert_s* next;
  96. vec3_t point;
  97. int num;
  98. int numplanes; // for corner determination
  99. int planenums[2];
  100. int numedges;
  101. }
  102. hashvert_t;
  103. // #define POINT_EPSILON 0.01
  104. #define POINT_EPSILON ON_EPSILON
  105. static hashvert_t hvertex[MAX_MAP_VERTS];
  106. static hashvert_t* hvert_p;
  107. static face_t* edgefaces[MAX_MAP_EDGES][2];
  108. static int firstmodeledge = 1;
  109. static int firstmodelface;
  110. //============================================================================
  111. #define NUM_HASH 4096
  112. static hashvert_t* hashverts[NUM_HASH];
  113. static vec3_t hash_min;
  114. static vec3_t hash_scale;
  115. // =====================================================================================
  116. // InitHash
  117. // =====================================================================================
  118. static void InitHash()
  119. {
  120. vec3_t size;
  121. vec_t volume;
  122. vec_t scale;
  123. int newsize[2];
  124. int i;
  125. memset(hashverts, 0, sizeof(hashverts));
  126. for (i = 0; i < 3; i++)
  127. {
  128. hash_min[i] = -8000;
  129. size[i] = 16000;
  130. }
  131. volume = size[0] * size[1];
  132. scale = sqrt(volume / NUM_HASH);
  133. newsize[0] = size[0] / scale;
  134. newsize[1] = size[1] / scale;
  135. hash_scale[0] = newsize[0] / size[0];
  136. hash_scale[1] = newsize[1] / size[1];
  137. hash_scale[2] = newsize[1];
  138. hvert_p = hvertex;
  139. }
  140. // =====================================================================================
  141. // HashVec
  142. // =====================================================================================
  143. static unsigned HashVec(const vec3_t vec)
  144. {
  145. unsigned h;
  146. h = hash_scale[0] * (vec[0] - hash_min[0]) * hash_scale[2] + hash_scale[1] * (vec[1] - hash_min[1]);
  147. if (h >= NUM_HASH)
  148. {
  149. return NUM_HASH - 1;
  150. }
  151. return h;
  152. }
  153. // =====================================================================================
  154. // GetVertex
  155. // =====================================================================================
  156. static int GetVertex(const vec3_t in, const int planenum)
  157. {
  158. int h;
  159. int i;
  160. hashvert_t* hv;
  161. vec3_t vert;
  162. for (i = 0; i < 3; i++)
  163. {
  164. if (fabs(in[i] - VectorRound(in[i])) < 0.001)
  165. {
  166. vert[i] = VectorRound(in[i]);
  167. }
  168. else
  169. {
  170. vert[i] = in[i];
  171. }
  172. }
  173. h = HashVec(vert);
  174. for (hv = hashverts[h]; hv; hv = hv->next)
  175. {
  176. if (fabs(hv->point[0] - vert[0]) < POINT_EPSILON
  177. && fabs(hv->point[1] - vert[1]) < POINT_EPSILON && fabs(hv->point[2] - vert[2]) < POINT_EPSILON)
  178. {
  179. hv->numedges++;
  180. if (hv->numplanes == 3)
  181. {
  182. return hv->num; // allready known to be a corner
  183. }
  184. for (i = 0; i < hv->numplanes; i++)
  185. {
  186. if (hv->planenums[i] == planenum)
  187. {
  188. return hv->num; // allready know this plane
  189. }
  190. }
  191. if (hv->numplanes != 2)
  192. {
  193. hv->planenums[hv->numplanes] = planenum;
  194. }
  195. hv->numplanes++;
  196. return hv->num;
  197. }
  198. }
  199. hv = hvert_p;
  200. hv->numedges = 1;
  201. hv->numplanes = 1;
  202. hv->planenums[0] = planenum;
  203. hv->next = hashverts[h];
  204. hashverts[h] = hv;
  205. VectorCopy(vert, hv->point);
  206. hv->num = g_numvertexes;
  207. hlassume(hv->num != MAX_MAP_VERTS, assume_MAX_MAP_VERTS);
  208. hvert_p++;
  209. // emit a vertex
  210. hlassume(g_numvertexes < MAX_MAP_VERTS, assume_MAX_MAP_VERTS);
  211. g_dvertexes[g_numvertexes].point[0] = vert[0];
  212. g_dvertexes[g_numvertexes].point[1] = vert[1];
  213. g_dvertexes[g_numvertexes].point[2] = vert[2];
  214. g_numvertexes++;
  215. return hv->num;
  216. }
  217. //===========================================================================
  218. // =====================================================================================
  219. // GetEdge
  220. // Don't allow four way edges
  221. // =====================================================================================
  222. int GetEdge(const vec3_t p1, const vec3_t p2, face_t* f)
  223. {
  224. int v1;
  225. int v2;
  226. dedge_t* edge;
  227. int i;
  228. hlassert(f->contents);
  229. v1 = GetVertex(p1, f->planenum);
  230. v2 = GetVertex(p2, f->planenum);
  231. for (i = firstmodeledge; i < g_numedges; i++)
  232. {
  233. edge = &g_dedges[i];
  234. if (v1 == edge->v[1] && v2 == edge->v[0] && !edgefaces[i][1] && edgefaces[i][0]->contents == f->contents)
  235. {
  236. edgefaces[i][1] = f;
  237. return -i;
  238. }
  239. }
  240. // emit an edge
  241. hlassume(g_numedges < MAX_MAP_EDGES, assume_MAX_MAP_EDGES);
  242. edge = &g_dedges[g_numedges];
  243. g_numedges++;
  244. edge->v[0] = v1;
  245. edge->v[1] = v2;
  246. edgefaces[i][0] = f;
  247. return i;
  248. }
  249. // =====================================================================================
  250. // MakeFaceEdges
  251. // =====================================================================================
  252. void MakeFaceEdges()
  253. {
  254. InitHash();
  255. firstmodeledge = g_numedges;
  256. firstmodelface = g_numfaces;
  257. }