lightmap.cpp 79 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437
  1. #include "qrad.h"
  2. edgeshare_t g_edgeshare[MAX_MAP_EDGES];
  3. vec3_t g_face_centroids[MAX_MAP_EDGES];
  4. bool g_sky_lighting_fix = DEFAULT_SKY_LIGHTING_FIX;
  5. extern bool g_warned_direct;
  6. #define TEXTURE_STEP 16.0
  7. // =====================================================================================
  8. // PairEdges
  9. // =====================================================================================
  10. void PairEdges()
  11. {
  12. int i, j, k;
  13. dface_t* f;
  14. edgeshare_t* e;
  15. memset(&g_edgeshare, 0, sizeof(g_edgeshare));
  16. f = g_dfaces;
  17. for (i = 0; i < g_numfaces; i++, f++)
  18. {
  19. for (j = 0; j < f->numedges; j++)
  20. {
  21. k = g_dsurfedges[f->firstedge + j];
  22. if (k < 0)
  23. {
  24. e = &g_edgeshare[-k];
  25. hlassert(e->faces[1] == NULL);
  26. e->faces[1] = f;
  27. }
  28. else
  29. {
  30. e = &g_edgeshare[k];
  31. hlassert(e->faces[0] == NULL);
  32. e->faces[0] = f;
  33. }
  34. if (e->faces[0] && e->faces[1]) {
  35. // determine if coplanar
  36. if (e->faces[0]->planenum == e->faces[1]->planenum) {
  37. e->coplanar = true;
  38. } else {
  39. // see if they fall into a "smoothing group" based on angle of the normals
  40. vec3_t normals[2];
  41. VectorCopy(getPlaneFromFace(e->faces[0])->normal, normals[0]);
  42. VectorCopy(getPlaneFromFace(e->faces[1])->normal, normals[1]);
  43. e->cos_normals_angle = DotProduct(normals[0], normals[1]);
  44. if (e->cos_normals_angle > (1.0 - NORMAL_EPSILON))
  45. {
  46. e->coplanar = true;
  47. }
  48. else if (g_smoothing_threshold > 0.0)
  49. {
  50. if (e->cos_normals_angle >= g_smoothing_threshold)
  51. {
  52. VectorAdd(normals[0], normals[1], e->interface_normal);
  53. VectorNormalize(e->interface_normal);
  54. }
  55. }
  56. }
  57. }
  58. }
  59. }
  60. }
  61. #define MAX_SINGLEMAP (18*18*4)
  62. typedef struct
  63. {
  64. vec_t* light;
  65. vec_t facedist;
  66. vec3_t facenormal;
  67. int numsurfpt;
  68. vec3_t surfpt[MAX_SINGLEMAP];
  69. vec3_t texorg;
  70. vec3_t worldtotex[2]; // s = (world - texorg) . worldtotex[0]
  71. vec3_t textoworld[2]; // world = texorg + s * textoworld[0]
  72. vec_t exactmins[2], exactmaxs[2];
  73. int texmins[2], texsize[2];
  74. int lightstyles[256];
  75. int surfnum;
  76. dface_t* face;
  77. }
  78. lightinfo_t;
  79. // =====================================================================================
  80. // TextureNameFromFace
  81. // =====================================================================================
  82. static const char* TextureNameFromFace(const dface_t* const f)
  83. {
  84. texinfo_t* tx;
  85. miptex_t* mt;
  86. int ofs;
  87. //
  88. // check for light emited by texture
  89. //
  90. tx = &g_texinfo[f->texinfo];
  91. ofs = ((dmiptexlump_t*)g_dtexdata)->dataofs[tx->miptex];
  92. mt = (miptex_t*)((byte*) g_dtexdata + ofs);
  93. return mt->name;
  94. }
  95. // =====================================================================================
  96. // CalcFaceExtents
  97. // Fills in s->texmins[] and s->texsize[]
  98. // also sets exactmins[] and exactmaxs[]
  99. // =====================================================================================
  100. static void CalcFaceExtents(lightinfo_t* l)
  101. {
  102. const int facenum = l->surfnum;
  103. dface_t* s;
  104. vec_t mins[2], maxs[2], val;
  105. int i, j, e;
  106. dvertex_t* v;
  107. texinfo_t* tex;
  108. s = l->face;
  109. mins[0] = mins[1] = 999999;
  110. maxs[0] = maxs[1] = -99999;
  111. tex = &g_texinfo[s->texinfo];
  112. for (i = 0; i < s->numedges; i++)
  113. {
  114. e = g_dsurfedges[s->firstedge + i];
  115. if (e >= 0)
  116. {
  117. v = g_dvertexes + g_dedges[e].v[0];
  118. }
  119. else
  120. {
  121. v = g_dvertexes + g_dedges[-e].v[1];
  122. }
  123. for (j = 0; j < 2; j++)
  124. {
  125. val = v->point[0] * tex->vecs[j][0] +
  126. v->point[1] * tex->vecs[j][1] + v->point[2] * tex->vecs[j][2] + tex->vecs[j][3];
  127. if (val < mins[j])
  128. {
  129. mins[j] = val;
  130. }
  131. if (val > maxs[j])
  132. {
  133. maxs[j] = val;
  134. }
  135. }
  136. }
  137. for (i = 0; i < 2; i++)
  138. {
  139. l->exactmins[i] = mins[i];
  140. l->exactmaxs[i] = maxs[i];
  141. mins[i] = floor(mins[i] / 16.0);
  142. maxs[i] = ceil(maxs[i] / 16.0);
  143. l->texmins[i] = mins[i];
  144. l->texsize[i] = maxs[i] - mins[i];
  145. }
  146. if (!(tex->flags & TEX_SPECIAL))
  147. {
  148. if ((l->texsize[0] > 16) || (l->texsize[1] > 16))
  149. {
  150. ThreadLock();
  151. PrintOnce("\nfor Face %d (texture %s) at ", s - g_dfaces, TextureNameFromFace(s));
  152. for (i = 0; i < s->numedges; i++)
  153. {
  154. e = g_dsurfedges[s->firstedge + i];
  155. if (e >= 0)
  156. {
  157. v = g_dvertexes + g_dedges[e].v[0];
  158. }
  159. else
  160. {
  161. v = g_dvertexes + g_dedges[-e].v[1];
  162. }
  163. VectorAdd(v->point, g_face_offset[facenum], v->point);
  164. Log("(%4.3f %4.3f %4.3f) ", v->point[0], v->point[1], v->point[2]);
  165. }
  166. Log("\n");
  167. Error( "Bad surface extents (%d x %d)\nCheck the file ZHLTProblems.html for a detailed explanation of this problem", l->texsize[0], l->texsize[1]);
  168. }
  169. }
  170. }
  171. // =====================================================================================
  172. // CalcFaceVectors
  173. // Fills in texorg, worldtotex. and textoworld
  174. // =====================================================================================
  175. static void CalcFaceVectors(lightinfo_t* l)
  176. {
  177. texinfo_t* tex;
  178. int i, j;
  179. vec3_t texnormal;
  180. vec_t distscale;
  181. vec_t dist, len;
  182. tex = &g_texinfo[l->face->texinfo];
  183. // convert from float to double
  184. for (i = 0; i < 2; i++)
  185. {
  186. for (j = 0; j < 3; j++)
  187. {
  188. l->worldtotex[i][j] = tex->vecs[i][j];
  189. }
  190. }
  191. // calculate a normal to the texture axis. points can be moved along this
  192. // without changing their S/T
  193. CrossProduct(tex->vecs[1], tex->vecs[0], texnormal);
  194. VectorNormalize(texnormal);
  195. // flip it towards plane normal
  196. distscale = DotProduct(texnormal, l->facenormal);
  197. if (distscale == 0.0)
  198. {
  199. const unsigned facenum = l->face - g_dfaces;
  200. ThreadLock();
  201. Log("Malformed face (%d) normal @ \n", facenum);
  202. Winding* w = new Winding(*l->face);
  203. {
  204. const unsigned numpoints = w->m_NumPoints;
  205. unsigned x;
  206. for (x=0; x<numpoints; x++)
  207. {
  208. VectorAdd(w->m_Points[x], g_face_offset[facenum], w->m_Points[x]);
  209. }
  210. }
  211. w->Print();
  212. delete w;
  213. ThreadUnlock();
  214. hlassume(false, assume_MalformedTextureFace);
  215. }
  216. if (distscale < 0)
  217. {
  218. distscale = -distscale;
  219. VectorSubtract(vec3_origin, texnormal, texnormal);
  220. }
  221. // distscale is the ratio of the distance along the texture normal to
  222. // the distance along the plane normal
  223. distscale = 1.0 / distscale;
  224. for (i = 0; i < 2; i++)
  225. {
  226. len = (float)VectorLength(l->worldtotex[i]);
  227. dist = DotProduct(l->worldtotex[i], l->facenormal);
  228. dist *= distscale;
  229. VectorMA(l->worldtotex[i], -dist, texnormal, l->textoworld[i]);
  230. VectorScale(l->textoworld[i], (1 / len) * (1 / len), l->textoworld[i]);
  231. }
  232. // calculate texorg on the texture plane
  233. for (i = 0; i < 3; i++)
  234. {
  235. l->texorg[i] = -tex->vecs[0][3] * l->textoworld[0][i] - tex->vecs[1][3] * l->textoworld[1][i];
  236. }
  237. // project back to the face plane
  238. dist = DotProduct(l->texorg, l->facenormal) - l->facedist - DEFAULT_HUNT_OFFSET;
  239. dist *= distscale;
  240. VectorMA(l->texorg, -dist, texnormal, l->texorg);
  241. }
  242. // =====================================================================================
  243. // SetSurfFromST
  244. // =====================================================================================
  245. static void SetSurfFromST(const lightinfo_t* const l, vec_t* surf, const vec_t s, const vec_t t)
  246. {
  247. const int facenum = l->surfnum;
  248. int j;
  249. for (j = 0; j < 3; j++)
  250. {
  251. surf[j] = l->texorg[j] + l->textoworld[0][j] * s + l->textoworld[1][j] * t;
  252. }
  253. // Adjust for origin-based models
  254. VectorAdd(surf, g_face_offset[facenum], surf);
  255. }
  256. // =====================================================================================
  257. // FindSurfaceMidpoint
  258. // =====================================================================================
  259. static dleaf_t* FindSurfaceMidpoint(const lightinfo_t* const l, vec_t* midpoint)
  260. {
  261. int s, t;
  262. int w, h;
  263. vec_t starts, startt;
  264. vec_t us, ut;
  265. vec3_t broken_midpoint;
  266. vec3_t surface_midpoint;
  267. int inside_point_count;
  268. dleaf_t* last_valid_leaf = NULL;
  269. dleaf_t* leaf_mid;
  270. const int facenum = l->surfnum;
  271. const dface_t* f = g_dfaces + facenum;
  272. const dplane_t* p = getPlaneFromFace(f);
  273. const vec_t* face_delta = g_face_offset[facenum];
  274. h = l->texsize[1] + 1;
  275. w = l->texsize[0] + 1;
  276. starts = (float)l->texmins[0] * 16;
  277. startt = (float)l->texmins[1] * 16;
  278. // General case
  279. inside_point_count = 0;
  280. VectorClear(surface_midpoint);
  281. for (t = 0; t < h; t++)
  282. {
  283. for (s = 0; s < w; s++)
  284. {
  285. us = starts + s * TEXTURE_STEP;
  286. ut = startt + t * TEXTURE_STEP;
  287. SetSurfFromST(l, midpoint, us, ut);
  288. if ((leaf_mid = PointInLeaf(midpoint)) != g_dleafs)
  289. {
  290. if ((leaf_mid->contents != CONTENTS_SKY) && (leaf_mid->contents != CONTENTS_SOLID))
  291. {
  292. last_valid_leaf = leaf_mid;
  293. inside_point_count++;
  294. VectorAdd(surface_midpoint, midpoint, surface_midpoint);
  295. }
  296. }
  297. }
  298. }
  299. if (inside_point_count > 1)
  300. {
  301. vec_t tmp = 1.0 / inside_point_count;
  302. VectorScale(surface_midpoint, tmp, midpoint);
  303. //Verbose("Trying general at (%4.3f %4.3f %4.3f) %d\n", surface_midpoint[0], surface_midpoint[1], surface_midpoint[2], inside_point_count);
  304. if (
  305. (leaf_mid =
  306. HuntForWorld(midpoint, face_delta, p, DEFAULT_HUNT_SIZE, DEFAULT_HUNT_SCALE, DEFAULT_HUNT_OFFSET)))
  307. {
  308. //Verbose("general method succeeded at (%4.3f %4.3f %4.3f)\n", midpoint[0], midpoint[1], midpoint[2]);
  309. return leaf_mid;
  310. }
  311. //Verbose("Tried general , failed at (%4.3f %4.3f %4.3f)\n", midpoint[0], midpoint[1], midpoint[2]);
  312. }
  313. else if (inside_point_count == 1)
  314. {
  315. //Verbose("Returning single point from general\n");
  316. VectorCopy(surface_midpoint, midpoint);
  317. return last_valid_leaf;
  318. }
  319. else
  320. {
  321. //Verbose("general failed (no points)\n");
  322. }
  323. // Try harder
  324. inside_point_count = 0;
  325. VectorClear(surface_midpoint);
  326. for (t = 0; t < h; t++)
  327. {
  328. for (s = 0; s < w; s++)
  329. {
  330. us = starts + s * TEXTURE_STEP;
  331. ut = startt + t * TEXTURE_STEP;
  332. SetSurfFromST(l, midpoint, us, ut);
  333. leaf_mid =
  334. HuntForWorld(midpoint, face_delta, p, DEFAULT_HUNT_SIZE, DEFAULT_HUNT_SCALE, DEFAULT_HUNT_OFFSET);
  335. if (leaf_mid != g_dleafs)
  336. {
  337. last_valid_leaf = leaf_mid;
  338. inside_point_count++;
  339. VectorAdd(surface_midpoint, midpoint, surface_midpoint);
  340. }
  341. }
  342. }
  343. if (inside_point_count > 1)
  344. {
  345. vec_t tmp = 1.0 / inside_point_count;
  346. VectorScale(surface_midpoint, tmp, midpoint);
  347. if (
  348. (leaf_mid =
  349. HuntForWorld(midpoint, face_delta, p, DEFAULT_HUNT_SIZE, DEFAULT_HUNT_SCALE, DEFAULT_HUNT_OFFSET)))
  350. {
  351. //Verbose("best method succeeded at (%4.3f %4.3f %4.3f)\n", midpoint[0], midpoint[1], midpoint[2]);
  352. return leaf_mid;
  353. }
  354. //Verbose("Tried best, failed at (%4.3f %4.3f %4.3f)\n", midpoint[0], midpoint[1], midpoint[2]);
  355. }
  356. else if (inside_point_count == 1)
  357. {
  358. //Verbose("Returning single point from best\n");
  359. VectorCopy(surface_midpoint, midpoint);
  360. return last_valid_leaf;
  361. }
  362. else
  363. {
  364. //Verbose("best failed (no points)\n");
  365. }
  366. // Original broken code
  367. {
  368. vec_t mids = (l->exactmaxs[0] + l->exactmins[0]) / 2;
  369. vec_t midt = (l->exactmaxs[1] + l->exactmins[1]) / 2;
  370. SetSurfFromST(l, midpoint, mids, midt);
  371. if ((leaf_mid = PointInLeaf(midpoint)) != g_dleafs)
  372. {
  373. if ((leaf_mid->contents != CONTENTS_SKY) && (leaf_mid->contents != CONTENTS_SOLID))
  374. {
  375. return leaf_mid;
  376. }
  377. }
  378. VectorCopy(midpoint, broken_midpoint);
  379. //Verbose("Tried original method, failed at (%4.3f %4.3f %4.3f)\n", midpoint[0], midpoint[1], midpoint[2]);
  380. }
  381. VectorCopy(broken_midpoint, midpoint);
  382. return HuntForWorld(midpoint, face_delta, p, DEFAULT_HUNT_SIZE, DEFAULT_HUNT_SCALE, DEFAULT_HUNT_OFFSET);
  383. }
  384. // =====================================================================================
  385. // SimpleNudge
  386. // Return vec_t in point only valid when function returns true
  387. // Use negative scales to push away from center instead
  388. // =====================================================================================
  389. static bool SimpleNudge(vec_t* const point, const lightinfo_t* const l, vec_t* const s, vec_t* const t, const vec_t delta)
  390. {
  391. const int facenum = l->surfnum;
  392. const dface_t* f = g_dfaces + facenum;
  393. const dplane_t* p = getPlaneFromFace(f);
  394. const vec_t* face_delta = g_face_offset[facenum];
  395. const int h = l->texsize[1] + 1;
  396. const int w = l->texsize[0] + 1;
  397. const vec_t half_w = (vec_t)(w - 1) / 2.0;
  398. const vec_t half_h = (vec_t)(h - 1) / 2.0;
  399. const vec_t s_vec = *s;
  400. const vec_t t_vec = *t;
  401. vec_t s1;
  402. vec_t t1;
  403. if (s_vec > half_w)
  404. {
  405. s1 = s_vec - delta;
  406. }
  407. else
  408. {
  409. s1 = s_vec + delta;
  410. }
  411. SetSurfFromST(l, point, s1, t_vec);
  412. if (HuntForWorld(point, face_delta, p, DEFAULT_HUNT_SIZE, DEFAULT_HUNT_SCALE, DEFAULT_HUNT_OFFSET))
  413. {
  414. *s = s1;
  415. return true;
  416. }
  417. if (t_vec > half_h)
  418. {
  419. t1 = t_vec - delta;
  420. }
  421. else
  422. {
  423. t1 = t_vec + delta;
  424. }
  425. SetSurfFromST(l, point, s_vec, t1);
  426. if (HuntForWorld(point, face_delta, p, DEFAULT_HUNT_SIZE, DEFAULT_HUNT_SCALE, DEFAULT_HUNT_OFFSET))
  427. {
  428. *t = t1;
  429. return true;
  430. }
  431. return false;
  432. }
  433. typedef enum
  434. {
  435. LightOutside, // Not lit
  436. LightShifted, // used HuntForWorld on 100% dark face
  437. LightShiftedInside, // moved to neighbhor on 2nd cleanup pass
  438. LightNormal, // Normally lit with no movement
  439. LightPulledInside, // Pulled inside by bleed code adjustments
  440. LightSimpleNudge, // A simple nudge 1/3 or 2/3 towards center along S or T axist
  441. LightSimpleNudgeEmbedded // A nudge either 1 full unit in each of S and T axis, or 1/3 or 2/3 AWAY from center
  442. }
  443. light_flag_t;
  444. // =====================================================================================
  445. // CalcPoints
  446. // For each texture aligned grid point, back project onto the plane
  447. // to get the world xyz value of the sample point
  448. // =====================================================================================
  449. static void CalcPoints(lightinfo_t* l)
  450. {
  451. const int facenum = l->surfnum;
  452. const dface_t* f = g_dfaces + facenum;
  453. const dplane_t* p = getPlaneFromFace(f);
  454. const vec_t* face_delta = g_face_offset[facenum];
  455. const eModelLightmodes lightmode = g_face_lightmode[facenum];
  456. const vec_t mids = (l->exactmaxs[0] + l->exactmins[0]) / 2;
  457. const vec_t midt = (l->exactmaxs[1] + l->exactmins[1]) / 2;
  458. const int h = l->texsize[1] + 1;
  459. const int w = l->texsize[0] + 1;
  460. const vec_t starts = (l->texmins[0] * 16);
  461. const vec_t startt = (l->texmins[1] * 16);
  462. light_flag_t LuxelFlags[MAX_SINGLEMAP];
  463. light_flag_t* pLuxelFlags;
  464. vec_t us, ut;
  465. vec_t* surf;
  466. vec3_t surface_midpoint;
  467. dleaf_t* leaf_mid;
  468. dleaf_t* leaf_surf;
  469. int s, t;
  470. int i;
  471. l->numsurfpt = w * h;
  472. memset(LuxelFlags, 0, sizeof(LuxelFlags));
  473. leaf_mid = FindSurfaceMidpoint(l, surface_midpoint);
  474. #if 0
  475. if (!leaf_mid)
  476. {
  477. Developer(DEVELOPER_LEVEL_FLUFF, "CalcPoints [face %d] (%4.3f %4.3f %4.3f) midpoint outside world\n",
  478. facenum, surface_midpoint[0], surface_midpoint[1], surface_midpoint[2]);
  479. }
  480. else
  481. {
  482. Developer(DEVELOPER_LEVEL_FLUFF, "FindSurfaceMidpoint [face %d] @ (%4.3f %4.3f %4.3f)\n",
  483. facenum, surface_midpoint[0], surface_midpoint[1], surface_midpoint[2]);
  484. }
  485. #endif
  486. // First pass, light normally, and pull any faces toward the center for bleed adjustment
  487. surf = l->surfpt[0];
  488. pLuxelFlags = LuxelFlags;
  489. for (t = 0; t < h; t++)
  490. {
  491. for (s = 0; s < w; s++, surf += 3, pLuxelFlags++)
  492. {
  493. vec_t original_s = us = starts + s * TEXTURE_STEP;
  494. vec_t original_t = ut = startt + t * TEXTURE_STEP;
  495. SetSurfFromST(l, surf, us, ut);
  496. leaf_surf = HuntForWorld(surf, face_delta, p, DEFAULT_HUNT_SIZE, DEFAULT_HUNT_SCALE, DEFAULT_HUNT_OFFSET);
  497. if (!leaf_surf)
  498. {
  499. // At first try a 1/3 and 2/3 distance to nearest in each S and T axis towards the face midpoint
  500. if (SimpleNudge(surf, l, &us, &ut, TEXTURE_STEP * (1.0 / 3.0)))
  501. {
  502. *pLuxelFlags = LightSimpleNudge;
  503. }
  504. else if (SimpleNudge(surf, l, &us, &ut, -TEXTURE_STEP * (1.0 / 3.0)))
  505. {
  506. *pLuxelFlags = LightSimpleNudge;
  507. }
  508. else if (SimpleNudge(surf, l, &us, &ut, TEXTURE_STEP * (2.0 / 3.0)))
  509. {
  510. *pLuxelFlags = LightSimpleNudge;
  511. }
  512. else if (SimpleNudge(surf, l, &us, &ut, -TEXTURE_STEP * (2.0 / 3.0)))
  513. {
  514. *pLuxelFlags = LightSimpleNudge;
  515. }
  516. // Next, if this is a model flagged with the 'Embedded' mode, try away from the facemid too
  517. else if (lightmode & eModelLightmodeEmbedded)
  518. {
  519. SetSurfFromST(l, surf, us, ut);
  520. if (SimpleNudge(surf, l, &us, &ut, TEXTURE_STEP))
  521. {
  522. *pLuxelFlags = LightSimpleNudgeEmbedded;
  523. continue;
  524. }
  525. if (SimpleNudge(surf, l, &us, &ut, -TEXTURE_STEP))
  526. {
  527. *pLuxelFlags = LightSimpleNudgeEmbedded;
  528. continue;
  529. }
  530. SetSurfFromST(l, surf, original_s, original_t);
  531. *pLuxelFlags = LightOutside;
  532. continue;
  533. }
  534. }
  535. if (!(lightmode & eModelLightmodeEmbedded))
  536. {
  537. // Pull the sample points towards the facemid if visibility is blocked
  538. // and the facemid is inside the world
  539. int nudge_divisor = max(max(w, h), 4);
  540. int max_nudge = nudge_divisor + 1;
  541. bool nudge_succeeded = false;
  542. vec_t nudge_s = (mids - us) / (vec_t)nudge_divisor;
  543. vec_t nudge_t = (midt - ut) / (vec_t)nudge_divisor;
  544. vec3_t transparency;
  545. // if a line can be traced from surf to facemid, the point is good
  546. for (i = 0; i < max_nudge; i++)
  547. {
  548. // Make sure we are "in the world"(Not the zero leaf)
  549. if (leaf_mid)
  550. {
  551. SetSurfFromST(l, surf, us, ut);
  552. leaf_surf =
  553. HuntForWorld(surf, face_delta, p, DEFAULT_HUNT_SIZE, DEFAULT_HUNT_SCALE,
  554. DEFAULT_HUNT_OFFSET);
  555. if (leaf_surf)
  556. {
  557. if (TestLine(surface_midpoint, surf) == CONTENTS_EMPTY)
  558. {
  559. if (lightmode & eModelLightmodeConcave)
  560. {
  561. #ifdef HLRAD_HULLU
  562. //removed reset of transparency - TestSegmentAgainstOpaqueList already resets to 1,1,1
  563. int blocking_facenum = TestSegmentAgainstOpaqueList(surface_midpoint, surf, transparency);
  564. #else
  565. int blocking_facenum = TestSegmentAgainstOpaqueList(surface_midpoint, surf);
  566. #endif
  567. if(blocking_facenum > -1 && blocking_facenum != facenum)
  568. {
  569. //Log("SDF::4\n");
  570. us += nudge_s;
  571. ut += nudge_t;
  572. continue; // Try nudge again, we hit an opaque face
  573. }
  574. }
  575. if (i)
  576. {
  577. *pLuxelFlags = LightPulledInside;
  578. }
  579. else
  580. {
  581. *pLuxelFlags = LightNormal;
  582. }
  583. nudge_succeeded = true;
  584. break;
  585. }
  586. }
  587. }
  588. else
  589. {
  590. leaf_surf = PointInLeaf(surf);
  591. if (leaf_surf != g_dleafs)
  592. {
  593. if ((leaf_surf->contents != CONTENTS_SKY) && (leaf_surf->contents != CONTENTS_SOLID))
  594. {
  595. *pLuxelFlags = LightNormal;
  596. nudge_succeeded = true;
  597. break;
  598. }
  599. }
  600. }
  601. us += nudge_s;
  602. ut += nudge_t;
  603. }
  604. if (!nudge_succeeded)
  605. {
  606. SetSurfFromST(l, surf, original_s, original_t);
  607. *pLuxelFlags = LightOutside;
  608. }
  609. }
  610. }
  611. }
  612. // 2nd Pass, find units that are not lit and try to move them one half or unit worth
  613. // in each direction and see if that is lit.
  614. // This handles 1 x N lightmaps which are all dark everywhere and have no frame of refernece
  615. // for a good center or directly lit areas
  616. surf = l->surfpt[0];
  617. pLuxelFlags = LuxelFlags;
  618. #if 0
  619. Developer(DEVELOPER_LEVEL_SPAM,
  620. "w (%d) h (%d) dim (%d) leafmid (%4.3f %4.3f %4.3f) plane normal (%4.3f) (%4.3f) (%4.3f) dist (%f)\n", w,
  621. h, w * h, surface_midpoint[0], surface_midpoint[1], surface_midpoint[2], p->normal[0], p->normal[1],
  622. p->normal[2], p->dist);
  623. #endif
  624. {
  625. int total_dark = 0;
  626. int total_adjusted = 0;
  627. for (t = 0; t < h; t++)
  628. {
  629. for (s = 0; s < w; s++, surf += 3, pLuxelFlags++)
  630. {
  631. if (!*pLuxelFlags)
  632. {
  633. #if 0
  634. Developer(DEVELOPER_LEVEL_FLUFF, "Dark (%d %d) (%4.3f %4.3f %4.3f)\n",
  635. s, t, surf[0], surf[1], surf[2]);
  636. #endif
  637. total_dark++;
  638. if (HuntForWorld(surf, face_delta, p, DEFAULT_HUNT_SIZE, DEFAULT_HUNT_SCALE, DEFAULT_HUNT_OFFSET))
  639. {
  640. #if 0
  641. Developer(DEVELOPER_LEVEL_FLUFF, "Shifted %d %d to (%4.3f %4.3f %4.3f)\n", s, t, surf[0],
  642. surf[1], surf[2]);
  643. #endif
  644. *pLuxelFlags = LightShifted;
  645. total_adjusted++;
  646. }
  647. else if (HuntForWorld(surf, face_delta, p, 101, 0.5, DEFAULT_HUNT_OFFSET))
  648. {
  649. #if 0
  650. Developer(DEVELOPER_LEVEL_FLUFF, "Shifted %d %d to (%4.3f %4.3f %4.3f)\n", s, t, surf[0],
  651. surf[1], surf[2]);
  652. #endif
  653. *pLuxelFlags = LightShifted;
  654. total_adjusted++;
  655. }
  656. }
  657. }
  658. }
  659. #if 0
  660. if (total_dark)
  661. {
  662. Developer(DEVELOPER_LEVEL_FLUFF, "Pass 2 : %d dark, %d corrected\n", total_dark, total_adjusted);
  663. }
  664. #endif
  665. }
  666. // 3rd Pass, find units that are not lit and move them towards neighbhors who are
  667. // Currently finds the first lit neighbhor and uses its data
  668. surf = l->surfpt[0];
  669. pLuxelFlags = LuxelFlags;
  670. {
  671. int total_dark = 0;
  672. int total_adjusted = 0;
  673. for (t = 0; t < h; t++)
  674. {
  675. for (s = 0; s < w; s++, surf += 3, pLuxelFlags++)
  676. {
  677. if (!*pLuxelFlags)
  678. {
  679. int x_min = max(0, s - 1);
  680. int x_max = min(w, s + 1);
  681. int y_min = max(0, t - 1);
  682. int y_max = min(t, t + 1);
  683. int x, y;
  684. #if 0
  685. Developer(DEVELOPER_LEVEL_FLUFF, "Point outside (%d %d) (%4.3f %4.3f %4.3f)\n",
  686. s, t, surf[0], surf[1], surf[2]);
  687. #endif
  688. total_dark++;
  689. for (x = x_min; x < x_max; x++)
  690. {
  691. for (y = y_min; y < y_max; y++)
  692. {
  693. if (*pLuxelFlags >= LightNormal)
  694. {
  695. dleaf_t* leaf;
  696. vec_t* other_surf = l->surfpt[0];
  697. other_surf += ((y * w) + x) * 3;
  698. leaf = PointInLeaf(other_surf);
  699. if ((leaf->contents != CONTENTS_SKY && leaf->contents != CONTENTS_SOLID))
  700. {
  701. *pLuxelFlags = LightShiftedInside;
  702. #if 0
  703. Developer(DEVELOPER_LEVEL_MESSAGE,
  704. "Nudged (%d %d) (%4.3f %4.3f %4.3f) to (%d %d) (%4.3f %4.3f %4.3f) \n",
  705. s, t, surf[0], surf[1], surf[2], x, y, other_surf[0], other_surf[1],
  706. other_surf[2]);
  707. #endif
  708. VectorCopy(other_surf, surf);
  709. total_adjusted++;
  710. goto found_it;
  711. }
  712. }
  713. }
  714. }
  715. }
  716. found_it:;
  717. }
  718. }
  719. #if 0
  720. if (total_dark)
  721. {
  722. Developer(DEVELOPER_LEVEL_FLUFF, "Pass 2 : %d dark, %d corrected\n", total_dark, total_adjusted);
  723. }
  724. #endif
  725. }
  726. }
  727. //==============================================================
  728. typedef struct
  729. {
  730. vec3_t pos;
  731. vec3_t light;
  732. }
  733. sample_t;
  734. typedef struct
  735. {
  736. int numsamples;
  737. sample_t* samples[MAXLIGHTMAPS];
  738. }
  739. facelight_t;
  740. static directlight_t* directlights[MAX_MAP_LEAFS];
  741. static facelight_t facelight[MAX_MAP_FACES];
  742. static int numdlights;
  743. #define DIRECT_SCALE 0.1f
  744. // =====================================================================================
  745. // CreateDirectLights
  746. // =====================================================================================
  747. void CreateDirectLights()
  748. {
  749. unsigned i;
  750. patch_t* p;
  751. directlight_t* dl;
  752. dleaf_t* leaf;
  753. int leafnum;
  754. entity_t* e;
  755. entity_t* e2;
  756. const char* name;
  757. const char* target;
  758. float angle;
  759. vec3_t dest;
  760. // AJM: coplaner lighting
  761. vec3_t temp_normal;
  762. numdlights = 0;
  763. //
  764. // surfaces
  765. //
  766. for (i = 0, p = g_patches; i < g_num_patches; i++, p++)
  767. {
  768. #ifdef ZHLT_TEXLIGHT
  769. if (VectorAvg(p->baselight) >= g_dlight_threshold) //LRC
  770. #else
  771. if (VectorAvg(p->totallight) >= g_dlight_threshold)
  772. #endif
  773. {
  774. numdlights++;
  775. dl = (directlight_t*)calloc(1, sizeof(directlight_t));
  776. VectorCopy(p->origin, dl->origin);
  777. leaf = PointInLeaf(dl->origin);
  778. leafnum = leaf - g_dleafs;
  779. dl->next = directlights[leafnum];
  780. directlights[leafnum] = dl;
  781. #ifdef ZHLT_TEXLIGHT
  782. dl->style = p->emitstyle; //LRC
  783. #endif
  784. dl->type = emit_surface;
  785. VectorCopy(getPlaneFromFaceNumber(p->faceNumber)->normal, dl->normal);
  786. #ifdef ZHLT_TEXLIGHT
  787. VectorCopy(p->baselight, dl->intensity); //LRC
  788. #else
  789. VectorCopy(p->totallight, dl->intensity);
  790. #endif
  791. VectorScale(dl->intensity, p->area, dl->intensity);
  792. VectorScale(dl->intensity, DIRECT_SCALE, dl->intensity);
  793. // --------------------------------------------------------------
  794. // Changes by Adam Foster - [email protected]
  795. // mazemaster's l33t backwards lighting (I still haven't a clue
  796. // what it's supposed to be for) :-)
  797. #ifdef HLRAD_WHOME
  798. if (g_softlight_hack[0] || g_softlight_hack[1] || g_softlight_hack[2])
  799. {
  800. numdlights++;
  801. dl = (directlight_t *) calloc(1, sizeof(directlight_t));
  802. VectorCopy(p->origin, dl->origin);
  803. leaf = PointInLeaf(dl->origin);
  804. leafnum = leaf - g_dleafs;
  805. dl->next = directlights[leafnum];
  806. directlights[leafnum] = dl;
  807. dl->type = emit_surface;
  808. VectorCopy(getPlaneFromFaceNumber(p->faceNumber)->normal, dl->normal);
  809. VectorScale(dl->normal, g_softlight_hack_distance, temp_normal);
  810. VectorAdd(dl->origin, temp_normal, dl->origin);
  811. VectorScale(dl->normal, -1, dl->normal);
  812. #ifdef ZHLT_TEXLIGHT
  813. VectorCopy(p->baselight, dl->intensity); //LRC
  814. #else
  815. VectorCopy(p->totallight, dl->intensity);
  816. #endif
  817. VectorScale(dl->intensity, p->area, dl->intensity);
  818. VectorScale(dl->intensity, DIRECT_SCALE, dl->intensity);
  819. dl->intensity[0] *= g_softlight_hack[0];
  820. dl->intensity[1] *= g_softlight_hack[1];
  821. dl->intensity[2] *= g_softlight_hack[2];
  822. }
  823. #endif
  824. // --------------------------------------------------------------
  825. }
  826. #ifdef ZHLT_TEXLIGHT
  827. //LRC VectorClear(p->totallight[0]);
  828. #else
  829. VectorClear(p->totallight);
  830. #endif
  831. }
  832. //
  833. // entities
  834. //
  835. for (i = 0; i < (unsigned)g_numentities; i++)
  836. {
  837. const char* pLight;
  838. double r, g, b, scaler;
  839. float l1;
  840. int argCnt;
  841. e = &g_entities[i];
  842. name = ValueForKey(e, "classname");
  843. if (strncmp(name, "light", 5))
  844. continue;
  845. numdlights++;
  846. dl = (directlight_t*)calloc(1, sizeof(directlight_t));
  847. GetVectorForKey(e, "origin", dl->origin);
  848. leaf = PointInLeaf(dl->origin);
  849. leafnum = leaf - g_dleafs;
  850. dl->next = directlights[leafnum];
  851. directlights[leafnum] = dl;
  852. dl->style = IntForKey(e, "style");
  853. #ifdef ZHLT_TEXLIGHT
  854. if (dl->style < 0)
  855. dl->style = -dl->style; //LRC
  856. #endif
  857. pLight = ValueForKey(e, "_light");
  858. // scanf into doubles, then assign, so it is vec_t size independent
  859. r = g = b = scaler = 0;
  860. argCnt = sscanf_s(pLight, "%lf %lf %lf %lf", &r, &g, &b, &scaler);
  861. dl->intensity[0] = (float)r;
  862. if (argCnt == 1)
  863. {
  864. // The R,G,B values are all equal.
  865. dl->intensity[1] = dl->intensity[2] = (float)r;
  866. }
  867. else if (argCnt == 3 || argCnt == 4)
  868. {
  869. // Save the other two G,B values.
  870. dl->intensity[1] = (float)g;
  871. dl->intensity[2] = (float)b;
  872. // Did we also get an "intensity" scaler value too?
  873. if (argCnt == 4)
  874. {
  875. // Scale the normalized 0-255 R,G,B values by the intensity scaler
  876. dl->intensity[0] = dl->intensity[0] / 255 * (float)scaler;
  877. dl->intensity[1] = dl->intensity[1] / 255 * (float)scaler;
  878. dl->intensity[2] = dl->intensity[2] / 255 * (float)scaler;
  879. }
  880. }
  881. else
  882. {
  883. Log("light at (%f,%f,%f) has bad or missing '_light' value : '%s'\n",
  884. dl->origin[0], dl->origin[1], dl->origin[2], pLight);
  885. continue;
  886. }
  887. dl->fade = FloatForKey(e, "_fade");
  888. if (dl->fade == 0.0)
  889. {
  890. dl->fade = g_fade;
  891. }
  892. dl->falloff = IntForKey(e, "_falloff");
  893. if (dl->falloff == 0)
  894. {
  895. dl->falloff = g_falloff;
  896. }
  897. target = ValueForKey(e, "target");
  898. if (!strcmp(name, "light_spot") || !strcmp(name, "light_environment") || target[0])
  899. {
  900. if (!VectorAvg(dl->intensity))
  901. {
  902. VectorFill(dl->intensity, 500);
  903. }
  904. dl->type = emit_spotlight;
  905. dl->stopdot = FloatForKey(e, "_cone");
  906. if (!dl->stopdot)
  907. {
  908. dl->stopdot = 10;
  909. }
  910. dl->stopdot2 = FloatForKey(e, "_cone2");
  911. if (!dl->stopdot2)
  912. {
  913. dl->stopdot2 = dl->stopdot;
  914. }
  915. if (dl->stopdot2 < dl->stopdot)
  916. {
  917. dl->stopdot2 = dl->stopdot;
  918. }
  919. dl->stopdot2 = (float)cos(dl->stopdot2 / 180 * Q_PI);
  920. dl->stopdot = (float)cos(dl->stopdot / 180 * Q_PI);
  921. if (target[0])
  922. { // point towards target
  923. e2 = FindTargetEntity(target);
  924. if (!e2)
  925. {
  926. Warning("light at (%i %i %i) has missing target",
  927. (int)dl->origin[0], (int)dl->origin[1], (int)dl->origin[2]);
  928. }
  929. else
  930. {
  931. GetVectorForKey(e2, "origin", dest);
  932. VectorSubtract(dest, dl->origin, dl->normal);
  933. VectorNormalize(dl->normal);
  934. }
  935. }
  936. else
  937. { // point down angle
  938. vec3_t vAngles;
  939. GetVectorForKey(e, "angles", vAngles);
  940. angle = (float)FloatForKey(e, "angle");
  941. if (angle == ANGLE_UP)
  942. {
  943. dl->normal[0] = dl->normal[1] = 0;
  944. dl->normal[2] = 1;
  945. }
  946. else if (angle == ANGLE_DOWN)
  947. {
  948. dl->normal[0] = dl->normal[1] = 0;
  949. dl->normal[2] = -1;
  950. }
  951. else
  952. {
  953. // if we don't have a specific "angle" use the "angles" YAW
  954. if (!angle)
  955. {
  956. angle = vAngles[1];
  957. }
  958. dl->normal[2] = 0;
  959. dl->normal[0] = (float)cos(angle / 180 * Q_PI);
  960. dl->normal[1] = (float)sin(angle / 180 * Q_PI);
  961. }
  962. angle = FloatForKey(e, "pitch");
  963. if (!angle)
  964. {
  965. // if we don't have a specific "pitch" use the "angles" PITCH
  966. angle = vAngles[0];
  967. }
  968. dl->normal[2] = (float)sin(angle / 180 * Q_PI);
  969. dl->normal[0] *= (float)cos(angle / 180 * Q_PI);
  970. dl->normal[1] *= (float)cos(angle / 180 * Q_PI);
  971. }
  972. if (FloatForKey(e, "_sky") || !strcmp(name, "light_environment"))
  973. {
  974. // -----------------------------------------------------------------------------------
  975. // Changes by Adam Foster - [email protected]
  976. // diffuse lighting hack - most of the following code nicked from earlier
  977. // need to get diffuse intensity from new _diffuse_light key
  978. //
  979. // What does _sky do for spotlights, anyway?
  980. // -----------------------------------------------------------------------------------
  981. #ifdef HLRAD_WHOME
  982. pLight = ValueForKey(e, "_diffuse_light");
  983. r = g = b = scaler = 0;
  984. argCnt = sscanf_s(pLight, "%lf %lf %lf %lf", &r, &g, &b, &scaler);
  985. dl->diffuse_intensity[0] = (float)r;
  986. if (argCnt == 1)
  987. {
  988. // The R,G,B values are all equal.
  989. dl->diffuse_intensity[1] = dl->diffuse_intensity[2] = (float)r;
  990. }
  991. else if (argCnt == 3 || argCnt == 4)
  992. {
  993. // Save the other two G,B values.
  994. dl->diffuse_intensity[1] = (float)g;
  995. dl->diffuse_intensity[2] = (float)b;
  996. // Did we also get an "intensity" scaler value too?
  997. if (argCnt == 4)
  998. {
  999. // Scale the normalized 0-255 R,G,B values by the intensity scaler
  1000. dl->diffuse_intensity[0] = dl->diffuse_intensity[0] / 255 * (float)scaler;
  1001. dl->diffuse_intensity[1] = dl->diffuse_intensity[1] / 255 * (float)scaler;
  1002. dl->diffuse_intensity[2] = dl->diffuse_intensity[2] / 255 * (float)scaler;
  1003. }
  1004. }
  1005. else
  1006. {
  1007. // backwards compatibility with maps without _diffuse_light
  1008. dl->diffuse_intensity[0] = dl->intensity[0];
  1009. dl->diffuse_intensity[1] = dl->intensity[1];
  1010. dl->diffuse_intensity[2] = dl->intensity[2];
  1011. }
  1012. #endif
  1013. // -----------------------------------------------------------------------------------
  1014. dl->type = emit_skylight;
  1015. dl->stopdot2 = FloatForKey(e, "_sky"); // hack stopdot2 to a sky key number
  1016. }
  1017. }
  1018. else
  1019. {
  1020. if (!VectorAvg(dl->intensity))
  1021. VectorFill(dl->intensity, 300);
  1022. dl->type = emit_point;
  1023. }
  1024. if (dl->type != emit_skylight)
  1025. {
  1026. l1 = max(dl->intensity[0], max(dl->intensity[1], dl->intensity[2]));
  1027. l1 = l1 * l1 / 10;
  1028. dl->intensity[0] *= l1;
  1029. dl->intensity[1] *= l1;
  1030. dl->intensity[2] *= l1;
  1031. }
  1032. }
  1033. hlassume(numdlights, assume_NoLights);
  1034. Log("Direct lights: %i\n", numdlights);
  1035. }
  1036. // =====================================================================================
  1037. // DeleteDirectLights
  1038. // =====================================================================================
  1039. void DeleteDirectLights()
  1040. {
  1041. int l;
  1042. directlight_t* dl;
  1043. for (l = 0; l < g_numleafs; l++)
  1044. {
  1045. dl = directlights[l];
  1046. while (dl)
  1047. {
  1048. directlights[l] = dl->next;
  1049. free(dl);
  1050. dl = directlights[l];
  1051. }
  1052. }
  1053. // AJM: todo: strip light entities out at this point
  1054. }
  1055. // =====================================================================================
  1056. // GatherSampleLight
  1057. // =====================================================================================
  1058. #define NUMVERTEXNORMALS 162
  1059. double r_avertexnormals[NUMVERTEXNORMALS][3] = {
  1060. #include "../common/anorms.h"
  1061. };
  1062. static void GatherSampleLight(const int input_facenum, const vec3_t pos, const byte* const pvs, const vec3_t normal, vec3_t* sample, byte* styles)
  1063. {
  1064. int i;
  1065. directlight_t* l;
  1066. vec3_t add;
  1067. vec3_t delta;
  1068. #ifdef HLRAD_FASTMATH2
  1069. const float LIGHT_EPSILON = ON_EPSILON;
  1070. float dot;
  1071. #else
  1072. float dot, dot2;
  1073. #endif
  1074. float dist;
  1075. float ratio;
  1076. #ifdef HLRAD_OPACITY // AJM
  1077. float l_opacity;
  1078. #endif
  1079. int style_index;
  1080. directlight_t* sky_used = NULL;
  1081. vec3_t transparency;
  1082. for (i = 1; i < g_numleafs; i++)
  1083. {
  1084. l = directlights[i];
  1085. if (l)
  1086. {
  1087. if (((l->type == emit_skylight) && (g_sky_lighting_fix)) || (pvs[(i - 1) >> 3] & (1 << ((i - 1) & 7))))
  1088. {
  1089. for (; l; l = l->next)
  1090. {
  1091. // skylights work fundamentally differently than normal lights
  1092. if (l->type == emit_skylight)
  1093. {
  1094. // only allow one of each sky type to hit any given point
  1095. if (sky_used)
  1096. {
  1097. continue;
  1098. }
  1099. sky_used = l;
  1100. // make sure the angle is okay
  1101. dot = -DotProduct(normal, l->normal);
  1102. if (dot <= ON_EPSILON / 10)
  1103. {
  1104. continue;
  1105. }
  1106. // search back to see if we can hit a sky brush
  1107. VectorScale(l->normal, -10000, delta);
  1108. VectorAdd(pos, delta, delta);
  1109. if (TestLine(pos, delta) != CONTENTS_SKY)
  1110. {
  1111. continue; // occluded
  1112. }
  1113. #ifdef HLRAD_HULLU
  1114. //removed reset of transparency - TestSegmentAgainstOpaqueList already resets to 1,1,1
  1115. int facenum = TestSegmentAgainstOpaqueList(pos, delta, transparency);
  1116. #else
  1117. int facenum = TestSegmentAgainstOpaqueList(pos, delta);
  1118. #endif
  1119. if(facenum > -1 && facenum != input_facenum)
  1120. {
  1121. continue;
  1122. }
  1123. VectorScale(l->intensity, dot, add);
  1124. #ifdef HLRAD_HULLU
  1125. VectorMultiply(add, transparency, add);
  1126. #endif
  1127. }
  1128. #ifdef HLRAD_FASTMATH2
  1129. else
  1130. {
  1131. VectorSubtract(l->origin,pos,delta);
  1132. dist = min(1,VectorNormalize(delta)); //VectorNormalize returns old length
  1133. dot = DotProduct(delta,normal);
  1134. if(dot <= LIGHT_EPSILON) { continue; } //behind surface
  1135. //calculate numberator factor caused by light type
  1136. switch(l->type)
  1137. {
  1138. case emit_point:
  1139. ratio = 1;
  1140. break;
  1141. case emit_surface:
  1142. ratio = -DotProduct(delta,l->normal);
  1143. if(ratio <= LIGHT_EPSILON) { continue; } //behind light surface
  1144. break;
  1145. case emit_spotlight:
  1146. ratio = -DotProduct(delta,l->normal);
  1147. if(ratio <= l->stopdot2) { continue; } //outside penumbra
  1148. if(ratio <= l->stopdot) //between umbra and penumbra - scale it
  1149. { ratio *= (ratio - l->stopdot2) / (l->stopdot - l->stopdot2); }
  1150. break;
  1151. default:
  1152. hlassume(false, assume_BadLightType);
  1153. break;
  1154. }
  1155. //primitive ratio (all types)
  1156. ratio *= dot;
  1157. ratio /= dist;
  1158. //calculate denominator factor caused by light type
  1159. switch(l->type)
  1160. {
  1161. case emit_point:
  1162. case emit_spotlight:
  1163. ratio /= l->fade;
  1164. if(l->falloff == 2)
  1165. { ratio /= dist; }
  1166. break;
  1167. case emit_surface:
  1168. ratio /= g_fade;
  1169. if(g_falloff == 2)
  1170. { ratio /= dist; }
  1171. break;
  1172. }
  1173. VectorScale(l->intensity, ratio, add);
  1174. }
  1175. #else
  1176. else
  1177. {
  1178. float denominator;
  1179. VectorSubtract(l->origin, pos, delta);
  1180. dist = VectorNormalize(delta);
  1181. dot = DotProduct(delta, normal);
  1182. // if (dot <= 0.0)
  1183. // continue;
  1184. if (dot <= ON_EPSILON / 10)
  1185. {
  1186. continue; // behind sample surface
  1187. }
  1188. if (dist < 1.0)
  1189. {
  1190. dist = 1.0;
  1191. }
  1192. // Variable power falloff (1 = inverse linear, 2 = inverse square
  1193. denominator = dist * l->fade;
  1194. if (l->falloff == 2)
  1195. {
  1196. denominator *= dist;
  1197. }
  1198. switch (l->type)
  1199. {
  1200. case emit_point:
  1201. {
  1202. // Variable power falloff (1 = inverse linear, 2 = inverse square
  1203. vec_t denominator = dist * l->fade;
  1204. if (l->falloff == 2)
  1205. {
  1206. denominator *= dist;
  1207. }
  1208. ratio = dot / denominator;
  1209. VectorScale(l->intensity, ratio, add);
  1210. break;
  1211. }
  1212. case emit_surface:
  1213. {
  1214. dot2 = -DotProduct(delta, l->normal);
  1215. if (dot2 <= ON_EPSILON / 10)
  1216. {
  1217. continue; // behind light surface
  1218. }
  1219. // Variable power falloff (1 = inverse linear, 2 = inverse square
  1220. vec_t denominator = dist * g_fade;
  1221. if (g_falloff == 2)
  1222. {
  1223. denominator *= dist;
  1224. }
  1225. ratio = dot * dot2 / denominator;
  1226. VectorScale(l->intensity, ratio, add);
  1227. break;
  1228. }
  1229. case emit_spotlight:
  1230. {
  1231. dot2 = -DotProduct(delta, l->normal);
  1232. if (dot2 <= l->stopdot2)
  1233. {
  1234. continue; // outside light cone
  1235. }
  1236. // Variable power falloff (1 = inverse linear, 2 = inverse square
  1237. vec_t denominator = dist * l->fade;
  1238. if (l->falloff == 2)
  1239. {
  1240. denominator *= dist;
  1241. }
  1242. ratio = dot * dot2 / denominator;
  1243. if (dot2 <= l->stopdot)
  1244. {
  1245. ratio *= (dot2 - l->stopdot2) / (l->stopdot - l->stopdot2);
  1246. }
  1247. VectorScale(l->intensity, ratio, add);
  1248. break;
  1249. }
  1250. default:
  1251. {
  1252. hlassume(false, assume_BadLightType);
  1253. break;
  1254. }
  1255. }
  1256. }
  1257. #endif
  1258. if (VectorMaximum(add) > (l->style ? g_coring : 0))
  1259. {
  1260. #ifdef HLRAD_HULLU
  1261. vec3_t transparency = {1.0,1.0,1.0};
  1262. #endif
  1263. if (l->type != emit_skylight && TestLine(pos, l->origin) != CONTENTS_EMPTY)
  1264. {
  1265. continue; // occluded
  1266. }
  1267. if (l->type != emit_skylight)
  1268. { // Don't test from light_environment entities to face, the special sky code occludes correctly
  1269. #ifdef HLRAD_HULLU
  1270. int facenum = TestSegmentAgainstOpaqueList(pos, delta, transparency);
  1271. #else
  1272. int facenum = TestSegmentAgainstOpaqueList(pos, delta);
  1273. #endif
  1274. if(facenum > -1 && facenum != input_facenum)
  1275. {
  1276. continue;
  1277. }
  1278. }
  1279. #ifdef HLRAD_OPACITY
  1280. //VectorScale(add, l_opacity, add);
  1281. #endif
  1282. for (style_index = 0; style_index < MAXLIGHTMAPS; style_index++)
  1283. {
  1284. if (styles[style_index] == l->style || styles[style_index] == 255)
  1285. {
  1286. break;
  1287. }
  1288. }
  1289. if (style_index == MAXLIGHTMAPS)
  1290. {
  1291. Warning("Too many direct light styles on a face(%f,%f,%f)", pos[0], pos[1], pos[2]);
  1292. continue;
  1293. }
  1294. if (styles[style_index] == 255)
  1295. {
  1296. styles[style_index] = l->style;
  1297. }
  1298. #ifdef HLRAD_HULLU
  1299. VectorMultiply(add,transparency,add);
  1300. #endif
  1301. VectorAdd(sample[style_index], add, sample[style_index]);
  1302. }
  1303. }
  1304. }
  1305. }
  1306. }
  1307. if (sky_used && g_indirect_sun != 0.0)
  1308. {
  1309. vec3_t total;
  1310. int j;
  1311. vec3_t sky_intensity;
  1312. // -----------------------------------------------------------------------------------
  1313. // Changes by Adam Foster - [email protected]
  1314. // Instead of using intensity from sky_used->intensity, get it from the new sky_used->diffuse_intensity
  1315. #ifdef HLRAD_WHOME
  1316. VectorScale(sky_used->diffuse_intensity, g_indirect_sun / (NUMVERTEXNORMALS * 2), sky_intensity);
  1317. #else
  1318. VectorScale(sky_used->intensity, g_indirect_sun / (NUMVERTEXNORMALS * 2), sky_intensity);
  1319. #endif
  1320. // That should be it. Who knows - it might actually work!
  1321. // AJM: It DOES actually work. Havent you ever heard of beta testing....
  1322. // -----------------------------------------------------------------------------------
  1323. total[0] = total[1] = total[2] = 0.0;
  1324. for (j = 0; j < NUMVERTEXNORMALS; j++)
  1325. {
  1326. // make sure the angle is okay
  1327. dot = -DotProduct(normal, r_avertexnormals[j]);
  1328. if (dot <= ON_EPSILON / 10)
  1329. {
  1330. continue;
  1331. }
  1332. // search back to see if we can hit a sky brush
  1333. VectorScale(r_avertexnormals[j], -10000, delta);
  1334. VectorAdd(pos, delta, delta);
  1335. if (TestLine(pos, delta) != CONTENTS_SKY)
  1336. {
  1337. continue; // occluded
  1338. }
  1339. VectorScale(sky_intensity, dot, add);
  1340. VectorAdd(total, add, total);
  1341. }
  1342. if (VectorMaximum(total) > 0)
  1343. {
  1344. for (style_index = 0; style_index < MAXLIGHTMAPS; style_index++)
  1345. {
  1346. if (styles[style_index] == sky_used->style || styles[style_index] == 255)
  1347. {
  1348. break;
  1349. }
  1350. }
  1351. if (style_index == MAXLIGHTMAPS)
  1352. {
  1353. Warning("Too many direct light styles on a face(%f,%f,%f)", pos[0], pos[1], pos[2]);
  1354. return;
  1355. }
  1356. if (styles[style_index] == 255)
  1357. {
  1358. styles[style_index] = sky_used->style;
  1359. }
  1360. VectorAdd(sample[style_index], total, sample[style_index]);
  1361. }
  1362. }
  1363. }
  1364. // =====================================================================================
  1365. // AddSampleToPatch
  1366. // Take the sample's collected light and add it back into the apropriate patch for the radiosity pass.
  1367. // =====================================================================================
  1368. #ifdef ZHLT_TEXLIGHT
  1369. static void AddSampleToPatch(const sample_t* const s, const int facenum, int style) //LRC
  1370. #else
  1371. static void AddSampleToPatch(const sample_t* const s, const int facenum)
  1372. #endif
  1373. {
  1374. patch_t* patch;
  1375. BoundingBox bounds;
  1376. int i;
  1377. if (g_numbounce == 0)
  1378. {
  1379. return;
  1380. }
  1381. for (patch = g_face_patches[facenum]; patch; patch = patch->next)
  1382. {
  1383. // see if the point is in this patch (roughly)
  1384. patch->winding->getBounds(bounds);
  1385. for (i = 0; i < 3; i++)
  1386. {
  1387. if (bounds.m_Mins[i] > s->pos[i] + 16)
  1388. {
  1389. goto nextpatch;
  1390. }
  1391. if (bounds.m_Maxs[i] < s->pos[i] - 16)
  1392. {
  1393. goto nextpatch;
  1394. }
  1395. }
  1396. // add the sample to the patch
  1397. #ifdef ZHLT_TEXLIGHT
  1398. //LRC:
  1399. for (i = 0; i < MAXLIGHTMAPS && patch->totalstyle[i] != 255; i++)
  1400. {
  1401. if (patch->totalstyle[i] == style)
  1402. break;
  1403. }
  1404. if (i == MAXLIGHTMAPS)
  1405. {
  1406. if(!g_warned_direct || g_verbose)
  1407. {
  1408. Warning("Too many light styles on a face(%f,%f,%f)",patch->origin[0],patch->origin[1],patch->origin[2]);
  1409. g_warned_direct = true;
  1410. }
  1411. }
  1412. else
  1413. {
  1414. if (patch->totalstyle[i] == 255)
  1415. {
  1416. patch->totalstyle[i] = style;
  1417. }
  1418. patch->samples[i]++;
  1419. VectorAdd(patch->samplelight[i], s->light, patch->samplelight[i]);
  1420. }
  1421. //LRC (ends)
  1422. #else
  1423. patch->samples++;
  1424. VectorAdd(patch->samplelight, s->light, patch->samplelight);
  1425. #endif
  1426. //return;
  1427. nextpatch:;
  1428. }
  1429. // don't worry if some samples don't find a patch
  1430. }
  1431. // =====================================================================================
  1432. // GetPhongNormal
  1433. // =====================================================================================
  1434. void GetPhongNormal(int facenum, vec3_t spot, vec3_t phongnormal)
  1435. {
  1436. int j;
  1437. const dface_t* f = g_dfaces + facenum;
  1438. const dplane_t* p = getPlaneFromFace(f);
  1439. vec3_t facenormal;
  1440. VectorCopy(p->normal, facenormal);
  1441. VectorCopy(facenormal, phongnormal);
  1442. if (g_smoothing_threshold > 0.0)
  1443. {
  1444. // Calculate modified point normal for surface
  1445. // Use the edge normals iff they are defined. Bend the surface towards the edge normal(s)
  1446. // Crude first attempt: find nearest edge normal and do a simple interpolation with facenormal.
  1447. // Second attempt: find edge points+center that bound the point and do a three-point triangulation(baricentric)
  1448. // Better third attempt: generate the point normals for all vertices and do baricentric triangulation.
  1449. for (j = 0; j < f->numedges; j++)
  1450. {
  1451. vec3_t p1;
  1452. vec3_t p2;
  1453. vec3_t v1;
  1454. vec3_t v2;
  1455. vec3_t vspot;
  1456. unsigned prev_edge;
  1457. unsigned next_edge;
  1458. int e;
  1459. int e1;
  1460. int e2;
  1461. edgeshare_t* es;
  1462. edgeshare_t* es1;
  1463. edgeshare_t* es2;
  1464. float a1;
  1465. float a2;
  1466. float aa;
  1467. float bb;
  1468. float ab;
  1469. if (j)
  1470. {
  1471. prev_edge = f->firstedge + ((j - 1) % f->numedges);
  1472. }
  1473. else
  1474. {
  1475. prev_edge = f->firstedge + f->numedges - 1;
  1476. }
  1477. if ((j + 1) != f->numedges)
  1478. {
  1479. next_edge = f->firstedge + ((j + 1) % f->numedges);
  1480. }
  1481. else
  1482. {
  1483. next_edge = f->firstedge;
  1484. }
  1485. e = g_dsurfedges[f->firstedge + j];
  1486. e1 = g_dsurfedges[prev_edge];
  1487. e2 = g_dsurfedges[next_edge];
  1488. es = &g_edgeshare[abs(e)];
  1489. es1 = &g_edgeshare[abs(e1)];
  1490. es2 = &g_edgeshare[abs(e2)];
  1491. if (
  1492. (es->coplanar && es1->coplanar && es2->coplanar)
  1493. ||
  1494. (VectorCompare(es->interface_normal, vec3_origin) &&
  1495. VectorCompare(es1->interface_normal, vec3_origin) &&
  1496. VectorCompare(es2->interface_normal, vec3_origin)))
  1497. {
  1498. continue;
  1499. }
  1500. if (e > 0)
  1501. {
  1502. VectorCopy(g_dvertexes[g_dedges[e].v[0]].point, p1);
  1503. VectorCopy(g_dvertexes[g_dedges[e].v[1]].point, p2);
  1504. }
  1505. else
  1506. {
  1507. VectorCopy(g_dvertexes[g_dedges[-e].v[1]].point, p1);
  1508. VectorCopy(g_dvertexes[g_dedges[-e].v[0]].point, p2);
  1509. }
  1510. // Adjust for origin-based models
  1511. VectorAdd(p1, g_face_offset[facenum], p1);
  1512. VectorAdd(p2, g_face_offset[facenum], p2);
  1513. // Build vectors from the middle of the face to the edge vertexes and the sample pos.
  1514. VectorSubtract(p1, g_face_centroids[facenum], v1);
  1515. VectorSubtract(p2, g_face_centroids[facenum], v2);
  1516. VectorSubtract(spot, g_face_centroids[facenum], vspot);
  1517. aa = DotProduct(v1, v1);
  1518. bb = DotProduct(v2, v2);
  1519. ab = DotProduct(v1, v2);
  1520. a1 = (bb * DotProduct(v1, vspot) - ab * DotProduct(vspot, v2)) / (aa * bb - ab * ab);
  1521. a2 = (DotProduct(vspot, v2) - a1 * ab) / bb;
  1522. // Test center to sample vector for inclusion between center to vertex vectors (Use dot product of vectors)
  1523. if (a1 >= 0.0 && a2 >= 0.0)
  1524. {
  1525. // calculate distance from edge to pos
  1526. vec3_t n1, n2;
  1527. vec3_t temp;
  1528. VectorAdd(es->interface_normal, es1->interface_normal, n1);
  1529. if (VectorCompare(n1, vec3_origin))
  1530. {
  1531. VectorCopy(facenormal, n1);
  1532. }
  1533. VectorNormalize(n1);
  1534. VectorAdd(es->interface_normal, es2->interface_normal, n2);
  1535. if (VectorCompare(n2, vec3_origin))
  1536. {
  1537. VectorCopy(facenormal, n2);
  1538. }
  1539. VectorNormalize(n2);
  1540. // Interpolate between the center and edge normals based on sample position
  1541. VectorScale(facenormal, 1.0 - a1 - a2, phongnormal);
  1542. VectorScale(n1, a1, temp);
  1543. VectorAdd(phongnormal, temp, phongnormal);
  1544. VectorScale(n2, a2, temp);
  1545. VectorAdd(phongnormal, temp, phongnormal);
  1546. VectorNormalize(phongnormal);
  1547. break;
  1548. }
  1549. }
  1550. }
  1551. }
  1552. const vec3_t s_circuscolors[] = {
  1553. {100000.0, 100000.0, 100000.0}, // white
  1554. {100000.0, 0.0, 0.0 }, // red
  1555. {0.0, 100000.0, 0.0 }, // green
  1556. {0.0, 0.0, 100000.0}, // blue
  1557. {0.0, 100000.0, 100000.0}, // cyan
  1558. {100000.0, 0.0, 100000.0}, // magenta
  1559. {100000.0, 100000.0, 0.0 } // yellow
  1560. };
  1561. // =====================================================================================
  1562. // BuildFacelights
  1563. // =====================================================================================
  1564. void BuildFacelights(const int facenum)
  1565. {
  1566. dface_t* f;
  1567. vec3_t sampled[MAXLIGHTMAPS];
  1568. lightinfo_t l;
  1569. int i;
  1570. int j;
  1571. int k;
  1572. sample_t* s;
  1573. vec_t* spot;
  1574. patch_t* patch;
  1575. const dplane_t* plane;
  1576. byte pvs[(MAX_MAP_LEAFS + 7) / 8];
  1577. int thisoffset = -1, lastoffset = -1;
  1578. int lightmapwidth;
  1579. int lightmapheight;
  1580. int size;
  1581. #ifdef HLRAD_HULLU
  1582. bool b_transparency_loss = false;
  1583. vec_t light_left_for_facelight = 1.0;
  1584. #endif
  1585. f = &g_dfaces[facenum];
  1586. //
  1587. // some surfaces don't need lightmaps
  1588. //
  1589. f->lightofs = -1;
  1590. for (j = 0; j < MAXLIGHTMAPS; j++)
  1591. {
  1592. f->styles[j] = 255;
  1593. }
  1594. if (g_texinfo[f->texinfo].flags & TEX_SPECIAL)
  1595. {
  1596. return; // non-lit texture
  1597. }
  1598. f->styles[0] = 0; // Everyone gets the style zero map.
  1599. memset(&l, 0, sizeof(l));
  1600. l.surfnum = facenum;
  1601. l.face = f;
  1602. //
  1603. // get transparency loss (part of light go through transparency faces.. reduce facelight on these)
  1604. //
  1605. #ifdef HLRAD_HULLU
  1606. for(unsigned int m = 0; m < g_opaque_face_count; m++)
  1607. {
  1608. opaqueList_t* opaque = &g_opaque_face_list[m];
  1609. if(opaque->facenum == facenum && opaque->transparency)
  1610. {
  1611. vec_t transparency = opaque->transparency;
  1612. b_transparency_loss = true;
  1613. light_left_for_facelight = 1.0 - transparency;
  1614. if( light_left_for_facelight < 0.0 ) light_left_for_facelight = 0.0;
  1615. if( light_left_for_facelight > 1.0 ) light_left_for_facelight = 1.0;
  1616. break;
  1617. }
  1618. }
  1619. #endif
  1620. //
  1621. // rotate plane
  1622. //
  1623. plane = getPlaneFromFace(f);
  1624. VectorCopy(plane->normal, l.facenormal);
  1625. l.facedist = plane->dist;
  1626. CalcFaceVectors(&l);
  1627. CalcFaceExtents(&l);
  1628. CalcPoints(&l);
  1629. lightmapwidth = l.texsize[0] + 1;
  1630. lightmapheight = l.texsize[1] + 1;
  1631. size = lightmapwidth * lightmapheight;
  1632. hlassume(size <= MAX_SINGLEMAP, assume_MAX_SINGLEMAP);
  1633. facelight[facenum].numsamples = l.numsurfpt;
  1634. for (k = 0; k < MAXLIGHTMAPS; k++)
  1635. {
  1636. facelight[facenum].samples[k] = (sample_t*)calloc(l.numsurfpt, sizeof(sample_t));
  1637. }
  1638. spot = l.surfpt[0];
  1639. for (i = 0; i < l.numsurfpt; i++, spot += 3)
  1640. {
  1641. vec3_t pointnormal = { 0, 0, 0 };
  1642. for (k = 0; k < MAXLIGHTMAPS; k++)
  1643. {
  1644. VectorCopy(spot, facelight[facenum].samples[k][i].pos);
  1645. }
  1646. // get the PVS for the pos to limit the number of checks
  1647. if (!g_visdatasize)
  1648. {
  1649. memset(pvs, 255, (g_numleafs + 7) / 8);
  1650. lastoffset = -1;
  1651. }
  1652. else
  1653. {
  1654. dleaf_t* leaf = PointInLeaf(spot);
  1655. thisoffset = leaf->visofs;
  1656. if (i == 0 || thisoffset != lastoffset)
  1657. {
  1658. hlassert(thisoffset != -1);
  1659. DecompressVis(&g_dvisdata[leaf->visofs], pvs, sizeof(pvs));
  1660. }
  1661. lastoffset = thisoffset;
  1662. }
  1663. memset(sampled, 0, sizeof(sampled));
  1664. // If we are doing "extra" samples, oversample the direct light around the point.
  1665. if (g_extra)
  1666. {
  1667. int weighting[3][3] = { {5, 9, 5}, {9, 16, 9}, {5, 9, 5} };
  1668. vec3_t pos;
  1669. int s, t, subsamples = 0;
  1670. for (t = -1; t <= 1; t++)
  1671. {
  1672. for (s = -1; s <= 1; s++)
  1673. {
  1674. int subsample = i + t * lightmapwidth + s;
  1675. int sample_s = i % lightmapwidth;
  1676. int sample_t = i / lightmapwidth;
  1677. if ((0 <= s + sample_s) && (s + sample_s < lightmapwidth)
  1678. && (0 <= t + sample_t)&&(t + sample_t <lightmapheight))
  1679. {
  1680. vec3_t subsampled[MAXLIGHTMAPS];
  1681. for (j = 0; j < MAXLIGHTMAPS; j++)
  1682. {
  1683. VectorFill(subsampled[j], 0);
  1684. }
  1685. // Calculate the point one third of the way toward the "subsample point"
  1686. VectorCopy(l.surfpt[i], pos);
  1687. VectorAdd(pos, l.surfpt[i], pos);
  1688. VectorAdd(pos, l.surfpt[subsample], pos);
  1689. VectorScale(pos, 1.0 / 3.0, pos);
  1690. GetPhongNormal(facenum, pos, pointnormal);
  1691. GatherSampleLight(facenum, pos, pvs, pointnormal, subsampled, f->styles);
  1692. for (j = 0; j < MAXLIGHTMAPS && (f->styles[j] != 255); j++)
  1693. {
  1694. VectorScale(subsampled[j], weighting[s + 1][t + 1], subsampled[j]);
  1695. VectorAdd(sampled[j], subsampled[j], sampled[j]);
  1696. }
  1697. subsamples += weighting[s + 1][t + 1];
  1698. }
  1699. }
  1700. }
  1701. for (j = 0; j < MAXLIGHTMAPS && (f->styles[j] != 255); j++)
  1702. {
  1703. VectorScale(sampled[j], 1.0 / subsamples, sampled[j]);
  1704. }
  1705. }
  1706. else
  1707. {
  1708. GetPhongNormal(facenum, spot, pointnormal);
  1709. GatherSampleLight(facenum, spot, pvs, pointnormal, sampled, f->styles);
  1710. }
  1711. for (j = 0; j < MAXLIGHTMAPS && (f->styles[j] != 255); j++)
  1712. {
  1713. VectorCopy(sampled[j], facelight[facenum].samples[j][i].light);
  1714. #ifdef HLRAD_HULLU
  1715. if(b_transparency_loss)
  1716. {
  1717. VectorScale(facelight[facenum].samples[j][i].light, light_left_for_facelight, facelight[facenum].samples[j][i].light);
  1718. }
  1719. #endif
  1720. #ifdef ZHLT_TEXLIGHT
  1721. AddSampleToPatch(&facelight[facenum].samples[j][i], facenum, f->styles[j]); //LRC
  1722. #else
  1723. if (f->styles[j] == 0)
  1724. {
  1725. AddSampleToPatch(&facelight[facenum].samples[j][i], facenum);
  1726. }
  1727. #endif
  1728. }
  1729. }
  1730. // average up the direct light on each patch for radiosity
  1731. if (g_numbounce > 0)
  1732. {
  1733. for (patch = g_face_patches[facenum]; patch; patch = patch->next)
  1734. {
  1735. #ifdef ZHLT_TEXLIGHT
  1736. //LRC:
  1737. unsigned istyle;
  1738. for (istyle = 0; istyle < MAXLIGHTMAPS && patch->totalstyle[istyle] != 255; istyle++)
  1739. {
  1740. if (patch->samples[istyle])
  1741. {
  1742. vec3_t v; // BUGBUG: Use a weighted average instead?
  1743. VectorScale(patch->samplelight[istyle], (1.0f / patch->samples[istyle]), v);
  1744. VectorAdd(patch->totallight[istyle], v, patch->totallight[istyle]);
  1745. VectorAdd(patch->directlight[istyle], v, patch->directlight[istyle]);
  1746. }
  1747. }
  1748. //LRC (ends)
  1749. #else
  1750. if (patch->samples)
  1751. {
  1752. vec3_t v; // BUGBUG: Use a weighted average instead?
  1753. VectorScale(patch->samplelight, (1.0f / patch->samples), v);
  1754. VectorAdd(patch->totallight, v, patch->totallight);
  1755. VectorAdd(patch->directlight, v, patch->directlight);
  1756. }
  1757. #endif
  1758. }
  1759. }
  1760. // add an ambient term if desired
  1761. if (g_ambient[0] || g_ambient[1] || g_ambient[2])
  1762. {
  1763. for (j = 0; j < MAXLIGHTMAPS && f->styles[j] != 255; j++)
  1764. {
  1765. if (f->styles[j] == 0)
  1766. {
  1767. s = facelight[facenum].samples[j];
  1768. for (i = 0; i < l.numsurfpt; i++, s++)
  1769. {
  1770. VectorAdd(s->light, g_ambient, s->light);
  1771. }
  1772. break;
  1773. }
  1774. }
  1775. }
  1776. // add circus lighting for finding black lightmaps
  1777. if (g_circus)
  1778. {
  1779. for (j = 0; j < MAXLIGHTMAPS && f->styles[j] != 255; j++)
  1780. {
  1781. if (f->styles[j] == 0)
  1782. {
  1783. int amt = 7;
  1784. s = facelight[facenum].samples[j];
  1785. while ((l.numsurfpt % amt) == 0)
  1786. {
  1787. amt--;
  1788. }
  1789. if (amt < 2)
  1790. {
  1791. amt = 7;
  1792. }
  1793. for (i = 0; i < l.numsurfpt; i++, s++)
  1794. {
  1795. if ((s->light[0] == 0) && (s->light[1] == 0) && (s->light[2] == 0))
  1796. {
  1797. VectorAdd(s->light, s_circuscolors[i % amt], s->light);
  1798. }
  1799. }
  1800. break;
  1801. }
  1802. }
  1803. }
  1804. // light from dlight_threshold and above is sent out, but the
  1805. // texture itself should still be full bright
  1806. // if( VectorAvg( face_patches[facenum]->baselight ) >= dlight_threshold) // Now all lighted surfaces glow
  1807. {
  1808. #ifdef ZHLT_TEXLIGHT
  1809. //LRC:
  1810. if (g_face_patches[facenum])
  1811. {
  1812. for (j = 0; j < MAXLIGHTMAPS && f->styles[j] != 255; j++)
  1813. {
  1814. if (f->styles[j] == g_face_patches[facenum]->emitstyle) //LRC
  1815. {
  1816. break;
  1817. }
  1818. }
  1819. if (j == MAXLIGHTMAPS)
  1820. {
  1821. if(!g_warned_direct || g_verbose)
  1822. {
  1823. Warning("Too many light styles on a face(%f,%f,%f)",g_face_patches[facenum]->origin[0],g_face_patches[facenum]->origin[1],g_face_patches[facenum]->origin[2]);
  1824. g_warned_direct = true;
  1825. }
  1826. }
  1827. else
  1828. {
  1829. if (f->styles[j] == 255)
  1830. {
  1831. f->styles[j] = g_face_patches[facenum]->emitstyle;
  1832. }
  1833. s = facelight[facenum].samples[j];
  1834. for (i = 0; i < l.numsurfpt; i++, s++)
  1835. {
  1836. VectorAdd(s->light, g_face_patches[facenum]->baselight, s->light);
  1837. }
  1838. }
  1839. }
  1840. //LRC (ends)
  1841. #else
  1842. for (j = 0; j < MAXLIGHTMAPS && f->styles[j] != 255; j++)
  1843. {
  1844. if (f->styles[j] == 0)
  1845. {
  1846. if (g_face_patches[facenum])
  1847. {
  1848. s = facelight[facenum].samples[j];
  1849. for (i = 0; i < l.numsurfpt; i++, s++)
  1850. {
  1851. VectorAdd(s->light, g_face_patches[facenum]->baselight, s->light);
  1852. }
  1853. break;
  1854. }
  1855. }
  1856. }
  1857. #endif
  1858. }
  1859. }
  1860. // =====================================================================================
  1861. // PrecompLightmapOffsets
  1862. // =====================================================================================
  1863. void PrecompLightmapOffsets()
  1864. {
  1865. int facenum;
  1866. dface_t* f;
  1867. facelight_t* fl;
  1868. int lightstyles;
  1869. #ifdef ZHLT_TEXLIGHT
  1870. int i; //LRC
  1871. patch_t* patch; //LRC
  1872. #endif
  1873. g_lightdatasize = 0;
  1874. for (facenum = 0; facenum < g_numfaces; facenum++)
  1875. {
  1876. f = &g_dfaces[facenum];
  1877. fl = &facelight[facenum];
  1878. if (g_texinfo[f->texinfo].flags & TEX_SPECIAL)
  1879. {
  1880. continue; // non-lit texture
  1881. }
  1882. #ifdef ZHLT_TEXLIGHT
  1883. //LRC - find all the patch lightstyles, and add them to the ones used by this face
  1884. patch = g_face_patches[facenum];
  1885. if (patch)
  1886. {
  1887. for (i = 0; i < MAXLIGHTMAPS && patch->totalstyle[i] != 255; i++)
  1888. {
  1889. for (lightstyles = 0; lightstyles < MAXLIGHTMAPS && f->styles[lightstyles] != 255; lightstyles++)
  1890. {
  1891. if (f->styles[lightstyles] == patch->totalstyle[i])
  1892. break;
  1893. }
  1894. if (lightstyles == MAXLIGHTMAPS)
  1895. {
  1896. if(!g_warned_direct || g_verbose)
  1897. {
  1898. Warning("Too many direct light styles on a face(%f,%f,%f)",patch->origin[0],patch->origin[1],patch->origin[2]);
  1899. g_warned_direct = true;
  1900. }
  1901. }
  1902. else if (f->styles[lightstyles] == 255)
  1903. {
  1904. f->styles[lightstyles] = patch->totalstyle[i];
  1905. // Log("Face acquires new lightstyle %d at offset %d\n", f->styles[lightstyles], lightstyles);
  1906. }
  1907. }
  1908. }
  1909. //LRC (ends)
  1910. #endif
  1911. for (lightstyles = 0; lightstyles < MAXLIGHTMAPS; lightstyles++)
  1912. {
  1913. if (f->styles[lightstyles] == 255)
  1914. {
  1915. break;
  1916. }
  1917. }
  1918. if (!lightstyles)
  1919. {
  1920. continue;
  1921. }
  1922. f->lightofs = g_lightdatasize;
  1923. g_lightdatasize += fl->numsamples * 3 * lightstyles;
  1924. }
  1925. }
  1926. // =====================================================================================
  1927. // FinalLightFace
  1928. // Add the indirect lighting on top of the direct lighting and save into final map format
  1929. // =====================================================================================
  1930. void FinalLightFace(const int facenum)
  1931. {
  1932. int i, j, k;
  1933. vec3_t lb, v;
  1934. facelight_t* fl;
  1935. sample_t* samp;
  1936. float minlight;
  1937. int lightstyles;
  1938. dface_t* f;
  1939. lerpTriangulation_t* trian = NULL;
  1940. // ------------------------------------------------------------------------
  1941. // Changes by Adam Foster - [email protected]
  1942. #ifdef HLRAD_WHOME
  1943. float temp_rand;
  1944. #endif
  1945. // ------------------------------------------------------------------------
  1946. f = &g_dfaces[facenum];
  1947. fl = &facelight[facenum];
  1948. if (g_texinfo[f->texinfo].flags & TEX_SPECIAL)
  1949. {
  1950. return; // non-lit texture
  1951. }
  1952. for (lightstyles = 0; lightstyles < MAXLIGHTMAPS; lightstyles++)
  1953. {
  1954. if (f->styles[lightstyles] == 255)
  1955. {
  1956. break;
  1957. }
  1958. }
  1959. if (!lightstyles)
  1960. {
  1961. return;
  1962. }
  1963. //
  1964. // set up the triangulation
  1965. //
  1966. if (g_numbounce)
  1967. {
  1968. trian = CreateTriangulation(facenum);
  1969. }
  1970. //
  1971. // sample the triangulation
  1972. //
  1973. minlight = FloatForKey(g_face_entity[facenum], "_minlight") * 128;
  1974. hlassume(f->lightofs + fl->numsamples*lightstyles*3 < g_max_map_lightdata, assume_MAX_MAP_LIGHTING);
  1975. for (k = 0; k < lightstyles; k++)
  1976. {
  1977. samp = fl->samples[k];
  1978. for (j = 0; j < fl->numsamples; j++, samp++)
  1979. {
  1980. // Should be a VectorCopy, but we scale by 2 to compensate for an earlier lighting flaw
  1981. // Specifically, the directlight contribution was included in the bounced light AND the directlight
  1982. // Since many of the levels were built with this assumption, this "fudge factor" compensates for it.
  1983. VectorScale(samp->light, g_direct_scale, lb);
  1984. #ifdef ZHLT_TEXLIGHT
  1985. if (g_numbounce)//LRC && (k == 0))
  1986. {
  1987. SampleTriangulation(trian, samp->pos, v, f->styles[k]); //LRC
  1988. #else
  1989. if (g_numbounce && (k == 0))
  1990. {
  1991. SampleTriangulation(trian, samp->pos, v);
  1992. #endif
  1993. if (isPointFinite(v))
  1994. {
  1995. VectorAdd(lb, v, lb);
  1996. }
  1997. else
  1998. {
  1999. Warning("point (%4.3f %4.3f %4.3f) infinite v (%4.3f %4.3f %4.3f)\n",
  2000. samp->pos[0], samp->pos[1], samp->pos[2], v[0], v[1], v[2]);
  2001. }
  2002. }
  2003. // ------------------------------------------------------------------------
  2004. // Changes by Adam Foster - [email protected]
  2005. // colour lightscale - code was originally:
  2006. #ifdef HLRAD_WHOME
  2007. lb[0] *= g_colour_lightscale[0];
  2008. lb[1] *= g_colour_lightscale[1];
  2009. lb[2] *= g_colour_lightscale[2];
  2010. #else
  2011. VectorScale(lb, g_lightscale, lb);
  2012. #endif
  2013. // ------------------------------------------------------------------------
  2014. // clip from the bottom first
  2015. for (i = 0; i < 3; i++)
  2016. {
  2017. if (lb[i] < minlight)
  2018. {
  2019. lb[i] = minlight;
  2020. }
  2021. }
  2022. // clip from the top
  2023. {
  2024. vec_t max = VectorMaximum(lb);
  2025. if (max > g_maxlight)
  2026. {
  2027. vec_t scale = g_maxlight / max;
  2028. lb[0] *= scale;
  2029. lb[1] *= scale;
  2030. lb[2] *= scale;
  2031. }
  2032. }
  2033. // ------------------------------------------------------------------------
  2034. // Changes by Adam Foster - [email protected]
  2035. #ifdef HLRAD_WHOME
  2036. // AJM: your code is formatted really wierd, and i cant understand a damn thing.
  2037. // so i reformatted it into a somewhat readable "normal" fashion. :P
  2038. // colour gamma - code was originally:
  2039. // if (g_qgamma != 1.0) {
  2040. // for (i = 0; i < 3; i++) {
  2041. // lb[i] = (float) pow(lb[i] / 256.0f, g_qgamma) * 256.0f;
  2042. // }
  2043. // }
  2044. if ( g_colour_qgamma[0] != 1.0 )
  2045. lb[0] = (float) pow(lb[0] / 256.0f, g_colour_qgamma[0]) * 256.0f;
  2046. if ( g_colour_qgamma[1] != 1.0 )
  2047. lb[1] = (float) pow(lb[1] / 256.0f, g_colour_qgamma[1]) * 256.0f;
  2048. if ( g_colour_qgamma[2] != 1.0 )
  2049. lb[2] = (float) pow(lb[2] / 256.0f, g_colour_qgamma[2]) * 256.0f;
  2050. // Two different ways of adding noise to the lightmap - colour jitter
  2051. // (red, green and blue channels are independent), and mono jitter
  2052. // (monochromatic noise). For simulating dithering, on the cheap. :)
  2053. // Tends to create seams between adjacent polygons, so not ideal.
  2054. // Got really weird results when it was set to limit values to 256.0f - it
  2055. // was as if r, g or b could wrap, going close to zero.
  2056. if (g_colour_jitter_hack[0] || g_colour_jitter_hack[1] || g_colour_jitter_hack[2])
  2057. {
  2058. for (i = 0; i < 3; i++)
  2059. {
  2060. lb[i] += g_colour_jitter_hack[i] * ((float)rand() / RAND_MAX - 0.5);
  2061. if (lb[i] < 0.0f)
  2062. {
  2063. lb[i] = 0.0f;
  2064. }
  2065. else if (lb[i] > 255.0f)
  2066. {
  2067. lb[i] = 255.0f;
  2068. }
  2069. }
  2070. }
  2071. if (g_jitter_hack[0] || g_jitter_hack[1] || g_jitter_hack[2])
  2072. {
  2073. temp_rand = (float)rand() / RAND_MAX - 0.5;
  2074. for (i = 0; i < 3; i++)
  2075. {
  2076. lb[i] += g_jitter_hack[i] * temp_rand;
  2077. if (lb[i] < 0.0f)
  2078. {
  2079. lb[i] = 0.0f;
  2080. }
  2081. else if (lb[i] > 255.0f)
  2082. {
  2083. lb[i] = 255.0f;
  2084. }
  2085. }
  2086. }
  2087. #else
  2088. if (g_qgamma != 1.0) {
  2089. for (i = 0; i < 3; i++) {
  2090. lb[i] = (float) pow(lb[i] / 256.0f, g_qgamma) * 256.0f;
  2091. }
  2092. }
  2093. #endif
  2094. // ------------------------------------------------------------------------
  2095. {
  2096. unsigned char* colors = &g_dlightdata[f->lightofs + k * fl->numsamples * 3 + j * 3];
  2097. colors[0] = (unsigned char)lb[0];
  2098. colors[1] = (unsigned char)lb[1];
  2099. colors[2] = (unsigned char)lb[2];
  2100. }
  2101. }
  2102. }
  2103. if (g_numbounce)
  2104. {
  2105. FreeTriangulation(trian);
  2106. }
  2107. }
  2108. #ifdef ZHLT_TEXLIGHT
  2109. //LRC
  2110. vec3_t totallight_default = { 0, 0, 0 };
  2111. //LRC - utility for getting the right totallight value from a patch
  2112. vec3_t* GetTotalLight(patch_t* patch, int style)
  2113. {
  2114. int i;
  2115. for (i = 0; i < MAXLIGHTMAPS && patch->totalstyle[i] != 255; i++)
  2116. {
  2117. if (patch->totalstyle[i] == style)
  2118. return &(patch->totallight[i]);
  2119. }
  2120. return &totallight_default;
  2121. }
  2122. #endif