lightmap.cpp 79 KB

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