vismatrixutil.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  1. #pragma warning(disable:4018) //amckern - 64bit - '<' Singed/Unsigned Mismatch
  2. #include "qrad.h"
  3. #ifdef HLRAD_HULLU
  4. #define HLRAD_HULLU_COMPRESSEDARRAY_TWEAK
  5. //#undef HLRAD_HULLU_COMPRESSEDARRAY_TWEAK
  6. #endif
  7. funcCheckVisBit g_CheckVisBit = NULL;
  8. unsigned g_total_transfer = 0;
  9. unsigned g_transfer_index_bytes = 0;
  10. unsigned g_transfer_data_bytes = 0;
  11. #define COMPRESSED_TRANSFERS
  12. //#undef COMPRESSED_TRANSFERS
  13. int FindTransferOffsetPatchnum(transfer_index_t* tIndex, const patch_t* const patch, const unsigned patchnum)
  14. {
  15. //
  16. // binary search for match
  17. //
  18. int low = 0;
  19. int high = patch->iIndex - 1;
  20. int offset;
  21. while (1)
  22. {
  23. offset = (low + high) / 2;
  24. if ((tIndex[offset].index + tIndex[offset].size) < patchnum)
  25. {
  26. low = offset + 1;
  27. }
  28. else if (tIndex[offset].index > patchnum)
  29. {
  30. high = offset - 1;
  31. }
  32. else
  33. {
  34. unsigned x;
  35. unsigned int rval = 0;
  36. transfer_index_t* pIndex = tIndex;
  37. for (x = 0; x < offset; x++, pIndex++)
  38. {
  39. rval += pIndex->size + 1;
  40. }
  41. rval += patchnum - tIndex[offset].index;
  42. return rval;
  43. }
  44. if (low > high)
  45. {
  46. return -1;
  47. }
  48. }
  49. }
  50. #ifdef COMPRESSED_TRANSFERS
  51. static unsigned GetLengthOfRun(const transfer_raw_index_t* raw, const transfer_raw_index_t* const end)
  52. {
  53. unsigned run_size = 0;
  54. while (raw < end)
  55. {
  56. if (((*raw) + 1) == (*(raw + 1)))
  57. {
  58. raw++;
  59. run_size++;
  60. if (run_size >= MAX_COMPRESSED_TRANSFER_INDEX_SIZE)
  61. {
  62. return run_size;
  63. }
  64. }
  65. else
  66. {
  67. return run_size;
  68. }
  69. }
  70. return run_size;
  71. }
  72. #ifdef HLRAD_HULLU_COMPRESSEDARRAY_TWEAK
  73. static transfer_index_t* CompressTransferIndicies(transfer_raw_index_t* tRaw, const unsigned rawSize, unsigned* iSize, transfer_index_t *CompressedArray)
  74. #else
  75. static transfer_index_t* CompressTransferIndicies(transfer_raw_index_t* tRaw, const unsigned rawSize, unsigned* iSize)
  76. #endif
  77. {
  78. unsigned x;
  79. unsigned size = rawSize;
  80. unsigned compressed_count = 0;
  81. transfer_raw_index_t* raw = tRaw;
  82. transfer_raw_index_t* end = tRaw + rawSize - 1; // -1 since we are comparing current with next and get errors when bumping into the 'end'
  83. #ifndef HLRAD_HULLU_COMPRESSEDARRAY_TWEAK
  84. transfer_index_t CompressedArray[MAX_PATCHES]; // somewhat big stack object (1 Mb with 256k patches)
  85. #endif
  86. transfer_index_t* compressed = CompressedArray;
  87. for (x = 0; x < size; x++, raw++, compressed++)
  88. {
  89. compressed->index = (*raw);
  90. compressed->size = GetLengthOfRun(raw, end); // Zero based (count 0 still implies 1 item in the list, so 256 max entries result)
  91. raw += compressed->size;
  92. x += compressed->size;
  93. compressed_count++; // number of entries in compressed table
  94. }
  95. *iSize = compressed_count;
  96. if (compressed_count)
  97. {
  98. unsigned compressed_array_size = sizeof(transfer_index_t) * compressed_count;
  99. transfer_index_t* rval = (transfer_index_t*)AllocBlock(compressed_array_size);
  100. ThreadLock();
  101. g_transfer_index_bytes += compressed_array_size;
  102. ThreadUnlock();
  103. memcpy(rval, CompressedArray, compressed_array_size);
  104. return rval;
  105. }
  106. else
  107. {
  108. return NULL;
  109. }
  110. }
  111. #else
  112. #ifdef HLRAD_HULLU_COMPRESSEDARRAY_TWEAK
  113. static transfer_index_t* CompressTransferIndicies(const transfer_raw_index_t* tRaw, const unsigned rawSize, unsigned* iSize, transfer_index_t *CompressedArray)
  114. #else
  115. static transfer_index_t* CompressTransferIndicies(const transfer_raw_index_t* tRaw, const unsigned rawSize, unsigned* iSize)
  116. #endif
  117. {
  118. unsigned x;
  119. unsigned size = rawSize;
  120. unsigned compressed_count = 0;
  121. transfer_raw_index_t* raw = tRaw;
  122. transfer_raw_index_t* end = tRaw + rawSize;
  123. #ifndef HLRAD_HULLU_COMPRESSEDARRAY_TWEAK
  124. transfer_index_t CompressedArray[MAX_PATCHES]; // somewhat big stack object (1 Mb with 256k patches)
  125. #endif
  126. transfer_index_t* compressed = CompressedArray;
  127. for (x = 0; x < size; x++, raw++, compressed++)
  128. {
  129. compressed->index = (*raw);
  130. compressed->size = 0;
  131. compressed_count++; // number of entries in compressed table
  132. }
  133. *iSize = compressed_count;
  134. if (compressed_count)
  135. {
  136. unsigned compressed_array_size = sizeof(transfer_index_t) * compressed_count;
  137. transfer_index_t* rval = AllocBlock(compressed_array_size);
  138. ThreadLock();
  139. g_transfer_index_bytes += compressed_array_size;
  140. ThreadUnlock();
  141. memcpy(rval, CompressedArray, compressed_array_size);
  142. return rval;
  143. }
  144. else
  145. {
  146. return NULL;
  147. }
  148. }
  149. #endif
  150. /*
  151. * =============
  152. * MakeScales
  153. *
  154. * This is the primary time sink.
  155. * It can be run multi threaded.
  156. * =============
  157. */
  158. #ifdef SYSTEM_WIN32
  159. #pragma warning(push)
  160. #pragma warning(disable:4100) // unreferenced formal parameter
  161. #endif
  162. void MakeScales(const int threadnum)
  163. {
  164. int i;
  165. unsigned j;
  166. vec3_t delta;
  167. vec_t dist;
  168. int count;
  169. float trans;
  170. patch_t* patch;
  171. patch_t* patch2;
  172. float send;
  173. vec3_t origin;
  174. vec_t area;
  175. const vec_t* normal1;
  176. const vec_t* normal2;
  177. #ifdef HLRAD_HULLU
  178. unsigned int fastfind_index;
  179. vec3_t transparency;
  180. #endif
  181. vec_t total;
  182. transfer_raw_index_t* tIndex;
  183. transfer_data_t* tData;
  184. transfer_raw_index_t* tIndex_All = (transfer_raw_index_t*)AllocBlock(sizeof(transfer_index_t) * MAX_PATCHES);
  185. transfer_data_t* tData_All = (transfer_data_t*)AllocBlock(sizeof(transfer_data_t) * MAX_PATCHES);
  186. #ifdef HLRAD_HULLU_COMPRESSEDARRAY_TWEAK
  187. //Simple optimization.. CompressTransferIndicies stack allocs 1MB object on ever run .. that's slooow :)
  188. //and some compilers cannot even make it work (Segfaults). Create array here and pass to CompressTransferIndicies
  189. transfer_index_t *CompressedArray = (transfer_index_t *)AllocBlock(sizeof(transfer_index_t) * MAX_PATCHES);
  190. #endif
  191. count = 0;
  192. #ifdef HLRAD_HULLU
  193. fastfind_index = 0;
  194. #endif
  195. while (1)
  196. {
  197. i = GetThreadWork();
  198. if (i == -1)
  199. break;
  200. patch = g_patches + i;
  201. patch->iIndex = 0;
  202. patch->iData = 0;
  203. total = 0.0;
  204. tIndex = tIndex_All;
  205. tData = tData_All;
  206. VectorCopy(patch->origin, origin);
  207. normal1 = getPlaneFromFaceNumber(patch->faceNumber)->normal;
  208. area = patch->area;
  209. // find out which patch2's will collect light
  210. // from patch
  211. for (j = 0, patch2 = g_patches; j < g_num_patches; j++, patch2++)
  212. {
  213. vec_t dot1;
  214. vec_t dot2;
  215. #ifdef HLRAD_HULLU
  216. VectorFill(transparency,1.0);
  217. if (!g_CheckVisBit(i, j, transparency, fastfind_index) || (i == j))
  218. #else
  219. if (!g_CheckVisBit(i, j) || (i == j))
  220. #endif
  221. {
  222. continue;
  223. }
  224. normal2 = getPlaneFromFaceNumber(patch2->faceNumber)->normal;
  225. // calculate transferemnce
  226. VectorSubtract(patch2->origin, origin, delta);
  227. dist = VectorNormalize(delta);
  228. dot1 = DotProduct(delta, normal1);
  229. dot2 = -DotProduct(delta, normal2);
  230. trans = (dot1 * dot2) / (dist * dist); // Inverse square falloff factoring angle between patch normals
  231. #ifdef HLRAD_HULLU
  232. trans = trans * VectorAvg(transparency); //hullu: add transparency effect
  233. #endif
  234. if (trans >= 0)
  235. {
  236. send = trans * patch2->area;
  237. // Caps light from getting weird
  238. if (send > 0.4f)
  239. {
  240. trans = 0.4f / patch2->area;
  241. send = 0.4f;
  242. }
  243. total += send;
  244. // scale to 16 bit (black magic)
  245. trans = trans * area * INVERSE_TRANSFER_SCALE;
  246. if (trans >= TRANSFER_SCALE_MAX)
  247. {
  248. trans = TRANSFER_SCALE_MAX;
  249. }
  250. }
  251. else
  252. {
  253. #if 0
  254. Warning("transfer < 0 (%f): dist=(%f)\n"
  255. " dot1=(%f) patch@(%4.3f %4.3f %4.3f) normal(%4.3f %4.3f %4.3f)\n"
  256. " dot2=(%f) patch@(%4.3f %4.3f %4.3f) normal(%4.3f %4.3f %4.3f)\n",
  257. trans, dist,
  258. dot1, patch->origin[0], patch->origin[1], patch->origin[2], patch->normal[0], patch->normal[1],
  259. patch->normal[2], dot2, patch2->origin[0], patch2->origin[1], patch2->origin[2],
  260. patch2->normal[0], patch2->normal[1], patch2->normal[2]);
  261. #endif
  262. trans = 0.0;
  263. }
  264. *tData = trans;
  265. *tIndex = j;
  266. tData++;
  267. tIndex++;
  268. patch->iData++;
  269. count++;
  270. }
  271. // copy the transfers out
  272. if (patch->iData)
  273. {
  274. unsigned data_size = patch->iData * sizeof(transfer_data_t);
  275. patch->tData = (transfer_data_t*)AllocBlock(data_size);
  276. #ifdef HLRAD_HULLU_COMPRESSEDARRAY_TWEAK
  277. patch->tIndex = CompressTransferIndicies(tIndex_All, patch->iData, &patch->iIndex, CompressedArray);
  278. #else
  279. patch->tIndex = CompressTransferIndicies(tIndex_All, patch->iData, &patch->iIndex);
  280. #endif
  281. hlassume(patch->tData != NULL, assume_NoMemory);
  282. hlassume(patch->tIndex != NULL, assume_NoMemory);
  283. ThreadLock();
  284. g_transfer_data_bytes += data_size;
  285. ThreadUnlock();
  286. //
  287. // normalize all transfers so exactly 50% of the light
  288. // is transfered to the surroundings
  289. //
  290. total = 0.5 / total;
  291. {
  292. unsigned x;
  293. transfer_data_t* t1 = patch->tData;
  294. transfer_data_t* t2 = tData_All;
  295. for (x = 0; x < patch->iData; x++, t1++, t2++)
  296. {
  297. (*t1) = (*t2) * total;
  298. }
  299. }
  300. }
  301. }
  302. FreeBlock(tIndex_All);
  303. FreeBlock(tData_All);
  304. #ifdef HLRAD_HULLU_COMPRESSEDARRAY_TWEAK
  305. FreeBlock( CompressedArray );
  306. #endif
  307. ThreadLock();
  308. g_total_transfer += count;
  309. ThreadUnlock();
  310. }
  311. #ifdef SYSTEM_WIN32
  312. #pragma warning(pop)
  313. #endif
  314. /*
  315. * =============
  316. * SwapTransfersTask
  317. *
  318. * Change transfers from light sent out to light collected in.
  319. * In an ideal world, they would be exactly symetrical, but
  320. * because the form factors are only aproximated, then normalized,
  321. * they will actually be rather different.
  322. * =============
  323. */
  324. void SwapTransfers(const int patchnum)
  325. {
  326. patch_t* patch = &g_patches[patchnum];
  327. transfer_index_t* tIndex = patch->tIndex;
  328. transfer_data_t* tData = patch->tData;
  329. unsigned x;
  330. for (x = 0; x < patch->iIndex; x++, tIndex++)
  331. {
  332. unsigned size = (tIndex->size + 1);
  333. unsigned patchnum2 = tIndex->index;
  334. unsigned y;
  335. for (y = 0; y < size; y++, tData++, patchnum2++)
  336. {
  337. patch_t* patch2 = &g_patches[patchnum2];
  338. if (patchnum2 > patchnum)
  339. { // done with this list
  340. return;
  341. }
  342. else if (!patch2->iData)
  343. { // Set to zero in this impossible case
  344. Log("patch2 has no iData\n");
  345. (*tData) = 0;
  346. continue;
  347. }
  348. else
  349. {
  350. transfer_index_t* tIndex2 = patch2->tIndex;
  351. transfer_data_t* tData2 = patch2->tData;
  352. int offset = FindTransferOffsetPatchnum(tIndex2, patch2, patchnum);
  353. if (offset >= 0)
  354. {
  355. transfer_data_t tmp = *tData;
  356. *tData = tData2[offset];
  357. tData2[offset] = tmp;
  358. }
  359. else
  360. { // Set to zero in this impossible case
  361. Log("FindTransferOffsetPatchnum returned -1 looking for patch %d in patch %d's transfer lists\n",
  362. patchnum, patchnum2);
  363. (*tData) = 0;
  364. return;
  365. }
  366. }
  367. }
  368. }
  369. }
  370. #ifdef HLRAD_HULLU
  371. /*
  372. * =============
  373. * MakeScales
  374. *
  375. * This is the primary time sink.
  376. * It can be run multi threaded.
  377. * =============
  378. */
  379. #ifdef SYSTEM_WIN32
  380. #pragma warning(push)
  381. #pragma warning(disable:4100) // unreferenced formal parameter
  382. #endif
  383. void MakeRGBScales(const int threadnum)
  384. {
  385. int i;
  386. unsigned j;
  387. vec3_t delta;
  388. vec_t dist;
  389. int count;
  390. float trans[3];
  391. float trans_one;
  392. patch_t* patch;
  393. patch_t* patch2;
  394. float send;
  395. vec3_t origin;
  396. vec_t area;
  397. const vec_t* normal1;
  398. const vec_t* normal2;
  399. unsigned int fastfind_index;
  400. vec3_t transparency;
  401. vec_t total;
  402. transfer_raw_index_t* tIndex;
  403. rgb_transfer_data_t* tRGBData;
  404. transfer_raw_index_t* tIndex_All = (transfer_raw_index_t*)AllocBlock(sizeof(transfer_index_t) * MAX_PATCHES);
  405. rgb_transfer_data_t* tRGBData_All = (rgb_transfer_data_t*)AllocBlock(sizeof(rgb_transfer_data_t) * MAX_PATCHES);
  406. #ifdef HLRAD_HULLU_COMPRESSEDARRAY_TWEAK
  407. //Simple optimization.. CompressTransferIndicies stack allocs 1MB object on ever run .. that's slooow :)
  408. //and some compilers cannot even make it work (Segfaults). Create array here and pass to CompressTransferIndicies
  409. transfer_index_t *CompressedArray = (transfer_index_t *)AllocBlock(sizeof(transfer_index_t) * MAX_PATCHES);
  410. #endif
  411. count = 0;
  412. fastfind_index = 0;
  413. while (1)
  414. {
  415. i = GetThreadWork();
  416. if (i == -1)
  417. break;
  418. patch = g_patches + i;
  419. patch->iIndex = 0;
  420. patch->iData = 0;
  421. total = 0.0;
  422. tIndex = tIndex_All;
  423. tRGBData = tRGBData_All;
  424. VectorCopy(patch->origin, origin);
  425. normal1 = getPlaneFromFaceNumber(patch->faceNumber)->normal;
  426. area = patch->area;
  427. // find out which patch2's will collect light
  428. // from patch
  429. for (j = 0, patch2 = g_patches; j < g_num_patches; j++, patch2++)
  430. {
  431. vec_t dot1;
  432. vec_t dot2;
  433. VectorFill( transparency, 1.0 );
  434. if (!g_CheckVisBit(i, j, transparency, fastfind_index) || (i == j))
  435. {
  436. continue;
  437. }
  438. normal2 = getPlaneFromFaceNumber(patch2->faceNumber)->normal;
  439. // calculate transferemnce
  440. VectorSubtract(patch2->origin, origin, delta);
  441. dist = VectorNormalize(delta);
  442. dot1 = DotProduct(delta, normal1);
  443. dot2 = -DotProduct(delta, normal2);
  444. trans_one = (dot1 * dot2) / (dist * dist); // Inverse square falloff factoring angle between patch normals
  445. VectorFill(trans, trans_one);
  446. VectorMultiply(trans, transparency, trans); //hullu: add transparency effect
  447. if (VectorAvg(trans) >= 0)
  448. {
  449. /////////////////////////////////////////RED
  450. send = trans[0] * patch2->area;
  451. // Caps light from getting weird
  452. if (send > 0.4f)
  453. {
  454. trans[0] = 0.4f / patch2->area;
  455. send = 0.4f;
  456. }
  457. total += send / 3.0f;
  458. /////////////////////////////////////////GREEN
  459. send = trans[1] * patch2->area;
  460. // Caps light from getting weird
  461. if (send > 0.4f)
  462. {
  463. trans[1] = 0.4f / patch2->area;
  464. send = 0.4f;
  465. }
  466. total += send / 3.0f;
  467. /////////////////////////////////////////BLUE
  468. send = trans[2] * patch2->area;
  469. // Caps light from getting weird
  470. if (send > 0.4f)
  471. {
  472. trans[2] = 0.4f / patch2->area;
  473. send = 0.4f;
  474. }
  475. total += send / 3.0f;
  476. // scale to 16 bit (black magic)
  477. VectorScale(trans, area * INVERSE_TRANSFER_SCALE, trans);
  478. if (trans[0] >= TRANSFER_SCALE_MAX)
  479. {
  480. trans[0] = TRANSFER_SCALE_MAX;
  481. }
  482. if (trans[1] >= TRANSFER_SCALE_MAX)
  483. {
  484. trans[1] = TRANSFER_SCALE_MAX;
  485. }
  486. if (trans[2] >= TRANSFER_SCALE_MAX)
  487. {
  488. trans[2] = TRANSFER_SCALE_MAX;
  489. }
  490. }
  491. else
  492. {
  493. #if 0
  494. Warning("transfer < 0 (%4.3f %4.3f %4.3f): dist=(%f)\n"
  495. " dot1=(%f) patch@(%4.3f %4.3f %4.3f) normal(%4.3f %4.3f %4.3f)\n"
  496. " dot2=(%f) patch@(%4.3f %4.3f %4.3f) normal(%4.3f %4.3f %4.3f)\n",
  497. trans[0], trans[1], trans[2], dist,
  498. dot1, patch->origin[0], patch->origin[1], patch->origin[2], patch->normal[0], patch->normal[1],
  499. patch->normal[2], dot2, patch2->origin[0], patch2->origin[1], patch2->origin[2],
  500. patch2->normal[0], patch2->normal[1], patch2->normal[2]);
  501. #endif
  502. VectorFill(trans,0.0);
  503. }
  504. VectorCopy(trans, *tRGBData);
  505. *tIndex = j;
  506. tRGBData++;
  507. tIndex++;
  508. patch->iData++;
  509. count++;
  510. }
  511. // copy the transfers out
  512. if (patch->iData)
  513. {
  514. unsigned data_size = patch->iData * sizeof(rgb_transfer_data_t);
  515. patch->tRGBData = (rgb_transfer_data_t*)AllocBlock(data_size);
  516. #ifdef HLRAD_HULLU_COMPRESSEDARRAY_TWEAK
  517. patch->tIndex = CompressTransferIndicies(tIndex_All, patch->iData, &patch->iIndex, CompressedArray);
  518. #else
  519. patch->tIndex = CompressTransferIndicies(tIndex_All, patch->iData, &patch->iIndex);
  520. #endif
  521. hlassume(patch->tRGBData != NULL, assume_NoMemory);
  522. hlassume(patch->tIndex != NULL, assume_NoMemory);
  523. ThreadLock();
  524. g_transfer_data_bytes += data_size;
  525. ThreadUnlock();
  526. //
  527. // normalize all transfers so exactly 50% of the light
  528. // is transfered to the surroundings
  529. //
  530. total = 0.5 / total;
  531. {
  532. unsigned x;
  533. rgb_transfer_data_t* t1 = patch->tRGBData;
  534. rgb_transfer_data_t* t2 = tRGBData_All;
  535. for (x = 0; x < patch->iData; x++, t1++, t2++)
  536. {
  537. VectorScale( *t2, total, *t1 );
  538. }
  539. }
  540. }
  541. }
  542. FreeBlock(tIndex_All);
  543. FreeBlock(tRGBData_All);
  544. #ifdef HLRAD_HULLU_COMPRESSEDARRAY_TWEAK
  545. FreeBlock( CompressedArray );
  546. #endif
  547. ThreadLock();
  548. g_total_transfer += count;
  549. ThreadUnlock();
  550. }
  551. #ifdef SYSTEM_WIN32
  552. #pragma warning(pop)
  553. #endif
  554. /*
  555. * =============
  556. * SwapTransfersTask
  557. *
  558. * Change transfers from light sent out to light collected in.
  559. * In an ideal world, they would be exactly symetrical, but
  560. * because the form factors are only aproximated, then normalized,
  561. * they will actually be rather different.
  562. * =============
  563. */
  564. void SwapRGBTransfers(const int patchnum)
  565. {
  566. patch_t* patch = &g_patches[patchnum];
  567. transfer_index_t* tIndex = patch->tIndex;
  568. rgb_transfer_data_t* tRGBData= patch->tRGBData;
  569. unsigned x;
  570. for (x = 0; x < patch->iIndex; x++, tIndex++)
  571. {
  572. unsigned size = (tIndex->size + 1);
  573. unsigned patchnum2 = tIndex->index;
  574. unsigned y;
  575. for (y = 0; y < size; y++, tRGBData++, patchnum2++)
  576. {
  577. patch_t* patch2 = &g_patches[patchnum2];
  578. if (patchnum2 > patchnum)
  579. { // done with this list
  580. return;
  581. }
  582. else if (!patch2->iData)
  583. { // Set to zero in this impossible case
  584. Log("patch2 has no iData\n");
  585. VectorFill(*tRGBData, 0);
  586. continue;
  587. }
  588. else
  589. {
  590. transfer_index_t* tIndex2 = patch2->tIndex;
  591. rgb_transfer_data_t* tRGBData2 = patch2->tRGBData;
  592. int offset = FindTransferOffsetPatchnum(tIndex2, patch2, patchnum);
  593. if (offset >= 0)
  594. {
  595. rgb_transfer_data_t tmp;
  596. VectorCopy(*tRGBData, tmp)
  597. VectorCopy(tRGBData2[offset], *tRGBData);
  598. VectorCopy(tmp, tRGBData2[offset]);
  599. }
  600. else
  601. { // Set to zero in this impossible case
  602. Log("FindTransferOffsetPatchnum returned -1 looking for patch %d in patch %d's transfer lists\n",
  603. patchnum, patchnum2);
  604. VectorFill(*tRGBData, 0);
  605. return;
  606. }
  607. }
  608. }
  609. }
  610. }
  611. #endif /*HLRAD_HULLU*/
  612. #ifndef HLRAD_HULLU
  613. void DumpTransfersMemoryUsage()
  614. {
  615. Log("Transfer Lists : %u transfers\n Indices : %u bytes\n Data : %u bytes\n",
  616. g_total_transfer, g_transfer_index_bytes, g_transfer_data_bytes);
  617. }
  618. #else
  619. //More human readable numbers
  620. void DumpTransfersMemoryUsage()
  621. {
  622. if(g_total_transfer > 1000*1000)
  623. Log("Transfer Lists : %11u : %7.2fM transfers\n", g_total_transfer, g_total_transfer/(1000.0f*1000.0f));
  624. else if(g_total_transfer > 1000)
  625. Log("Transfer Lists : %11u : %7.2fk transfers\n", g_total_transfer, g_total_transfer/1000.0f);
  626. else
  627. Log("Transfer Lists : %11u transfers\n", g_total_transfer);
  628. if(g_transfer_index_bytes > 1024*1024)
  629. Log(" Indices : %11u : %7.2fM bytes\n", g_transfer_index_bytes, g_transfer_index_bytes/(1024.0f * 1024.0f));
  630. else if(g_transfer_index_bytes > 1024)
  631. Log(" Indices : %11u : %7.2fk bytes\n", g_transfer_index_bytes, g_transfer_index_bytes/1024.0f);
  632. else
  633. Log(" Indices : %11u bytes\n", g_transfer_index_bytes);
  634. if(g_transfer_data_bytes > 1024*1024)
  635. Log(" Data : %11u : %7.2fM bytes\n", g_transfer_data_bytes, g_transfer_data_bytes/(1024.0f * 1024.0f));
  636. else if(g_transfer_data_bytes > 1024)
  637. Log(" Data : %11u : %7.2fk bytes\n", g_transfer_data_bytes, g_transfer_data_bytes/1024.0f);
  638. else
  639. Log(" Indices : %11u bytes\n", g_transfer_data_bytes);
  640. }
  641. #endif