Objekt_editor_raytracing.cpp 85 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344
  1. /*
  2. Ray-tracing sceny
  3. */
  4. #include "mss_on.h"
  5. #include <windows.h>
  6. #include <stdio.h>
  7. #include <math.h>
  8. #include <direct.h>
  9. #include <float.h>
  10. #include <assert.h>
  11. #include "objekt_editor_all.h"
  12. //#include "dbgwnd.h"
  13. __inline void ray_svetlost_vertex_poly_diff(TEXT_KOORD * p_koord);
  14. __inline void ray_svetlost_vertex_poly(K_EDITOR * p_cnf, TEXT_KOORD * p_koord,
  15. float lesk);
  16. __inline dword ray_interpoluj_2_barvy(dword b1, dword b2, float vaha2);
  17. __inline dword ray_svetlost_bodu(K_EDITOR * p_cnf, BOD * p_p,
  18. LIGHTMAP_INFO * p_akt, byte stiny, dword ambient, int no_phong);
  19. #define BLBA_BARVA 0xff0000
  20. #define BLBA_BARVA2 0xff0000
  21. /*
  22. #define OKRAJ 4
  23. #define MIN_X_TEXTURA 16
  24. #define MIN_Y_TEXTURA 16
  25. */
  26. #define OKRAJ (p_cnf->ray.okraj)
  27. #define MIN_X_TEXTURA (p_cnf->ray.text_min_x)
  28. #define MIN_Y_TEXTURA (p_cnf->ray.text_min_y)
  29. /*
  30. Brutalni 9-ti pixelovej filtr - radkovej
  31. */
  32. void ray_surface_filtruj_ctverec_9(bitmapa * p_bmp)
  33. {
  34. bitmapa *p_tmp;
  35. dword barva, r = 0, g = 0, b = 0;
  36. int cisel, i;
  37. int tabulka[] = { 1, 0, 1, 1, 0, 1, -1, 1, -1, 0, -1, -1, 0, -1, 1, -1 };
  38. int x, y, dx, dy;
  39. int px, py;
  40. p_tmp = bmp_kopituj(p_bmp);
  41. dx = p_bmp->x;
  42. dy = p_bmp->y;
  43. for (x = 0; x < dx; x++) {
  44. for (y = 0; y < dy; y++) {
  45. barva = bmp_getpixel(p_tmp, x, y);
  46. r = GetRValue(barva);
  47. g = GetGValue(barva);
  48. b = GetBValue(barva);
  49. cisel = 1;
  50. for (i = 0; i < 16; i += 2) {
  51. px = x + tabulka[i];
  52. py = y + tabulka[i + 1];
  53. if (px >= 0 && px < dx && py >= 0 && py < dy) {
  54. barva = bmp_getpixel(p_tmp, px, py);
  55. if (barva != BLBA_BARVA) {
  56. r += GetRValue(barva);
  57. g += GetGValue(barva);
  58. b += GetBValue(barva);
  59. cisel++;
  60. }
  61. }
  62. }
  63. mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) cisel);
  64. bmp_putpixel(p_bmp, x, y, barva);
  65. }
  66. }
  67. bmp_zrus(&p_tmp);
  68. }
  69. void ray_surface_filtruj_ctverec_25(bitmapa * p_bmp)
  70. {
  71. bitmapa *p_tmp;
  72. dword barva, r = 0, g = 0, b = 0;
  73. int cisel, i;
  74. int tabulka[] = { 0, 0,
  75. 1, 0, 1, 1, 0, 1, -1, 1,
  76. -1, 0, -1, -1, 0, -1, 1, -1,
  77. -2, -2, -1, -2, 0, -2, 1, -2, 2, -2, // spodek
  78. -2, 2, -1, 2, 0, 2, 1, 2, 2, 2, // vrsek
  79. -2, 1, -2, 0, -2, -1,
  80. 2, 1, 2, 0, 2, -1
  81. };
  82. int x, y, dx, dy;
  83. int px, py;
  84. p_tmp = bmp_kopituj(p_bmp);
  85. dx = p_bmp->x;
  86. dy = p_bmp->y;
  87. for (x = 0; x < dx; x++) {
  88. for (y = 0; y < dy; y++) {
  89. r = g = b = 0;
  90. cisel = 0;
  91. for (i = 0; i < 25; i += 2) {
  92. px = x + tabulka[i];
  93. py = y + tabulka[i + 1];
  94. if (px >= 0 && px < dx && py >= 0 && py < dy) {
  95. barva = bmp_getpixel(p_tmp, px, py);
  96. r += GetRValue(barva);
  97. g += GetGValue(barva);
  98. b += GetBValue(barva);
  99. cisel++;
  100. }
  101. }
  102. mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) cisel);
  103. bmp_putpixel(p_bmp, x, y, barva);
  104. }
  105. }
  106. bmp_zrus(&p_tmp);
  107. }
  108. void ray_surface_filtruj_krizem_9(bitmapa * p_bmp)
  109. {
  110. bitmapa *p_tmp;
  111. dword barva, r = 0, g = 0, b = 0;
  112. int cisel, i;
  113. int tabulka[] = { 0, 0, 0, 1, 0, -1, 1, 0, -1, 0 };
  114. int x, y, dx, dy;
  115. int px, py;
  116. p_tmp = bmp_kopituj(p_bmp);
  117. dx = p_bmp->x;
  118. dy = p_bmp->y;
  119. for (x = 0; x < dx; x++) {
  120. for (y = 0; y < dy; y++) {
  121. r = g = b = 0;
  122. cisel = 0;
  123. for (i = 0; i < 10; i += 2) {
  124. px = x + tabulka[i];
  125. py = y + tabulka[i + 1];
  126. if (px >= 0 && px < dx && py >= 0 && py < dy) {
  127. barva = bmp_getpixel(p_tmp, px, py);
  128. r += GetRValue(barva);
  129. g += GetGValue(barva);
  130. b += GetBValue(barva);
  131. cisel++;
  132. }
  133. }
  134. mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) cisel);
  135. bmp_putpixel(p_bmp, x, y, barva);
  136. }
  137. }
  138. bmp_zrus(&p_tmp);
  139. }
  140. void ray_surface_filtruj_krizem_25(bitmapa * p_bmp)
  141. {
  142. bitmapa *p_tmp;
  143. dword barva, r = 0, g = 0, b = 0;
  144. int cisel, i;
  145. int tabulka[] = { 0, 0,
  146. 0, 1, 0, -1, 1, 0, -1, 0,
  147. 0, 2, 0, -2, 2, 0, -2, 0
  148. };
  149. int x, y, dx, dy;
  150. int px, py;
  151. p_tmp = bmp_kopituj(p_bmp);
  152. dx = p_bmp->x;
  153. dy = p_bmp->y;
  154. for (x = 0; x < dx; x++) {
  155. for (y = 0; y < dy; y++) {
  156. r = g = b = 0;
  157. cisel = 0;
  158. for (i = 0; i < 18; i += 2) {
  159. px = x + tabulka[i];
  160. py = y + tabulka[i + 1];
  161. if (px >= 0 && px < dx && py >= 0 && py < dy) {
  162. barva = bmp_getpixel(p_tmp, px, py);
  163. r += GetRValue(barva);
  164. g += GetGValue(barva);
  165. b += GetBValue(barva);
  166. cisel++;
  167. }
  168. }
  169. mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) cisel);
  170. bmp_putpixel(p_bmp, x, y, barva);
  171. }
  172. }
  173. bmp_zrus(&p_tmp);
  174. }
  175. void ray_surface_filtruj_rovne_25(bitmapa * p_bmp)
  176. {
  177. bitmapa *p_tmp;
  178. dword barva, r = 0, g = 0, b = 0;
  179. int cisel, i;
  180. int tabulka[] = { 0, 0,
  181. 1, 0, -1, 0,
  182. 2, 0, -2, 0
  183. };
  184. int x, y, dx, dy;
  185. int px, py;
  186. p_tmp = bmp_kopituj(p_bmp);
  187. dx = p_bmp->x;
  188. dy = p_bmp->y;
  189. for (x = 0; x < dx; x++) {
  190. for (y = 0; y < dy; y++) {
  191. r = g = b = 0;
  192. cisel = 0;
  193. for (i = 0; i < 10; i += 2) {
  194. px = x + tabulka[i];
  195. py = y + tabulka[i + 1];
  196. if (px >= 0 && px < dx && py >= 0 && py < dy) {
  197. barva = bmp_getpixel(p_tmp, px, py);
  198. r += GetRValue(barva);
  199. g += GetGValue(barva);
  200. b += GetBValue(barva);
  201. cisel++;
  202. }
  203. }
  204. mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) cisel);
  205. bmp_putpixel(p_bmp, x, y, barva);
  206. }
  207. }
  208. bmp_zrus(&p_tmp);
  209. }
  210. static int ray_surface_filtruj_medianem_compare(const void *p_b1,
  211. const void *p_b2)
  212. {
  213. float b1, b2;
  214. b1 = ((RGB *) p_b1)->r + ((RGB *) p_b1)->g + ((RGB *) p_b1)->b;
  215. b2 = ((RGB *) p_b2)->r + ((RGB *) p_b2)->g + ((RGB *) p_b2)->b;
  216. return ((int) ((b2 - b1) * 0.0001f));
  217. }
  218. void ray_surface_filtruj_medianem(bitmapa * p_bmp)
  219. {
  220. bitmapa *p_tmp;
  221. dword barva;
  222. float b[3];
  223. int i;
  224. int tabulka[] = { 1, 0, 1, 1, 0, 1, -1, 1, -1, 0, -1, -1, 0, -1, 1, -1,
  225. 2, 0, 2, 1, 2, 2, 1, 2, 0, 2, -1, 2, -2, 2, -2, 1, -2, 0, -2, -1, -2, -2,
  226. -1, -2, 0, -2, 1, -2, 2, -2, -2, 1
  227. };
  228. RGB ct[25];
  229. int p;
  230. int x, y, dx, dy;
  231. int px, py;
  232. p_tmp = bmp_kopituj(p_bmp);
  233. dx = p_bmp->x;
  234. dy = p_bmp->y;
  235. for (x = 0; x < dx; x++) {
  236. for (y = 0; y < dy; y++) {
  237. barva = bmp_getpixel(p_tmp, x, y);
  238. p = 0;
  239. if (barva != BLBA_BARVA) {
  240. rgb_float(barva, &ct[p].r);
  241. p++;
  242. for (i = 0; i < 50; i += 2) {
  243. px = x + tabulka[i];
  244. py = y + tabulka[i + 1];
  245. if (px > 0 && px < dx && py > 0 && py < dy) {
  246. barva = bmp_getpixel(p_tmp, px, py);
  247. if (barva != BLBA_BARVA) {
  248. rgb_float(barva, &ct[p].r);
  249. p++;
  250. }
  251. }
  252. }
  253. //spocitam prumer
  254. b[0] = b[1] = b[3] = 0.0f;
  255. for (i = 0; i < p; i++) {
  256. b[0] += ct[i].r;
  257. b[1] += ct[i].g;
  258. b[2] += ct[i].b;
  259. }
  260. b[0] /= p;
  261. b[1] /= p;
  262. b[2] /= p;
  263. bmp_putpixel(p_bmp, x, y, float_rgb(b));
  264. }
  265. }
  266. }
  267. bmp_zrus(&p_tmp);
  268. }
  269. /*
  270. Prevedu pole lightmap na jednotliva podpole s poctama lightmap
  271. */
  272. void ray_poly_optim_lightmap(EDIT_MESH_POLY * p_poly)
  273. {
  274. EDIT_TEXT **p_klight =
  275. (EDIT_TEXT **) _alloca(p_poly->lightnum * sizeof(EDIT_TEXT *));
  276. int *p_pocty = (int *) _alloca(p_poly->lightnum * sizeof(int *));
  277. EDIT_TEXT *p_last = NULL;
  278. int i, p;
  279. if (p_poly->p_lightnum) {
  280. assert(0);
  281. }
  282. for (i = 0, p = -1; i < p_poly->lightnum; i++) {
  283. if (p_last != p_poly->p_light[i]) {
  284. p++;
  285. p_last = p_klight[p] = p_poly->p_light[i];
  286. p_pocty[p] = 3;
  287. }
  288. else {
  289. p_pocty[p] += 3; //pocty facu
  290. }
  291. }
  292. // pocet lightmap je p+1
  293. p_poly->lightnum = ++p;
  294. free(p_poly->p_light);
  295. if (!(p_poly->p_light = (EDIT_TEXT **) malloc(sizeof(EDIT_TEXT *) * p)))
  296. chyba("Pamet");
  297. if (!(p_poly->p_lightnum = (int *) malloc(sizeof(int) * p)))
  298. chyba("Pamet");
  299. memcpy(p_poly->p_light, p_klight, sizeof(EDIT_TEXT *) * p);
  300. memcpy(p_poly->p_lightnum, p_pocty, sizeof(int) * p);
  301. }
  302. /* return
  303. 0 - vrsek
  304. 1 - bok
  305. 2 - druhy bok
  306. 3 - fuck
  307. -- plati pro bod s barvou 0xff000000
  308. */
  309. int ray_surface_pozice_bodu(bitmapa * p_bmp, int px, int py)
  310. {
  311. int dx = p_bmp->x, dy = p_bmp->y;
  312. if (py + 1 >= dy)
  313. return (3);
  314. if (py - 1 <= 0)
  315. return (0);
  316. if (px + 1 >= dx)
  317. return (2);
  318. if (px - 1 <= 0)
  319. return (1);
  320. if (bmp_getpixel(p_bmp, px, py + 1) != BLBA_BARVA)
  321. return (0);
  322. else {
  323. if (bmp_getpixel(p_bmp, px, py - 1) == BLBA_BARVA)
  324. return (3);
  325. if (bmp_getpixel(p_bmp, px - 1, py) != BLBA_BARVA)
  326. return (2);
  327. if (bmp_getpixel(p_bmp, px + 1, py) != BLBA_BARVA)
  328. return (1);
  329. else
  330. return (3);
  331. }
  332. }
  333. void ray_surface_filtruj_okraj(bitmapa * p_bmp, int okraj, dword * p_p1,
  334. int dp1, dword * p_p2, int dp2, dword * p_p3, int dp3)
  335. {
  336. dword barva, r = 0, g = 0, b = 0;
  337. int cisel, i;
  338. int tabulka[] =
  339. { 0, 0, 1, 0, 1, 1, 0, 1, -1, 1, -1, 0, -1, -1, 0, -1, 1, -1 };
  340. // int tabulka[] = {0,0, 1,0, 0,1, -1,0, 0,-1};
  341. int x, y, dx, dy;
  342. int px, py;
  343. dx = p_bmp->x;
  344. dy = p_bmp->y;
  345. for (x = okraj; x < (dx - okraj); x++) {
  346. for (y = okraj; y < (dy - okraj); y++) {
  347. if (bmp_getpixel(p_bmp, x, y) == BLBA_BARVA)
  348. continue;
  349. for (i = 0, cisel = 0; i < 18; i += 2) {
  350. // for(i = 0, cisel = 0; i < 10; i+=2) {
  351. px = x + tabulka[i];
  352. py = y + tabulka[i + 1];
  353. if (px > 0 && px < dx && py > 0 && py < dy) {
  354. barva = bmp_getpixel(p_bmp, px, py);
  355. if (barva != BLBA_BARVA) {
  356. r += GetRValue(barva);
  357. g += GetGValue(barva);
  358. b += GetBValue(barva);
  359. cisel++;
  360. }
  361. else {
  362. // nacteni barvy z pruhu
  363. // 1. zjistim jaky to je pripad (odkud to nacist)
  364. switch (ray_surface_pozice_bodu(p_bmp, px, py)) {
  365. case 0: // je to vrchni pixel
  366. if (dp1) {
  367. barva = p_p1[px];
  368. r += GetRValue(barva);
  369. g += GetGValue(barva);
  370. b += GetBValue(barva);
  371. cisel++;
  372. }
  373. break;
  374. case 1: // je to levy-bocni pixel
  375. if (dp2) {
  376. barva = p_p2[py];
  377. r += GetRValue(barva);
  378. g += GetGValue(barva);
  379. b += GetBValue(barva);
  380. cisel++;
  381. }
  382. break;
  383. case 2: // je to pravy-bocni pixel
  384. if (dp3) {
  385. barva = p_p3[py];
  386. r += GetRValue(barva);
  387. g += GetGValue(barva);
  388. b += GetBValue(barva);
  389. cisel++;
  390. }
  391. break;
  392. default: // je to neco divnyho
  393. break;
  394. }
  395. }
  396. }
  397. }
  398. mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) cisel);
  399. r = g = b = 0;
  400. bmp_putpixel(p_bmp, x, y, barva);
  401. }
  402. }
  403. }
  404. dword ray_interpoluj_barvy(dword * p_barva, int pocet)
  405. {
  406. dword r = 0, g = 0, b = 0, barva;
  407. int i;
  408. for (i = 0; i < pocet; i++) {
  409. r += GetRValue(p_barva[i]);
  410. g += GetGValue(p_barva[i]);
  411. b += GetBValue(p_barva[i]);
  412. }
  413. mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) pocet);
  414. return (barva);
  415. }
  416. int ray_okraj_roztahni(dword ** p_prh, int delka, int new_delka)
  417. {
  418. dword *p_pruh = *p_prh;
  419. dword *p_npruh;
  420. int i;
  421. float kf;
  422. if (delka == new_delka)
  423. return (new_delka);
  424. if (!(p_npruh = malloc(new_delka * sizeof(dword))))
  425. chyba("Pamet");
  426. memset(p_npruh, 0, new_delka * sizeof(dword));
  427. kf = (float) delka / (float) new_delka;
  428. for (i = 0; i < new_delka; i++) {
  429. assert((int) floor(kf * i) < delka);
  430. p_npruh[i] = p_pruh[(int) floor(kf * i)];
  431. }
  432. free(*p_prh);
  433. *p_prh = p_npruh;
  434. return (new_delka);
  435. }
  436. __inline dword ray_interpoluj_2_barvy(dword b1, dword b2, float vaha2)
  437. {
  438. dword r, g, b, barva;
  439. r = GetRValue(b1) + (dword) (vaha2 * GetRValue(b2));
  440. g = GetGValue(b1) + (dword) (vaha2 * GetGValue(b2));
  441. b = GetBValue(b1) + (dword) (vaha2 * GetBValue(b2));
  442. mult_color_rgb_max(&barva, r, g, b, 1.0f / (vaha2 + 1));
  443. return (barva);
  444. }
  445. void ray_surface_nastav_barvu_bodu(bitmapa * p_bmp, QBOD * p_hity, int delka,
  446. dword barva)
  447. {
  448. int x, y;
  449. int i;
  450. for (i = 0; i < delka; i++) {
  451. if (p_hity[i].z) {
  452. x = p_hity[i].x;
  453. y = p_hity[i].y;
  454. bmp_putpixel(p_bmp, x, y, barva);
  455. }
  456. }
  457. }
  458. /*
  459. Zpusob prace:
  460. while(stupen) {
  461. 0. Nacteni okraju vsech surfacu
  462. 1. Doplneni okraju do surfacu
  463. Udelani ke kazdemu surfacu seznam zapsanych bodu
  464. 3. Filtrovani surfacu (vcetne hranicnich bodu)
  465. 4. Smaz okraje
  466. }
  467. 5. Nacti spolecne okraje
  468. 6. Pokud spolu plosky sousedi -> vytvor spolecny okraj
  469. 7. Vloz okraje
  470. 8. Roztahni textury (dopln na pozadovane rozmery)
  471. */
  472. void ray_poly_filtruj_lightmapy(POLY_INDICIE * p_ind, int indnum,
  473. EDIT_MESH_POLY * p_poly_list, EDIT_TEXT * p_src,
  474. int stupen, int mezi, int filtrace)
  475. {
  476. int st;
  477. int i;
  478. if (!stupen)
  479. return;
  480. for (st = 0; st < stupen; st++) {
  481. /************************************************
  482. Filtruj surfacy plosek
  483. *************************************************/
  484. if (filtrace) {
  485. for (i = 0; i < indnum; i++) {
  486. p_cnf->ray.p_akt_filtr_func->p_fnc(p_src[i].p_bmp);
  487. }
  488. }
  489. }
  490. }
  491. /*
  492. transformace bodu 3D -> 2D a zpet
  493. Pro kazdou plosku:
  494. 0. transformovat 3D plosku do 2D
  495. 1. podle rozmeru vyrobit mapu
  496. 2. vyrobit rastr a pro vsechny body:
  497. 3. kazdy bod mapy transformovat z 2D do 3D
  498. 4. zjistit svetlo bodu
  499. 5. Zapsat svetlo do mapy
  500. */
  501. /*
  502. Postup:
  503. Ke kazdemu svetlu ve scene
  504. */
  505. void calc_face_matrix(TRIANGLE * p_tri, GLMATRIX * p_mat)
  506. {
  507. GLMATRIX cm;
  508. BOD s, up, ri, fr;
  509. float vzd1, vzd2, vzd3, vzdn, ti;
  510. MUJ_BOD a, b, c;
  511. ROVINA r;
  512. BOD p;
  513. init_matrix(&cm);
  514. // stred trojuhelniku
  515. s.x = (p_tri->a.x + p_tri->b.x + p_tri->c.x) / 3.0f;
  516. s.y = (p_tri->a.y + p_tri->b.y + p_tri->c.y) / 3.0f;
  517. s.z = (p_tri->a.z + p_tri->b.z + p_tri->c.z) / 3.0f;
  518. // nejdelsi strana trojuhelnika
  519. vzd1 = vzdal_bodu(&p_tri->a, &p_tri->b);
  520. vzd2 = vzdal_bodu(&p_tri->b, &p_tri->c);
  521. vzd3 = vzdal_bodu(&p_tri->c, &p_tri->a);
  522. if (vzd1 > vzd2) {
  523. if (vzd1 > vzd3) {
  524. // nejvetsi vzd1
  525. a = p_tri->a;
  526. b = p_tri->b;
  527. c = p_tri->c;
  528. vzdn = vzd1;
  529. }
  530. else {
  531. // nejvetsi vzd3
  532. a = p_tri->c;
  533. b = p_tri->a;
  534. c = p_tri->b;
  535. vzdn = vzd3;
  536. }
  537. }
  538. else {
  539. if (vzd2 > vzd3) {
  540. // nejvetsi vzd2
  541. a = p_tri->b;
  542. b = p_tri->c;
  543. c = p_tri->a;
  544. vzdn = vzd2;
  545. }
  546. else {
  547. // nejvetsi vzd3
  548. a = p_tri->c;
  549. b = p_tri->a;
  550. c = p_tri->b;
  551. vzdn = vzd3;
  552. }
  553. }
  554. // p je bod na te primce
  555. ti =
  556. ((b.x - a.x) * (s.x - a.x) + (b.y - a.y) * (s.y - a.y) + (b.z -
  557. a.z) * (s.z - a.z)) / (vzdn * vzdn);
  558. p.x = a.x + (b.x - a.x) * ti;
  559. p.y = a.y + (b.y - a.y) * ti;
  560. p.z = a.z + (b.z - a.z) * ti;
  561. // preskladani plosky -> mezi a-b je nejvetsi delka
  562. p_tri->a = a;
  563. p_tri->b = b;
  564. p_tri->c = c;
  565. // vektor nahoru
  566. up.x = p.x - s.x;
  567. up.y = p.y - s.y;
  568. up.z = p.z - s.z;
  569. // vektor dopredu -> norm vekt. plosky
  570. calc_rovinu(&a, &b, &c, &r);
  571. fr.x = r.x;
  572. fr.y = r.y;
  573. fr.z = r.z;
  574. // vektor nabok -> osa x
  575. vektor_soucin(&fr, &up, &ri);
  576. // prisel cas normalizace
  577. norm_vect(&fr.x, &fr.y, &fr.z);
  578. norm_vect(&up.x, &up.y, &up.z);
  579. norm_vect(&ri.x, &ri.y, &ri.z);
  580. cm._11 = ri.x;
  581. cm._21 = ri.y;
  582. cm._31 = ri.z; // x vektor -> ri
  583. cm._12 = up.x;
  584. cm._22 = up.y;
  585. cm._32 = up.z; // y vektor -> up
  586. cm._13 = fr.x;
  587. cm._23 = fr.y;
  588. cm._33 = fr.z; // z vektor -> fr
  589. cm._41 = s.x; // umisteni kamery
  590. cm._42 = s.y;
  591. cm._43 = s.z;
  592. //invert_matrix(&cm,p_mat);
  593. *p_mat = cm;
  594. }
  595. /*
  596. transformuje 3D face do 2D prostoru
  597. */
  598. void trface(TRIANGLE * p_tri, TRIANGLE * p_tr, GLMATRIX * p_mat, float faktor)
  599. {
  600. transf_3d_2d_matrix_float_text(p_tri->a.x, p_tri->a.y, p_tri->a.z,
  601. &p_tr->a.x, &p_tr->a.y, &p_tr->a.z, p_mat, faktor);
  602. transf_3d_2d_matrix_float_text(p_tri->b.x, p_tri->b.y, p_tri->b.z,
  603. &p_tr->b.x, &p_tr->b.y, &p_tr->b.z, p_mat, faktor);
  604. transf_3d_2d_matrix_float_text(p_tri->c.x, p_tri->c.y, p_tri->c.z,
  605. &p_tr->c.x, &p_tr->c.y, &p_tr->c.z, p_mat, faktor);
  606. }
  607. /*
  608. Prusecit 2D trojuhelniku s 2D bodem
  609. // validni je akorat x a y ve vsech bodech
  610. */
  611. __inline int ray_intersect_tri_point(BOD * p_a, BOD * p_b, BOD * p_c,
  612. BOD * p_p)
  613. {
  614. float k1, k2, q1, q2;
  615. float x;
  616. calc_primku_2d(p_a, p_c, &k1, &q1);
  617. calc_primku_2d(p_b, p_c, &k2, &q2);
  618. x = (p_p->y - q1) / k1;
  619. if (x > p_p->x)
  620. return (FALSE);
  621. x = (p_p->y - q2) / k2;
  622. if (x < p_p->x)
  623. return (FALSE);
  624. else
  625. return (TRUE);
  626. }
  627. // 2D interpolace normaloveho vektoru
  628. __inline void interpolace_vektoru(TRIANGLE * p_tri, BOD * p_a, BOD * p_b,
  629. BOD * p_c, BOD * p_p, BOD * p_int)
  630. {
  631. BOD p1, p2, v1, v2;
  632. float k1, k2, q1, q2;
  633. float vzd1, vzd2;
  634. calc_primku_2d(p_a, p_c, &k1, &q1);
  635. calc_primku_2d(p_b, p_c, &k2, &q2);
  636. p1.y = p2.y = p_p->y;
  637. p1.x = (p_p->y - q1) / k1;
  638. p2.x = (p_p->y - q2) / k2;
  639. vzd1 = vzdal_bodu_2D_bod(p_a, &p1);
  640. vzd2 = vzdal_bodu_2D_bod(p_c, &p1);
  641. v1.x = (p_tri->a.nx * vzd2 + p_tri->c.nx * vzd1) / (vzd1 + vzd2);
  642. v1.y = (p_tri->a.ny * vzd2 + p_tri->c.ny * vzd1) / (vzd1 + vzd2);
  643. v1.z = (p_tri->a.nz * vzd2 + p_tri->c.nz * vzd1) / (vzd1 + vzd2);
  644. vzd1 = vzdal_bodu_2D_bod(p_b, &p2);
  645. vzd2 = vzdal_bodu_2D_bod(p_c, &p2);
  646. v2.x = (p_tri->b.nx * vzd2 + p_tri->c.nx * vzd1) / (vzd1 + vzd2);
  647. v2.y = (p_tri->b.ny * vzd2 + p_tri->c.ny * vzd1) / (vzd1 + vzd2);
  648. v2.z = (p_tri->b.nz * vzd2 + p_tri->c.nz * vzd1) / (vzd1 + vzd2);
  649. vzd1 = p_p->x - p1.x;
  650. vzd2 = p2.x - p_p->x;
  651. p_int->x = (v1.x * vzd2 + v2.x * vzd1) / (vzd1 + vzd2);
  652. p_int->y = (v1.y * vzd2 + v2.y * vzd1) / (vzd1 + vzd2);
  653. p_int->z = (v1.z * vzd2 + v2.z * vzd1) / (vzd1 + vzd2);
  654. }
  655. // y = k*x + q
  656. /*
  657. transformace bodu 3D -> 2D a zpet
  658. Pro kazdou plosku:
  659. 0. transformovat 3D plosku do 2D
  660. 1. podle rozmeru vyrobit mapu
  661. 2. vyrobit rastr a pro vsechny body:
  662. 3. kazdy bod mapy transformovat z 2D do 3D
  663. 4. zjistit svetlo bodu
  664. 5. Zapsat svetlo do mapy
  665. typedef struct _LIGHTMAP_INFO {
  666. int k,o,f;
  667. } LIGHTMAP_INFO;
  668. #define RAY_TEXTUR 200
  669. bitmapa * p_tray[RAY_TEXTUR]; // light-map textury k ray-tracingu
  670. LIGHTMAP_INFO face[RAY_TEXTUR]; // popis
  671. int ray_posledni = 0;
  672. */
  673. void ray_calc_korekci_koordinatu(TRIANGLE * p_tri, TEXT_KOORD * p_koord,
  674. bitmapa * p_bmp)
  675. {
  676. BODUV *p_ua, *p_ub, *p_uc;
  677. BOD *p_da, *p_db, *p_dc;
  678. float x_tk;
  679. float y_tk;
  680. p_da = (BOD *) & p_tri->a;
  681. p_db = (BOD *) & p_tri->b;
  682. p_dc = (BOD *) & p_tri->c;
  683. p_ua = (BODUV *) & p_koord[0].tul;
  684. p_ub = (BODUV *) & p_koord[1].tul;
  685. p_uc = (BODUV *) & p_koord[2].tul;
  686. if (OKRAJ) {
  687. x_tk = (float) OKRAJ / p_bmp->x;
  688. y_tk = (float) OKRAJ / p_bmp->y;
  689. }
  690. else {
  691. x_tk = 0;
  692. y_tk = 0;
  693. }
  694. p_ua->u = 0.0f + x_tk;
  695. p_ua->v = 0.0f + y_tk;
  696. p_ub->u = 1.0f - x_tk;
  697. p_ub->v = 0.0f + y_tk;
  698. p_uc->u = ((p_da->x - p_dc->x) / (p_da->x - p_db->x)) + x_tk;
  699. p_uc->v = 1.0f - y_tk;
  700. }
  701. bitmapa *ray_calc_lightmap_face(K_EDITOR * p_cnf, TRIANGLE * p_tri,
  702. TRIANGLE * p_tri2d, LIGHTMAP_INFO * p_akt, byte stiny, int no_phong)
  703. {
  704. bitmapa *p_text;
  705. GLMATRIX m, inv_m;
  706. int dx, dy, x, y;
  707. float iddx, iddy;
  708. float dx_faktor, dy_faktor;
  709. float fx, fy, fz;
  710. float x_tk;
  711. float y_tk;
  712. BOD p, a, b, c, pp;
  713. dword barva;
  714. int stinovani = p_cnf->ray.stinovani;
  715. int max_x, max_y;
  716. float mx, my, mz;
  717. calc_face_matrix(p_tri, &m); //transf. matice teto plosky
  718. invert_matrix(&m, &inv_m); // inverzni matice
  719. trface(p_tri, p_tri2d, &m, p_cnf->ray.faktor); // preved plosku do 2D
  720. //assert(p_tri2d->a.x < p_tri2d->b.x);
  721. if (p_tri2d->a.x >= p_tri2d->b.x)
  722. kprintf(TRUE, "p_tri2d->a.x >= p_tri2d->b.x... p = %d f = %f",
  723. p_akt->poly, p_akt->f);
  724. mujbod2bod(&a, &p_tri2d->a);
  725. mujbod2bod(&b, &p_tri2d->b);
  726. mujbod2bod(&c, &p_tri2d->c);
  727. // uprava na ctverec a spocitani ctvercovych scale faktoru
  728. // sirka mezi body trojuhelniku
  729. iddx = (float) fabs(a.x - b.x);
  730. iddy = (float) fabs(a.y - c.y);
  731. max_x = p_cnf->ray.max_x_surface >> 1;
  732. max_y = p_cnf->ray.max_y_surface >> 1;
  733. for (dx = MIN_X_TEXTURA;
  734. (dx - 2 * OKRAJ) < iddx && (dx - 2 * OKRAJ) < max_x; dx <<= 1);
  735. for (dy = MIN_Y_TEXTURA;
  736. (dy - 2 * OKRAJ) < iddy && (dy - 2 * OKRAJ) < max_y; dy <<= 1);
  737. // faktor - sirka jednoho texelu
  738. dx_faktor = iddx / (float) (dx - 2 * OKRAJ);
  739. dy_faktor = iddy / (float) (dy - 2 * OKRAJ);
  740. /*
  741. text korekce je sirka jednoho pixelu
  742. */
  743. if (OKRAJ) {
  744. x_tk = (float) OKRAJ / dx;
  745. y_tk = (float) OKRAJ / dy;
  746. }
  747. else {
  748. x_tk = 0;
  749. y_tk = 0;
  750. }
  751. p_tri->a.tul = 0.0f + x_tk;
  752. p_tri->a.tvl = 0.0f + y_tk;
  753. p_tri->b.tul = 1.0f - x_tk;
  754. p_tri->b.tvl = 0.0f + y_tk;
  755. p_tri->c.tul = ((a.x - c.x) / (a.x - b.x));
  756. p_tri->c.tvl = 1.0f - y_tk;
  757. // soupni do light akt facenormal
  758. p_akt->normal.x = m._13;
  759. p_akt->normal.y = m._23;
  760. p_akt->normal.z = m._33;
  761. if (stinovani == SHAD_FLAT)
  762. p_akt->normal_bod = p_akt->normal;
  763. // vyrob odpovidajici texturu
  764. if ((p_text = bmp_vyrob(dx, dy)) == NULL)
  765. chybat(STC, "Vyroba bmp -> dx = %d, dy = %d bpp = %d", dx, dy, 32);
  766. bmp_smaz(p_text, BLBA_BARVA);
  767. // I. pruchod -> pocitam pixely ulozene uvnitr trojuhelniku
  768. for (y = 0; y < dy; y++) {
  769. for (x = 0; x < dx; x++) {
  770. // prevedu bod textury do 3D
  771. fx = a.x + ((float) (x - OKRAJ + 0.5f) * dx_faktor);
  772. fy = a.y - ((float) (y - OKRAJ + 0.5f) * dy_faktor);
  773. fz = a.z;
  774. mx = fx / p_cnf->ray.faktor;
  775. my = fy / p_cnf->ray.faktor;
  776. mz = fz / p_cnf->ray.faktor;
  777. p.x = inv_m._11 * mx + inv_m._21 * my + inv_m._31 * mz + inv_m._41;
  778. p.y = inv_m._12 * mx + inv_m._22 * my + inv_m._32 * mz + inv_m._42;
  779. p.z = inv_m._13 * mx + inv_m._23 * my + inv_m._33 * mz + inv_m._43;
  780. pp.x = fx;
  781. pp.y = fy;
  782. pp.z = fz;
  783. p_cnf->stat.ray_bodu++; // statistika pouziti
  784. if (stinovani == SHAD_PHONG) {
  785. interpolace_vektoru(p_tri, &a, &b, &c, &pp, &p_akt->normal_bod);
  786. }
  787. barva =
  788. ray_svetlost_bodu(p_cnf, &p, p_akt, stiny, p_cnf->ray.ambient,
  789. no_phong);
  790. barva &= 0x00ffffff;
  791. bmp_putpixel(p_text, x, y, barva);
  792. }
  793. }
  794. return (p_text);
  795. }
  796. void ray_dopln_okraj_surf(bitmapa * p_bmp)
  797. {
  798. int x, y, dx, dy;
  799. int faze;
  800. dword barva, clamp_barva;
  801. dx = p_bmp->x;
  802. dy = p_bmp->y;
  803. // II. pruchod -> doplnim pixely ulozene vne trojuhelniku
  804. for (y = OKRAJ; y < (dy - OKRAJ); y++) {
  805. faze = 0;
  806. for (x = 0; x < dx; x++) {
  807. barva = bmp_getpixel(p_bmp, x, y);
  808. if (barva == BLBA_BARVA) {
  809. if (faze)
  810. bmp_putpixel(p_bmp, x, y, clamp_barva);
  811. }
  812. else {
  813. if (faze)
  814. clamp_barva = barva;
  815. else {
  816. faze = x;
  817. for (x = 0; x < faze; x++)
  818. bmp_putpixel(p_bmp, x, y, barva);
  819. faze = TRUE;
  820. }
  821. }
  822. }
  823. }
  824. if (OKRAJ) {
  825. for (x = 0; x < dx; x++) {
  826. barva = bmp_getpixel(p_bmp, x, OKRAJ);
  827. bmp_putpixel(p_bmp, x, 0, barva);
  828. barva = bmp_getpixel(p_bmp, x, dy - OKRAJ - 1);
  829. if (barva == BLBA_BARVA) {
  830. barva = bmp_getpixel(p_bmp, x, dy - OKRAJ - 2);
  831. bmp_putpixel(p_bmp, x, dy - OKRAJ - 1, barva);
  832. }
  833. bmp_putpixel(p_bmp, x, dy - 1, barva);
  834. }
  835. }
  836. }
  837. void ray_dopln_okraje(K_EDITOR * p_cnf, EDIT_TEXT * p_src, int textnum)
  838. {
  839. int t;
  840. for (t = 0; t < textnum; t++) {
  841. ray_dopln_okraj_surf(p_src[t].p_bmp);
  842. }
  843. }
  844. #define SUPER_MIN_X 8
  845. #define SUPER_MIN_Y 8
  846. bitmapa *ray_surface_supersampl(bitmapa * p_zdroj, byte hloubka, int kx,
  847. int ky)
  848. {
  849. bitmapa *p_cil = NULL;
  850. bitmapa *p_src = NULL;
  851. dword r, g, b;
  852. int x, y, dx, dy;
  853. int sx, sy, h, p;
  854. dword barva = 0;
  855. for (h = 0; h < hloubka; h++) {
  856. if (p_src) {
  857. bmp_zrus(&p_src);
  858. p_src = p_cil;
  859. }
  860. else {
  861. p_src = bmp_kopituj(p_zdroj);
  862. }
  863. dx = p_src->x;
  864. dy = p_src->y;
  865. if (dx / kx < SUPER_MIN_X || dy / ky < SUPER_MIN_Y) {
  866. return (p_src);
  867. }
  868. p_cil = bmp_vyrob(dx / kx, dy / ky);
  869. if (!p_cil)
  870. chyba("Vyrobeni surfacy !");
  871. for (y = 0; y < dy; y += kx) {
  872. for (x = 0; x < dx; x += ky) {
  873. r = g = b = p = 0;
  874. for (sy = 0; sy < ky; sy++) {
  875. for (sx = 0; sx < kx; sx++) {
  876. barva = bmp_getpixel(p_src, x + sx, y + sy);
  877. if (barva != BLBA_BARVA) {
  878. r += GetRValue(barva);
  879. g += GetGValue(barva);
  880. b += GetBValue(barva);
  881. p++;
  882. }
  883. }
  884. }
  885. if (p) {
  886. mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) p);
  887. bmp_putpixel(p_cil, x / kx, y / ky, barva);
  888. }
  889. }
  890. }
  891. }
  892. bmp_zrus(&p_src);
  893. return (p_cil);
  894. }
  895. void ray_surface_supersampling(POLY_INDICIE * p_ind, int indnum,
  896. TRIANGLE * p_tri, EDIT_MESH_POLY * p_poly, EDIT_TEXT * p_src, byte hloubka,
  897. int kx, int ky)
  898. {
  899. bitmapa *p_text;
  900. int i;
  901. for (i = 0; i < indnum; i++) {
  902. p_text = ray_surface_supersampl(p_src[i].p_bmp, hloubka, kx, ky);
  903. bmp_zrus(&p_src[i].p_bmp);
  904. p_src[i].p_bmp = p_text;
  905. ray_calc_korekci_koordinatu(p_tri + i,
  906. p_poly[p_ind[i].poly].p_koord + p_ind[i].face, p_text);
  907. }
  908. }
  909. void ray_dopln_okraj_spodni(bitmapa * p_bmp, int okraj)
  910. {
  911. int x, dx, dy;
  912. dword barva;
  913. dx = p_bmp->x;
  914. dy = p_bmp->y;
  915. assert(okraj < 2);
  916. if (okraj) {
  917. for (x = 0; x < dx; x++) {
  918. barva = bmp_getpixel(p_bmp, x, dy - okraj - 1);
  919. bmp_putpixel(p_bmp, x, dy - 1, barva);
  920. }
  921. }
  922. }
  923. __inline static int ray_zacatek_masky(dword maska)
  924. {
  925. int i = 0;
  926. while (!(maska & 0x1)) {
  927. maska >>= 1;
  928. i++;
  929. }
  930. return (i);
  931. }
  932. #define MIN_T 0.99f
  933. int ray_intersect_poly(EDIT_MESH_POLY * p_poly, BOD * p_orig, BOD * p_dir,
  934. LIGHTMAP_INFO * p_akt)
  935. {
  936. BOD p1, p2, p3;
  937. float t, u, v, mint = MIN_T;
  938. int f, mf;
  939. if (p_poly->mail == p_akt->mail)
  940. return (FALSE);
  941. else
  942. p_poly->mail = p_akt->mail;
  943. if (obb_intersect_line(&p_poly->obb, p_orig, p_dir)) {
  944. for (f = 0; f < p_poly->facenum; f += 3) {
  945. if ((p_poly->poly == p_akt->poly) && (f == p_akt->f
  946. || f == p_akt->vface[0] || f == p_akt->vface[1]
  947. || f == p_akt->vface[2]))
  948. continue;
  949. p1.x = p_poly->p_koord[f].x;
  950. p1.y = p_poly->p_koord[f].y;
  951. p1.z = p_poly->p_koord[f].z;
  952. p2.x = p_poly->p_koord[f + 1].x;
  953. p2.y = p_poly->p_koord[f + 1].y;
  954. p2.z = p_poly->p_koord[f + 1].z;
  955. p3.x = p_poly->p_koord[f + 2].x;
  956. p3.y = p_poly->p_koord[f + 2].y;
  957. p3.z = p_poly->p_koord[f + 2].z;
  958. if (intersect_triangle_ncull(p_orig, p_dir, &p1, &p2, &p3, &t, &u, &v)) {
  959. if (t > 0.0f && t < mint) {
  960. mint = t;
  961. mf = f;
  962. }
  963. }
  964. }
  965. }
  966. return (mint != MIN_T);
  967. }
  968. int ray_intersect_kont(EDIT_KONTEJNER * p_kont, BOD * p_orig, BOD * p_dir,
  969. LIGHTMAP_INFO * p_akt)
  970. {
  971. BOD p1, p2, p3, *p_tmp;
  972. EDIT_OBJEKT *p_obj;
  973. float t = 1.0f, u, v, mint = MIN_T;
  974. int f, mf, o, h = 0;
  975. if (p_kont->mailbox == p_akt->mail)
  976. return (FALSE);
  977. else
  978. p_kont->mailbox = p_akt->mail;
  979. if (obb_intersect_line(&p_kont->obb, p_orig, p_dir)) {
  980. for (o = 0; o < p_kont->objektu; o++) {
  981. p_obj = p_kont->p_obj[o];
  982. assert(p_obj);
  983. if (p_kont->objektu && !obb_intersect_line(&p_obj->obb, p_orig, p_dir))
  984. continue;
  985. for (f = 0; f < p_obj->facenum; f += 3) {
  986. p_tmp = (BOD *) (p_obj->p_vertex + p_obj->p_face[f]);
  987. p1 = *p_tmp;
  988. p_tmp = (BOD *) (p_obj->p_vertex + p_obj->p_face[f + 1]);
  989. p2 = *p_tmp;
  990. p_tmp = (BOD *) (p_obj->p_vertex + p_obj->p_face[f + 2]);
  991. p3 = *p_tmp;
  992. if (intersect_triangle_ncull(p_orig, p_dir, &p1, &p2, &p3, &t, &u,
  993. &v)) {
  994. if (t > 0.0f && t < mint) {
  995. mint = t;
  996. mf = f;
  997. h++;
  998. }
  999. }
  1000. }
  1001. }
  1002. }
  1003. return (mint != MIN_T);
  1004. }
  1005. /*
  1006. Prusecik stinoveho paprsku se stromem -> presne rozmery paprsku
  1007. */
  1008. /*
  1009. Intersektuje scenu paprsku -> zacne tam kde je cil paprsku
  1010. 1. Testuj posledni hit
  1011. 2. Vlez tam kde je cil posledniho hitu (texel)
  1012. 3. Testuj prusecik v teto oblasti
  1013. 4. Pokud neni hit->testuj okoli smerem ke zdroji
  1014. */
  1015. BOD oct_cilovy_bod;
  1016. int oct_intersect_tree_shadow_ray(KD_BUNKA * p_prvni, BOD * p_orig,
  1017. BOD * p_dir, LIGHTMAP_INFO * p_akt)
  1018. {
  1019. KD_BUNKA *p_list[2];
  1020. KD_BUNKA *p_bunka = p_prvni;
  1021. BOD cil;
  1022. int i, hit = 0;
  1023. BOD s1, s2;
  1024. /*
  1025. Stinovy paprsek
  1026. */
  1027. cil.x = p_orig->x + p_dir->x;
  1028. cil.y = p_orig->y + p_dir->y;
  1029. cil.z = p_orig->z + p_dir->z;
  1030. /*
  1031. Odkud vychazet
  1032. */
  1033. while (p_bunka->p_next) { // test na pouzitou rovinu
  1034. switch (p_bunka->rovina) {
  1035. case 0: // rovina x
  1036. i = (cil.x > p_bunka->vzdal) ? 1 : 0;
  1037. break;
  1038. case 1: // rovina y
  1039. i = (cil.y > p_bunka->vzdal) ? 1 : 0;
  1040. break;
  1041. case 2: // rovina z
  1042. i = (cil.z > p_bunka->vzdal) ? 1 : 0;
  1043. break;
  1044. default:
  1045. assert(0);
  1046. break;
  1047. }
  1048. p_bunka = p_bunka->p_next + i;
  1049. }
  1050. while (1) {
  1051. /*
  1052. Je prusecik v teto kostce
  1053. */
  1054. if (!kd_intersect_kostku_dir(p_orig, p_dir, &p_bunka->min, &p_bunka->max)) {
  1055. p_bunka->mail = p_akt->mail;
  1056. if (!(p_bunka = p_bunka->p_up)) {
  1057. p_akt->ray_phit = K_CHYBA;
  1058. p_akt->ray_khit = K_CHYBA;
  1059. return (FALSE);
  1060. }
  1061. }
  1062. /*
  1063. Nalezena intersekce v teto bunce
  1064. */
  1065. if (!p_bunka->p_next) {
  1066. /*
  1067. Je to list stromu
  1068. */
  1069. if (p_bunka->p_polozka) {
  1070. for (i = 0; i < p_bunka->polozek; i++) {
  1071. if (p_bunka->p_polozka_typ[i] == KD_POLY) {
  1072. if (ray_intersect_poly(p_bunka->p_polozka[i], p_orig, p_dir,
  1073. p_akt)) {
  1074. p_akt->ray_phit =
  1075. ((EDIT_MESH_POLY *) (p_bunka->p_polozka[i]))->poly;
  1076. p_akt->ray_khit = K_CHYBA;
  1077. return (TRUE);
  1078. }
  1079. }
  1080. else {
  1081. if (ray_intersect_kont(p_bunka->p_polozka[i], p_orig, p_dir,
  1082. p_akt)) {
  1083. p_akt->ray_phit = K_CHYBA;
  1084. p_akt->ray_khit =
  1085. ((EDIT_KONTEJNER *) p_bunka->p_polozka[i])->kont;
  1086. return (TRUE);
  1087. }
  1088. }
  1089. }
  1090. }
  1091. /*
  1092. V listu nenalezena intersekce -> okolni listy
  1093. + posun nahoru
  1094. Nastavim u miss bunky mail-flag
  1095. */
  1096. p_bunka->mail = p_akt->mail;
  1097. /*
  1098. Level-Up, pokud jsem u konce
  1099. */
  1100. if (!(p_bunka = p_bunka->p_up)) {
  1101. p_akt->ray_phit = K_CHYBA;
  1102. p_akt->ray_khit = K_CHYBA;
  1103. return (FALSE);
  1104. }
  1105. }
  1106. else {
  1107. /*
  1108. Je to uzel stromu -> spracuj podstromy
  1109. seradim podle stredu blizkosti k originu
  1110. */
  1111. oct_cilovy_bod.x = p_orig->x;
  1112. oct_cilovy_bod.y = p_orig->y;
  1113. oct_cilovy_bod.z = p_orig->z;
  1114. p_list[0] = p_bunka->p_next;
  1115. p_list[1] = p_bunka->p_next + 1;
  1116. kd_stred_bunky(&p_list[0]->min, &p_list[0]->max, &s1);
  1117. kd_stred_bunky(&p_list[1]->min, &p_list[1]->max, &s2);
  1118. if (vzdal_bodu_bod(&s1, &oct_cilovy_bod) > vzdal_bodu_bod(&s2,
  1119. &oct_cilovy_bod)) {
  1120. p_list[1] = p_bunka->p_next;
  1121. p_list[0] = p_bunka->p_next + 1;
  1122. }
  1123. for (i = 0; i < 2; i++) {
  1124. if (p_list[i]->mail != p_akt->mail && (p_list[i]->p_next
  1125. || p_list[i]->p_polozka)) {
  1126. if (kd_intersect_kostku_dir(p_orig, p_dir, &p_list[i]->min,
  1127. &p_list[i]->max)) {
  1128. p_bunka = p_list[i];
  1129. break;
  1130. }
  1131. else {
  1132. p_list[i]->mail = p_akt->mail;
  1133. }
  1134. }
  1135. }
  1136. /* Level-Up
  1137. */
  1138. if (i == 2) {
  1139. p_bunka->mail = p_akt->mail;
  1140. if (!(p_bunka = p_bunka->p_up)) {
  1141. p_akt->ray_phit = K_CHYBA;
  1142. p_akt->ray_khit = K_CHYBA;
  1143. return (FALSE);
  1144. }
  1145. }
  1146. }
  1147. }
  1148. }
  1149. // spocita svetlost bodu ve scene
  1150. // pomoci paprsku
  1151. /*
  1152. typedef struct _STATIC_LIGHT {
  1153. byte jmeno[50]; // jmeno svetla
  1154. int index; // index svetla
  1155. BOD p; // pozice svetla
  1156. dword rgb; // barva
  1157. float k1,k2,k3; // tlumici koeficienty
  1158. float dosah; // max. dosah svetla
  1159. } STATIC_LIGHT;
  1160. */
  1161. // p_p je bod pro ktery pocitam
  1162. #define MIN_LIGHT 0.002f
  1163. // pokud je pixel uvnitr trojuhelniku -> vloz interpolaci
  1164. // pokud je pixel ven z trojuhelniku -> vloz hodnotu barvy nejblizsi hrany
  1165. __inline dword ray_svetlost_bodu(K_EDITOR * p_cnf, BOD * p_p,
  1166. LIGHTMAP_INFO * p_akt, byte stiny, dword ambient, int no_phong)
  1167. {
  1168. STATIC_LIGHT *p_light;
  1169. BOD sv, dir, mdir;
  1170. int barva = 0;
  1171. int l, h;
  1172. static int akt_ray = 0;
  1173. float dist, k1, k2, k3, I, uhel, dd[3];
  1174. rgb_float(ambient, dd);
  1175. for (l = 0; l < p_cnf->lightnum; l++) {
  1176. p_light = p_cnf->light + l;
  1177. if (!p_light->akt)
  1178. continue;
  1179. I = 1;
  1180. sv = p_cnf->light[l].p;
  1181. dist = vzdal_bodu_bod_vec(p_p, sv);
  1182. if (dist > p_light->dosah)
  1183. continue;
  1184. calc_vect_dir_vec(sv, p_p, dir);
  1185. mdir = dir;
  1186. norm_vect(&dir.x, &dir.y, &dir.z);
  1187. if (!no_phong) {
  1188. uhel = (skal_soucin(p_akt->normal_bod, dir)); //cosinus uhlu
  1189. if (uhel > 0 && p_light->uhel)
  1190. I = uhel;
  1191. else
  1192. I = p_light->uhel ? 0.0f : 1.0f;
  1193. }
  1194. if (p_light->utlum) {
  1195. k1 = p_light->k1;
  1196. k2 = p_light->k2;
  1197. k3 = p_light->k3;
  1198. I *= 1.0f / (k1 + k2 * dist + k3 * dist * dist);
  1199. }
  1200. if (I > MIN_LIGHT && stiny) {
  1201. p_akt->mail = ++akt_ray;
  1202. /*
  1203. Test posledniho hitu -> neni to pribuzny ?
  1204. */
  1205. if (p_light->last_poly != K_CHYBA) {
  1206. if (ray_intersect_poly(p_cnf->p_poly + p_light->last_poly, &sv, &mdir,
  1207. p_akt)) {
  1208. continue;
  1209. }
  1210. }
  1211. if (p_light->last_kont != K_CHYBA) {
  1212. if (ray_intersect_kont(p_cnf->p_kont_raytracer[p_light->last_kont],
  1213. &sv, &mdir, p_akt)) {
  1214. continue;
  1215. }
  1216. }
  1217. /*
  1218. Jinak -> frcime full-serach
  1219. */
  1220. h = oct_intersect_tree_shadow_ray(&p_cnf->kdtree, &sv, &mdir, p_akt);
  1221. p_light->last_poly = p_akt->ray_phit;
  1222. p_light->last_kont = p_akt->ray_khit;
  1223. I = (h) ? 0.0f : I;
  1224. }
  1225. dd[0] += p_light->r * I;
  1226. dd[1] += p_light->g * I;
  1227. dd[2] += p_light->b * I;
  1228. if (dd[0] > 1.0f && dd[1] > 1.0f && dd[2] > 1.0f) {
  1229. break;
  1230. }
  1231. }
  1232. if (dd[0] > 1.0f)
  1233. dd[0] = 1.0f;
  1234. if (dd[1] > 1.0f)
  1235. dd[1] = 1.0f;
  1236. if (dd[2] > 1.0f)
  1237. dd[2] = 1.0f;
  1238. return (float_rgb(dd));
  1239. }
  1240. void propocitej_barvu_bod(OBJ_VERTEX * p_bod, BOD * p_light, dword rgb,
  1241. float I, GLMATRIX * p_word)
  1242. {
  1243. float px, py, pz;
  1244. float tx, ty, tz;
  1245. float uhel;
  1246. px = p_bod->nx; // normalovy vektor
  1247. py = p_bod->ny;
  1248. pz = p_bod->nz;
  1249. tx = p_word->_11 * px + p_word->_21 * py + p_word->_31 * pz; // transformace norm vektoru
  1250. ty = p_word->_12 * px + p_word->_22 * py + p_word->_32 * pz;
  1251. tz = p_word->_13 * px + p_word->_23 * py + p_word->_33 * pz;
  1252. uhel = (float) sqrt(p_light->x * p_light->x + p_light->y * p_light->y +
  1253. p_light->z * p_light->z) * (float) sqrt(tx * tx + ty * ty + tz * tz);
  1254. uhel = (tx * p_light->x + ty * p_light->y + tz * p_light->z) / uhel;
  1255. if (uhel > 0)
  1256. add_mult_color_dword(&p_bod->dr, rgb, uhel);
  1257. }
  1258. #define EPSILON_DIST 0.0001f
  1259. void sloz_vertex(OBJ_VERTEX * p_bod, TEXT_KOORD * p_koord)
  1260. {
  1261. p_bod->x = p_koord->x;
  1262. p_bod->y = p_koord->y;
  1263. p_bod->z = p_koord->z;
  1264. p_bod->nx = p_koord->nx;
  1265. p_bod->ny = p_koord->ny;
  1266. p_bod->nz = p_koord->nz;
  1267. p_bod->dr = p_koord->dr;
  1268. p_bod->dg = p_koord->dg;
  1269. p_bod->db = p_koord->db;
  1270. p_bod->da = p_koord->da;
  1271. p_bod->sr = p_koord->sr;
  1272. p_bod->sg = p_koord->sg;
  1273. p_bod->sb = p_koord->sb;
  1274. p_bod->msr = p_koord->msr;
  1275. p_bod->msg = p_koord->msg;
  1276. p_bod->msb = p_koord->msb;
  1277. p_bod->tu1 = p_koord->tu1;
  1278. p_bod->tv1 = p_koord->tv1;
  1279. p_bod->tu2 = p_koord->tu2;
  1280. p_bod->tv2 = p_koord->tv2;
  1281. p_bod->tul = p_koord->tul;
  1282. p_bod->tvl = p_koord->tvl;
  1283. }
  1284. void sloz_vertex_zpet(TEXT_KOORD * p_koord, OBJ_VERTEX * p_bod)
  1285. {
  1286. p_koord->x = p_bod->x;
  1287. p_koord->y = p_bod->y;
  1288. p_koord->z = p_bod->z;
  1289. p_koord->nx = p_bod->nx;
  1290. p_koord->ny = p_bod->ny;
  1291. p_koord->nz = p_bod->nz;
  1292. p_koord->dr = p_bod->dr;
  1293. p_koord->dg = p_bod->dg;
  1294. p_koord->db = p_bod->db;
  1295. p_koord->da = p_bod->da;
  1296. p_koord->sr = p_bod->sr;
  1297. p_koord->sg = p_bod->sg;
  1298. p_koord->sb = p_bod->sb;
  1299. p_koord->msr = p_bod->msr;
  1300. p_koord->msg = p_bod->msg;
  1301. p_koord->msb = p_bod->msb;
  1302. p_koord->tu1 = p_bod->tu1;
  1303. p_koord->tv1 = p_bod->tv1;
  1304. p_koord->tu2 = p_bod->tu2;
  1305. p_koord->tv2 = p_bod->tv2;
  1306. p_koord->tul = p_bod->tul;
  1307. p_koord->tvl = p_bod->tvl;
  1308. }
  1309. void ray_poly_vyrob_lightmap(EDIT_MESH_POLY * p_poly)
  1310. {
  1311. int lightmap = p_poly->facenum / 3;
  1312. if (p_poly->p_light) {
  1313. free(p_poly->p_light);
  1314. }
  1315. if (p_poly->p_lightnum) {
  1316. free(p_poly->p_lightnum);
  1317. p_poly->p_lightnum = NULL;
  1318. }
  1319. p_poly->p_light = (EDIT_TEXT **) malloc(sizeof(EDIT_TEXT *) * lightmap);
  1320. mtest(p_poly->p_light);
  1321. memset(p_poly->p_light, 0, sizeof(EDIT_TEXT *) * lightmap);
  1322. p_poly->lightnum = lightmap;
  1323. }
  1324. void ray_smaz_blby_plosky(K_EDITOR * p_cnf)
  1325. {
  1326. int flag = p_cnf->elm.flag;
  1327. p_cnf->elm.flag =
  1328. ELIM_MAZAT | ELIM_STATIC | ELIM_DYNAMIC | ELIM_PRVKY | ELIM_OKOLI;
  1329. oe_prikaz_decimace_sceny(p_cnf);
  1330. if (p_cnf->groupfacenum) {
  1331. oe_prikaz_smaz_face(p_cnf, TRUE);
  1332. }
  1333. p_cnf->elm.flag = flag;
  1334. }
  1335. void ray_preved_barvy_do_materialu(K_EDITOR * p_cnf)
  1336. {
  1337. EDIT_KONTEJNER *p_kont;
  1338. EDIT_OBJEKT *p_obj;
  1339. int ak, ao;
  1340. int mat, v;
  1341. oe_klist_reset(&ak);
  1342. while ((p_kont = oe_klist_next(p_cnf, &ak))) {
  1343. if (p_kont->kflag & KONT_STATIC && p_kont->kflag & KONT_VERTEX_LIGHT) {
  1344. oe_olist_reset(&ao);
  1345. while ((p_obj = oe_olist_next(p_kont, &ao))) {
  1346. mat = p_obj->material;
  1347. if (p_cnf->p_mat[mat]->flag2 & MAT2_DIFFUSE_RAY) {
  1348. for (v = 0; v < p_obj->vertexnum; v++) {
  1349. p_obj->p_vertex[v].mdr = p_obj->p_vertex[v].dr;
  1350. p_obj->p_vertex[v].mdg = p_obj->p_vertex[v].dg;
  1351. p_obj->p_vertex[v].mdb = p_obj->p_vertex[v].db;
  1352. }
  1353. }
  1354. }
  1355. }
  1356. }
  1357. }
  1358. BOOL CALLBACK doe_callback_raytracer(HWND hDlg, UINT msg, WPARAM wParam,
  1359. LPARAM lParam)
  1360. {
  1361. switch (msg) {
  1362. case WM_COMMAND:
  1363. switch (LOWORD(wParam)) {
  1364. case IDOK:
  1365. EndDialog(hDlg, 1);
  1366. break;
  1367. case IDCANCEL:
  1368. EndDialog(hDlg, 0);
  1369. break;
  1370. default:
  1371. return FALSE;
  1372. }
  1373. break;
  1374. case WM_INITDIALOG:
  1375. break;
  1376. case WM_DESTROY:
  1377. EndDialog(hDlg, IDCANCEL);
  1378. break;
  1379. default:
  1380. return FALSE;
  1381. }
  1382. return TRUE;
  1383. }
  1384. // prepocita osvetleni stat. map
  1385. // spocita z polygonu p_cnf->p_poly
  1386. /*
  1387. typedef struct _EDIT_MESH_POLY { //celej kontejner
  1388. POZICE_BODU *p_pozice; // list bodu
  1389. TEXT_KOORD *p_koord; // list texture koordinatu - plosky po 3
  1390. word flag; // flag meshu -> stejne jako u kontejneru
  1391. int facenum; // co face to objekt -> kazdy face ma svuj material
  1392. int matnum; // pocet materialu
  1393. word *p_pocty; // pocty plosek
  1394. int *p_mat; // pole pointeru na materialy na jednotlive objekty
  1395. EDIT_TEXT **p_light; // pole light-map
  1396. } EDIT_MESH_POLY;
  1397. */
  1398. void ray_prepocitej_staticke_osvetleni(K_EDITOR * p_cnf, int ticho)
  1399. {
  1400. EDIT_KONTEJNER *p_kont;
  1401. EDIT_OBJEKT *p_obj;
  1402. int ak, ao;
  1403. EDIT_TEXT_KONFIG konf;
  1404. LIGHTMAP_INFO linf;
  1405. int indnum;
  1406. POLY_INDICIE *p_ind;
  1407. EDIT_TEXT *p_src;
  1408. TRIANGLE *p_tri2d, tri;
  1409. BOD vert;
  1410. int p, f, fm, i, aface = 0, proc, mat, v;
  1411. int vel_bmp;
  1412. int no_phong;
  1413. byte shadow, nadpis[200];
  1414. dword stime, ptime, p2time, barva;
  1415. HWND hwnd = NULL;
  1416. if (!ticho && !doe_prikaz_raytracer(&p_cnf->ray))
  1417. return;
  1418. /* Eliminace degenerovanych plosek
  1419. */
  1420. if (p_cnf->cnf.druh_sceny != SCENA_POLY) {
  1421. kprintf(TRUE, "Prevadim scenu do renderovaciho formatu...");
  1422. oe_scena_to_game(p_cnf);
  1423. }
  1424. stime = timeGetTime();
  1425. shadow = p_cnf->ray.stiny;
  1426. oe_prepocitat_stat_svetla(p_cnf);
  1427. for (i = 0; i < MAX_RAY_TEXTUR; i++) {
  1428. if (p_cnf->p_lightmap[i].p_bmp) {
  1429. bmp_zrus(&p_cnf->p_lightmap[i].p_bmp);
  1430. p_cnf->p_lightmap[i].jmeno[0] = 0;
  1431. }
  1432. }
  1433. if (!ticho) {
  1434. hwnd =
  1435. CreateDialog(hinst, MAKEINTRESOURCE(IDD_PROGRES), hwnd_plocha,
  1436. doe_callback_raytracer);
  1437. doe_printf(hwnd, IDC_STATIC1, "---- Leharo ----");
  1438. }
  1439. p_cnf->stat.ray_bodu = FALSE;
  1440. // rendering sceny - diffusni svetlo
  1441. if (!ticho) {
  1442. doe_progresbar_nastav(hwnd, IDC_PROGRESS3, 0, p_cnf->stat.polyface / 3);
  1443. doe_printf(hwnd, IDC_STATIC2, "Renderuju scenu...");
  1444. doe_printf(hwnd, IDC_STATIC1, "Vertex-listy...");
  1445. doe_printf(hwnd, IDC_STATIC4, "%d:%d", 00, 7);
  1446. }
  1447. oe_klist_reset(&ak);
  1448. while ((p_kont = oe_klist_next(p_cnf, &ak))) {
  1449. if (p_kont->kflag & KONT_STATIC && p_kont->kflag & KONT_VERTEX_LIGHT) {
  1450. shadow = p_kont->kflag & KONT_NO_SELF_SHADOW ? FALSE : p_cnf->ray.stiny;
  1451. no_phong = p_kont->k2flag & KONT2_NO_PHONG;
  1452. oe_olist_reset(&ao);
  1453. while ((p_obj = oe_olist_next(p_kont, &ao))) {
  1454. if (!ticho) {
  1455. doe_printf(hwnd, IDC_STATIC1, "List %s", p_obj->jmeno);
  1456. }
  1457. mat = p_obj->material;
  1458. if (p_cnf->p_mat[mat]->flag2 & MAT2_DIFFUSE_RAY) {
  1459. for (v = 0; v < p_obj->vertexnum; v++) {
  1460. vert.x = p_obj->p_vertex[v].x;
  1461. vert.y = p_obj->p_vertex[v].y;
  1462. vert.z = p_obj->p_vertex[v].z;
  1463. linf.normal_bod.x = p_obj->p_vertex[v].nx;
  1464. linf.normal_bod.y = p_obj->p_vertex[v].ny;
  1465. linf.normal_bod.z = p_obj->p_vertex[v].nz;
  1466. barva =
  1467. ray_svetlost_bodu(p_cnf, &vert, &linf, shadow,
  1468. p_cnf->ray.ambient, no_phong);
  1469. rgb_float(barva, &p_obj->p_vertex[v].dr);
  1470. p_obj->p_vertex[v].dr *= p_obj->p_vertex[v].mdr;
  1471. p_obj->p_vertex[v].dg *= p_obj->p_vertex[v].mdg;
  1472. p_obj->p_vertex[v].db *= p_obj->p_vertex[v].mdb;
  1473. }
  1474. }
  1475. }
  1476. }
  1477. }
  1478. shadow = p_cnf->ray.stiny;
  1479. indnum = 0;
  1480. for (p = 0; p < p_cnf->polynum; p++) {
  1481. indnum += p_cnf->p_poly[p].facenum / 3;
  1482. ray_poly_vyrob_lightmap(p_cnf->p_poly + p);
  1483. p_cnf->p_poly[p].kreslit = FALSE;
  1484. }
  1485. p_ind = malloc(sizeof(p_ind[0]) * indnum);
  1486. mtest(p_ind);
  1487. memset(p_ind, 0, sizeof(p_ind[0]) * indnum);
  1488. indnum = 0;
  1489. for (p = 0; p < p_cnf->polynum; p++) {
  1490. if (p_cnf->p_poly[p].kflag & (KONT_PRVEK | KONT_PODLOZKA)) {
  1491. for (i = indnum,
  1492. indnum += p_cnf->p_poly[p].facenum / 3, f = 0; i < indnum; i++) {
  1493. p_ind[i].poly = p;
  1494. p_ind[i].face = f;
  1495. f += 3;
  1496. }
  1497. if (p + 1 < p_cnf->polynum
  1498. && p_cnf->p_poly[p + 1].kflag & (KONT_PRVEK | KONT_PODLOZKA)) {
  1499. continue;
  1500. }
  1501. }
  1502. else {
  1503. indnum = p_cnf->p_poly[p].facenum / 3;
  1504. for (i = 0; i < indnum; i++) {
  1505. p_ind[i].poly = p;
  1506. p_ind[i].face = i * 3;
  1507. }
  1508. }
  1509. // Hotove indicie jsou hotove
  1510. p_src = malloc(sizeof(p_src[0]) * indnum);
  1511. mtest(p_src);
  1512. p_tri2d = malloc(sizeof(p_tri2d[0]) * indnum);
  1513. mtest(p_tri2d);
  1514. if (ticho) {
  1515. kprintf(TRUE, "Poly %d z %d", p, p_cnf->polynum);
  1516. }
  1517. p = K_CHYBA;
  1518. // Rendering z indicii
  1519. for (i = 0; i < indnum; i++) {
  1520. // Prvni vyskyt urciteho poly - prvnotni inicializace
  1521. if (p != p_ind[i].poly) {
  1522. /* Nahozeni zakladnich hodnot
  1523. */
  1524. p = p_ind[i].poly;
  1525. mat = p_cnf->p_poly[p].material;
  1526. no_phong = p_cnf->p_poly[p].k2flag & KONT2_NO_PHONG;
  1527. /* Testy barev
  1528. */
  1529. //if(!(p_cnf->p_mat[mat]->flag2&MAT2_DIFFUSE_RAY))
  1530. //goto dalsi_poly;
  1531. /* stiny/bez stinu
  1532. */
  1533. shadow =
  1534. (p_cnf->p_poly[p].kflag & KONT_NO_SELF_SHADOW) ? FALSE : p_cnf->ray.
  1535. stiny;
  1536. /* Predpocitani spekularnich barev
  1537. */
  1538. if (p_cnf->p_mat[mat]->flag2 & MAT2_SPECULAR_RAY) {
  1539. int fmax = p_cnf->p_poly[p].facenum;
  1540. for (f = 0; f < fmax; f++) {
  1541. ray_svetlost_vertex_poly(p_cnf,
  1542. p_cnf->p_poly[p].p_koord + f, p_cnf->p_mat[mat]->lesk);
  1543. }
  1544. }
  1545. }
  1546. f = p_ind[i].face;
  1547. fm = p_ind[i].face / 3;
  1548. ptime = (timeGetTime() - stime);
  1549. p2time = ptime / 1000;
  1550. if (!ticho) {
  1551. doe_printf(hwnd, IDC_STATIC1,
  1552. "Polygon-list %d/%d face %d/%d face-bodu %d", p, p_cnf->polynum, fm,
  1553. p_cnf->p_poly[p].facenum / 3, p_cnf->stat.ray_bodu);
  1554. doe_printf(hwnd, IDC_STATIC4, "%d:%d", p2time / 60, p2time % 60);
  1555. proc = ftoi(((float) (aface +=
  1556. 3) / (float) p_cnf->stat.polyface) * 100.0f);
  1557. doe_printf(hwnd, IDC_STATIC5, "%d%%", proc);
  1558. sprintf(nadpis, "Render %d%% hotovo - plna priorita", proc);
  1559. SetWindowText(hwnd_aplikace, nadpis);
  1560. spracuj_spravy(TRUE);
  1561. }
  1562. linf.f = f;
  1563. linf.poly = p;
  1564. linf.k = p;
  1565. linf.vface[0] = p_cnf->p_poly[p].p_fsous[f];
  1566. linf.vface[1] = p_cnf->p_poly[p].p_fsous[f + 1];
  1567. linf.vface[2] = p_cnf->p_poly[p].p_fsous[f + 2];
  1568. ray_svetlost_vertex_poly_diff(p_cnf->p_poly[p].p_koord + f);
  1569. ray_svetlost_vertex_poly_diff(p_cnf->p_poly[p].p_koord + f + 1);
  1570. ray_svetlost_vertex_poly_diff(p_cnf->p_poly[p].p_koord + f + 2);
  1571. sloz_vertex(&tri.a, p_cnf->p_poly[p].p_koord + f);
  1572. sloz_vertex(&tri.b, p_cnf->p_poly[p].p_koord + f + 1);
  1573. sloz_vertex(&tri.c, p_cnf->p_poly[p].p_koord + f + 2);
  1574. p_src[i].p_bmp =
  1575. ray_calc_lightmap_face(p_cnf, &tri, p_tri2d + i, &linf, shadow,
  1576. no_phong);
  1577. sloz_vertex_zpet(p_cnf->p_poly[p].p_koord + f, &tri.a);
  1578. sloz_vertex_zpet(p_cnf->p_poly[p].p_koord + f + 1, &tri.b);
  1579. sloz_vertex_zpet(p_cnf->p_poly[p].p_koord + f + 2, &tri.c);
  1580. doe_progresbar_posun(hwnd, IDC_PROGRESS3, 1);
  1581. }
  1582. //ray_dopln_okraje(p_cnf, p_src, indnum);
  1583. if (p_cnf->ray.filtrace) {
  1584. if (!ticho) {
  1585. doe_printf(hwnd, IDC_STATIC1, "Filtrace...");
  1586. }
  1587. ray_poly_filtruj_lightmapy(p_ind, indnum, p_cnf->p_poly, p_src,
  1588. p_cnf->ray.stupen_filtrace,
  1589. p_cnf->ray.disk_mezi, p_cnf->ray.filtrace);
  1590. }
  1591. if (p_cnf->ray.supersampl) {
  1592. if (!ticho) {
  1593. doe_printf(hwnd, IDC_STATIC1, "Supersampling...");
  1594. }
  1595. ray_surface_supersampling(p_ind, indnum, p_tri2d, p_cnf->p_poly,
  1596. p_src,
  1597. p_cnf->ray.sup_hloubka,
  1598. p_cnf->ray.sup_velikost_x, p_cnf->ray.sup_velikost_y);
  1599. }
  1600. if (p_cnf->ray.disk_mezi) {
  1601. for (i = 0; i < indnum; i++) {
  1602. sprintf(p_src[i].jmeno, "e:\\lihen\\lightmap\\face-i%.3d_s.bmp", i);
  1603. bmp_uloz(p_src[i].jmeno, p_src[i].p_bmp);
  1604. }
  1605. }
  1606. if (!ticho) {
  1607. doe_printf(hwnd, IDC_STATIC1, "Lepeni...");
  1608. }
  1609. ray_slep_lightmapy(p_cnf, p_ind, indnum, p_src);
  1610. for (i = 0; i < indnum; i++)
  1611. bmp_zrus(&p_src[i].p_bmp);
  1612. free(p_src);
  1613. p_src = NULL;
  1614. free(p_tri2d);
  1615. indnum = 0;
  1616. }
  1617. free(p_ind);
  1618. for (p = 0; p < p_cnf->polynum; p++) {
  1619. ray_poly_optim_lightmap(p_cnf->p_poly + p);
  1620. p_cnf->p_poly[p].kreslit = TRUE;
  1621. }
  1622. ptime = (timeGetTime() - stime);
  1623. stime = ptime / 1000;
  1624. vel_bmp = 0;
  1625. for (i = 0, mat = 0; i < MAX_RAY_TEXTUR; i++) {
  1626. if (p_cnf->p_lightmap[i].p_bmp) {
  1627. mat = i + 1;
  1628. vel_bmp +=
  1629. p_cnf->p_lightmap[i].p_bmp->x * p_cnf->p_lightmap[i].p_bmp->y * 4;
  1630. }
  1631. }
  1632. if (!ticho) {
  1633. doe_printf(hwnd, IDC_STATIC1, "---- Prevod light-map do textur ----");
  1634. doe_progresbar_nastav(hwnd, IDC_PROGRESS3, 0, mat);
  1635. }
  1636. {
  1637. int zal_filtr = txconf.text_filtr;
  1638. txconf.text_filtr = p_cnf->ray.lightmap_filtr;
  1639. txt_lightmap_konfig(&konf);
  1640. txconf.text_filtr = zal_filtr;
  1641. }
  1642. if (!ticho) {
  1643. for (i = 0; i < mat; i++) {
  1644. if (p_cnf->p_lightmap[i].p_bmp) {
  1645. //bmp_to_16bit(p_cnf->p_lightmap[i].p_bmp,0x7,FALSE);
  1646. // txt_bmp2textura(p_cnf->p_lightmap[i].p_bmp, p_cnf->p_lightmap+i,&konf);
  1647. p_cnf->p_lightmap[i].load = TRUE;
  1648. doe_progresbar_posun(hwnd, IDC_PROGRESS3, 1);
  1649. }
  1650. }
  1651. }
  1652. for (p = 0; p < p_cnf->polynum; p++) {
  1653. p_cnf->p_poly[p].kreslit = TRUE;
  1654. }
  1655. kprintf(TRUE, "Ray-tracing info:");
  1656. kprintf(TRUE, "Cas (%d:%d:%d)", stime / 60, stime % 60, ptime % 1000);
  1657. kprintf(TRUE, "Bodu %d", p_cnf->stat.ray_bodu);
  1658. kprintf(TRUE, "Velikost %d Byte", vel_bmp);
  1659. kprintf(TRUE, "Stiny %d", p_cnf->ray.stiny);
  1660. kprintf(TRUE, "Faktor %f", p_cnf->ray.faktor);
  1661. kprintf(TRUE, "Filtr %d", p_cnf->ray.stupen_filtrace);
  1662. kprintf(TRUE, "Disk %d", p_cnf->ray.disk);
  1663. if (!ticho) {
  1664. EndDialog(hwnd, TRUE);
  1665. }
  1666. }
  1667. __inline void ray_rozmnoz_diffuse(OBJ_VERTEX * p_vert)
  1668. {
  1669. p_vert->da = p_vert->mda;
  1670. p_vert->dr = p_vert->mdr;
  1671. p_vert->dg = p_vert->mdg;
  1672. p_vert->db = p_vert->mdb;
  1673. }
  1674. __inline void ray_rozmnoz_specular(OBJ_VERTEX * p_vert)
  1675. {
  1676. p_vert->sr = p_vert->msr;
  1677. p_vert->sg = p_vert->msg;
  1678. p_vert->sb = p_vert->msb;
  1679. }
  1680. // Prepocitani bodu
  1681. __inline void ray_svetlost_vertex_bodu(K_EDITOR * p_cnf, OBJ_VERTEX * p_vert,
  1682. GLMATRIX * p_word, int diff, int spec, float lesk, dword ambient)
  1683. {
  1684. STATIC_LIGHT *p_light;
  1685. BOD v, n;
  1686. BOD sv, dir;
  1687. float dist, k, I, Is, uhel;
  1688. int l;
  1689. v.x = p_vert->x;
  1690. v.y = p_vert->y;
  1691. v.z = p_vert->z;
  1692. n.x = p_vert->nx;
  1693. n.y = p_vert->ny;
  1694. n.z = p_vert->nz;
  1695. rgb_float(ambient, &p_vert->dr);
  1696. p_vert->sr = p_vert->sg = p_vert->sb = 0.0f;
  1697. transformuj_bod_matici(&v.x, &v.y, &v.z, p_word);
  1698. transformuj_nbod_matici(&n, p_word);
  1699. for (l = 0; l < p_cnf->lightnum; l++) {
  1700. p_light = p_cnf->light + l;
  1701. if (!p_light->akt || p_light->bez_prev)
  1702. continue;
  1703. Is = I = 1;
  1704. if (p_light->flag2 & SL2_MESH) {
  1705. transformuj_bod_matici_bod(&p_light->p,
  1706. kont_world_matrix(p_light->p_mesh_data), &sv);
  1707. }
  1708. else {
  1709. sv = p_light->p;
  1710. }
  1711. dist = vzdal_bodu_bod(&v, &sv);
  1712. if (dist > p_light->dosah)
  1713. continue;
  1714. vektor_sub(&v, &sv, &dir);
  1715. norm_vect(&dir.x, &dir.y, &dir.z);
  1716. if (!p_cnf->cnf.svetla_bez_gourandu) {
  1717. // vektor bod->vektor
  1718. uhel = (skal_soucin(n, dir)); //cosinus uhlu
  1719. if (uhel > 0 && p_light->uhel) {
  1720. Is = I = uhel;
  1721. Is *= lesk;
  1722. }
  1723. else {
  1724. Is = I = p_light->uhel ? 0.0f : 1.0f;
  1725. }
  1726. }
  1727. if (p_light->utlum) {
  1728. k =
  1729. 1.0f / (p_light->k1 + p_light->k2 * dist + p_light->k3 * dist * dist);
  1730. I *= k;
  1731. Is *= k;
  1732. }
  1733. if (diff) {
  1734. p_vert->dr += p_vert->mdr * p_light->r * I;
  1735. p_vert->dg += p_vert->mdg * p_light->g * I;
  1736. p_vert->db += p_vert->mdb * p_light->b * I;
  1737. }
  1738. if (spec) {
  1739. p_vert->sr += p_vert->msr * p_light->r * Is;
  1740. p_vert->sg += p_vert->msg * p_light->g * Is;
  1741. p_vert->sb += p_vert->msb * p_light->b * Is;
  1742. }
  1743. }
  1744. if (p_vert->dr > 1.0f)
  1745. p_vert->dr = 1.0f;
  1746. if (p_vert->dg > 1.0f)
  1747. p_vert->dg = 1.0f;
  1748. if (p_vert->db > 1.0f)
  1749. p_vert->db = 1.0f;
  1750. if (p_vert->sr > 1.0f)
  1751. p_vert->sr = 1.0f;
  1752. if (p_vert->sg > 1.0f)
  1753. p_vert->sg = 1.0f;
  1754. if (p_vert->sb > 1.0f)
  1755. p_vert->sb = 1.0f;
  1756. }
  1757. /* Provede update dynamickych svetel
  1758. */
  1759. void ray_objekt_pridej_ddlight(K_EDITOR * p_cnf, DYN_LIGHT * p_ddlight,
  1760. int ddlightnum, EDIT_KONTEJNER * p_kont,
  1761. EDIT_OBJEKT * p_obj, GLMATRIX * p_m)
  1762. {
  1763. GLMATRIX *p_mat;
  1764. DYN_LIGHT *p_dlight;
  1765. BOD *p_vertex_pos;
  1766. BOD *p_vertex_norm;
  1767. BODRGBA *p_vertex_diff;
  1768. BODRGBA *p_vertex_diff_mat;
  1769. BOD p, n, d;
  1770. int i, v, dflag, m2flag, j;
  1771. int diffuse;
  1772. int diffuse_ray;
  1773. int dyn_light = 1;
  1774. int kflag;
  1775. float vzdal, I, lesk = 1.0f;
  1776. float *p_looksqrt_linear_float = p_cnf->p_looksqrt_linear_float;
  1777. float *p_looksqrt_quad_float = p_cnf->p_looksqrt_quadratic_float;
  1778. kflag = p_kont->kflag & KONT_KEYFRAME;
  1779. m2flag = p_kont->m2flag;
  1780. diffuse = m2flag & MAT2_DIFFUSE;
  1781. diffuse_ray = m2flag & MAT2_DIFFUSE_RAY;
  1782. if (!(diffuse))
  1783. return;
  1784. for (v = 0; v < p_obj->vertexnum; v++) {
  1785. p_vertex_pos = (BOD *) & p_obj->p_vertex[v].x;
  1786. p_vertex_norm = (BOD *) & p_obj->p_vertex[v].nx;
  1787. transformuj_bod_matici_bod((BOD *) & p_vertex_pos->x, p_m, &p);
  1788. transformuj_nbod_matici_bod((BOD *) & p_vertex_norm->x, p_m, &n);
  1789. p_vertex_diff = (RGBA *) & p_obj->p_vertex[v].dr;
  1790. p_vertex_diff_mat = (RGBA *) & p_obj->p_vertex[v].mdr;
  1791. for (i = 0; i < ddlightnum; i++) {
  1792. p_dlight = p_ddlight + i;
  1793. dflag = p_dlight->flag;
  1794. if (dflag & SDL_MESH && p_dlight->p_mesh_data) { // pod-meshove svetlo preved s world space kontejneru
  1795. p_mat = kont_world_matrix(p_dlight->p_mesh_data);
  1796. transformuj_bod_matici_bod(&p_dlight->np, p_mat, &d);
  1797. vzdal = vzdal_bodu_bod(&p_dlight->np, &d);
  1798. }
  1799. else {
  1800. vzdal = vzdal_bodu_bod(&p_dlight->np, &p);
  1801. }
  1802. if (vzdal > p_dlight->dosah)
  1803. continue;
  1804. if (vzdal <= p_dlight->min) {
  1805. if (dflag & SDL_ADD_SUB) {
  1806. p_vertex_diff->r += p_vertex_diff_mat->r * p_dlight->dr;
  1807. p_vertex_diff->g += p_vertex_diff_mat->g * p_dlight->dg;
  1808. p_vertex_diff->b += p_vertex_diff_mat->b * p_dlight->db;
  1809. p_vertex_diff->r -= p_vertex_diff_mat->r * p_dlight->sr;
  1810. p_vertex_diff->g -= p_vertex_diff_mat->g * p_dlight->sg;
  1811. p_vertex_diff->b -= p_vertex_diff_mat->b * p_dlight->sb;
  1812. }
  1813. else if (dflag & SDL_SUB) {
  1814. p_vertex_diff->r -= p_vertex_diff_mat->r * p_dlight->dr;
  1815. p_vertex_diff->g -= p_vertex_diff_mat->g * p_dlight->dg;
  1816. p_vertex_diff->b -= p_vertex_diff_mat->b * p_dlight->db;
  1817. }
  1818. else {
  1819. p_vertex_diff->r += p_vertex_diff_mat->r * p_dlight->dr;
  1820. p_vertex_diff->g += p_vertex_diff_mat->g * p_dlight->dg;
  1821. p_vertex_diff->b += p_vertex_diff_mat->b * p_dlight->db;
  1822. }
  1823. }
  1824. else {
  1825. j =
  1826. ftoi(((vzdal - p_dlight->min) / (p_dlight->max -
  1827. p_dlight->min)) * 255.0f);
  1828. I =
  1829. (dflag & SDL_UTLUM_LINEAR) ? p_looksqrt_linear_float[j] :
  1830. p_looksqrt_quad_float[j];
  1831. if (I < DELTA_MIN)
  1832. continue;
  1833. if (dflag & SDL_ADD_SUB) {
  1834. p_vertex_diff->r += p_vertex_diff_mat->r * p_dlight->dr * I;
  1835. p_vertex_diff->g += p_vertex_diff_mat->g * p_dlight->dg * I;
  1836. p_vertex_diff->b += p_vertex_diff_mat->b * p_dlight->db * I;
  1837. p_vertex_diff->r -= p_vertex_diff_mat->r * p_dlight->sr * I;
  1838. p_vertex_diff->g -= p_vertex_diff_mat->g * p_dlight->sg * I;
  1839. p_vertex_diff->b -= p_vertex_diff_mat->b * p_dlight->sb * I;
  1840. }
  1841. else if (dflag & SDL_SUB) {
  1842. p_vertex_diff->r -= p_vertex_diff_mat->r * p_dlight->dr * I;
  1843. p_vertex_diff->g -= p_vertex_diff_mat->g * p_dlight->dg * I;
  1844. p_vertex_diff->b -= p_vertex_diff_mat->b * p_dlight->db * I;
  1845. }
  1846. else {
  1847. p_vertex_diff->r += p_vertex_diff_mat->r * p_dlight->dr * I;
  1848. p_vertex_diff->g += p_vertex_diff_mat->g * p_dlight->dg * I;
  1849. p_vertex_diff->b += p_vertex_diff_mat->b * p_dlight->db * I;
  1850. }
  1851. }
  1852. }
  1853. }
  1854. }
  1855. /* Provede update extra-dynamickych svetel
  1856. */
  1857. void ray_objekt_pridej_edlight(K_EDITOR * p_cnf, EXTRA_DYN_LIGHT * p_edlight,
  1858. int edlightnum, EDIT_KONTEJNER * p_kont,
  1859. EDIT_OBJEKT * p_obj, GLMATRIX * p_m)
  1860. {
  1861. EXTRA_DYN_LIGHT *p_light;
  1862. BOD *p_vertex_pos;
  1863. BOD *p_vertex_norm;
  1864. BODRGBA *p_vertex_diff;
  1865. BODRGB *p_vertex_spec;
  1866. BOD p, n, d, dir;
  1867. int i, v, dflag, m2flag;
  1868. int dyn_light = 1;
  1869. int kflag;
  1870. float vzdal, I, lesk = 1.0f;
  1871. kflag = p_kont->kflag & KONT_KEYFRAME;
  1872. m2flag = p_kont->m2flag;
  1873. for (v = 0; v < p_obj->vertexnum; v++) {
  1874. p_vertex_pos = (BOD *) & p_obj->p_vertex[v].x;
  1875. p_vertex_norm = (BOD *) & p_obj->p_vertex[v].nx;
  1876. transformuj_bod_matici_bod((BOD *) & p_vertex_pos->x, p_m, &p);
  1877. transformuj_nbod_matici_bod((BOD *) & p_vertex_norm->x, p_m, &n);
  1878. p_vertex_diff = (RGBA *) & p_obj->p_vertex[v].dr;
  1879. p_vertex_spec = (RGB *) & p_obj->p_vertex[v].sr;
  1880. for (i = 0; i < p_cnf->edl_lightnum; i++) {
  1881. p_light = p_cnf->p_edlight + i;
  1882. if (p_light->akt) {
  1883. dflag = p_light->flag;
  1884. if (dflag & EDL_MESH) {
  1885. transformuj_bod_matici_bod(&p_light->np,
  1886. kont_world_matrix(p_light->p_mesh_data), &d);
  1887. }
  1888. else {
  1889. d = p_light->np;
  1890. }
  1891. if (dflag & EDL_DOSAH) {
  1892. if (dflag & EDL_BODOVE) {
  1893. vzdal = vzdal_bodu_bod(&d, &p);
  1894. }
  1895. else if (dflag & (EDL_PLOSNE_X | EDL_PLOSNE_Y | EDL_PLOSNE_Z)) {
  1896. if (dflag & EDL_PLOSNE_X) {
  1897. vzdal = fabsf(d.x - p.x);
  1898. }
  1899. else if (dflag & EDL_PLOSNE_Y) {
  1900. vzdal = fabsf(d.y - p.y);
  1901. }
  1902. else {
  1903. vzdal = fabsf(d.z - p.z);
  1904. }
  1905. }
  1906. if (vzdal >= p_light->dosah)
  1907. continue;
  1908. if (dflag & EDL_UTLUM_LIN) {
  1909. vzdal = 1.0f - (vzdal * p_light->utlum) / p_light->dosah;
  1910. if (vzdal < DELTA_MIN)
  1911. continue;
  1912. }
  1913. else if (dflag & EDL_UTLUM_KVAD) {
  1914. vzdal = 1.0f - (vzdal * vzdal * p_light->utlum) / p_light->dosah;
  1915. if (vzdal < DELTA_MIN)
  1916. continue;
  1917. }
  1918. else {
  1919. vzdal = 1.0f;
  1920. }
  1921. }
  1922. else {
  1923. vzdal = 1.0f;
  1924. }
  1925. if (dflag & EDL_GOURAND) {
  1926. vektor_sub(&p, &d, &dir);
  1927. norm_vect(&dir.x, &dir.y, &dir.z);
  1928. I = vektor_dot_product(&n, &dir) * vzdal * p_light->gourand;
  1929. if (I < DELTA_MIN)
  1930. continue;
  1931. }
  1932. else {
  1933. I = vzdal;
  1934. }
  1935. // Nastav alfa slozku
  1936. if (dflag & (EDL_ALFA_MOD | EDL_ALFA_SET | EDL_ALFA_ADD |
  1937. EDL_ALFA_SUB)) {
  1938. if (dflag & EDL_ALFA_ADD) {
  1939. p_vertex_diff->a += p_light->da * I;
  1940. }
  1941. else if (dflag & EDL_ALFA_MOD) {
  1942. p_vertex_diff->a *= p_light->da * I;
  1943. }
  1944. else if (dflag & EDL_ALFA_SUB) {
  1945. p_vertex_diff->a -= p_light->da * I;
  1946. }
  1947. else if (dflag & EDL_ALFA_SET) {
  1948. p_vertex_diff->a = p_light->da * I;
  1949. }
  1950. }
  1951. // Nastav spekularni slozku
  1952. if (dflag & (EDL_SPEC_MOD | EDL_SPEC_SET | EDL_SPEC_ADD |
  1953. EDL_SPEC_SUB)) {
  1954. if (dflag & EDL_SPEC_ADD) {
  1955. p_vertex_spec->r += p_light->sr * I;
  1956. p_vertex_spec->g += p_light->sg * I;
  1957. p_vertex_spec->b += p_light->sb * I;
  1958. }
  1959. else if (dflag & EDL_SPEC_MOD) {
  1960. p_vertex_spec->r *= p_light->sr * I;
  1961. p_vertex_spec->g *= p_light->sg * I;
  1962. p_vertex_spec->b *= p_light->sb * I;
  1963. }
  1964. else if (dflag & EDL_SPEC_SUB) {
  1965. p_vertex_spec->r -= p_light->sr * I;
  1966. p_vertex_spec->g -= p_light->sg * I;
  1967. p_vertex_spec->b -= p_light->sb * I;
  1968. }
  1969. else if (dflag & EDL_SPEC_SET) {
  1970. p_vertex_spec->r = p_light->sr * I;
  1971. p_vertex_spec->g = p_light->sg * I;
  1972. p_vertex_spec->b = p_light->sb * I;
  1973. }
  1974. }
  1975. }
  1976. }
  1977. }
  1978. }
  1979. #define RYCHLOST_ZMENY 100
  1980. // Musi byt vsechny veci nachystany -> normalove vektory + barvy md a ms
  1981. // Prepocet pokud je scena v obycejnym modu
  1982. void ray_prepocitej_staticke_osvetleni_vertexy(K_EDITOR * p_cnf)
  1983. {
  1984. EDIT_MATERIAL **p_mat = p_cnf->p_mat;
  1985. EDIT_OBJEKT *p_obj;
  1986. GLMATRIX *p_m;
  1987. dword kflag;
  1988. int i, o, v, d, s;
  1989. static dword stary_cas = 0;
  1990. dword akt_cas = timeGetTime();
  1991. float lesk;
  1992. if (akt_cas - stary_cas < RYCHLOST_ZMENY
  1993. || p_cnf->cnf.druh_sceny == SCENA_POLY)
  1994. return;
  1995. stary_cas = akt_cas;
  1996. for (i = 0; i < KONT_NUM; i++) {
  1997. if (!p_cnf->p_kont[i])
  1998. continue;
  1999. kflag = p_cnf->p_kont[i]->kflag;
  2000. if (!(kflag & KONT_KEYFRAME))
  2001. p_m = kont_world_matrix(p_cnf->p_kont[i]);
  2002. for (o = 0; o < MAX_KONT_OBJEKTU; o++) {
  2003. p_obj = p_cnf->p_kont[i]->p_obj[o];
  2004. if (!p_obj)
  2005. continue;
  2006. if (kflag & KONT_KEYFRAME)
  2007. p_m = &p_obj->m;
  2008. d = p_mat[p_obj->material]->flag2 & MAT2_DIFFUSE_RAY;
  2009. s = p_mat[p_obj->material]->flag2 & MAT2_SPECULAR_RAY;
  2010. lesk = p_mat[p_obj->material]->lesk;
  2011. if (d || s) {
  2012. for (v = 0; v < p_obj->vertexnum; v++) {
  2013. ray_svetlost_vertex_bodu(p_cnf, p_obj->p_vertex + v, p_m, d, s,
  2014. lesk, p_cnf->ray.ambient);
  2015. }
  2016. }
  2017. ray_objekt_pridej_ddlight(p_cnf, p_cnf->p_dlight, p_cnf->dl_lightnum,
  2018. p_cnf->p_kont[i], p_obj, p_m);
  2019. ray_objekt_pridej_edlight(p_cnf, p_cnf->p_edlight, p_cnf->edl_lightnum,
  2020. p_cnf->p_kont[i], p_obj, p_m);
  2021. }
  2022. }
  2023. }
  2024. void ray_zrus_staticke_osvetleni_vertexy(K_EDITOR * p_cnf)
  2025. {
  2026. EDIT_OBJEKT *p_obj;
  2027. int i, o, v;
  2028. for (i = 0; i < KONT_NUM; i++) {
  2029. if (!p_cnf->p_kont[i])
  2030. continue;
  2031. for (o = 0; o < MAX_KONT_OBJEKTU; o++) {
  2032. p_obj = p_cnf->p_kont[i]->p_obj[o];
  2033. if (!p_obj)
  2034. continue;
  2035. for (v = 0; v < p_obj->vertexnum; v++) {
  2036. ray_rozmnoz_diffuse(p_obj->p_vertex + v);
  2037. ray_rozmnoz_specular(p_obj->p_vertex + v);
  2038. }
  2039. }
  2040. }
  2041. }
  2042. __inline void ray_svetlost_vertex_poly(K_EDITOR * p_cnf, TEXT_KOORD * p_koord,
  2043. float lesk)
  2044. {
  2045. STATIC_LIGHT *p_light;
  2046. BOD v, n;
  2047. BOD sv, dir;
  2048. float dist, k, Is, uhel;
  2049. int l;
  2050. v.x = p_koord->x;
  2051. v.y = p_koord->y;
  2052. v.z = p_koord->z;
  2053. n.x = p_koord->nx;
  2054. n.y = p_koord->ny;
  2055. n.z = p_koord->nz;
  2056. p_koord->sr = p_koord->sg = p_koord->sb = 0.0f;
  2057. for (l = 0; l < p_cnf->lightnum; l++) {
  2058. p_light = p_cnf->light + l;
  2059. if (!p_light->akt)
  2060. continue;
  2061. Is = 1;
  2062. sv = p_cnf->light[l].p;
  2063. dist = vzdal_bodu_bod(&v, &sv);
  2064. vektor_sub(&v, &sv, &dir);
  2065. norm_vect(&dir.x, &dir.y, &dir.z);
  2066. if (dist > p_light->dosah)
  2067. continue;
  2068. if (!p_cnf->cnf.svetla_bez_gourandu) {
  2069. // vektor bod->vektor
  2070. uhel = (skal_soucin(n, dir)); //cosinus uhlu
  2071. if (uhel > 0 && p_light->uhel) {
  2072. Is = uhel * lesk;
  2073. }
  2074. else {
  2075. Is = p_light->uhel ? 0.0f : 1.0f;
  2076. }
  2077. }
  2078. if (p_light->utlum) {
  2079. k =
  2080. 1.0f / (p_light->k1 + p_light->k2 * dist + p_light->k3 * dist * dist);
  2081. Is *= k;
  2082. }
  2083. p_koord->sr += p_koord->msr * p_light->r * Is;
  2084. p_koord->sg += p_koord->msg * p_light->g * Is;
  2085. p_koord->sb += p_koord->msb * p_light->b * Is;
  2086. }
  2087. }
  2088. __inline void ray_svetlost_vertex_poly_diff(TEXT_KOORD * p_koord)
  2089. {
  2090. p_koord->dr = p_koord->mdr;
  2091. p_koord->dg = p_koord->mdg;
  2092. p_koord->db = p_koord->mdb;
  2093. p_koord->da = p_koord->mda;
  2094. }
  2095. void ray_uloz_lightmapy(K_EDITOR * p_cnf, byte * p_file, byte * p_dir)
  2096. {
  2097. FFILE f;
  2098. int i;
  2099. byte pom[200];
  2100. strcpy(pom, p_file);
  2101. zamen_koncovku(pom, KONCOVKA_LIGHTMAPY);
  2102. if ((f = ffopen(pom, "wb"))) {
  2103. for (i = 0; i < MAX_RAY_TEXTUR; i++) {
  2104. if (p_cnf->p_lightmap[i].p_bmp) {
  2105. ffwrite(&i, sizeof(i), 1, f);
  2106. bmp_uloz_pack(f, p_cnf->p_lightmap[i].p_bmp);
  2107. }
  2108. }
  2109. ffclose(f);
  2110. }
  2111. }
  2112. /*
  2113. void ray_uloz_lightmapy(K_EDITOR *p_cnf, byte *p_file, byte *p_dir)
  2114. {
  2115. int i;
  2116. byte pom[200];
  2117. for(i = 0; i < MAX_RAY_TEXTUR; i++) {
  2118. if(p_cnf->p_lightmap[i].p_bmp) {
  2119. sprintf(pom,"l%d.bmp",i);
  2120. bmp_uloz(pom,p_cnf->p_lightmap[i].p_bmp);
  2121. }
  2122. }
  2123. }
  2124. */
  2125. int ray_vyrob_poly_lightmap_compare(const void *p_poly1, const void *p_poly2)
  2126. {
  2127. int cmp;
  2128. cmp = ((LIGHTMAP_INFO *) p_poly1)->poly - ((LIGHTMAP_INFO *) p_poly2)->poly;
  2129. if (cmp)
  2130. return (cmp);
  2131. cmp = ((LIGHTMAP_INFO *) p_poly2)->dy - ((LIGHTMAP_INFO *) p_poly1)->dy;
  2132. if (cmp)
  2133. return (cmp);
  2134. cmp = ((LIGHTMAP_INFO *) p_poly2)->dx - ((LIGHTMAP_INFO *) p_poly1)->dx;
  2135. return (cmp);
  2136. }
  2137. /*
  2138. typedef struct _LIGHTMAP_INFO {
  2139. BOD normal; // face normal
  2140. int p,k,o,f; // umisteni light-mapy
  2141. int dx,dy; // rozmery light-mapy
  2142. int material;
  2143. } LIGHTMAP_INFO;
  2144. */
  2145. typedef struct _LINKA_TEXTURY
  2146. {
  2147. RECT r; // ulozeni a velikost na mape
  2148. int radek; // radek
  2149. int vyska_radku; //
  2150. int dx, dy; // pomocne recy
  2151. int indicie; // odpovidajici indicie
  2152. struct _LINKA_TEXTURY *p_dalsi; // pod-bunky -> NULL == Konec
  2153. } LINKA_TEXTURY;
  2154. __inline LINKA_TEXTURY *ray_vloz_volnou_linku(LINKA_TEXTURY ** p_volne_linky,
  2155. LINKA_TEXTURY * p_tmp, int left, int top, int right, int bottom)
  2156. {
  2157. SetRect(&p_tmp->r, left, top, right, bottom);
  2158. p_tmp->dx = right - left;
  2159. p_tmp->dy = bottom - top;
  2160. p_tmp->radek = K_CHYBA;
  2161. p_tmp->vyska_radku = p_tmp->dy;
  2162. p_tmp->p_dalsi = *p_volne_linky;
  2163. *p_volne_linky = p_tmp;
  2164. return (p_tmp);
  2165. }
  2166. __inline LINKA_TEXTURY *ray_vloz_volnou_linku_all(LINKA_TEXTURY **
  2167. p_volne_linky, int left, int top, int right, int bottom, int indicie)
  2168. {
  2169. LINKA_TEXTURY *p_tmp;
  2170. p_tmp = malloc(sizeof(p_tmp[0]));
  2171. mtest(p_tmp);
  2172. memset(p_tmp, 0, sizeof(p_tmp[0]));
  2173. p_tmp->indicie = indicie;
  2174. return (ray_vloz_volnou_linku(p_volne_linky, p_tmp, left, top, right,
  2175. bottom));
  2176. }
  2177. /* Vlozi linku do lightmapy
  2178. */
  2179. int ray_vloz_linku(LINKA_TEXTURY ** p_linka, LINKA_TEXTURY ** p_volne_linky,
  2180. LIGHTMAP_INFO * p_mapa, int max_x_surface, int max_y_surface)
  2181. {
  2182. LINKA_TEXTURY *p_nova;
  2183. LINKA_TEXTURY *p_tmp, *p_tmp2, *p_tmp3;
  2184. int zbyva_bodu; // x zbyvajicich bodu do konce radku
  2185. int radek_vyska; // vyska zacatku radku v pixelech
  2186. int radek; // cislo aktualniho radku
  2187. int best_fit = -1;
  2188. int best_score = 0x0fffffff, score;
  2189. /* Alokace pameti na novou polozku v seznamu pod-textur
  2190. */
  2191. if (!(p_nova = (LINKA_TEXTURY *) malloc(sizeof(LINKA_TEXTURY))))
  2192. chyba("Pamet!");
  2193. p_nova->dx = p_mapa->dx;
  2194. p_nova->dy = p_mapa->dy;
  2195. p_nova->indicie = p_mapa->indicie;
  2196. p_nova->p_dalsi = NULL;
  2197. /* Je to prvni textura lightmapy
  2198. */
  2199. if (!*p_linka) { // insert-first
  2200. SetRect(&p_nova->r, 0, 0, p_mapa->dx, p_mapa->dy);
  2201. p_nova->radek = 0;
  2202. p_nova->vyska_radku = p_nova->dy;
  2203. *p_linka = p_nova;
  2204. return (TRUE);
  2205. }
  2206. else {
  2207. /* Hledam jestli neni misto v dirach...
  2208. */
  2209. // zkusit hledat v pribuznych lightmapach ? - pribuzne
  2210. // sou na vedlejsich poly
  2211. p_tmp = *p_volne_linky;
  2212. radek = 0;
  2213. if (p_tmp) {
  2214. // test prvni
  2215. while (p_tmp) {
  2216. //p_mapa->dx p_mapa->dy
  2217. if (p_tmp->dx >= p_mapa->dx && p_tmp->dy >= p_mapa->dy) {
  2218. score = (p_tmp->dy - p_mapa->dy) * 1000 + (p_tmp->dx - p_mapa->dx);
  2219. if (score < best_score) {
  2220. best_score = score;
  2221. best_fit = radek;
  2222. }
  2223. }
  2224. p_tmp = p_tmp->p_dalsi;
  2225. radek++;
  2226. }
  2227. if (best_fit != K_CHYBA) {
  2228. // najiti diry
  2229. p_tmp = *p_volne_linky;
  2230. if (!best_fit) { // best-fit je 0 - prvni
  2231. ray_vloz_volnou_linku(p_linka, p_nova,
  2232. p_tmp->r.left,
  2233. p_tmp->r.top,
  2234. p_tmp->r.left + p_nova->dx, p_tmp->r.top + p_nova->dy);
  2235. *p_volne_linky = (*p_volne_linky)->p_dalsi;
  2236. if (best_score) {
  2237. if (p_tmp->dx > p_nova->dx) { // pridej linku do konce radku
  2238. ray_vloz_volnou_linku_all(p_volne_linky,
  2239. p_nova->r.right,
  2240. p_nova->r.top, max_x_surface, p_nova->r.bottom, 0);
  2241. }
  2242. if (p_tmp->dy > p_nova->dy) { // pridej top-linku
  2243. ray_vloz_volnou_linku_all(p_volne_linky,
  2244. p_nova->r.left,
  2245. p_nova->r.bottom, max_x_surface, p_tmp->r.bottom, 0);
  2246. }
  2247. }
  2248. free(p_tmp);
  2249. return (TRUE);
  2250. }
  2251. else {
  2252. radek = 1;
  2253. while (p_tmp->p_dalsi) {
  2254. if (radek == best_fit) {
  2255. p_tmp2 =
  2256. ray_vloz_volnou_linku_all(p_linka, p_tmp->p_dalsi->r.left,
  2257. p_tmp->p_dalsi->r.top, p_tmp->p_dalsi->r.left + p_nova->dx,
  2258. p_tmp->p_dalsi->r.top + p_nova->dy, p_nova->indicie);
  2259. if (best_score) { // je tam dira - vyrob dalsi volne linky
  2260. p_tmp3 = p_tmp; // zazalohuju aktualni tmp
  2261. p_tmp = p_tmp->p_dalsi;
  2262. if (p_tmp->dx > p_tmp2->dx) { // pridej linku do konce radku
  2263. ray_vloz_volnou_linku_all(p_volne_linky,
  2264. p_tmp2->r.right,
  2265. p_tmp2->r.top, p_tmp->r.right, p_tmp2->r.bottom, 0);
  2266. }
  2267. if (p_tmp->dy > p_tmp2->dy) { // pridej top-linku
  2268. ray_vloz_volnou_linku_all(p_volne_linky,
  2269. p_tmp->r.left,
  2270. p_tmp2->r.bottom, p_tmp->r.right, p_tmp->r.bottom, 0);
  2271. }
  2272. p_tmp = p_tmp3; // obnovim puvodni p_tmp
  2273. }
  2274. p_tmp2 = p_tmp->p_dalsi;
  2275. p_tmp->p_dalsi = p_tmp->p_dalsi->p_dalsi;
  2276. free(p_tmp2);
  2277. return (TRUE);
  2278. }
  2279. p_tmp = p_tmp->p_dalsi;
  2280. radek++;
  2281. }
  2282. }
  2283. }
  2284. }
  2285. /* Najdu konec a hledam umisteni...
  2286. */
  2287. zbyva_bodu = max_x_surface;
  2288. radek = 0;
  2289. radek_vyska = 0; // zacatek radku v pixelech
  2290. p_tmp = (*p_linka); // zacnu od zacatku...
  2291. while (p_tmp && p_tmp->radek == K_CHYBA) {
  2292. p_tmp = p_tmp->p_dalsi;
  2293. }
  2294. zbyva_bodu = max_x_surface - p_tmp->dx;
  2295. do {
  2296. /* Preteceni vysky lightmapy
  2297. */
  2298. if (radek_vyska + p_mapa->dy > max_y_surface) {
  2299. free(p_nova);
  2300. p_nova = NULL;
  2301. return (FALSE);
  2302. }
  2303. /* Vlozeni za soucastnou lightmapu na konec radku
  2304. nebo do mezery ktera je do konce radku
  2305. */
  2306. if (zbyva_bodu >= p_mapa->dx && (p_tmp->p_dalsi == NULL || // v pripade konce radku
  2307. p_tmp->p_dalsi->radek > radek)) { // v pripade ze dalsi lightmapa
  2308. // je na dalsim radku
  2309. // max vyska je vyska predchozi textury
  2310. assert(p_tmp->vyska_radku >= p_mapa->dy);
  2311. p_nova->radek = radek;
  2312. p_nova->vyska_radku = p_tmp->vyska_radku;
  2313. p_nova->p_dalsi = p_tmp->p_dalsi; // insert-first
  2314. p_tmp->p_dalsi = p_nova;
  2315. // rect nove
  2316. SetRect(&p_nova->r, max_x_surface - zbyva_bodu,
  2317. radek_vyska,
  2318. max_x_surface - zbyva_bodu + p_nova->dx, radek_vyska + p_nova->dy);
  2319. // pridam do derovniku volne diry
  2320. if (p_mapa->dy < p_tmp->dy) {
  2321. ray_vloz_volnou_linku_all(p_volne_linky,
  2322. max_x_surface - zbyva_bodu,
  2323. radek_vyska + p_mapa->dy,
  2324. max_x_surface, radek_vyska + p_tmp->dy, 0);
  2325. }
  2326. return (TRUE);
  2327. }
  2328. // Vytvoreni noveho radku + pridani na konec
  2329. if (zbyva_bodu < p_mapa->dx && p_tmp->p_dalsi == NULL) {
  2330. radek_vyska += p_tmp->vyska_radku;
  2331. // Radek presahl vysku lightmapy
  2332. if (radek_vyska + p_nova->dy > max_y_surface) {
  2333. free(p_nova);
  2334. return (FALSE);
  2335. }
  2336. // Vlozeni lightmapy na zacatek noveho radku
  2337. p_nova->radek = ++radek;
  2338. p_nova->vyska_radku = p_mapa->dy;
  2339. SetRect(&p_nova->r, 0, radek_vyska, p_nova->dx,
  2340. radek_vyska + p_nova->dy);
  2341. p_nova->p_dalsi = NULL;
  2342. p_tmp->p_dalsi = p_nova;
  2343. return (TRUE);
  2344. }
  2345. // pokracovani v prohledavani
  2346. if (p_tmp->p_dalsi) {
  2347. // mezi-radkova korekce
  2348. while (p_tmp->p_dalsi && p_tmp->p_dalsi->radek == K_CHYBA) {
  2349. p_tmp = p_tmp->p_dalsi;
  2350. }
  2351. // prechod na dalsi radek
  2352. if (p_tmp->p_dalsi->radek > radek) {
  2353. radek_vyska += p_tmp->vyska_radku;
  2354. zbyva_bodu = max_x_surface - p_tmp->p_dalsi->dx;
  2355. radek = p_tmp->p_dalsi->radek;
  2356. }
  2357. else
  2358. zbyva_bodu -= p_tmp->p_dalsi->dx;
  2359. // pokracovani v soucastnem
  2360. p_tmp = p_tmp->p_dalsi;
  2361. }
  2362. else {
  2363. free(p_nova);
  2364. return (FALSE); // konec seznamu
  2365. }
  2366. } while (p_tmp);
  2367. free(p_nova);
  2368. p_nova = NULL;
  2369. return (FALSE); // uz se tam light-mapa nevleze
  2370. }
  2371. }
  2372. int ray_statistika_linek(LINKA_TEXTURY ** p_linka, int *p_x, int *p_y)
  2373. {
  2374. LINKA_TEXTURY *p_tmp;
  2375. int dx = 0, dy = 0;
  2376. if (!*p_linka)
  2377. return (FALSE);
  2378. p_tmp = *p_linka;
  2379. while (p_tmp) {
  2380. if (dy < p_tmp->r.bottom)
  2381. dy = p_tmp->r.bottom;
  2382. if (dx < p_tmp->r.right)
  2383. dx = p_tmp->r.right;
  2384. p_tmp = p_tmp->p_dalsi;
  2385. }
  2386. *p_x = dx;
  2387. *p_y = dy;
  2388. return (TRUE);
  2389. }
  2390. void ray_free_linky(LINKA_TEXTURY * p_linka)
  2391. {
  2392. if (p_linka) {
  2393. ray_free_linky(p_linka->p_dalsi);
  2394. free(p_linka);
  2395. p_linka = NULL;
  2396. }
  2397. }
  2398. /*
  2399. */
  2400. LINKA_TEXTURY **ray_vyrob_poly_lightmap(POLY_INDICIE * p_ind, int indnum,
  2401. EDIT_MESH_POLY * p_poly, int *p_linek,
  2402. LIGHTMAP_INFO * p_mapy, int max_x_surface, int max_y_surface)
  2403. {
  2404. LINKA_TEXTURY **p_linka;
  2405. LINKA_TEXTURY *p_linka_volna = NULL, *p_tmp;
  2406. int linek;
  2407. int i;
  2408. int umistenych;
  2409. int umistenych_celkem;
  2410. p_linka = (LINKA_TEXTURY **) malloc(sizeof(LINKA_TEXTURY *) * indnum);
  2411. mtest(p_linka);
  2412. memset(p_linka, 0, sizeof(LINKA_TEXTURY *) * indnum);
  2413. /* Setridim lightmapy poly podle velikosti y,x
  2414. (prednost ma y, potom x)
  2415. */
  2416. qsort(p_mapy, indnum, sizeof(LIGHTMAP_INFO),
  2417. ray_vyrob_poly_lightmap_compare);
  2418. /*
  2419. Optimalizace -> opakovane vkladami mensich textur
  2420. do vetsich
  2421. */
  2422. for (i = 0; i < indnum; i++)
  2423. p_mapy[i].umistena = FALSE;
  2424. /* Dokud neumistim vsechny plosky-opakuj proceduru
  2425. */
  2426. umistenych_celkem = 0;
  2427. linek = 0;
  2428. while (umistenych_celkem != indnum) {
  2429. umistenych = 0;
  2430. for (i = 0; i < indnum; i++) {
  2431. if (!p_mapy[i].umistena) {
  2432. if (ray_vloz_linku(p_linka + linek, &p_linka_volna, p_mapy + i,
  2433. max_x_surface, max_y_surface)) {
  2434. p_mapy[i].umistena = TRUE;
  2435. umistenych++;
  2436. umistenych_celkem++;
  2437. }
  2438. }
  2439. }
  2440. if (!umistenych) {
  2441. //free lin seznam p_linka_volna
  2442. linek++;
  2443. }
  2444. }
  2445. linek++;
  2446. *p_linek = linek;
  2447. /* Uvolneni volnych linek
  2448. */
  2449. while (p_linka_volna) {
  2450. p_tmp = p_linka_volna;
  2451. p_linka_volna = p_linka_volna->p_dalsi;
  2452. free(p_tmp);
  2453. }
  2454. return (p_linka);
  2455. }
  2456. void ray_link_to_lightmap(EDIT_TEXT * p_dest, EDIT_TEXT * p_src,
  2457. LINKA_TEXTURY * p_linka);
  2458. void ray_prepocitej_texture_koordinaty(EDIT_MESH_POLY * p_poly_list,
  2459. POLY_INDICIE * p_ind, LINKA_TEXTURY * p_linka, int dest_x, int dest_y,
  2460. EDIT_TEXT * p_text);
  2461. void ray_tiskni_linky(LINKA_TEXTURY * p_linka)
  2462. {
  2463. if (p_linka) {
  2464. kprintf(TRUE, "indicie %d -> (%d %d %d %d)", p_linka->indicie,
  2465. p_linka->r.left, p_linka->r.top, p_linka->r.right, p_linka->r.bottom);
  2466. ray_tiskni_linky(p_linka->p_dalsi);
  2467. }
  2468. }
  2469. void ray_slep_lightmapy(K_EDITOR * p_cnf, POLY_INDICIE * p_ind, int indnum,
  2470. EDIT_TEXT * p_src)
  2471. {
  2472. LIGHTMAP_INFO *p_mapy;
  2473. LINKA_TEXTURY **p_linky;
  2474. int l, x, y, dx, dy, t;
  2475. int linek;
  2476. int i;
  2477. if (!(p_mapy = (LIGHTMAP_INFO *) _alloca(sizeof(LIGHTMAP_INFO) * indnum)))
  2478. chyba("Pamet");
  2479. for (i = 0; i < indnum; i++) {
  2480. bmp_cti_rozmery(p_src[i].p_bmp, &p_mapy[i].dx, &p_mapy[i].dy);
  2481. p_mapy[i].material = p_cnf->p_poly[p_ind[i].poly].material;
  2482. p_mapy[i].poly = p_ind[i].poly;
  2483. p_mapy[i].f = p_ind[i].face / 3;
  2484. p_mapy[i].indicie = i;
  2485. }
  2486. // vyrobi seznam lightmap pro tento poly
  2487. p_linky = ray_vyrob_poly_lightmap(p_ind, indnum, p_cnf->p_poly,
  2488. &linek, p_mapy, p_cnf->ray.max_x_lepic, p_cnf->ray.max_y_lepic);
  2489. // preved to do oficialnich light-map
  2490. for (l = 0; l < linek; l++) {
  2491. if (ray_statistika_linek(p_linky + l, &x, &y)) {
  2492. if ((t =
  2493. lo_najdi_volnou_texturu(p_cnf->p_lightmap,
  2494. MAX_RAY_TEXTUR)) == K_CHYBA)
  2495. chyba("Neni volna texutra !");
  2496. for (dx = 2; dx < x; dx <<= 1);
  2497. for (dy = 2; dy < y; dy <<= 1);
  2498. if ((p_cnf->p_lightmap[t].p_bmp = bmp_vyrob(dx, dy)) == NULL)
  2499. chyba("Textura");
  2500. bmp_smaz(p_cnf->p_lightmap[t].p_bmp, BLBA_BARVA2);
  2501. sprintf(p_cnf->p_lightmap[t].jmeno, "light%d", t);
  2502. ray_link_to_lightmap(p_cnf->p_lightmap + t, p_src, p_linky[l]);
  2503. ray_prepocitej_texture_koordinaty(p_cnf->p_poly, p_ind, p_linky[l], dx,
  2504. dy, p_cnf->p_lightmap + t);
  2505. ray_free_linky(p_linky[l]);
  2506. }
  2507. }
  2508. free(p_linky);
  2509. p_linky = NULL;
  2510. }
  2511. void ray_link_to_lightmap(EDIT_TEXT * p_dest, EDIT_TEXT * p_src,
  2512. LINKA_TEXTURY * p_linka)
  2513. {
  2514. // pridej akt bunku
  2515. // cil = p_dest + rec
  2516. // src = p_src[face]
  2517. if (p_linka) {
  2518. ray_link_to_lightmap(p_dest, p_src, p_linka->p_dalsi);
  2519. bmp_kopiruj_rec(p_src[p_linka->indicie].p_bmp, p_dest->p_bmp,
  2520. p_linka->r.left, p_linka->r.top);
  2521. }
  2522. }
  2523. // in je rect uvnitr
  2524. void ray_prepocitej_texture_koordinaty(EDIT_MESH_POLY * p_poly_list,
  2525. POLY_INDICIE * p_ind,
  2526. LINKA_TEXTURY * p_linka, int dest_x, int dest_y, EDIT_TEXT * p_text)
  2527. {
  2528. EDIT_MESH_POLY *p_poly;
  2529. float x_start, y_start, dx, dy;
  2530. int f, ind;
  2531. if (p_linka) {
  2532. ray_prepocitej_texture_koordinaty(p_poly_list, p_ind, p_linka->p_dalsi,
  2533. dest_x, dest_y, p_text);
  2534. x_start = (float) p_linka->r.left / (float) dest_x;
  2535. y_start = (float) p_linka->r.top / (float) dest_y;
  2536. dx = (float) (p_linka->r.right - p_linka->r.left) / (float) dest_x;
  2537. dy = (float) (p_linka->r.bottom - p_linka->r.top) / (float) dest_y;
  2538. ind = p_linka->indicie;
  2539. p_poly = p_poly_list + p_ind[ind].poly;
  2540. f = p_ind[ind].face;
  2541. p_poly->p_koord[f].tul = dx * p_poly->p_koord[f].tul + x_start;
  2542. p_poly->p_koord[f].tvl = dy * p_poly->p_koord[f].tvl + y_start;
  2543. p_poly->p_koord[f + 1].tul = dx * p_poly->p_koord[f + 1].tul + x_start;
  2544. p_poly->p_koord[f + 1].tvl = dy * p_poly->p_koord[f + 1].tvl + y_start;
  2545. p_poly->p_koord[f + 2].tul = dx * p_poly->p_koord[f + 2].tul + x_start;
  2546. p_poly->p_koord[f + 2].tvl = dy * p_poly->p_koord[f + 2].tvl + y_start;
  2547. p_poly->p_light[f / 3] = p_text;
  2548. }
  2549. }
  2550. /****************************************************************************
  2551. Staticke-bodove svetla
  2552. ****************************************************************************
  2553. */
  2554. int oe_vloz_staticke_bodove_svetlo(K_EDITOR * p_cnf, STATIC_LIGHT * p_light)
  2555. {
  2556. p_cnf->light[p_light->index] = *p_light;
  2557. p_cnf->light[p_light->index].akt = TRUE;
  2558. p_cnf->light[p_light->index].flag = POSUN_VSE;
  2559. //ddw("Svetlo %s na %d upraveno.",p_light->jmeno,p_light->index);
  2560. return (p_light->index);
  2561. }
  2562. int oe_smaz_staticke_bodove_svetlo(K_EDITOR * p_cnf, STATIC_LIGHT * p_light)
  2563. {
  2564. int li = p_light->index;
  2565. p_cnf->light[li].akt = FALSE;
  2566. if (p_cnf->light[li].p_flare) {
  2567. oe_smaz_flare(p_cnf, p_cnf->light[li].p_flare);
  2568. }
  2569. if (p_light->flag2 & SL2_MESH) {
  2570. if (!p_light->p_prev) { // mazu prvni svetlo kontejneru
  2571. EDIT_KONTEJNER *p_kont = (EDIT_KONTEJNER *) p_light->p_mesh_data;
  2572. assert(p_light == p_kont->p_slight);
  2573. p_kont->p_slight = p_light->p_next;
  2574. if (p_light->p_next)
  2575. p_light->p_next->p_prev = NULL;
  2576. }
  2577. else {
  2578. p_light->p_prev->p_next = p_light->p_next;
  2579. if (p_light->p_next)
  2580. p_light->p_next->p_prev = p_light->p_prev;
  2581. }
  2582. }
  2583. memset(p_light, 0, sizeof(p_light[0]));
  2584. return (TRUE);
  2585. }
  2586. int oe_najdi_volne_stat_svetlo(K_EDITOR * p_cnf)
  2587. {
  2588. int i;
  2589. for (i = 0; i < MAX_EDIT_SVETEL; i++) {
  2590. if (!p_cnf->light[i].akt)
  2591. return (i);
  2592. }
  2593. return (K_CHYBA);
  2594. }
  2595. void oe_prikaz_pridej_staticke_svetlo(K_EDITOR * p_cnf)
  2596. {
  2597. int l = oe_najdi_volne_stat_svetlo(p_cnf);
  2598. byte pom[200];
  2599. int k = p_cnf->vybr_kont;
  2600. STATIC_LIGHT light, *p_light;
  2601. if (!p_cnf->cnf.svetla_sceny) {
  2602. n_kont(k);
  2603. }
  2604. memset(&light, 0, sizeof(light));
  2605. light.dosah = 10000.0f;
  2606. light.index = l;
  2607. light.r = light.g = light.b = 1.0f;
  2608. light.k1 = 1;
  2609. light.uhel = light.utlum = 1;
  2610. light.p_flare = NULL;
  2611. light.akt = TRUE;
  2612. sprintf(light.jmeno, "Svetlo %d", l);
  2613. if (p_cnf->cnf.svetla_sceny) {
  2614. strcpy(pom, "Pridat bodove svetlo sceny...");
  2615. }
  2616. else {
  2617. sprintf(pom, "Pridat bodove svetlo kontejneru %s (%d)",
  2618. p_cnf->p_kont[k]->jmeno, k);
  2619. }
  2620. if (doe_prikaz_bodove_svetlo(hwnd_aplikace, pom, &light)) {
  2621. p_cnf->lightakt = oe_vloz_staticke_bodove_svetlo(p_cnf, &light);
  2622. p_light = p_cnf->light + p_cnf->lightakt;
  2623. if (p_cnf->cnf.svetla_dynamicke) {
  2624. oe_prepocitat_stat_svetla(p_cnf);
  2625. ray_prepocitej_staticke_osvetleni_vertexy(p_cnf);
  2626. }
  2627. if (!p_cnf->cnf.svetla_sceny) {
  2628. p_light->flag2 = SL2_MESH;
  2629. p_light->p_mesh_data = p_cnf->p_kont[k];
  2630. p_light->p_next = p_cnf->p_kont[k]->p_slight;
  2631. p_light->p_prev = NULL;
  2632. p_cnf->p_kont[k]->p_slight = p_light;
  2633. if (p_light->p_next) {
  2634. p_light->p_next->p_prev = p_light;
  2635. }
  2636. }
  2637. }
  2638. }
  2639. void oe_uprav_staticke_svetlo(K_EDITOR * p_cnf, STATIC_LIGHT * p_light)
  2640. {
  2641. STATIC_LIGHT light = *p_light;
  2642. byte pom[200];
  2643. if (p_light->flag2 & SL2_MESH) {
  2644. EDIT_KONTEJNER *p_kont = p_light->p_mesh_data;
  2645. sprintf(pom, "Uprav bodove svetlo kontejneru %s...", p_kont->jmeno);
  2646. }
  2647. else {
  2648. strcpy(pom, "Uprav bodove svetlo sceny...");
  2649. }
  2650. if (doe_prikaz_bodove_svetlo(hwnd_aplikace, pom, &light))
  2651. oe_vloz_staticke_bodove_svetlo(p_cnf, &light);
  2652. }
  2653. void oe_prepocitat_stat_svetla(K_EDITOR * p_cnf)
  2654. {
  2655. STATIC_LIGHT *p_light;
  2656. int i;
  2657. float dist, I, det, a1, a2;
  2658. p_cnf->lightnum = 0;
  2659. for (i = 0; i < MAX_EDIT_SVETEL; i++) {
  2660. if (p_cnf->light[i].akt) {
  2661. p_light = p_cnf->light + i;
  2662. p_cnf->lightnum = i + 1;
  2663. // posledni kontejner&poly je nic
  2664. p_light->last_kont = p_light->last_poly = K_CHYBA;
  2665. // prepocitam dosah podle utlumu
  2666. if (p_light->utlum) {
  2667. dist = p_light->dosah;
  2668. I =
  2669. 1.0f / (p_light->k1 + p_light->k2 * dist +
  2670. p_light->k3 * dist * dist);
  2671. // nastavim dosah podle utlumu
  2672. if (I < MIN_LIGHT) {
  2673. det =
  2674. p_light->k2 * p_light->k2 - 4 * p_light->k3 * (p_light->k1 -
  2675. 1.0f / MIN_LIGHT);
  2676. a1 = (-p_light->k2 + sqrtf(det)) / (2 * p_light->k3);
  2677. a2 = (-p_light->k2 - sqrtf(det)) / (2 * p_light->k3);
  2678. if (a1 > dist || a1 < 0.0f)
  2679. a1 = dist;
  2680. if (a2 > dist || a2 < 0.0f)
  2681. a2 = dist;
  2682. p_light->dosah = (a2 > a1) ? a1 : a2;
  2683. }
  2684. }
  2685. }
  2686. }
  2687. }
  2688. /*******************************
  2689. Ray-Casting
  2690. *******************************
  2691. Motto:
  2692. "To je vec, ktera je dnes uz naprosty standard.
  2693. Vsechny gamesy, pokud vim, to takhle delaji.
  2694. Pekne to popisuje Michael Abrash v Ramblings
  2695. in Realtime (o vyvoji Quaka), posilam ti to PDFko.
  2696. Jde to, ze kazdemu polygonu sceny udelas lightmapu
  2697. tak, ze vytvoris nejakou pravidelnou sit o ne moc
  2698. velkem poctu stejne vzdalenych uzlu, takovy grid
  2699. rovnomerne napamovany na cely polygon. Z kazdeho
  2700. toho uzlu pak vystrelis papresek ke vsem zdrojum
  2701. svetla, kdyz se s nicim neprotne, tak je tam svetlo
  2702. jinak tma. Muzes merit i vzdalenost od svetla a tim
  2703. korigovat mnozstvi energie. Vysledek pak zprumerujes
  2704. s nekolika okolnima uzlama a ziskas tak mekke stiny.
  2705. Kdyz zvolis raster moc veliky, tak jsou mapy kvalitni
  2706. ale zase zabiraji moc mista, takze se tezko rvou do
  2707. akceleratoru. Je dobre zvolit mensi kompromis, pak se
  2708. jsou sice ve vetsi vzdalenosti od svetla videt takove
  2709. rozblurovane ctverce (viz. nektere levely v Quaku),
  2710. ale to je dan pometovym narokum."
  2711. ReDox^Movsd
  2712. */
  2713. void oe_uloz_screen(byte * p_file)
  2714. {
  2715. /* Nacte HDC a ulozi to na disk
  2716. */
  2717. }
  2718. /**************************************************************************
  2719. Optimalizacni kvadratura
  2720. *************************************************************************
  2721. */
  2722. // analizuje scenu a vyplivne rozmery kvadrat. stromu
  2723. #define X_BUNKA 2
  2724. #define Y_BUNKA 2
  2725. #define Z_BUNKA 2
  2726. void ray_analizuj_scenu(K_EDITOR * p_cnf, BOD * p_start, BOD * p_bunek,
  2727. BOD * p_roz)
  2728. {
  2729. EDIT_MESH_POLY *p_poly;
  2730. BOD kon = { -FLT_MAX, -FLT_MAX, -FLT_MAX }, zac = {
  2731. FLT_MAX, FLT_MAX, FLT_MAX}, a;
  2732. int p, f;
  2733. for (p = 0; p < p_cnf->polynum; p++) {
  2734. p_poly = p_cnf->p_poly + p;
  2735. for (f = 0; f < p_poly->facenum; f++) {
  2736. a.x = p_poly->p_koord[f].x;
  2737. a.y = p_poly->p_koord[f].y;
  2738. a.z = p_poly->p_koord[f].z;
  2739. if (a.x < zac.x)
  2740. zac.x = a.x;
  2741. if (a.y < zac.y)
  2742. zac.y = a.y;
  2743. if (a.z < zac.z)
  2744. zac.z = a.z;
  2745. if (a.x > kon.x)
  2746. kon.x = a.x;
  2747. if (a.y > kon.y)
  2748. kon.y = a.y;
  2749. if (a.z > kon.z)
  2750. kon.z = a.z;
  2751. }
  2752. }
  2753. *p_start = zac;
  2754. p_bunek->x =
  2755. (float) ceil((2.0f * ceil(kon.x - zac.x)) / (float) p_roz->x) + 1;
  2756. p_bunek->y =
  2757. (float) ceil((2.0f * ceil(kon.y - zac.y)) / (float) p_roz->y) + 1;
  2758. p_bunek->z =
  2759. (float) ceil((2.0f * ceil(kon.z - zac.z)) / (float) p_roz->z) + 1;
  2760. }
  2761. int ray_bod_do_qbod(QUAD_TREE * p_qtree, QBOD * p_q, BOD * p_b)
  2762. {
  2763. p_q->x = (int) floor((p_b->x - p_qtree->st.x) / p_qtree->bunka.x);
  2764. p_q->y = (int) floor((p_b->y - p_qtree->st.y) / p_qtree->bunka.y);
  2765. p_q->z = (int) floor((p_b->z - p_qtree->st.z) / p_qtree->bunka.z);
  2766. if (p_q->x >= 0 && p_q->x < p_qtree->rad.x &&
  2767. p_q->y >= 0 && p_q->y < p_qtree->rad.y &&
  2768. p_q->z >= 0 && p_q->z < p_qtree->rad.z)
  2769. return (TRUE);
  2770. else
  2771. return (FALSE);
  2772. }
  2773. BOD *ray_interpoluj_face_bodama(BOD * p_face, int *p_bodu)
  2774. {
  2775. BOD q1, q2, h1, h2, hq, *p_list;
  2776. int i, j, bodu, lbodu;
  2777. int cbodu;
  2778. float k1, k2, t, dt, ht, hdt;
  2779. float krok = 0.05f;
  2780. k1 = vzdal_bodu_bod(p_face, p_face + 2);
  2781. k2 = vzdal_bodu_bod(p_face + 1, p_face + 2);
  2782. bodu = (int) ceil((k1 < k2) ? k2 / krok : k1 / krok);
  2783. bodu++;
  2784. p_list = malloc(sizeof(BOD) * bodu * bodu);
  2785. if (!p_list)
  2786. chyba("Pamet!");
  2787. cbodu = 0;
  2788. // t je parametr od 0 do 1
  2789. calc_primku_3d(p_face, p_face + 2, &q1);
  2790. calc_primku_3d(p_face + 1, p_face + 2, &q2);
  2791. // P = d + q*t
  2792. // t = 0-1 -> po k1 krocich
  2793. t = 0;
  2794. dt = 1.0f / (float) (bodu - 1);
  2795. for (i = 0; i < bodu; i++) {
  2796. // d[0] -> d[2]
  2797. h1.x = p_face[0].x + q1.x * t;
  2798. h1.y = p_face[0].y + q1.y * t;
  2799. h1.z = p_face[0].z + q1.z * t;
  2800. h2.x = p_face[1].x + q2.x * t;
  2801. h2.y = p_face[1].y + q2.y * t;
  2802. h2.z = p_face[1].z + q2.z * t;
  2803. t += dt;
  2804. // 2 body a mezi nema interpolovat
  2805. // h1 a h2
  2806. lbodu = (int) ceil(vzdal_bodu_bod(&h1, &h2) / krok);
  2807. lbodu++;
  2808. calc_primku_3d(&h1, &h2, &hq);
  2809. ht = 0.0f;
  2810. hdt = 1.0f / ((float) (lbodu - 1));
  2811. for (j = 0; j < lbodu; j++) {
  2812. p_list[cbodu].x = (h1.x + hq.x * ht);
  2813. p_list[cbodu].y = (h1.y + hq.y * ht);
  2814. p_list[cbodu].z = (h1.z + hq.z * ht);
  2815. ht += hdt;
  2816. cbodu++;
  2817. }
  2818. }
  2819. *p_bodu = cbodu;
  2820. return (p_list);
  2821. }