vismatrix.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. #include "qrad.h"
  2. ////////////////////////////
  3. // begin old vismat.c
  4. //
  5. #define HALFBIT
  6. // =====================================================================================
  7. //
  8. // VISIBILITY MATRIX
  9. // Determine which patches can see each other
  10. // Use the PVS to accelerate if available
  11. //
  12. // =====================================================================================
  13. static byte* s_vismatrix;
  14. #ifdef HLRAD_HULLU
  15. // =====================================================================================
  16. // OPACITY ARRAY
  17. // =====================================================================================
  18. typedef struct {
  19. unsigned bitpos;
  20. vec3_t transparency;
  21. } transparency_t;
  22. static transparency_t *s_transparency_list = NULL;
  23. static unsigned long s_transparency_count = 0;
  24. static unsigned long s_max_transparency_count=0;
  25. static void FindOpacity(const unsigned bitpos, vec3_t &out)
  26. {
  27. for(unsigned long i = 0; i < s_transparency_count; i++)
  28. {
  29. if( s_transparency_list[i].bitpos == bitpos )
  30. {
  31. VectorCopy(s_transparency_list[i].transparency, out);
  32. return;
  33. }
  34. }
  35. VectorFill(out, 1.0);
  36. }
  37. #endif /*HLRAD_HULLU*/
  38. // =====================================================================================
  39. // TestPatchToFace
  40. // Sets vis bits for all patches in the face
  41. // =====================================================================================
  42. static void TestPatchToFace(const unsigned patchnum, const int facenum, const int head, const unsigned int bitpos)
  43. {
  44. patch_t* patch = &g_patches[patchnum];
  45. patch_t* patch2 = g_face_patches[facenum];
  46. #ifdef HLRAD_HULLU
  47. vec3_t transparency;
  48. #endif
  49. // if emitter is behind that face plane, skip all patches
  50. if (patch2)
  51. {
  52. const dplane_t* plane2 = getPlaneFromFaceNumber(facenum);
  53. if (DotProduct(patch->origin, plane2->normal) > (PatchPlaneDist(patch2) + MINIMUM_PATCH_DISTANCE))
  54. {
  55. // we need to do a real test
  56. const dplane_t* plane = getPlaneFromFaceNumber(patch->faceNumber);
  57. for (; patch2; patch2 = patch2->next)
  58. {
  59. unsigned m = patch2 - g_patches;
  60. // check vis between patch and patch2
  61. // if bit has not already been set
  62. // && v2 is not behind light plane
  63. // && v2 is visible from v1
  64. #ifdef HLRAD_HULLU
  65. //removed reset of transparency - TestSegmentAgainstOpaqueList already resets to 1,1,1
  66. int facenum = TestSegmentAgainstOpaqueList(patch->origin, patch2->origin, transparency);
  67. #else
  68. int facenum = TestSegmentAgainstOpaqueList(patch->origin, patch2->origin);
  69. #endif
  70. if (m > patchnum
  71. && (facenum < 0 || facenum == patch2->faceNumber)
  72. && (DotProduct(patch2->origin, plane->normal) > (PatchPlaneDist(patch) + MINIMUM_PATCH_DISTANCE))
  73. && (TestLine_r(0, patch->origin, patch2->origin) == CONTENTS_EMPTY))
  74. {
  75. //Log("SDF::3\n");
  76. // patchnum can see patch m
  77. unsigned bitset = bitpos + m;
  78. #ifdef HLRAD_HULLU
  79. // transparency face fix table
  80. // TODO: this method makes MakeScale extreamly slow.. find new one
  81. if(g_customshadow_with_bouncelight && VectorCompare(transparency, vec3_one))
  82. {
  83. AddTransparencyToRawArray(patchnum, m, transparency);
  84. }
  85. #endif /*HLRAD_HULLU*/
  86. s_vismatrix[bitset >> 3] |= 1 << (bitset & 7);
  87. }
  88. }
  89. }
  90. }
  91. }
  92. // =====================================================================================
  93. // BuildVisRow
  94. // Calc vis bits from a single patch
  95. // =====================================================================================
  96. static void BuildVisRow(const int patchnum, byte* pvs, const int head, const unsigned int bitpos)
  97. {
  98. int j, k, l;
  99. byte face_tested[MAX_MAP_FACES];
  100. dleaf_t* leaf;
  101. memset(face_tested, 0, g_numfaces);
  102. // leaf 0 is the solid leaf (skipped)
  103. for (j = 1, leaf = g_dleafs + 1; j < g_numleafs; j++, leaf++)
  104. {
  105. if (!(pvs[(j - 1) >> 3] & (1 << ((j - 1) & 7))))
  106. continue; // not in pvs
  107. for (k = 0; k < leaf->nummarksurfaces; k++)
  108. {
  109. l = g_dmarksurfaces[leaf->firstmarksurface + k];
  110. // faces can be marksurfed by multiple leaves, but
  111. // don't bother testing again
  112. if (face_tested[l])
  113. continue;
  114. face_tested[l] = 1;
  115. TestPatchToFace(patchnum, l, head, bitpos);
  116. }
  117. }
  118. }
  119. // =====================================================================================
  120. // BuildVisLeafs
  121. // This is run by multiple threads
  122. // =====================================================================================
  123. #ifdef SYSTEM_WIN32
  124. #pragma warning(push)
  125. #pragma warning(disable:4100) // unreferenced formal parameter
  126. #endif
  127. static void BuildVisLeafs(int threadnum)
  128. {
  129. int i;
  130. int lface, facenum, facenum2;
  131. byte pvs[(MAX_MAP_LEAFS + 7) / 8];
  132. dleaf_t* srcleaf;
  133. dleaf_t* leaf;
  134. patch_t* patch;
  135. int head;
  136. unsigned bitpos;
  137. unsigned patchnum;
  138. while (1)
  139. {
  140. //
  141. // build a minimal BSP tree that only
  142. // covers areas relevent to the PVS
  143. //
  144. i = GetThreadWork();
  145. if (i == -1)
  146. break;
  147. i++; // skip leaf 0
  148. srcleaf = &g_dleafs[i];
  149. DecompressVis(&g_dvisdata[srcleaf->visofs], pvs, sizeof(pvs));
  150. head = 0;
  151. //
  152. // go through all the faces inside the
  153. // leaf, and process the patches that
  154. // actually have origins inside
  155. //
  156. for (lface = 0; lface < srcleaf->nummarksurfaces; lface++)
  157. {
  158. facenum = g_dmarksurfaces[srcleaf->firstmarksurface + lface];
  159. for (patch = g_face_patches[facenum]; patch; patch = patch->next)
  160. {
  161. leaf = PointInLeaf(patch->origin);
  162. if (leaf != srcleaf)
  163. continue;
  164. patchnum = patch - g_patches;
  165. #ifdef HALFBIT
  166. bitpos = patchnum * g_num_patches - (patchnum * (patchnum + 1)) / 2;
  167. #else
  168. bitpos = patchnum * g_num_patches;
  169. #endif
  170. // build to all other world leafs
  171. BuildVisRow(patchnum, pvs, head, bitpos);
  172. // build to bmodel faces
  173. if (g_nummodels < 2)
  174. continue;
  175. for (facenum2 = g_dmodels[1].firstface; facenum2 < g_numfaces; facenum2++)
  176. TestPatchToFace(patchnum, facenum2, head, bitpos);
  177. }
  178. }
  179. }
  180. }
  181. #ifdef SYSTEM_WIN32
  182. #pragma warning(pop)
  183. #endif
  184. // =====================================================================================
  185. // BuildVisMatrix
  186. // =====================================================================================
  187. static void BuildVisMatrix()
  188. {
  189. int c;
  190. #ifdef HALFBIT
  191. c = ((g_num_patches + 1) * (g_num_patches + 1)) / 16;
  192. #else
  193. c = g_num_patches * ((g_num_patches + 7) / 8);
  194. #endif
  195. Log("%-20s: %5.1f megs\n", "visibility matrix", c / (1024 * 1024.0));
  196. s_vismatrix = (byte*)AllocBlock(c);
  197. if (!s_vismatrix)
  198. {
  199. Log("Failed to allocate s_vismatrix");
  200. hlassume(s_vismatrix != NULL, assume_NoMemory);
  201. }
  202. NamedRunThreadsOn(g_numleafs - 1, g_estimate, BuildVisLeafs);
  203. }
  204. static void FreeVisMatrix()
  205. {
  206. if (s_vismatrix)
  207. {
  208. if (FreeBlock(s_vismatrix))
  209. {
  210. s_vismatrix = NULL;
  211. }
  212. else
  213. {
  214. Warning("Unable to free s_vismatrix");
  215. }
  216. }
  217. }
  218. // =====================================================================================
  219. // CheckVisBit
  220. // =====================================================================================
  221. #ifdef HLRAD_HULLU
  222. static bool CheckVisBitVismatrix(unsigned p1, unsigned p2, vec3_t &transparency_out, unsigned int &next_index)
  223. #else
  224. static bool CheckVisBitVismatrix(unsigned p1, unsigned p2)
  225. #endif
  226. {
  227. unsigned bitpos;
  228. #ifdef HLRAD_HULLU
  229. const unsigned a = p1;
  230. const unsigned b = p2;
  231. VectorFill(transparency_out, 1.0);
  232. #endif
  233. if (p1 > p2)
  234. {
  235. #ifndef HLRAD_HULLU
  236. const unsigned a = p1;
  237. const unsigned b = p2;
  238. #endif
  239. p1 = b;
  240. p2 = a;
  241. }
  242. if (p1 > g_num_patches)
  243. {
  244. Warning("in CheckVisBit(), p1 > num_patches");
  245. }
  246. if (p2 > g_num_patches)
  247. {
  248. Warning("in CheckVisBit(), p2 > num_patches");
  249. }
  250. #ifdef HALFBIT
  251. bitpos = p1 * g_num_patches - (p1 * (p1 + 1)) / 2 + p2;
  252. #else
  253. bitpos = p1 * g_num_patches + p2;
  254. #endif
  255. if (s_vismatrix[bitpos >> 3] & (1 << (bitpos & 7)))
  256. {
  257. #ifdef HLRAD_HULLU
  258. if(g_customshadow_with_bouncelight)
  259. {
  260. GetTransparency( a, b, transparency_out, next_index );
  261. }
  262. #endif
  263. return true;
  264. }
  265. return false;
  266. }
  267. //
  268. // end old vismat.c
  269. ////////////////////////////
  270. // =====================================================================================
  271. // MakeScalesVismatrix
  272. // =====================================================================================
  273. void MakeScalesVismatrix()
  274. {
  275. char transferfile[_MAX_PATH];
  276. hlassume(g_num_patches < MAX_VISMATRIX_PATCHES, assume_MAX_PATCHES);
  277. safe_strncpy(transferfile, g_source, _MAX_PATH);
  278. StripExtension(transferfile);
  279. DefaultExtension(transferfile, ".inc");
  280. if (!g_incremental || !readtransfers(transferfile, g_num_patches))
  281. {
  282. // determine visibility between g_patches
  283. BuildVisMatrix();
  284. g_CheckVisBit = CheckVisBitVismatrix;
  285. #ifdef HLRAD_HULLU
  286. CreateFinalTransparencyArrays("custom shadow array");
  287. #endif
  288. #ifndef HLRAD_HULLU
  289. NamedRunThreadsOn(g_num_patches, g_estimate, MakeScales);
  290. #else
  291. if(g_rgb_transfers)
  292. {NamedRunThreadsOn(g_num_patches, g_estimate, MakeRGBScales);}
  293. else
  294. {NamedRunThreadsOn(g_num_patches, g_estimate, MakeScales);}
  295. #endif
  296. FreeVisMatrix();
  297. #ifdef HLRAD_HULLU
  298. FreeTransparencyArrays();
  299. #endif
  300. // invert the transfers for gather vs scatter
  301. #ifndef HLRAD_HULLU
  302. NamedRunThreadsOnIndividual(g_num_patches, g_estimate, SwapTransfers);
  303. #else
  304. if(g_rgb_transfers)
  305. {NamedRunThreadsOnIndividual(g_num_patches, g_estimate, SwapRGBTransfers);}
  306. else
  307. {NamedRunThreadsOnIndividual(g_num_patches, g_estimate, SwapTransfers);}
  308. #endif
  309. if (g_incremental)
  310. writetransfers(transferfile, g_num_patches);
  311. else
  312. _unlink(transferfile);
  313. DumpTransfersMemoryUsage();
  314. }
  315. }