12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344 |
- /*
- Ray-tracing sceny
- */
- #include "mss_on.h"
- #include <windows.h>
- #include <stdio.h>
- #include <math.h>
- #include <direct.h>
- #include <float.h>
- #include <assert.h>
- #include "objekt_editor_all.h"
- //#include "dbgwnd.h"
- __inline void ray_svetlost_vertex_poly_diff(TEXT_KOORD * p_koord);
- __inline void ray_svetlost_vertex_poly(K_EDITOR * p_cnf, TEXT_KOORD * p_koord,
- float lesk);
- __inline dword ray_interpoluj_2_barvy(dword b1, dword b2, float vaha2);
- __inline dword ray_svetlost_bodu(K_EDITOR * p_cnf, BOD * p_p,
- LIGHTMAP_INFO * p_akt, byte stiny, dword ambient, int no_phong);
- #define BLBA_BARVA 0xff0000
- #define BLBA_BARVA2 0xff0000
- /*
- #define OKRAJ 4
- #define MIN_X_TEXTURA 16
- #define MIN_Y_TEXTURA 16
- */
- #define OKRAJ (p_cnf->ray.okraj)
- #define MIN_X_TEXTURA (p_cnf->ray.text_min_x)
- #define MIN_Y_TEXTURA (p_cnf->ray.text_min_y)
- /*
- Brutalni 9-ti pixelovej filtr - radkovej
- */
- void ray_surface_filtruj_ctverec_9(bitmapa * p_bmp)
- {
- bitmapa *p_tmp;
- dword barva, r = 0, g = 0, b = 0;
- int cisel, i;
- int tabulka[] = { 1, 0, 1, 1, 0, 1, -1, 1, -1, 0, -1, -1, 0, -1, 1, -1 };
- int x, y, dx, dy;
- int px, py;
- p_tmp = bmp_kopituj(p_bmp);
- dx = p_bmp->x;
- dy = p_bmp->y;
- for (x = 0; x < dx; x++) {
- for (y = 0; y < dy; y++) {
- barva = bmp_getpixel(p_tmp, x, y);
- r = GetRValue(barva);
- g = GetGValue(barva);
- b = GetBValue(barva);
- cisel = 1;
- for (i = 0; i < 16; i += 2) {
- px = x + tabulka[i];
- py = y + tabulka[i + 1];
- if (px >= 0 && px < dx && py >= 0 && py < dy) {
- barva = bmp_getpixel(p_tmp, px, py);
- if (barva != BLBA_BARVA) {
- r += GetRValue(barva);
- g += GetGValue(barva);
- b += GetBValue(barva);
- cisel++;
- }
- }
- }
- mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) cisel);
- bmp_putpixel(p_bmp, x, y, barva);
- }
- }
- bmp_zrus(&p_tmp);
- }
- void ray_surface_filtruj_ctverec_25(bitmapa * p_bmp)
- {
- bitmapa *p_tmp;
- dword barva, r = 0, g = 0, b = 0;
- int cisel, i;
- int tabulka[] = { 0, 0,
- 1, 0, 1, 1, 0, 1, -1, 1,
- -1, 0, -1, -1, 0, -1, 1, -1,
- -2, -2, -1, -2, 0, -2, 1, -2, 2, -2, // spodek
- -2, 2, -1, 2, 0, 2, 1, 2, 2, 2, // vrsek
- -2, 1, -2, 0, -2, -1,
- 2, 1, 2, 0, 2, -1
- };
- int x, y, dx, dy;
- int px, py;
- p_tmp = bmp_kopituj(p_bmp);
- dx = p_bmp->x;
- dy = p_bmp->y;
- for (x = 0; x < dx; x++) {
- for (y = 0; y < dy; y++) {
- r = g = b = 0;
- cisel = 0;
- for (i = 0; i < 25; i += 2) {
- px = x + tabulka[i];
- py = y + tabulka[i + 1];
- if (px >= 0 && px < dx && py >= 0 && py < dy) {
- barva = bmp_getpixel(p_tmp, px, py);
- r += GetRValue(barva);
- g += GetGValue(barva);
- b += GetBValue(barva);
- cisel++;
- }
- }
- mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) cisel);
- bmp_putpixel(p_bmp, x, y, barva);
- }
- }
- bmp_zrus(&p_tmp);
- }
- void ray_surface_filtruj_krizem_9(bitmapa * p_bmp)
- {
- bitmapa *p_tmp;
- dword barva, r = 0, g = 0, b = 0;
- int cisel, i;
- int tabulka[] = { 0, 0, 0, 1, 0, -1, 1, 0, -1, 0 };
- int x, y, dx, dy;
- int px, py;
- p_tmp = bmp_kopituj(p_bmp);
- dx = p_bmp->x;
- dy = p_bmp->y;
- for (x = 0; x < dx; x++) {
- for (y = 0; y < dy; y++) {
- r = g = b = 0;
- cisel = 0;
- for (i = 0; i < 10; i += 2) {
- px = x + tabulka[i];
- py = y + tabulka[i + 1];
- if (px >= 0 && px < dx && py >= 0 && py < dy) {
- barva = bmp_getpixel(p_tmp, px, py);
- r += GetRValue(barva);
- g += GetGValue(barva);
- b += GetBValue(barva);
- cisel++;
- }
- }
- mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) cisel);
- bmp_putpixel(p_bmp, x, y, barva);
- }
- }
- bmp_zrus(&p_tmp);
- }
- void ray_surface_filtruj_krizem_25(bitmapa * p_bmp)
- {
- bitmapa *p_tmp;
- dword barva, r = 0, g = 0, b = 0;
- int cisel, i;
- int tabulka[] = { 0, 0,
- 0, 1, 0, -1, 1, 0, -1, 0,
- 0, 2, 0, -2, 2, 0, -2, 0
- };
- int x, y, dx, dy;
- int px, py;
- p_tmp = bmp_kopituj(p_bmp);
- dx = p_bmp->x;
- dy = p_bmp->y;
- for (x = 0; x < dx; x++) {
- for (y = 0; y < dy; y++) {
- r = g = b = 0;
- cisel = 0;
- for (i = 0; i < 18; i += 2) {
- px = x + tabulka[i];
- py = y + tabulka[i + 1];
- if (px >= 0 && px < dx && py >= 0 && py < dy) {
- barva = bmp_getpixel(p_tmp, px, py);
- r += GetRValue(barva);
- g += GetGValue(barva);
- b += GetBValue(barva);
- cisel++;
- }
- }
- mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) cisel);
- bmp_putpixel(p_bmp, x, y, barva);
- }
- }
- bmp_zrus(&p_tmp);
- }
- void ray_surface_filtruj_rovne_25(bitmapa * p_bmp)
- {
- bitmapa *p_tmp;
- dword barva, r = 0, g = 0, b = 0;
- int cisel, i;
- int tabulka[] = { 0, 0,
- 1, 0, -1, 0,
- 2, 0, -2, 0
- };
- int x, y, dx, dy;
- int px, py;
- p_tmp = bmp_kopituj(p_bmp);
- dx = p_bmp->x;
- dy = p_bmp->y;
- for (x = 0; x < dx; x++) {
- for (y = 0; y < dy; y++) {
- r = g = b = 0;
- cisel = 0;
- for (i = 0; i < 10; i += 2) {
- px = x + tabulka[i];
- py = y + tabulka[i + 1];
- if (px >= 0 && px < dx && py >= 0 && py < dy) {
- barva = bmp_getpixel(p_tmp, px, py);
- r += GetRValue(barva);
- g += GetGValue(barva);
- b += GetBValue(barva);
- cisel++;
- }
- }
- mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) cisel);
- bmp_putpixel(p_bmp, x, y, barva);
- }
- }
- bmp_zrus(&p_tmp);
- }
- static int ray_surface_filtruj_medianem_compare(const void *p_b1,
- const void *p_b2)
- {
- float b1, b2;
- b1 = ((RGB *) p_b1)->r + ((RGB *) p_b1)->g + ((RGB *) p_b1)->b;
- b2 = ((RGB *) p_b2)->r + ((RGB *) p_b2)->g + ((RGB *) p_b2)->b;
- return ((int) ((b2 - b1) * 0.0001f));
- }
- void ray_surface_filtruj_medianem(bitmapa * p_bmp)
- {
- bitmapa *p_tmp;
- dword barva;
- float b[3];
- int i;
- int tabulka[] = { 1, 0, 1, 1, 0, 1, -1, 1, -1, 0, -1, -1, 0, -1, 1, -1,
- 2, 0, 2, 1, 2, 2, 1, 2, 0, 2, -1, 2, -2, 2, -2, 1, -2, 0, -2, -1, -2, -2,
- -1, -2, 0, -2, 1, -2, 2, -2, -2, 1
- };
- RGB ct[25];
- int p;
- int x, y, dx, dy;
- int px, py;
- p_tmp = bmp_kopituj(p_bmp);
- dx = p_bmp->x;
- dy = p_bmp->y;
- for (x = 0; x < dx; x++) {
- for (y = 0; y < dy; y++) {
- barva = bmp_getpixel(p_tmp, x, y);
- p = 0;
- if (barva != BLBA_BARVA) {
- rgb_float(barva, &ct[p].r);
- p++;
- for (i = 0; i < 50; i += 2) {
- px = x + tabulka[i];
- py = y + tabulka[i + 1];
- if (px > 0 && px < dx && py > 0 && py < dy) {
- barva = bmp_getpixel(p_tmp, px, py);
- if (barva != BLBA_BARVA) {
- rgb_float(barva, &ct[p].r);
- p++;
- }
- }
- }
- //spocitam prumer
- b[0] = b[1] = b[3] = 0.0f;
- for (i = 0; i < p; i++) {
- b[0] += ct[i].r;
- b[1] += ct[i].g;
- b[2] += ct[i].b;
- }
- b[0] /= p;
- b[1] /= p;
- b[2] /= p;
- bmp_putpixel(p_bmp, x, y, float_rgb(b));
- }
- }
- }
- bmp_zrus(&p_tmp);
- }
- /*
- Prevedu pole lightmap na jednotliva podpole s poctama lightmap
- */
- void ray_poly_optim_lightmap(EDIT_MESH_POLY * p_poly)
- {
- EDIT_TEXT **p_klight =
- (EDIT_TEXT **) _alloca(p_poly->lightnum * sizeof(EDIT_TEXT *));
- int *p_pocty = (int *) _alloca(p_poly->lightnum * sizeof(int *));
- EDIT_TEXT *p_last = NULL;
- int i, p;
- if (p_poly->p_lightnum) {
- assert(0);
- }
- for (i = 0, p = -1; i < p_poly->lightnum; i++) {
- if (p_last != p_poly->p_light[i]) {
- p++;
- p_last = p_klight[p] = p_poly->p_light[i];
- p_pocty[p] = 3;
- }
- else {
- p_pocty[p] += 3; //pocty facu
- }
- }
- // pocet lightmap je p+1
- p_poly->lightnum = ++p;
- free(p_poly->p_light);
- if (!(p_poly->p_light = (EDIT_TEXT **) malloc(sizeof(EDIT_TEXT *) * p)))
- chyba("Pamet");
- if (!(p_poly->p_lightnum = (int *) malloc(sizeof(int) * p)))
- chyba("Pamet");
- memcpy(p_poly->p_light, p_klight, sizeof(EDIT_TEXT *) * p);
- memcpy(p_poly->p_lightnum, p_pocty, sizeof(int) * p);
- }
- /* return
-
- 0 - vrsek
- 1 - bok
- 2 - druhy bok
- 3 - fuck
- -- plati pro bod s barvou 0xff000000
- */
- int ray_surface_pozice_bodu(bitmapa * p_bmp, int px, int py)
- {
- int dx = p_bmp->x, dy = p_bmp->y;
- if (py + 1 >= dy)
- return (3);
- if (py - 1 <= 0)
- return (0);
- if (px + 1 >= dx)
- return (2);
- if (px - 1 <= 0)
- return (1);
- if (bmp_getpixel(p_bmp, px, py + 1) != BLBA_BARVA)
- return (0);
- else {
- if (bmp_getpixel(p_bmp, px, py - 1) == BLBA_BARVA)
- return (3);
- if (bmp_getpixel(p_bmp, px - 1, py) != BLBA_BARVA)
- return (2);
- if (bmp_getpixel(p_bmp, px + 1, py) != BLBA_BARVA)
- return (1);
- else
- return (3);
- }
- }
- void ray_surface_filtruj_okraj(bitmapa * p_bmp, int okraj, dword * p_p1,
- int dp1, dword * p_p2, int dp2, dword * p_p3, int dp3)
- {
- dword barva, r = 0, g = 0, b = 0;
- int cisel, i;
- int tabulka[] =
- { 0, 0, 1, 0, 1, 1, 0, 1, -1, 1, -1, 0, -1, -1, 0, -1, 1, -1 };
- // int tabulka[] = {0,0, 1,0, 0,1, -1,0, 0,-1};
- int x, y, dx, dy;
- int px, py;
- dx = p_bmp->x;
- dy = p_bmp->y;
- for (x = okraj; x < (dx - okraj); x++) {
- for (y = okraj; y < (dy - okraj); y++) {
- if (bmp_getpixel(p_bmp, x, y) == BLBA_BARVA)
- continue;
- for (i = 0, cisel = 0; i < 18; i += 2) {
- // for(i = 0, cisel = 0; i < 10; i+=2) {
- px = x + tabulka[i];
- py = y + tabulka[i + 1];
- if (px > 0 && px < dx && py > 0 && py < dy) {
- barva = bmp_getpixel(p_bmp, px, py);
- if (barva != BLBA_BARVA) {
- r += GetRValue(barva);
- g += GetGValue(barva);
- b += GetBValue(barva);
- cisel++;
- }
- else {
- // nacteni barvy z pruhu
- // 1. zjistim jaky to je pripad (odkud to nacist)
- switch (ray_surface_pozice_bodu(p_bmp, px, py)) {
- case 0: // je to vrchni pixel
- if (dp1) {
- barva = p_p1[px];
- r += GetRValue(barva);
- g += GetGValue(barva);
- b += GetBValue(barva);
- cisel++;
- }
- break;
- case 1: // je to levy-bocni pixel
- if (dp2) {
- barva = p_p2[py];
- r += GetRValue(barva);
- g += GetGValue(barva);
- b += GetBValue(barva);
- cisel++;
- }
- break;
- case 2: // je to pravy-bocni pixel
- if (dp3) {
- barva = p_p3[py];
- r += GetRValue(barva);
- g += GetGValue(barva);
- b += GetBValue(barva);
- cisel++;
- }
- break;
- default: // je to neco divnyho
- break;
- }
- }
- }
- }
- mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) cisel);
- r = g = b = 0;
- bmp_putpixel(p_bmp, x, y, barva);
- }
- }
- }
- dword ray_interpoluj_barvy(dword * p_barva, int pocet)
- {
- dword r = 0, g = 0, b = 0, barva;
- int i;
- for (i = 0; i < pocet; i++) {
- r += GetRValue(p_barva[i]);
- g += GetGValue(p_barva[i]);
- b += GetBValue(p_barva[i]);
- }
- mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) pocet);
- return (barva);
- }
- int ray_okraj_roztahni(dword ** p_prh, int delka, int new_delka)
- {
- dword *p_pruh = *p_prh;
- dword *p_npruh;
- int i;
- float kf;
- if (delka == new_delka)
- return (new_delka);
- if (!(p_npruh = malloc(new_delka * sizeof(dword))))
- chyba("Pamet");
- memset(p_npruh, 0, new_delka * sizeof(dword));
- kf = (float) delka / (float) new_delka;
- for (i = 0; i < new_delka; i++) {
- assert((int) floor(kf * i) < delka);
- p_npruh[i] = p_pruh[(int) floor(kf * i)];
- }
- free(*p_prh);
- *p_prh = p_npruh;
- return (new_delka);
- }
- __inline dword ray_interpoluj_2_barvy(dword b1, dword b2, float vaha2)
- {
- dword r, g, b, barva;
- r = GetRValue(b1) + (dword) (vaha2 * GetRValue(b2));
- g = GetGValue(b1) + (dword) (vaha2 * GetGValue(b2));
- b = GetBValue(b1) + (dword) (vaha2 * GetBValue(b2));
- mult_color_rgb_max(&barva, r, g, b, 1.0f / (vaha2 + 1));
- return (barva);
- }
- void ray_surface_nastav_barvu_bodu(bitmapa * p_bmp, QBOD * p_hity, int delka,
- dword barva)
- {
- int x, y;
- int i;
- for (i = 0; i < delka; i++) {
- if (p_hity[i].z) {
- x = p_hity[i].x;
- y = p_hity[i].y;
- bmp_putpixel(p_bmp, x, y, barva);
- }
- }
- }
- /*
- Zpusob prace:
- while(stupen) {
- 0. Nacteni okraju vsech surfacu
- 1. Doplneni okraju do surfacu
- Udelani ke kazdemu surfacu seznam zapsanych bodu
- 3. Filtrovani surfacu (vcetne hranicnich bodu)
- 4. Smaz okraje
- }
- 5. Nacti spolecne okraje
- 6. Pokud spolu plosky sousedi -> vytvor spolecny okraj
- 7. Vloz okraje
- 8. Roztahni textury (dopln na pozadovane rozmery)
- */
- void ray_poly_filtruj_lightmapy(POLY_INDICIE * p_ind, int indnum,
- EDIT_MESH_POLY * p_poly_list, EDIT_TEXT * p_src,
- int stupen, int mezi, int filtrace)
- {
- int st;
- int i;
- if (!stupen)
- return;
- for (st = 0; st < stupen; st++) {
- /************************************************
- Filtruj surfacy plosek
- *************************************************/
- if (filtrace) {
- for (i = 0; i < indnum; i++) {
- p_cnf->ray.p_akt_filtr_func->p_fnc(p_src[i].p_bmp);
- }
- }
- }
- }
- /*
- transformace bodu 3D -> 2D a zpet
- Pro kazdou plosku:
- 0. transformovat 3D plosku do 2D
- 1. podle rozmeru vyrobit mapu
- 2. vyrobit rastr a pro vsechny body:
- 3. kazdy bod mapy transformovat z 2D do 3D
- 4. zjistit svetlo bodu
- 5. Zapsat svetlo do mapy
- */
- /*
- Postup:
- Ke kazdemu svetlu ve scene
- */
- void calc_face_matrix(TRIANGLE * p_tri, GLMATRIX * p_mat)
- {
- GLMATRIX cm;
- BOD s, up, ri, fr;
- float vzd1, vzd2, vzd3, vzdn, ti;
- MUJ_BOD a, b, c;
- ROVINA r;
- BOD p;
- init_matrix(&cm);
- // stred trojuhelniku
- s.x = (p_tri->a.x + p_tri->b.x + p_tri->c.x) / 3.0f;
- s.y = (p_tri->a.y + p_tri->b.y + p_tri->c.y) / 3.0f;
- s.z = (p_tri->a.z + p_tri->b.z + p_tri->c.z) / 3.0f;
- // nejdelsi strana trojuhelnika
- vzd1 = vzdal_bodu(&p_tri->a, &p_tri->b);
- vzd2 = vzdal_bodu(&p_tri->b, &p_tri->c);
- vzd3 = vzdal_bodu(&p_tri->c, &p_tri->a);
- if (vzd1 > vzd2) {
- if (vzd1 > vzd3) {
- // nejvetsi vzd1
- a = p_tri->a;
- b = p_tri->b;
- c = p_tri->c;
- vzdn = vzd1;
- }
- else {
- // nejvetsi vzd3
- a = p_tri->c;
- b = p_tri->a;
- c = p_tri->b;
- vzdn = vzd3;
- }
- }
- else {
- if (vzd2 > vzd3) {
- // nejvetsi vzd2
- a = p_tri->b;
- b = p_tri->c;
- c = p_tri->a;
- vzdn = vzd2;
- }
- else {
- // nejvetsi vzd3
- a = p_tri->c;
- b = p_tri->a;
- c = p_tri->b;
- vzdn = vzd3;
- }
- }
- // p je bod na te primce
- ti =
- ((b.x - a.x) * (s.x - a.x) + (b.y - a.y) * (s.y - a.y) + (b.z -
- a.z) * (s.z - a.z)) / (vzdn * vzdn);
- p.x = a.x + (b.x - a.x) * ti;
- p.y = a.y + (b.y - a.y) * ti;
- p.z = a.z + (b.z - a.z) * ti;
- // preskladani plosky -> mezi a-b je nejvetsi delka
- p_tri->a = a;
- p_tri->b = b;
- p_tri->c = c;
- // vektor nahoru
- up.x = p.x - s.x;
- up.y = p.y - s.y;
- up.z = p.z - s.z;
- // vektor dopredu -> norm vekt. plosky
- calc_rovinu(&a, &b, &c, &r);
- fr.x = r.x;
- fr.y = r.y;
- fr.z = r.z;
- // vektor nabok -> osa x
- vektor_soucin(&fr, &up, &ri);
- // prisel cas normalizace
- norm_vect(&fr.x, &fr.y, &fr.z);
- norm_vect(&up.x, &up.y, &up.z);
- norm_vect(&ri.x, &ri.y, &ri.z);
- cm._11 = ri.x;
- cm._21 = ri.y;
- cm._31 = ri.z; // x vektor -> ri
- cm._12 = up.x;
- cm._22 = up.y;
- cm._32 = up.z; // y vektor -> up
- cm._13 = fr.x;
- cm._23 = fr.y;
- cm._33 = fr.z; // z vektor -> fr
- cm._41 = s.x; // umisteni kamery
- cm._42 = s.y;
- cm._43 = s.z;
- //invert_matrix(&cm,p_mat);
- *p_mat = cm;
- }
- /*
- transformuje 3D face do 2D prostoru
- */
- void trface(TRIANGLE * p_tri, TRIANGLE * p_tr, GLMATRIX * p_mat, float faktor)
- {
- transf_3d_2d_matrix_float_text(p_tri->a.x, p_tri->a.y, p_tri->a.z,
- &p_tr->a.x, &p_tr->a.y, &p_tr->a.z, p_mat, faktor);
- transf_3d_2d_matrix_float_text(p_tri->b.x, p_tri->b.y, p_tri->b.z,
- &p_tr->b.x, &p_tr->b.y, &p_tr->b.z, p_mat, faktor);
- transf_3d_2d_matrix_float_text(p_tri->c.x, p_tri->c.y, p_tri->c.z,
- &p_tr->c.x, &p_tr->c.y, &p_tr->c.z, p_mat, faktor);
- }
- /*
- Prusecit 2D trojuhelniku s 2D bodem
- // validni je akorat x a y ve vsech bodech
- */
- __inline int ray_intersect_tri_point(BOD * p_a, BOD * p_b, BOD * p_c,
- BOD * p_p)
- {
- float k1, k2, q1, q2;
- float x;
- calc_primku_2d(p_a, p_c, &k1, &q1);
- calc_primku_2d(p_b, p_c, &k2, &q2);
- x = (p_p->y - q1) / k1;
- if (x > p_p->x)
- return (FALSE);
- x = (p_p->y - q2) / k2;
- if (x < p_p->x)
- return (FALSE);
- else
- return (TRUE);
- }
- // 2D interpolace normaloveho vektoru
- __inline void interpolace_vektoru(TRIANGLE * p_tri, BOD * p_a, BOD * p_b,
- BOD * p_c, BOD * p_p, BOD * p_int)
- {
- BOD p1, p2, v1, v2;
- float k1, k2, q1, q2;
- float vzd1, vzd2;
- calc_primku_2d(p_a, p_c, &k1, &q1);
- calc_primku_2d(p_b, p_c, &k2, &q2);
- p1.y = p2.y = p_p->y;
- p1.x = (p_p->y - q1) / k1;
- p2.x = (p_p->y - q2) / k2;
- vzd1 = vzdal_bodu_2D_bod(p_a, &p1);
- vzd2 = vzdal_bodu_2D_bod(p_c, &p1);
- v1.x = (p_tri->a.nx * vzd2 + p_tri->c.nx * vzd1) / (vzd1 + vzd2);
- v1.y = (p_tri->a.ny * vzd2 + p_tri->c.ny * vzd1) / (vzd1 + vzd2);
- v1.z = (p_tri->a.nz * vzd2 + p_tri->c.nz * vzd1) / (vzd1 + vzd2);
- vzd1 = vzdal_bodu_2D_bod(p_b, &p2);
- vzd2 = vzdal_bodu_2D_bod(p_c, &p2);
- v2.x = (p_tri->b.nx * vzd2 + p_tri->c.nx * vzd1) / (vzd1 + vzd2);
- v2.y = (p_tri->b.ny * vzd2 + p_tri->c.ny * vzd1) / (vzd1 + vzd2);
- v2.z = (p_tri->b.nz * vzd2 + p_tri->c.nz * vzd1) / (vzd1 + vzd2);
- vzd1 = p_p->x - p1.x;
- vzd2 = p2.x - p_p->x;
- p_int->x = (v1.x * vzd2 + v2.x * vzd1) / (vzd1 + vzd2);
- p_int->y = (v1.y * vzd2 + v2.y * vzd1) / (vzd1 + vzd2);
- p_int->z = (v1.z * vzd2 + v2.z * vzd1) / (vzd1 + vzd2);
- }
- // y = k*x + q
- /*
- transformace bodu 3D -> 2D a zpet
- Pro kazdou plosku:
- 0. transformovat 3D plosku do 2D
- 1. podle rozmeru vyrobit mapu
- 2. vyrobit rastr a pro vsechny body:
- 3. kazdy bod mapy transformovat z 2D do 3D
- 4. zjistit svetlo bodu
- 5. Zapsat svetlo do mapy
- typedef struct _LIGHTMAP_INFO {
- int k,o,f;
- } LIGHTMAP_INFO;
- #define RAY_TEXTUR 200
- bitmapa * p_tray[RAY_TEXTUR]; // light-map textury k ray-tracingu
- LIGHTMAP_INFO face[RAY_TEXTUR]; // popis
- int ray_posledni = 0;
- */
- void ray_calc_korekci_koordinatu(TRIANGLE * p_tri, TEXT_KOORD * p_koord,
- bitmapa * p_bmp)
- {
- BODUV *p_ua, *p_ub, *p_uc;
- BOD *p_da, *p_db, *p_dc;
- float x_tk;
- float y_tk;
- p_da = (BOD *) & p_tri->a;
- p_db = (BOD *) & p_tri->b;
- p_dc = (BOD *) & p_tri->c;
- p_ua = (BODUV *) & p_koord[0].tul;
- p_ub = (BODUV *) & p_koord[1].tul;
- p_uc = (BODUV *) & p_koord[2].tul;
- if (OKRAJ) {
- x_tk = (float) OKRAJ / p_bmp->x;
- y_tk = (float) OKRAJ / p_bmp->y;
- }
- else {
- x_tk = 0;
- y_tk = 0;
- }
- p_ua->u = 0.0f + x_tk;
- p_ua->v = 0.0f + y_tk;
- p_ub->u = 1.0f - x_tk;
- p_ub->v = 0.0f + y_tk;
- p_uc->u = ((p_da->x - p_dc->x) / (p_da->x - p_db->x)) + x_tk;
- p_uc->v = 1.0f - y_tk;
- }
- bitmapa *ray_calc_lightmap_face(K_EDITOR * p_cnf, TRIANGLE * p_tri,
- TRIANGLE * p_tri2d, LIGHTMAP_INFO * p_akt, byte stiny, int no_phong)
- {
- bitmapa *p_text;
- GLMATRIX m, inv_m;
- int dx, dy, x, y;
- float iddx, iddy;
- float dx_faktor, dy_faktor;
- float fx, fy, fz;
- float x_tk;
- float y_tk;
- BOD p, a, b, c, pp;
- dword barva;
- int stinovani = p_cnf->ray.stinovani;
- int max_x, max_y;
- float mx, my, mz;
- calc_face_matrix(p_tri, &m); //transf. matice teto plosky
- invert_matrix(&m, &inv_m); // inverzni matice
- trface(p_tri, p_tri2d, &m, p_cnf->ray.faktor); // preved plosku do 2D
- //assert(p_tri2d->a.x < p_tri2d->b.x);
- if (p_tri2d->a.x >= p_tri2d->b.x)
- kprintf(TRUE, "p_tri2d->a.x >= p_tri2d->b.x... p = %d f = %f",
- p_akt->poly, p_akt->f);
- mujbod2bod(&a, &p_tri2d->a);
- mujbod2bod(&b, &p_tri2d->b);
- mujbod2bod(&c, &p_tri2d->c);
- // uprava na ctverec a spocitani ctvercovych scale faktoru
- // sirka mezi body trojuhelniku
- iddx = (float) fabs(a.x - b.x);
- iddy = (float) fabs(a.y - c.y);
- max_x = p_cnf->ray.max_x_surface >> 1;
- max_y = p_cnf->ray.max_y_surface >> 1;
- for (dx = MIN_X_TEXTURA;
- (dx - 2 * OKRAJ) < iddx && (dx - 2 * OKRAJ) < max_x; dx <<= 1);
- for (dy = MIN_Y_TEXTURA;
- (dy - 2 * OKRAJ) < iddy && (dy - 2 * OKRAJ) < max_y; dy <<= 1);
- // faktor - sirka jednoho texelu
- dx_faktor = iddx / (float) (dx - 2 * OKRAJ);
- dy_faktor = iddy / (float) (dy - 2 * OKRAJ);
- /*
- text korekce je sirka jednoho pixelu
- */
- if (OKRAJ) {
- x_tk = (float) OKRAJ / dx;
- y_tk = (float) OKRAJ / dy;
- }
- else {
- x_tk = 0;
- y_tk = 0;
- }
- p_tri->a.tul = 0.0f + x_tk;
- p_tri->a.tvl = 0.0f + y_tk;
- p_tri->b.tul = 1.0f - x_tk;
- p_tri->b.tvl = 0.0f + y_tk;
- p_tri->c.tul = ((a.x - c.x) / (a.x - b.x));
- p_tri->c.tvl = 1.0f - y_tk;
- // soupni do light akt facenormal
- p_akt->normal.x = m._13;
- p_akt->normal.y = m._23;
- p_akt->normal.z = m._33;
- if (stinovani == SHAD_FLAT)
- p_akt->normal_bod = p_akt->normal;
- // vyrob odpovidajici texturu
- if ((p_text = bmp_vyrob(dx, dy)) == NULL)
- chybat(STC, "Vyroba bmp -> dx = %d, dy = %d bpp = %d", dx, dy, 32);
- bmp_smaz(p_text, BLBA_BARVA);
- // I. pruchod -> pocitam pixely ulozene uvnitr trojuhelniku
- for (y = 0; y < dy; y++) {
- for (x = 0; x < dx; x++) {
- // prevedu bod textury do 3D
- fx = a.x + ((float) (x - OKRAJ + 0.5f) * dx_faktor);
- fy = a.y - ((float) (y - OKRAJ + 0.5f) * dy_faktor);
- fz = a.z;
- mx = fx / p_cnf->ray.faktor;
- my = fy / p_cnf->ray.faktor;
- mz = fz / p_cnf->ray.faktor;
- p.x = inv_m._11 * mx + inv_m._21 * my + inv_m._31 * mz + inv_m._41;
- p.y = inv_m._12 * mx + inv_m._22 * my + inv_m._32 * mz + inv_m._42;
- p.z = inv_m._13 * mx + inv_m._23 * my + inv_m._33 * mz + inv_m._43;
- pp.x = fx;
- pp.y = fy;
- pp.z = fz;
- p_cnf->stat.ray_bodu++; // statistika pouziti
- if (stinovani == SHAD_PHONG) {
- interpolace_vektoru(p_tri, &a, &b, &c, &pp, &p_akt->normal_bod);
- }
- barva =
- ray_svetlost_bodu(p_cnf, &p, p_akt, stiny, p_cnf->ray.ambient,
- no_phong);
- barva &= 0x00ffffff;
- bmp_putpixel(p_text, x, y, barva);
- }
- }
- return (p_text);
- }
- void ray_dopln_okraj_surf(bitmapa * p_bmp)
- {
- int x, y, dx, dy;
- int faze;
- dword barva, clamp_barva;
- dx = p_bmp->x;
- dy = p_bmp->y;
- // II. pruchod -> doplnim pixely ulozene vne trojuhelniku
- for (y = OKRAJ; y < (dy - OKRAJ); y++) {
- faze = 0;
- for (x = 0; x < dx; x++) {
- barva = bmp_getpixel(p_bmp, x, y);
- if (barva == BLBA_BARVA) {
- if (faze)
- bmp_putpixel(p_bmp, x, y, clamp_barva);
- }
- else {
- if (faze)
- clamp_barva = barva;
- else {
- faze = x;
- for (x = 0; x < faze; x++)
- bmp_putpixel(p_bmp, x, y, barva);
- faze = TRUE;
- }
- }
- }
- }
- if (OKRAJ) {
- for (x = 0; x < dx; x++) {
- barva = bmp_getpixel(p_bmp, x, OKRAJ);
- bmp_putpixel(p_bmp, x, 0, barva);
- barva = bmp_getpixel(p_bmp, x, dy - OKRAJ - 1);
- if (barva == BLBA_BARVA) {
- barva = bmp_getpixel(p_bmp, x, dy - OKRAJ - 2);
- bmp_putpixel(p_bmp, x, dy - OKRAJ - 1, barva);
- }
- bmp_putpixel(p_bmp, x, dy - 1, barva);
- }
- }
- }
- void ray_dopln_okraje(K_EDITOR * p_cnf, EDIT_TEXT * p_src, int textnum)
- {
- int t;
- for (t = 0; t < textnum; t++) {
- ray_dopln_okraj_surf(p_src[t].p_bmp);
- }
- }
- #define SUPER_MIN_X 8
- #define SUPER_MIN_Y 8
- bitmapa *ray_surface_supersampl(bitmapa * p_zdroj, byte hloubka, int kx,
- int ky)
- {
- bitmapa *p_cil = NULL;
- bitmapa *p_src = NULL;
- dword r, g, b;
- int x, y, dx, dy;
- int sx, sy, h, p;
- dword barva = 0;
- for (h = 0; h < hloubka; h++) {
- if (p_src) {
- bmp_zrus(&p_src);
- p_src = p_cil;
- }
- else {
- p_src = bmp_kopituj(p_zdroj);
- }
- dx = p_src->x;
- dy = p_src->y;
- if (dx / kx < SUPER_MIN_X || dy / ky < SUPER_MIN_Y) {
- return (p_src);
- }
- p_cil = bmp_vyrob(dx / kx, dy / ky);
- if (!p_cil)
- chyba("Vyrobeni surfacy !");
- for (y = 0; y < dy; y += kx) {
- for (x = 0; x < dx; x += ky) {
- r = g = b = p = 0;
- for (sy = 0; sy < ky; sy++) {
- for (sx = 0; sx < kx; sx++) {
- barva = bmp_getpixel(p_src, x + sx, y + sy);
- if (barva != BLBA_BARVA) {
- r += GetRValue(barva);
- g += GetGValue(barva);
- b += GetBValue(barva);
- p++;
- }
- }
- }
- if (p) {
- mult_color_rgb_max(&barva, r, g, b, 1.0f / (float) p);
- bmp_putpixel(p_cil, x / kx, y / ky, barva);
- }
- }
- }
- }
- bmp_zrus(&p_src);
- return (p_cil);
- }
- void ray_surface_supersampling(POLY_INDICIE * p_ind, int indnum,
- TRIANGLE * p_tri, EDIT_MESH_POLY * p_poly, EDIT_TEXT * p_src, byte hloubka,
- int kx, int ky)
- {
- bitmapa *p_text;
- int i;
- for (i = 0; i < indnum; i++) {
- p_text = ray_surface_supersampl(p_src[i].p_bmp, hloubka, kx, ky);
- bmp_zrus(&p_src[i].p_bmp);
- p_src[i].p_bmp = p_text;
- ray_calc_korekci_koordinatu(p_tri + i,
- p_poly[p_ind[i].poly].p_koord + p_ind[i].face, p_text);
- }
- }
- void ray_dopln_okraj_spodni(bitmapa * p_bmp, int okraj)
- {
- int x, dx, dy;
- dword barva;
- dx = p_bmp->x;
- dy = p_bmp->y;
- assert(okraj < 2);
- if (okraj) {
- for (x = 0; x < dx; x++) {
- barva = bmp_getpixel(p_bmp, x, dy - okraj - 1);
- bmp_putpixel(p_bmp, x, dy - 1, barva);
- }
- }
- }
- __inline static int ray_zacatek_masky(dword maska)
- {
- int i = 0;
- while (!(maska & 0x1)) {
- maska >>= 1;
- i++;
- }
- return (i);
- }
- #define MIN_T 0.99f
- int ray_intersect_poly(EDIT_MESH_POLY * p_poly, BOD * p_orig, BOD * p_dir,
- LIGHTMAP_INFO * p_akt)
- {
- BOD p1, p2, p3;
- float t, u, v, mint = MIN_T;
- int f, mf;
- if (p_poly->mail == p_akt->mail)
- return (FALSE);
- else
- p_poly->mail = p_akt->mail;
- if (obb_intersect_line(&p_poly->obb, p_orig, p_dir)) {
- for (f = 0; f < p_poly->facenum; f += 3) {
- if ((p_poly->poly == p_akt->poly) && (f == p_akt->f
- || f == p_akt->vface[0] || f == p_akt->vface[1]
- || f == p_akt->vface[2]))
- continue;
- p1.x = p_poly->p_koord[f].x;
- p1.y = p_poly->p_koord[f].y;
- p1.z = p_poly->p_koord[f].z;
- p2.x = p_poly->p_koord[f + 1].x;
- p2.y = p_poly->p_koord[f + 1].y;
- p2.z = p_poly->p_koord[f + 1].z;
- p3.x = p_poly->p_koord[f + 2].x;
- p3.y = p_poly->p_koord[f + 2].y;
- p3.z = p_poly->p_koord[f + 2].z;
- if (intersect_triangle_ncull(p_orig, p_dir, &p1, &p2, &p3, &t, &u, &v)) {
- if (t > 0.0f && t < mint) {
- mint = t;
- mf = f;
- }
- }
- }
- }
- return (mint != MIN_T);
- }
- int ray_intersect_kont(EDIT_KONTEJNER * p_kont, BOD * p_orig, BOD * p_dir,
- LIGHTMAP_INFO * p_akt)
- {
- BOD p1, p2, p3, *p_tmp;
- EDIT_OBJEKT *p_obj;
- float t = 1.0f, u, v, mint = MIN_T;
- int f, mf, o, h = 0;
- if (p_kont->mailbox == p_akt->mail)
- return (FALSE);
- else
- p_kont->mailbox = p_akt->mail;
- if (obb_intersect_line(&p_kont->obb, p_orig, p_dir)) {
- for (o = 0; o < p_kont->objektu; o++) {
- p_obj = p_kont->p_obj[o];
- assert(p_obj);
- if (p_kont->objektu && !obb_intersect_line(&p_obj->obb, p_orig, p_dir))
- continue;
- for (f = 0; f < p_obj->facenum; f += 3) {
- p_tmp = (BOD *) (p_obj->p_vertex + p_obj->p_face[f]);
- p1 = *p_tmp;
- p_tmp = (BOD *) (p_obj->p_vertex + p_obj->p_face[f + 1]);
- p2 = *p_tmp;
- p_tmp = (BOD *) (p_obj->p_vertex + p_obj->p_face[f + 2]);
- p3 = *p_tmp;
- if (intersect_triangle_ncull(p_orig, p_dir, &p1, &p2, &p3, &t, &u,
- &v)) {
- if (t > 0.0f && t < mint) {
- mint = t;
- mf = f;
- h++;
- }
- }
- }
- }
- }
- return (mint != MIN_T);
- }
- /*
- Prusecik stinoveho paprsku se stromem -> presne rozmery paprsku
- */
- /*
- Intersektuje scenu paprsku -> zacne tam kde je cil paprsku
- 1. Testuj posledni hit
- 2. Vlez tam kde je cil posledniho hitu (texel)
- 3. Testuj prusecik v teto oblasti
- 4. Pokud neni hit->testuj okoli smerem ke zdroji
- */
- BOD oct_cilovy_bod;
- int oct_intersect_tree_shadow_ray(KD_BUNKA * p_prvni, BOD * p_orig,
- BOD * p_dir, LIGHTMAP_INFO * p_akt)
- {
- KD_BUNKA *p_list[2];
- KD_BUNKA *p_bunka = p_prvni;
- BOD cil;
- int i, hit = 0;
- BOD s1, s2;
- /*
- Stinovy paprsek
- */
- cil.x = p_orig->x + p_dir->x;
- cil.y = p_orig->y + p_dir->y;
- cil.z = p_orig->z + p_dir->z;
- /*
- Odkud vychazet
- */
- while (p_bunka->p_next) { // test na pouzitou rovinu
- switch (p_bunka->rovina) {
- case 0: // rovina x
- i = (cil.x > p_bunka->vzdal) ? 1 : 0;
- break;
- case 1: // rovina y
- i = (cil.y > p_bunka->vzdal) ? 1 : 0;
- break;
- case 2: // rovina z
- i = (cil.z > p_bunka->vzdal) ? 1 : 0;
- break;
- default:
- assert(0);
- break;
- }
- p_bunka = p_bunka->p_next + i;
- }
- while (1) {
- /*
- Je prusecik v teto kostce
- */
- if (!kd_intersect_kostku_dir(p_orig, p_dir, &p_bunka->min, &p_bunka->max)) {
- p_bunka->mail = p_akt->mail;
- if (!(p_bunka = p_bunka->p_up)) {
- p_akt->ray_phit = K_CHYBA;
- p_akt->ray_khit = K_CHYBA;
- return (FALSE);
- }
- }
- /*
- Nalezena intersekce v teto bunce
- */
- if (!p_bunka->p_next) {
- /*
- Je to list stromu
- */
- if (p_bunka->p_polozka) {
- for (i = 0; i < p_bunka->polozek; i++) {
- if (p_bunka->p_polozka_typ[i] == KD_POLY) {
- if (ray_intersect_poly(p_bunka->p_polozka[i], p_orig, p_dir,
- p_akt)) {
- p_akt->ray_phit =
- ((EDIT_MESH_POLY *) (p_bunka->p_polozka[i]))->poly;
- p_akt->ray_khit = K_CHYBA;
- return (TRUE);
- }
- }
- else {
- if (ray_intersect_kont(p_bunka->p_polozka[i], p_orig, p_dir,
- p_akt)) {
- p_akt->ray_phit = K_CHYBA;
- p_akt->ray_khit =
- ((EDIT_KONTEJNER *) p_bunka->p_polozka[i])->kont;
- return (TRUE);
- }
- }
- }
- }
- /*
- V listu nenalezena intersekce -> okolni listy
- + posun nahoru
- Nastavim u miss bunky mail-flag
- */
- p_bunka->mail = p_akt->mail;
- /*
- Level-Up, pokud jsem u konce
- */
- if (!(p_bunka = p_bunka->p_up)) {
- p_akt->ray_phit = K_CHYBA;
- p_akt->ray_khit = K_CHYBA;
- return (FALSE);
- }
- }
- else {
- /*
- Je to uzel stromu -> spracuj podstromy
- seradim podle stredu blizkosti k originu
- */
- oct_cilovy_bod.x = p_orig->x;
- oct_cilovy_bod.y = p_orig->y;
- oct_cilovy_bod.z = p_orig->z;
- p_list[0] = p_bunka->p_next;
- p_list[1] = p_bunka->p_next + 1;
- kd_stred_bunky(&p_list[0]->min, &p_list[0]->max, &s1);
- kd_stred_bunky(&p_list[1]->min, &p_list[1]->max, &s2);
- if (vzdal_bodu_bod(&s1, &oct_cilovy_bod) > vzdal_bodu_bod(&s2,
- &oct_cilovy_bod)) {
- p_list[1] = p_bunka->p_next;
- p_list[0] = p_bunka->p_next + 1;
- }
- for (i = 0; i < 2; i++) {
- if (p_list[i]->mail != p_akt->mail && (p_list[i]->p_next
- || p_list[i]->p_polozka)) {
- if (kd_intersect_kostku_dir(p_orig, p_dir, &p_list[i]->min,
- &p_list[i]->max)) {
- p_bunka = p_list[i];
- break;
- }
- else {
- p_list[i]->mail = p_akt->mail;
- }
- }
- }
- /* Level-Up
- */
- if (i == 2) {
- p_bunka->mail = p_akt->mail;
- if (!(p_bunka = p_bunka->p_up)) {
- p_akt->ray_phit = K_CHYBA;
- p_akt->ray_khit = K_CHYBA;
- return (FALSE);
- }
- }
- }
- }
- }
- // spocita svetlost bodu ve scene
- // pomoci paprsku
- /*
- typedef struct _STATIC_LIGHT {
- byte jmeno[50]; // jmeno svetla
- int index; // index svetla
- BOD p; // pozice svetla
- dword rgb; // barva
- float k1,k2,k3; // tlumici koeficienty
- float dosah; // max. dosah svetla
-
- } STATIC_LIGHT;
- */
- // p_p je bod pro ktery pocitam
- #define MIN_LIGHT 0.002f
- // pokud je pixel uvnitr trojuhelniku -> vloz interpolaci
- // pokud je pixel ven z trojuhelniku -> vloz hodnotu barvy nejblizsi hrany
- __inline dword ray_svetlost_bodu(K_EDITOR * p_cnf, BOD * p_p,
- LIGHTMAP_INFO * p_akt, byte stiny, dword ambient, int no_phong)
- {
- STATIC_LIGHT *p_light;
- BOD sv, dir, mdir;
- int barva = 0;
- int l, h;
- static int akt_ray = 0;
- float dist, k1, k2, k3, I, uhel, dd[3];
- rgb_float(ambient, dd);
- for (l = 0; l < p_cnf->lightnum; l++) {
- p_light = p_cnf->light + l;
- if (!p_light->akt)
- continue;
- I = 1;
- sv = p_cnf->light[l].p;
- dist = vzdal_bodu_bod_vec(p_p, sv);
- if (dist > p_light->dosah)
- continue;
- calc_vect_dir_vec(sv, p_p, dir);
- mdir = dir;
- norm_vect(&dir.x, &dir.y, &dir.z);
- if (!no_phong) {
- uhel = (skal_soucin(p_akt->normal_bod, dir)); //cosinus uhlu
- if (uhel > 0 && p_light->uhel)
- I = uhel;
- else
- I = p_light->uhel ? 0.0f : 1.0f;
- }
- if (p_light->utlum) {
- k1 = p_light->k1;
- k2 = p_light->k2;
- k3 = p_light->k3;
- I *= 1.0f / (k1 + k2 * dist + k3 * dist * dist);
- }
- if (I > MIN_LIGHT && stiny) {
- p_akt->mail = ++akt_ray;
- /*
- Test posledniho hitu -> neni to pribuzny ?
- */
- if (p_light->last_poly != K_CHYBA) {
- if (ray_intersect_poly(p_cnf->p_poly + p_light->last_poly, &sv, &mdir,
- p_akt)) {
- continue;
- }
- }
- if (p_light->last_kont != K_CHYBA) {
- if (ray_intersect_kont(p_cnf->p_kont_raytracer[p_light->last_kont],
- &sv, &mdir, p_akt)) {
- continue;
- }
- }
- /*
- Jinak -> frcime full-serach
- */
- h = oct_intersect_tree_shadow_ray(&p_cnf->kdtree, &sv, &mdir, p_akt);
- p_light->last_poly = p_akt->ray_phit;
- p_light->last_kont = p_akt->ray_khit;
- I = (h) ? 0.0f : I;
- }
- dd[0] += p_light->r * I;
- dd[1] += p_light->g * I;
- dd[2] += p_light->b * I;
- if (dd[0] > 1.0f && dd[1] > 1.0f && dd[2] > 1.0f) {
- break;
- }
- }
- if (dd[0] > 1.0f)
- dd[0] = 1.0f;
- if (dd[1] > 1.0f)
- dd[1] = 1.0f;
- if (dd[2] > 1.0f)
- dd[2] = 1.0f;
- return (float_rgb(dd));
- }
- void propocitej_barvu_bod(OBJ_VERTEX * p_bod, BOD * p_light, dword rgb,
- float I, GLMATRIX * p_word)
- {
- float px, py, pz;
- float tx, ty, tz;
- float uhel;
- px = p_bod->nx; // normalovy vektor
- py = p_bod->ny;
- pz = p_bod->nz;
- tx = p_word->_11 * px + p_word->_21 * py + p_word->_31 * pz; // transformace norm vektoru
- ty = p_word->_12 * px + p_word->_22 * py + p_word->_32 * pz;
- tz = p_word->_13 * px + p_word->_23 * py + p_word->_33 * pz;
- uhel = (float) sqrt(p_light->x * p_light->x + p_light->y * p_light->y +
- p_light->z * p_light->z) * (float) sqrt(tx * tx + ty * ty + tz * tz);
- uhel = (tx * p_light->x + ty * p_light->y + tz * p_light->z) / uhel;
- if (uhel > 0)
- add_mult_color_dword(&p_bod->dr, rgb, uhel);
- }
- #define EPSILON_DIST 0.0001f
- void sloz_vertex(OBJ_VERTEX * p_bod, TEXT_KOORD * p_koord)
- {
- p_bod->x = p_koord->x;
- p_bod->y = p_koord->y;
- p_bod->z = p_koord->z;
- p_bod->nx = p_koord->nx;
- p_bod->ny = p_koord->ny;
- p_bod->nz = p_koord->nz;
- p_bod->dr = p_koord->dr;
- p_bod->dg = p_koord->dg;
- p_bod->db = p_koord->db;
- p_bod->da = p_koord->da;
- p_bod->sr = p_koord->sr;
- p_bod->sg = p_koord->sg;
- p_bod->sb = p_koord->sb;
- p_bod->msr = p_koord->msr;
- p_bod->msg = p_koord->msg;
- p_bod->msb = p_koord->msb;
- p_bod->tu1 = p_koord->tu1;
- p_bod->tv1 = p_koord->tv1;
- p_bod->tu2 = p_koord->tu2;
- p_bod->tv2 = p_koord->tv2;
- p_bod->tul = p_koord->tul;
- p_bod->tvl = p_koord->tvl;
- }
- void sloz_vertex_zpet(TEXT_KOORD * p_koord, OBJ_VERTEX * p_bod)
- {
- p_koord->x = p_bod->x;
- p_koord->y = p_bod->y;
- p_koord->z = p_bod->z;
- p_koord->nx = p_bod->nx;
- p_koord->ny = p_bod->ny;
- p_koord->nz = p_bod->nz;
- p_koord->dr = p_bod->dr;
- p_koord->dg = p_bod->dg;
- p_koord->db = p_bod->db;
- p_koord->da = p_bod->da;
- p_koord->sr = p_bod->sr;
- p_koord->sg = p_bod->sg;
- p_koord->sb = p_bod->sb;
- p_koord->msr = p_bod->msr;
- p_koord->msg = p_bod->msg;
- p_koord->msb = p_bod->msb;
- p_koord->tu1 = p_bod->tu1;
- p_koord->tv1 = p_bod->tv1;
- p_koord->tu2 = p_bod->tu2;
- p_koord->tv2 = p_bod->tv2;
- p_koord->tul = p_bod->tul;
- p_koord->tvl = p_bod->tvl;
- }
- void ray_poly_vyrob_lightmap(EDIT_MESH_POLY * p_poly)
- {
- int lightmap = p_poly->facenum / 3;
- if (p_poly->p_light) {
- free(p_poly->p_light);
- }
- if (p_poly->p_lightnum) {
- free(p_poly->p_lightnum);
- p_poly->p_lightnum = NULL;
- }
- p_poly->p_light = (EDIT_TEXT **) malloc(sizeof(EDIT_TEXT *) * lightmap);
- mtest(p_poly->p_light);
- memset(p_poly->p_light, 0, sizeof(EDIT_TEXT *) * lightmap);
- p_poly->lightnum = lightmap;
- }
- void ray_smaz_blby_plosky(K_EDITOR * p_cnf)
- {
- int flag = p_cnf->elm.flag;
- p_cnf->elm.flag =
- ELIM_MAZAT | ELIM_STATIC | ELIM_DYNAMIC | ELIM_PRVKY | ELIM_OKOLI;
- oe_prikaz_decimace_sceny(p_cnf);
- if (p_cnf->groupfacenum) {
- oe_prikaz_smaz_face(p_cnf, TRUE);
- }
- p_cnf->elm.flag = flag;
- }
- void ray_preved_barvy_do_materialu(K_EDITOR * p_cnf)
- {
- EDIT_KONTEJNER *p_kont;
- EDIT_OBJEKT *p_obj;
- int ak, ao;
- int mat, v;
- oe_klist_reset(&ak);
- while ((p_kont = oe_klist_next(p_cnf, &ak))) {
- if (p_kont->kflag & KONT_STATIC && p_kont->kflag & KONT_VERTEX_LIGHT) {
- oe_olist_reset(&ao);
- while ((p_obj = oe_olist_next(p_kont, &ao))) {
- mat = p_obj->material;
- if (p_cnf->p_mat[mat]->flag2 & MAT2_DIFFUSE_RAY) {
- for (v = 0; v < p_obj->vertexnum; v++) {
- p_obj->p_vertex[v].mdr = p_obj->p_vertex[v].dr;
- p_obj->p_vertex[v].mdg = p_obj->p_vertex[v].dg;
- p_obj->p_vertex[v].mdb = p_obj->p_vertex[v].db;
- }
- }
- }
- }
- }
- }
- BOOL CALLBACK doe_callback_raytracer(HWND hDlg, UINT msg, WPARAM wParam,
- LPARAM lParam)
- {
- switch (msg) {
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDOK:
- EndDialog(hDlg, 1);
- break;
- case IDCANCEL:
- EndDialog(hDlg, 0);
- break;
- default:
- return FALSE;
- }
- break;
- case WM_INITDIALOG:
- break;
- case WM_DESTROY:
- EndDialog(hDlg, IDCANCEL);
- break;
- default:
- return FALSE;
- }
- return TRUE;
- }
- // prepocita osvetleni stat. map
- // spocita z polygonu p_cnf->p_poly
- /*
- typedef struct _EDIT_MESH_POLY { //celej kontejner
-
- POZICE_BODU *p_pozice; // list bodu
- TEXT_KOORD *p_koord; // list texture koordinatu - plosky po 3
-
- word flag; // flag meshu -> stejne jako u kontejneru
- int facenum; // co face to objekt -> kazdy face ma svuj material
- int matnum; // pocet materialu
- word *p_pocty; // pocty plosek
- int *p_mat; // pole pointeru na materialy na jednotlive objekty
- EDIT_TEXT **p_light; // pole light-map
- } EDIT_MESH_POLY;
- */
- void ray_prepocitej_staticke_osvetleni(K_EDITOR * p_cnf, int ticho)
- {
- EDIT_KONTEJNER *p_kont;
- EDIT_OBJEKT *p_obj;
- int ak, ao;
- EDIT_TEXT_KONFIG konf;
- LIGHTMAP_INFO linf;
- int indnum;
- POLY_INDICIE *p_ind;
- EDIT_TEXT *p_src;
- TRIANGLE *p_tri2d, tri;
- BOD vert;
- int p, f, fm, i, aface = 0, proc, mat, v;
- int vel_bmp;
- int no_phong;
- byte shadow, nadpis[200];
- dword stime, ptime, p2time, barva;
- HWND hwnd = NULL;
- if (!ticho && !doe_prikaz_raytracer(&p_cnf->ray))
- return;
- /* Eliminace degenerovanych plosek
- */
- if (p_cnf->cnf.druh_sceny != SCENA_POLY) {
- kprintf(TRUE, "Prevadim scenu do renderovaciho formatu...");
- oe_scena_to_game(p_cnf);
- }
- stime = timeGetTime();
- shadow = p_cnf->ray.stiny;
- oe_prepocitat_stat_svetla(p_cnf);
- for (i = 0; i < MAX_RAY_TEXTUR; i++) {
- if (p_cnf->p_lightmap[i].p_bmp) {
- bmp_zrus(&p_cnf->p_lightmap[i].p_bmp);
- p_cnf->p_lightmap[i].jmeno[0] = 0;
- }
- }
- if (!ticho) {
- hwnd =
- CreateDialog(hinst, MAKEINTRESOURCE(IDD_PROGRES), hwnd_plocha,
- doe_callback_raytracer);
- doe_printf(hwnd, IDC_STATIC1, "---- Leharo ----");
- }
- p_cnf->stat.ray_bodu = FALSE;
- // rendering sceny - diffusni svetlo
- if (!ticho) {
- doe_progresbar_nastav(hwnd, IDC_PROGRESS3, 0, p_cnf->stat.polyface / 3);
- doe_printf(hwnd, IDC_STATIC2, "Renderuju scenu...");
- doe_printf(hwnd, IDC_STATIC1, "Vertex-listy...");
- doe_printf(hwnd, IDC_STATIC4, "%d:%d", 00, 7);
- }
- oe_klist_reset(&ak);
- while ((p_kont = oe_klist_next(p_cnf, &ak))) {
- if (p_kont->kflag & KONT_STATIC && p_kont->kflag & KONT_VERTEX_LIGHT) {
- shadow = p_kont->kflag & KONT_NO_SELF_SHADOW ? FALSE : p_cnf->ray.stiny;
- no_phong = p_kont->k2flag & KONT2_NO_PHONG;
- oe_olist_reset(&ao);
- while ((p_obj = oe_olist_next(p_kont, &ao))) {
- if (!ticho) {
- doe_printf(hwnd, IDC_STATIC1, "List %s", p_obj->jmeno);
- }
- mat = p_obj->material;
- if (p_cnf->p_mat[mat]->flag2 & MAT2_DIFFUSE_RAY) {
- for (v = 0; v < p_obj->vertexnum; v++) {
- vert.x = p_obj->p_vertex[v].x;
- vert.y = p_obj->p_vertex[v].y;
- vert.z = p_obj->p_vertex[v].z;
- linf.normal_bod.x = p_obj->p_vertex[v].nx;
- linf.normal_bod.y = p_obj->p_vertex[v].ny;
- linf.normal_bod.z = p_obj->p_vertex[v].nz;
- barva =
- ray_svetlost_bodu(p_cnf, &vert, &linf, shadow,
- p_cnf->ray.ambient, no_phong);
- rgb_float(barva, &p_obj->p_vertex[v].dr);
- p_obj->p_vertex[v].dr *= p_obj->p_vertex[v].mdr;
- p_obj->p_vertex[v].dg *= p_obj->p_vertex[v].mdg;
- p_obj->p_vertex[v].db *= p_obj->p_vertex[v].mdb;
- }
- }
- }
- }
- }
- shadow = p_cnf->ray.stiny;
- indnum = 0;
- for (p = 0; p < p_cnf->polynum; p++) {
- indnum += p_cnf->p_poly[p].facenum / 3;
- ray_poly_vyrob_lightmap(p_cnf->p_poly + p);
- p_cnf->p_poly[p].kreslit = FALSE;
- }
- p_ind = malloc(sizeof(p_ind[0]) * indnum);
- mtest(p_ind);
- memset(p_ind, 0, sizeof(p_ind[0]) * indnum);
- indnum = 0;
- for (p = 0; p < p_cnf->polynum; p++) {
- if (p_cnf->p_poly[p].kflag & (KONT_PRVEK | KONT_PODLOZKA)) {
- for (i = indnum,
- indnum += p_cnf->p_poly[p].facenum / 3, f = 0; i < indnum; i++) {
- p_ind[i].poly = p;
- p_ind[i].face = f;
- f += 3;
- }
- if (p + 1 < p_cnf->polynum
- && p_cnf->p_poly[p + 1].kflag & (KONT_PRVEK | KONT_PODLOZKA)) {
- continue;
- }
- }
- else {
- indnum = p_cnf->p_poly[p].facenum / 3;
- for (i = 0; i < indnum; i++) {
- p_ind[i].poly = p;
- p_ind[i].face = i * 3;
- }
- }
- // Hotove indicie jsou hotove
- p_src = malloc(sizeof(p_src[0]) * indnum);
- mtest(p_src);
- p_tri2d = malloc(sizeof(p_tri2d[0]) * indnum);
- mtest(p_tri2d);
- if (ticho) {
- kprintf(TRUE, "Poly %d z %d", p, p_cnf->polynum);
- }
- p = K_CHYBA;
- // Rendering z indicii
- for (i = 0; i < indnum; i++) {
- // Prvni vyskyt urciteho poly - prvnotni inicializace
- if (p != p_ind[i].poly) {
- /* Nahozeni zakladnich hodnot
- */
- p = p_ind[i].poly;
- mat = p_cnf->p_poly[p].material;
- no_phong = p_cnf->p_poly[p].k2flag & KONT2_NO_PHONG;
- /* Testy barev
- */
- //if(!(p_cnf->p_mat[mat]->flag2&MAT2_DIFFUSE_RAY))
- //goto dalsi_poly;
- /* stiny/bez stinu
- */
- shadow =
- (p_cnf->p_poly[p].kflag & KONT_NO_SELF_SHADOW) ? FALSE : p_cnf->ray.
- stiny;
- /* Predpocitani spekularnich barev
- */
- if (p_cnf->p_mat[mat]->flag2 & MAT2_SPECULAR_RAY) {
- int fmax = p_cnf->p_poly[p].facenum;
- for (f = 0; f < fmax; f++) {
- ray_svetlost_vertex_poly(p_cnf,
- p_cnf->p_poly[p].p_koord + f, p_cnf->p_mat[mat]->lesk);
- }
- }
- }
- f = p_ind[i].face;
- fm = p_ind[i].face / 3;
- ptime = (timeGetTime() - stime);
- p2time = ptime / 1000;
- if (!ticho) {
- doe_printf(hwnd, IDC_STATIC1,
- "Polygon-list %d/%d face %d/%d face-bodu %d", p, p_cnf->polynum, fm,
- p_cnf->p_poly[p].facenum / 3, p_cnf->stat.ray_bodu);
- doe_printf(hwnd, IDC_STATIC4, "%d:%d", p2time / 60, p2time % 60);
- proc = ftoi(((float) (aface +=
- 3) / (float) p_cnf->stat.polyface) * 100.0f);
- doe_printf(hwnd, IDC_STATIC5, "%d%%", proc);
- sprintf(nadpis, "Render %d%% hotovo - plna priorita", proc);
- SetWindowText(hwnd_aplikace, nadpis);
- spracuj_spravy(TRUE);
- }
- linf.f = f;
- linf.poly = p;
- linf.k = p;
- linf.vface[0] = p_cnf->p_poly[p].p_fsous[f];
- linf.vface[1] = p_cnf->p_poly[p].p_fsous[f + 1];
- linf.vface[2] = p_cnf->p_poly[p].p_fsous[f + 2];
- ray_svetlost_vertex_poly_diff(p_cnf->p_poly[p].p_koord + f);
- ray_svetlost_vertex_poly_diff(p_cnf->p_poly[p].p_koord + f + 1);
- ray_svetlost_vertex_poly_diff(p_cnf->p_poly[p].p_koord + f + 2);
- sloz_vertex(&tri.a, p_cnf->p_poly[p].p_koord + f);
- sloz_vertex(&tri.b, p_cnf->p_poly[p].p_koord + f + 1);
- sloz_vertex(&tri.c, p_cnf->p_poly[p].p_koord + f + 2);
- p_src[i].p_bmp =
- ray_calc_lightmap_face(p_cnf, &tri, p_tri2d + i, &linf, shadow,
- no_phong);
- sloz_vertex_zpet(p_cnf->p_poly[p].p_koord + f, &tri.a);
- sloz_vertex_zpet(p_cnf->p_poly[p].p_koord + f + 1, &tri.b);
- sloz_vertex_zpet(p_cnf->p_poly[p].p_koord + f + 2, &tri.c);
- doe_progresbar_posun(hwnd, IDC_PROGRESS3, 1);
- }
- //ray_dopln_okraje(p_cnf, p_src, indnum);
- if (p_cnf->ray.filtrace) {
- if (!ticho) {
- doe_printf(hwnd, IDC_STATIC1, "Filtrace...");
- }
- ray_poly_filtruj_lightmapy(p_ind, indnum, p_cnf->p_poly, p_src,
- p_cnf->ray.stupen_filtrace,
- p_cnf->ray.disk_mezi, p_cnf->ray.filtrace);
- }
- if (p_cnf->ray.supersampl) {
- if (!ticho) {
- doe_printf(hwnd, IDC_STATIC1, "Supersampling...");
- }
- ray_surface_supersampling(p_ind, indnum, p_tri2d, p_cnf->p_poly,
- p_src,
- p_cnf->ray.sup_hloubka,
- p_cnf->ray.sup_velikost_x, p_cnf->ray.sup_velikost_y);
- }
- if (p_cnf->ray.disk_mezi) {
- for (i = 0; i < indnum; i++) {
- sprintf(p_src[i].jmeno, "e:\\lihen\\lightmap\\face-i%.3d_s.bmp", i);
- bmp_uloz(p_src[i].jmeno, p_src[i].p_bmp);
- }
- }
- if (!ticho) {
- doe_printf(hwnd, IDC_STATIC1, "Lepeni...");
- }
- ray_slep_lightmapy(p_cnf, p_ind, indnum, p_src);
- for (i = 0; i < indnum; i++)
- bmp_zrus(&p_src[i].p_bmp);
- free(p_src);
- p_src = NULL;
- free(p_tri2d);
- indnum = 0;
- }
- free(p_ind);
- for (p = 0; p < p_cnf->polynum; p++) {
- ray_poly_optim_lightmap(p_cnf->p_poly + p);
- p_cnf->p_poly[p].kreslit = TRUE;
- }
- ptime = (timeGetTime() - stime);
- stime = ptime / 1000;
- vel_bmp = 0;
- for (i = 0, mat = 0; i < MAX_RAY_TEXTUR; i++) {
- if (p_cnf->p_lightmap[i].p_bmp) {
- mat = i + 1;
- vel_bmp +=
- p_cnf->p_lightmap[i].p_bmp->x * p_cnf->p_lightmap[i].p_bmp->y * 4;
- }
- }
- if (!ticho) {
- doe_printf(hwnd, IDC_STATIC1, "---- Prevod light-map do textur ----");
- doe_progresbar_nastav(hwnd, IDC_PROGRESS3, 0, mat);
- }
- {
- int zal_filtr = txconf.text_filtr;
- txconf.text_filtr = p_cnf->ray.lightmap_filtr;
- txt_lightmap_konfig(&konf);
- txconf.text_filtr = zal_filtr;
- }
- if (!ticho) {
- for (i = 0; i < mat; i++) {
- if (p_cnf->p_lightmap[i].p_bmp) {
- //bmp_to_16bit(p_cnf->p_lightmap[i].p_bmp,0x7,FALSE);
- // txt_bmp2textura(p_cnf->p_lightmap[i].p_bmp, p_cnf->p_lightmap+i,&konf);
- p_cnf->p_lightmap[i].load = TRUE;
- doe_progresbar_posun(hwnd, IDC_PROGRESS3, 1);
- }
- }
- }
- for (p = 0; p < p_cnf->polynum; p++) {
- p_cnf->p_poly[p].kreslit = TRUE;
- }
- kprintf(TRUE, "Ray-tracing info:");
- kprintf(TRUE, "Cas (%d:%d:%d)", stime / 60, stime % 60, ptime % 1000);
- kprintf(TRUE, "Bodu %d", p_cnf->stat.ray_bodu);
- kprintf(TRUE, "Velikost %d Byte", vel_bmp);
- kprintf(TRUE, "Stiny %d", p_cnf->ray.stiny);
- kprintf(TRUE, "Faktor %f", p_cnf->ray.faktor);
- kprintf(TRUE, "Filtr %d", p_cnf->ray.stupen_filtrace);
- kprintf(TRUE, "Disk %d", p_cnf->ray.disk);
- if (!ticho) {
- EndDialog(hwnd, TRUE);
- }
- }
- __inline void ray_rozmnoz_diffuse(OBJ_VERTEX * p_vert)
- {
- p_vert->da = p_vert->mda;
- p_vert->dr = p_vert->mdr;
- p_vert->dg = p_vert->mdg;
- p_vert->db = p_vert->mdb;
- }
- __inline void ray_rozmnoz_specular(OBJ_VERTEX * p_vert)
- {
- p_vert->sr = p_vert->msr;
- p_vert->sg = p_vert->msg;
- p_vert->sb = p_vert->msb;
- }
- // Prepocitani bodu
- __inline void ray_svetlost_vertex_bodu(K_EDITOR * p_cnf, OBJ_VERTEX * p_vert,
- GLMATRIX * p_word, int diff, int spec, float lesk, dword ambient)
- {
- STATIC_LIGHT *p_light;
- BOD v, n;
- BOD sv, dir;
- float dist, k, I, Is, uhel;
- int l;
- v.x = p_vert->x;
- v.y = p_vert->y;
- v.z = p_vert->z;
- n.x = p_vert->nx;
- n.y = p_vert->ny;
- n.z = p_vert->nz;
- rgb_float(ambient, &p_vert->dr);
- p_vert->sr = p_vert->sg = p_vert->sb = 0.0f;
- transformuj_bod_matici(&v.x, &v.y, &v.z, p_word);
- transformuj_nbod_matici(&n, p_word);
- for (l = 0; l < p_cnf->lightnum; l++) {
- p_light = p_cnf->light + l;
- if (!p_light->akt || p_light->bez_prev)
- continue;
- Is = I = 1;
- if (p_light->flag2 & SL2_MESH) {
- transformuj_bod_matici_bod(&p_light->p,
- kont_world_matrix(p_light->p_mesh_data), &sv);
- }
- else {
- sv = p_light->p;
- }
- dist = vzdal_bodu_bod(&v, &sv);
- if (dist > p_light->dosah)
- continue;
- vektor_sub(&v, &sv, &dir);
- norm_vect(&dir.x, &dir.y, &dir.z);
- if (!p_cnf->cnf.svetla_bez_gourandu) {
- // vektor bod->vektor
- uhel = (skal_soucin(n, dir)); //cosinus uhlu
- if (uhel > 0 && p_light->uhel) {
- Is = I = uhel;
- Is *= lesk;
- }
- else {
- Is = I = p_light->uhel ? 0.0f : 1.0f;
- }
- }
- if (p_light->utlum) {
- k =
- 1.0f / (p_light->k1 + p_light->k2 * dist + p_light->k3 * dist * dist);
- I *= k;
- Is *= k;
- }
- if (diff) {
- p_vert->dr += p_vert->mdr * p_light->r * I;
- p_vert->dg += p_vert->mdg * p_light->g * I;
- p_vert->db += p_vert->mdb * p_light->b * I;
- }
- if (spec) {
- p_vert->sr += p_vert->msr * p_light->r * Is;
- p_vert->sg += p_vert->msg * p_light->g * Is;
- p_vert->sb += p_vert->msb * p_light->b * Is;
- }
- }
- if (p_vert->dr > 1.0f)
- p_vert->dr = 1.0f;
- if (p_vert->dg > 1.0f)
- p_vert->dg = 1.0f;
- if (p_vert->db > 1.0f)
- p_vert->db = 1.0f;
- if (p_vert->sr > 1.0f)
- p_vert->sr = 1.0f;
- if (p_vert->sg > 1.0f)
- p_vert->sg = 1.0f;
- if (p_vert->sb > 1.0f)
- p_vert->sb = 1.0f;
- }
- /* Provede update dynamickych svetel
- */
- void ray_objekt_pridej_ddlight(K_EDITOR * p_cnf, DYN_LIGHT * p_ddlight,
- int ddlightnum, EDIT_KONTEJNER * p_kont,
- EDIT_OBJEKT * p_obj, GLMATRIX * p_m)
- {
- GLMATRIX *p_mat;
- DYN_LIGHT *p_dlight;
- BOD *p_vertex_pos;
- BOD *p_vertex_norm;
- BODRGBA *p_vertex_diff;
- BODRGBA *p_vertex_diff_mat;
- BOD p, n, d;
- int i, v, dflag, m2flag, j;
- int diffuse;
- int diffuse_ray;
- int dyn_light = 1;
- int kflag;
- float vzdal, I, lesk = 1.0f;
- float *p_looksqrt_linear_float = p_cnf->p_looksqrt_linear_float;
- float *p_looksqrt_quad_float = p_cnf->p_looksqrt_quadratic_float;
- kflag = p_kont->kflag & KONT_KEYFRAME;
- m2flag = p_kont->m2flag;
- diffuse = m2flag & MAT2_DIFFUSE;
- diffuse_ray = m2flag & MAT2_DIFFUSE_RAY;
- if (!(diffuse))
- return;
- for (v = 0; v < p_obj->vertexnum; v++) {
- p_vertex_pos = (BOD *) & p_obj->p_vertex[v].x;
- p_vertex_norm = (BOD *) & p_obj->p_vertex[v].nx;
- transformuj_bod_matici_bod((BOD *) & p_vertex_pos->x, p_m, &p);
- transformuj_nbod_matici_bod((BOD *) & p_vertex_norm->x, p_m, &n);
- p_vertex_diff = (RGBA *) & p_obj->p_vertex[v].dr;
- p_vertex_diff_mat = (RGBA *) & p_obj->p_vertex[v].mdr;
- for (i = 0; i < ddlightnum; i++) {
- p_dlight = p_ddlight + i;
- dflag = p_dlight->flag;
- if (dflag & SDL_MESH && p_dlight->p_mesh_data) { // pod-meshove svetlo preved s world space kontejneru
- p_mat = kont_world_matrix(p_dlight->p_mesh_data);
- transformuj_bod_matici_bod(&p_dlight->np, p_mat, &d);
- vzdal = vzdal_bodu_bod(&p_dlight->np, &d);
- }
- else {
- vzdal = vzdal_bodu_bod(&p_dlight->np, &p);
- }
- if (vzdal > p_dlight->dosah)
- continue;
- if (vzdal <= p_dlight->min) {
- if (dflag & SDL_ADD_SUB) {
- p_vertex_diff->r += p_vertex_diff_mat->r * p_dlight->dr;
- p_vertex_diff->g += p_vertex_diff_mat->g * p_dlight->dg;
- p_vertex_diff->b += p_vertex_diff_mat->b * p_dlight->db;
- p_vertex_diff->r -= p_vertex_diff_mat->r * p_dlight->sr;
- p_vertex_diff->g -= p_vertex_diff_mat->g * p_dlight->sg;
- p_vertex_diff->b -= p_vertex_diff_mat->b * p_dlight->sb;
- }
- else if (dflag & SDL_SUB) {
- p_vertex_diff->r -= p_vertex_diff_mat->r * p_dlight->dr;
- p_vertex_diff->g -= p_vertex_diff_mat->g * p_dlight->dg;
- p_vertex_diff->b -= p_vertex_diff_mat->b * p_dlight->db;
- }
- else {
- p_vertex_diff->r += p_vertex_diff_mat->r * p_dlight->dr;
- p_vertex_diff->g += p_vertex_diff_mat->g * p_dlight->dg;
- p_vertex_diff->b += p_vertex_diff_mat->b * p_dlight->db;
- }
- }
- else {
- j =
- ftoi(((vzdal - p_dlight->min) / (p_dlight->max -
- p_dlight->min)) * 255.0f);
- I =
- (dflag & SDL_UTLUM_LINEAR) ? p_looksqrt_linear_float[j] :
- p_looksqrt_quad_float[j];
- if (I < DELTA_MIN)
- continue;
- if (dflag & SDL_ADD_SUB) {
- p_vertex_diff->r += p_vertex_diff_mat->r * p_dlight->dr * I;
- p_vertex_diff->g += p_vertex_diff_mat->g * p_dlight->dg * I;
- p_vertex_diff->b += p_vertex_diff_mat->b * p_dlight->db * I;
- p_vertex_diff->r -= p_vertex_diff_mat->r * p_dlight->sr * I;
- p_vertex_diff->g -= p_vertex_diff_mat->g * p_dlight->sg * I;
- p_vertex_diff->b -= p_vertex_diff_mat->b * p_dlight->sb * I;
- }
- else if (dflag & SDL_SUB) {
- p_vertex_diff->r -= p_vertex_diff_mat->r * p_dlight->dr * I;
- p_vertex_diff->g -= p_vertex_diff_mat->g * p_dlight->dg * I;
- p_vertex_diff->b -= p_vertex_diff_mat->b * p_dlight->db * I;
- }
- else {
- p_vertex_diff->r += p_vertex_diff_mat->r * p_dlight->dr * I;
- p_vertex_diff->g += p_vertex_diff_mat->g * p_dlight->dg * I;
- p_vertex_diff->b += p_vertex_diff_mat->b * p_dlight->db * I;
- }
- }
- }
- }
- }
- /* Provede update extra-dynamickych svetel
- */
- void ray_objekt_pridej_edlight(K_EDITOR * p_cnf, EXTRA_DYN_LIGHT * p_edlight,
- int edlightnum, EDIT_KONTEJNER * p_kont,
- EDIT_OBJEKT * p_obj, GLMATRIX * p_m)
- {
- EXTRA_DYN_LIGHT *p_light;
- BOD *p_vertex_pos;
- BOD *p_vertex_norm;
- BODRGBA *p_vertex_diff;
- BODRGB *p_vertex_spec;
- BOD p, n, d, dir;
- int i, v, dflag, m2flag;
- int dyn_light = 1;
- int kflag;
- float vzdal, I, lesk = 1.0f;
- kflag = p_kont->kflag & KONT_KEYFRAME;
- m2flag = p_kont->m2flag;
- for (v = 0; v < p_obj->vertexnum; v++) {
- p_vertex_pos = (BOD *) & p_obj->p_vertex[v].x;
- p_vertex_norm = (BOD *) & p_obj->p_vertex[v].nx;
- transformuj_bod_matici_bod((BOD *) & p_vertex_pos->x, p_m, &p);
- transformuj_nbod_matici_bod((BOD *) & p_vertex_norm->x, p_m, &n);
- p_vertex_diff = (RGBA *) & p_obj->p_vertex[v].dr;
- p_vertex_spec = (RGB *) & p_obj->p_vertex[v].sr;
- for (i = 0; i < p_cnf->edl_lightnum; i++) {
- p_light = p_cnf->p_edlight + i;
- if (p_light->akt) {
- dflag = p_light->flag;
- if (dflag & EDL_MESH) {
- transformuj_bod_matici_bod(&p_light->np,
- kont_world_matrix(p_light->p_mesh_data), &d);
- }
- else {
- d = p_light->np;
- }
- if (dflag & EDL_DOSAH) {
- if (dflag & EDL_BODOVE) {
- vzdal = vzdal_bodu_bod(&d, &p);
- }
- else if (dflag & (EDL_PLOSNE_X | EDL_PLOSNE_Y | EDL_PLOSNE_Z)) {
- if (dflag & EDL_PLOSNE_X) {
- vzdal = fabsf(d.x - p.x);
- }
- else if (dflag & EDL_PLOSNE_Y) {
- vzdal = fabsf(d.y - p.y);
- }
- else {
- vzdal = fabsf(d.z - p.z);
- }
- }
- if (vzdal >= p_light->dosah)
- continue;
- if (dflag & EDL_UTLUM_LIN) {
- vzdal = 1.0f - (vzdal * p_light->utlum) / p_light->dosah;
- if (vzdal < DELTA_MIN)
- continue;
- }
- else if (dflag & EDL_UTLUM_KVAD) {
- vzdal = 1.0f - (vzdal * vzdal * p_light->utlum) / p_light->dosah;
- if (vzdal < DELTA_MIN)
- continue;
- }
- else {
- vzdal = 1.0f;
- }
- }
- else {
- vzdal = 1.0f;
- }
- if (dflag & EDL_GOURAND) {
- vektor_sub(&p, &d, &dir);
- norm_vect(&dir.x, &dir.y, &dir.z);
- I = vektor_dot_product(&n, &dir) * vzdal * p_light->gourand;
- if (I < DELTA_MIN)
- continue;
- }
- else {
- I = vzdal;
- }
- // Nastav alfa slozku
- if (dflag & (EDL_ALFA_MOD | EDL_ALFA_SET | EDL_ALFA_ADD |
- EDL_ALFA_SUB)) {
- if (dflag & EDL_ALFA_ADD) {
- p_vertex_diff->a += p_light->da * I;
- }
- else if (dflag & EDL_ALFA_MOD) {
- p_vertex_diff->a *= p_light->da * I;
- }
- else if (dflag & EDL_ALFA_SUB) {
- p_vertex_diff->a -= p_light->da * I;
- }
- else if (dflag & EDL_ALFA_SET) {
- p_vertex_diff->a = p_light->da * I;
- }
- }
- // Nastav spekularni slozku
- if (dflag & (EDL_SPEC_MOD | EDL_SPEC_SET | EDL_SPEC_ADD |
- EDL_SPEC_SUB)) {
- if (dflag & EDL_SPEC_ADD) {
- p_vertex_spec->r += p_light->sr * I;
- p_vertex_spec->g += p_light->sg * I;
- p_vertex_spec->b += p_light->sb * I;
- }
- else if (dflag & EDL_SPEC_MOD) {
- p_vertex_spec->r *= p_light->sr * I;
- p_vertex_spec->g *= p_light->sg * I;
- p_vertex_spec->b *= p_light->sb * I;
- }
- else if (dflag & EDL_SPEC_SUB) {
- p_vertex_spec->r -= p_light->sr * I;
- p_vertex_spec->g -= p_light->sg * I;
- p_vertex_spec->b -= p_light->sb * I;
- }
- else if (dflag & EDL_SPEC_SET) {
- p_vertex_spec->r = p_light->sr * I;
- p_vertex_spec->g = p_light->sg * I;
- p_vertex_spec->b = p_light->sb * I;
- }
- }
- }
- }
- }
- }
- #define RYCHLOST_ZMENY 100
- // Musi byt vsechny veci nachystany -> normalove vektory + barvy md a ms
- // Prepocet pokud je scena v obycejnym modu
- void ray_prepocitej_staticke_osvetleni_vertexy(K_EDITOR * p_cnf)
- {
- EDIT_MATERIAL **p_mat = p_cnf->p_mat;
- EDIT_OBJEKT *p_obj;
- GLMATRIX *p_m;
- dword kflag;
- int i, o, v, d, s;
- static dword stary_cas = 0;
- dword akt_cas = timeGetTime();
- float lesk;
- if (akt_cas - stary_cas < RYCHLOST_ZMENY
- || p_cnf->cnf.druh_sceny == SCENA_POLY)
- return;
- stary_cas = akt_cas;
- for (i = 0; i < KONT_NUM; i++) {
- if (!p_cnf->p_kont[i])
- continue;
- kflag = p_cnf->p_kont[i]->kflag;
- if (!(kflag & KONT_KEYFRAME))
- p_m = kont_world_matrix(p_cnf->p_kont[i]);
- for (o = 0; o < MAX_KONT_OBJEKTU; o++) {
- p_obj = p_cnf->p_kont[i]->p_obj[o];
- if (!p_obj)
- continue;
- if (kflag & KONT_KEYFRAME)
- p_m = &p_obj->m;
- d = p_mat[p_obj->material]->flag2 & MAT2_DIFFUSE_RAY;
- s = p_mat[p_obj->material]->flag2 & MAT2_SPECULAR_RAY;
- lesk = p_mat[p_obj->material]->lesk;
- if (d || s) {
- for (v = 0; v < p_obj->vertexnum; v++) {
- ray_svetlost_vertex_bodu(p_cnf, p_obj->p_vertex + v, p_m, d, s,
- lesk, p_cnf->ray.ambient);
- }
- }
- ray_objekt_pridej_ddlight(p_cnf, p_cnf->p_dlight, p_cnf->dl_lightnum,
- p_cnf->p_kont[i], p_obj, p_m);
- ray_objekt_pridej_edlight(p_cnf, p_cnf->p_edlight, p_cnf->edl_lightnum,
- p_cnf->p_kont[i], p_obj, p_m);
- }
- }
- }
- void ray_zrus_staticke_osvetleni_vertexy(K_EDITOR * p_cnf)
- {
- EDIT_OBJEKT *p_obj;
- int i, o, v;
- for (i = 0; i < KONT_NUM; i++) {
- if (!p_cnf->p_kont[i])
- continue;
- for (o = 0; o < MAX_KONT_OBJEKTU; o++) {
- p_obj = p_cnf->p_kont[i]->p_obj[o];
- if (!p_obj)
- continue;
- for (v = 0; v < p_obj->vertexnum; v++) {
- ray_rozmnoz_diffuse(p_obj->p_vertex + v);
- ray_rozmnoz_specular(p_obj->p_vertex + v);
- }
- }
- }
- }
- __inline void ray_svetlost_vertex_poly(K_EDITOR * p_cnf, TEXT_KOORD * p_koord,
- float lesk)
- {
- STATIC_LIGHT *p_light;
- BOD v, n;
- BOD sv, dir;
- float dist, k, Is, uhel;
- int l;
- v.x = p_koord->x;
- v.y = p_koord->y;
- v.z = p_koord->z;
- n.x = p_koord->nx;
- n.y = p_koord->ny;
- n.z = p_koord->nz;
- p_koord->sr = p_koord->sg = p_koord->sb = 0.0f;
- for (l = 0; l < p_cnf->lightnum; l++) {
- p_light = p_cnf->light + l;
- if (!p_light->akt)
- continue;
- Is = 1;
- sv = p_cnf->light[l].p;
- dist = vzdal_bodu_bod(&v, &sv);
- vektor_sub(&v, &sv, &dir);
- norm_vect(&dir.x, &dir.y, &dir.z);
- if (dist > p_light->dosah)
- continue;
- if (!p_cnf->cnf.svetla_bez_gourandu) {
- // vektor bod->vektor
- uhel = (skal_soucin(n, dir)); //cosinus uhlu
- if (uhel > 0 && p_light->uhel) {
- Is = uhel * lesk;
- }
- else {
- Is = p_light->uhel ? 0.0f : 1.0f;
- }
- }
- if (p_light->utlum) {
- k =
- 1.0f / (p_light->k1 + p_light->k2 * dist + p_light->k3 * dist * dist);
- Is *= k;
- }
- p_koord->sr += p_koord->msr * p_light->r * Is;
- p_koord->sg += p_koord->msg * p_light->g * Is;
- p_koord->sb += p_koord->msb * p_light->b * Is;
- }
- }
- __inline void ray_svetlost_vertex_poly_diff(TEXT_KOORD * p_koord)
- {
- p_koord->dr = p_koord->mdr;
- p_koord->dg = p_koord->mdg;
- p_koord->db = p_koord->mdb;
- p_koord->da = p_koord->mda;
- }
- void ray_uloz_lightmapy(K_EDITOR * p_cnf, byte * p_file, byte * p_dir)
- {
- FFILE f;
- int i;
- byte pom[200];
- strcpy(pom, p_file);
- zamen_koncovku(pom, KONCOVKA_LIGHTMAPY);
- if ((f = ffopen(pom, "wb"))) {
- for (i = 0; i < MAX_RAY_TEXTUR; i++) {
- if (p_cnf->p_lightmap[i].p_bmp) {
- ffwrite(&i, sizeof(i), 1, f);
- bmp_uloz_pack(f, p_cnf->p_lightmap[i].p_bmp);
- }
- }
- ffclose(f);
- }
- }
- /*
- void ray_uloz_lightmapy(K_EDITOR *p_cnf, byte *p_file, byte *p_dir)
- {
- int i;
- byte pom[200];
- for(i = 0; i < MAX_RAY_TEXTUR; i++) {
- if(p_cnf->p_lightmap[i].p_bmp) {
- sprintf(pom,"l%d.bmp",i);
- bmp_uloz(pom,p_cnf->p_lightmap[i].p_bmp);
- }
- }
- }
- */
- int ray_vyrob_poly_lightmap_compare(const void *p_poly1, const void *p_poly2)
- {
- int cmp;
- cmp = ((LIGHTMAP_INFO *) p_poly1)->poly - ((LIGHTMAP_INFO *) p_poly2)->poly;
- if (cmp)
- return (cmp);
- cmp = ((LIGHTMAP_INFO *) p_poly2)->dy - ((LIGHTMAP_INFO *) p_poly1)->dy;
- if (cmp)
- return (cmp);
- cmp = ((LIGHTMAP_INFO *) p_poly2)->dx - ((LIGHTMAP_INFO *) p_poly1)->dx;
- return (cmp);
- }
- /*
- typedef struct _LIGHTMAP_INFO {
- BOD normal; // face normal
- int p,k,o,f; // umisteni light-mapy
- int dx,dy; // rozmery light-mapy
- int material;
- } LIGHTMAP_INFO;
- */
- typedef struct _LINKA_TEXTURY
- {
- RECT r; // ulozeni a velikost na mape
- int radek; // radek
- int vyska_radku; //
- int dx, dy; // pomocne recy
- int indicie; // odpovidajici indicie
- struct _LINKA_TEXTURY *p_dalsi; // pod-bunky -> NULL == Konec
- } LINKA_TEXTURY;
- __inline LINKA_TEXTURY *ray_vloz_volnou_linku(LINKA_TEXTURY ** p_volne_linky,
- LINKA_TEXTURY * p_tmp, int left, int top, int right, int bottom)
- {
- SetRect(&p_tmp->r, left, top, right, bottom);
- p_tmp->dx = right - left;
- p_tmp->dy = bottom - top;
- p_tmp->radek = K_CHYBA;
- p_tmp->vyska_radku = p_tmp->dy;
- p_tmp->p_dalsi = *p_volne_linky;
- *p_volne_linky = p_tmp;
- return (p_tmp);
- }
- __inline LINKA_TEXTURY *ray_vloz_volnou_linku_all(LINKA_TEXTURY **
- p_volne_linky, int left, int top, int right, int bottom, int indicie)
- {
- LINKA_TEXTURY *p_tmp;
- p_tmp = malloc(sizeof(p_tmp[0]));
- mtest(p_tmp);
- memset(p_tmp, 0, sizeof(p_tmp[0]));
- p_tmp->indicie = indicie;
- return (ray_vloz_volnou_linku(p_volne_linky, p_tmp, left, top, right,
- bottom));
- }
- /* Vlozi linku do lightmapy
- */
- int ray_vloz_linku(LINKA_TEXTURY ** p_linka, LINKA_TEXTURY ** p_volne_linky,
- LIGHTMAP_INFO * p_mapa, int max_x_surface, int max_y_surface)
- {
- LINKA_TEXTURY *p_nova;
- LINKA_TEXTURY *p_tmp, *p_tmp2, *p_tmp3;
- int zbyva_bodu; // x zbyvajicich bodu do konce radku
- int radek_vyska; // vyska zacatku radku v pixelech
- int radek; // cislo aktualniho radku
- int best_fit = -1;
- int best_score = 0x0fffffff, score;
- /* Alokace pameti na novou polozku v seznamu pod-textur
- */
- if (!(p_nova = (LINKA_TEXTURY *) malloc(sizeof(LINKA_TEXTURY))))
- chyba("Pamet!");
- p_nova->dx = p_mapa->dx;
- p_nova->dy = p_mapa->dy;
- p_nova->indicie = p_mapa->indicie;
- p_nova->p_dalsi = NULL;
- /* Je to prvni textura lightmapy
- */
- if (!*p_linka) { // insert-first
- SetRect(&p_nova->r, 0, 0, p_mapa->dx, p_mapa->dy);
- p_nova->radek = 0;
- p_nova->vyska_radku = p_nova->dy;
- *p_linka = p_nova;
- return (TRUE);
- }
- else {
- /* Hledam jestli neni misto v dirach...
- */
- // zkusit hledat v pribuznych lightmapach ? - pribuzne
- // sou na vedlejsich poly
- p_tmp = *p_volne_linky;
- radek = 0;
- if (p_tmp) {
- // test prvni
- while (p_tmp) {
- //p_mapa->dx p_mapa->dy
- if (p_tmp->dx >= p_mapa->dx && p_tmp->dy >= p_mapa->dy) {
- score = (p_tmp->dy - p_mapa->dy) * 1000 + (p_tmp->dx - p_mapa->dx);
- if (score < best_score) {
- best_score = score;
- best_fit = radek;
- }
- }
- p_tmp = p_tmp->p_dalsi;
- radek++;
- }
- if (best_fit != K_CHYBA) {
- // najiti diry
- p_tmp = *p_volne_linky;
- if (!best_fit) { // best-fit je 0 - prvni
- ray_vloz_volnou_linku(p_linka, p_nova,
- p_tmp->r.left,
- p_tmp->r.top,
- p_tmp->r.left + p_nova->dx, p_tmp->r.top + p_nova->dy);
- *p_volne_linky = (*p_volne_linky)->p_dalsi;
- if (best_score) {
- if (p_tmp->dx > p_nova->dx) { // pridej linku do konce radku
- ray_vloz_volnou_linku_all(p_volne_linky,
- p_nova->r.right,
- p_nova->r.top, max_x_surface, p_nova->r.bottom, 0);
- }
- if (p_tmp->dy > p_nova->dy) { // pridej top-linku
- ray_vloz_volnou_linku_all(p_volne_linky,
- p_nova->r.left,
- p_nova->r.bottom, max_x_surface, p_tmp->r.bottom, 0);
- }
- }
- free(p_tmp);
- return (TRUE);
- }
- else {
- radek = 1;
- while (p_tmp->p_dalsi) {
- if (radek == best_fit) {
- p_tmp2 =
- ray_vloz_volnou_linku_all(p_linka, p_tmp->p_dalsi->r.left,
- p_tmp->p_dalsi->r.top, p_tmp->p_dalsi->r.left + p_nova->dx,
- p_tmp->p_dalsi->r.top + p_nova->dy, p_nova->indicie);
- if (best_score) { // je tam dira - vyrob dalsi volne linky
- p_tmp3 = p_tmp; // zazalohuju aktualni tmp
- p_tmp = p_tmp->p_dalsi;
- if (p_tmp->dx > p_tmp2->dx) { // pridej linku do konce radku
- ray_vloz_volnou_linku_all(p_volne_linky,
- p_tmp2->r.right,
- p_tmp2->r.top, p_tmp->r.right, p_tmp2->r.bottom, 0);
- }
- if (p_tmp->dy > p_tmp2->dy) { // pridej top-linku
- ray_vloz_volnou_linku_all(p_volne_linky,
- p_tmp->r.left,
- p_tmp2->r.bottom, p_tmp->r.right, p_tmp->r.bottom, 0);
- }
- p_tmp = p_tmp3; // obnovim puvodni p_tmp
- }
- p_tmp2 = p_tmp->p_dalsi;
- p_tmp->p_dalsi = p_tmp->p_dalsi->p_dalsi;
- free(p_tmp2);
- return (TRUE);
- }
- p_tmp = p_tmp->p_dalsi;
- radek++;
- }
- }
- }
- }
- /* Najdu konec a hledam umisteni...
- */
- zbyva_bodu = max_x_surface;
- radek = 0;
- radek_vyska = 0; // zacatek radku v pixelech
- p_tmp = (*p_linka); // zacnu od zacatku...
- while (p_tmp && p_tmp->radek == K_CHYBA) {
- p_tmp = p_tmp->p_dalsi;
- }
- zbyva_bodu = max_x_surface - p_tmp->dx;
- do {
- /* Preteceni vysky lightmapy
- */
- if (radek_vyska + p_mapa->dy > max_y_surface) {
- free(p_nova);
- p_nova = NULL;
- return (FALSE);
- }
- /* Vlozeni za soucastnou lightmapu na konec radku
- nebo do mezery ktera je do konce radku
- */
- if (zbyva_bodu >= p_mapa->dx && (p_tmp->p_dalsi == NULL || // v pripade konce radku
- p_tmp->p_dalsi->radek > radek)) { // v pripade ze dalsi lightmapa
- // je na dalsim radku
- // max vyska je vyska predchozi textury
- assert(p_tmp->vyska_radku >= p_mapa->dy);
- p_nova->radek = radek;
- p_nova->vyska_radku = p_tmp->vyska_radku;
- p_nova->p_dalsi = p_tmp->p_dalsi; // insert-first
- p_tmp->p_dalsi = p_nova;
- // rect nove
- SetRect(&p_nova->r, max_x_surface - zbyva_bodu,
- radek_vyska,
- max_x_surface - zbyva_bodu + p_nova->dx, radek_vyska + p_nova->dy);
- // pridam do derovniku volne diry
- if (p_mapa->dy < p_tmp->dy) {
- ray_vloz_volnou_linku_all(p_volne_linky,
- max_x_surface - zbyva_bodu,
- radek_vyska + p_mapa->dy,
- max_x_surface, radek_vyska + p_tmp->dy, 0);
- }
- return (TRUE);
- }
- // Vytvoreni noveho radku + pridani na konec
- if (zbyva_bodu < p_mapa->dx && p_tmp->p_dalsi == NULL) {
- radek_vyska += p_tmp->vyska_radku;
- // Radek presahl vysku lightmapy
- if (radek_vyska + p_nova->dy > max_y_surface) {
- free(p_nova);
- return (FALSE);
- }
- // Vlozeni lightmapy na zacatek noveho radku
- p_nova->radek = ++radek;
- p_nova->vyska_radku = p_mapa->dy;
- SetRect(&p_nova->r, 0, radek_vyska, p_nova->dx,
- radek_vyska + p_nova->dy);
- p_nova->p_dalsi = NULL;
- p_tmp->p_dalsi = p_nova;
- return (TRUE);
- }
- // pokracovani v prohledavani
- if (p_tmp->p_dalsi) {
- // mezi-radkova korekce
- while (p_tmp->p_dalsi && p_tmp->p_dalsi->radek == K_CHYBA) {
- p_tmp = p_tmp->p_dalsi;
- }
- // prechod na dalsi radek
- if (p_tmp->p_dalsi->radek > radek) {
- radek_vyska += p_tmp->vyska_radku;
- zbyva_bodu = max_x_surface - p_tmp->p_dalsi->dx;
- radek = p_tmp->p_dalsi->radek;
- }
- else
- zbyva_bodu -= p_tmp->p_dalsi->dx;
- // pokracovani v soucastnem
- p_tmp = p_tmp->p_dalsi;
- }
- else {
- free(p_nova);
- return (FALSE); // konec seznamu
- }
- } while (p_tmp);
- free(p_nova);
- p_nova = NULL;
- return (FALSE); // uz se tam light-mapa nevleze
- }
- }
- int ray_statistika_linek(LINKA_TEXTURY ** p_linka, int *p_x, int *p_y)
- {
- LINKA_TEXTURY *p_tmp;
- int dx = 0, dy = 0;
- if (!*p_linka)
- return (FALSE);
- p_tmp = *p_linka;
- while (p_tmp) {
- if (dy < p_tmp->r.bottom)
- dy = p_tmp->r.bottom;
- if (dx < p_tmp->r.right)
- dx = p_tmp->r.right;
- p_tmp = p_tmp->p_dalsi;
- }
- *p_x = dx;
- *p_y = dy;
- return (TRUE);
- }
- void ray_free_linky(LINKA_TEXTURY * p_linka)
- {
- if (p_linka) {
- ray_free_linky(p_linka->p_dalsi);
- free(p_linka);
- p_linka = NULL;
- }
- }
- /*
- */
- LINKA_TEXTURY **ray_vyrob_poly_lightmap(POLY_INDICIE * p_ind, int indnum,
- EDIT_MESH_POLY * p_poly, int *p_linek,
- LIGHTMAP_INFO * p_mapy, int max_x_surface, int max_y_surface)
- {
- LINKA_TEXTURY **p_linka;
- LINKA_TEXTURY *p_linka_volna = NULL, *p_tmp;
- int linek;
- int i;
- int umistenych;
- int umistenych_celkem;
- p_linka = (LINKA_TEXTURY **) malloc(sizeof(LINKA_TEXTURY *) * indnum);
- mtest(p_linka);
- memset(p_linka, 0, sizeof(LINKA_TEXTURY *) * indnum);
- /* Setridim lightmapy poly podle velikosti y,x
- (prednost ma y, potom x)
- */
- qsort(p_mapy, indnum, sizeof(LIGHTMAP_INFO),
- ray_vyrob_poly_lightmap_compare);
- /*
- Optimalizace -> opakovane vkladami mensich textur
- do vetsich
- */
- for (i = 0; i < indnum; i++)
- p_mapy[i].umistena = FALSE;
- /* Dokud neumistim vsechny plosky-opakuj proceduru
- */
- umistenych_celkem = 0;
- linek = 0;
- while (umistenych_celkem != indnum) {
- umistenych = 0;
- for (i = 0; i < indnum; i++) {
- if (!p_mapy[i].umistena) {
- if (ray_vloz_linku(p_linka + linek, &p_linka_volna, p_mapy + i,
- max_x_surface, max_y_surface)) {
- p_mapy[i].umistena = TRUE;
- umistenych++;
- umistenych_celkem++;
- }
- }
- }
- if (!umistenych) {
- //free lin seznam p_linka_volna
- linek++;
- }
- }
- linek++;
- *p_linek = linek;
- /* Uvolneni volnych linek
- */
- while (p_linka_volna) {
- p_tmp = p_linka_volna;
- p_linka_volna = p_linka_volna->p_dalsi;
- free(p_tmp);
- }
- return (p_linka);
- }
- void ray_link_to_lightmap(EDIT_TEXT * p_dest, EDIT_TEXT * p_src,
- LINKA_TEXTURY * p_linka);
- void ray_prepocitej_texture_koordinaty(EDIT_MESH_POLY * p_poly_list,
- POLY_INDICIE * p_ind, LINKA_TEXTURY * p_linka, int dest_x, int dest_y,
- EDIT_TEXT * p_text);
- void ray_tiskni_linky(LINKA_TEXTURY * p_linka)
- {
- if (p_linka) {
- kprintf(TRUE, "indicie %d -> (%d %d %d %d)", p_linka->indicie,
- p_linka->r.left, p_linka->r.top, p_linka->r.right, p_linka->r.bottom);
- ray_tiskni_linky(p_linka->p_dalsi);
- }
- }
- void ray_slep_lightmapy(K_EDITOR * p_cnf, POLY_INDICIE * p_ind, int indnum,
- EDIT_TEXT * p_src)
- {
- LIGHTMAP_INFO *p_mapy;
- LINKA_TEXTURY **p_linky;
- int l, x, y, dx, dy, t;
- int linek;
- int i;
- if (!(p_mapy = (LIGHTMAP_INFO *) _alloca(sizeof(LIGHTMAP_INFO) * indnum)))
- chyba("Pamet");
- for (i = 0; i < indnum; i++) {
- bmp_cti_rozmery(p_src[i].p_bmp, &p_mapy[i].dx, &p_mapy[i].dy);
- p_mapy[i].material = p_cnf->p_poly[p_ind[i].poly].material;
- p_mapy[i].poly = p_ind[i].poly;
- p_mapy[i].f = p_ind[i].face / 3;
- p_mapy[i].indicie = i;
- }
- // vyrobi seznam lightmap pro tento poly
- p_linky = ray_vyrob_poly_lightmap(p_ind, indnum, p_cnf->p_poly,
- &linek, p_mapy, p_cnf->ray.max_x_lepic, p_cnf->ray.max_y_lepic);
- // preved to do oficialnich light-map
- for (l = 0; l < linek; l++) {
- if (ray_statistika_linek(p_linky + l, &x, &y)) {
- if ((t =
- lo_najdi_volnou_texturu(p_cnf->p_lightmap,
- MAX_RAY_TEXTUR)) == K_CHYBA)
- chyba("Neni volna texutra !");
- for (dx = 2; dx < x; dx <<= 1);
- for (dy = 2; dy < y; dy <<= 1);
- if ((p_cnf->p_lightmap[t].p_bmp = bmp_vyrob(dx, dy)) == NULL)
- chyba("Textura");
- bmp_smaz(p_cnf->p_lightmap[t].p_bmp, BLBA_BARVA2);
- sprintf(p_cnf->p_lightmap[t].jmeno, "light%d", t);
- ray_link_to_lightmap(p_cnf->p_lightmap + t, p_src, p_linky[l]);
- ray_prepocitej_texture_koordinaty(p_cnf->p_poly, p_ind, p_linky[l], dx,
- dy, p_cnf->p_lightmap + t);
- ray_free_linky(p_linky[l]);
- }
- }
- free(p_linky);
- p_linky = NULL;
- }
- void ray_link_to_lightmap(EDIT_TEXT * p_dest, EDIT_TEXT * p_src,
- LINKA_TEXTURY * p_linka)
- {
- // pridej akt bunku
- // cil = p_dest + rec
- // src = p_src[face]
- if (p_linka) {
- ray_link_to_lightmap(p_dest, p_src, p_linka->p_dalsi);
- bmp_kopiruj_rec(p_src[p_linka->indicie].p_bmp, p_dest->p_bmp,
- p_linka->r.left, p_linka->r.top);
- }
- }
- // in je rect uvnitr
- void ray_prepocitej_texture_koordinaty(EDIT_MESH_POLY * p_poly_list,
- POLY_INDICIE * p_ind,
- LINKA_TEXTURY * p_linka, int dest_x, int dest_y, EDIT_TEXT * p_text)
- {
- EDIT_MESH_POLY *p_poly;
- float x_start, y_start, dx, dy;
- int f, ind;
- if (p_linka) {
- ray_prepocitej_texture_koordinaty(p_poly_list, p_ind, p_linka->p_dalsi,
- dest_x, dest_y, p_text);
- x_start = (float) p_linka->r.left / (float) dest_x;
- y_start = (float) p_linka->r.top / (float) dest_y;
- dx = (float) (p_linka->r.right - p_linka->r.left) / (float) dest_x;
- dy = (float) (p_linka->r.bottom - p_linka->r.top) / (float) dest_y;
- ind = p_linka->indicie;
- p_poly = p_poly_list + p_ind[ind].poly;
- f = p_ind[ind].face;
- p_poly->p_koord[f].tul = dx * p_poly->p_koord[f].tul + x_start;
- p_poly->p_koord[f].tvl = dy * p_poly->p_koord[f].tvl + y_start;
- p_poly->p_koord[f + 1].tul = dx * p_poly->p_koord[f + 1].tul + x_start;
- p_poly->p_koord[f + 1].tvl = dy * p_poly->p_koord[f + 1].tvl + y_start;
- p_poly->p_koord[f + 2].tul = dx * p_poly->p_koord[f + 2].tul + x_start;
- p_poly->p_koord[f + 2].tvl = dy * p_poly->p_koord[f + 2].tvl + y_start;
- p_poly->p_light[f / 3] = p_text;
- }
- }
- /****************************************************************************
- Staticke-bodove svetla
- ****************************************************************************
- */
- int oe_vloz_staticke_bodove_svetlo(K_EDITOR * p_cnf, STATIC_LIGHT * p_light)
- {
- p_cnf->light[p_light->index] = *p_light;
- p_cnf->light[p_light->index].akt = TRUE;
- p_cnf->light[p_light->index].flag = POSUN_VSE;
- //ddw("Svetlo %s na %d upraveno.",p_light->jmeno,p_light->index);
- return (p_light->index);
- }
- int oe_smaz_staticke_bodove_svetlo(K_EDITOR * p_cnf, STATIC_LIGHT * p_light)
- {
- int li = p_light->index;
- p_cnf->light[li].akt = FALSE;
- if (p_cnf->light[li].p_flare) {
- oe_smaz_flare(p_cnf, p_cnf->light[li].p_flare);
- }
- if (p_light->flag2 & SL2_MESH) {
- if (!p_light->p_prev) { // mazu prvni svetlo kontejneru
- EDIT_KONTEJNER *p_kont = (EDIT_KONTEJNER *) p_light->p_mesh_data;
- assert(p_light == p_kont->p_slight);
- p_kont->p_slight = p_light->p_next;
- if (p_light->p_next)
- p_light->p_next->p_prev = NULL;
- }
- else {
- p_light->p_prev->p_next = p_light->p_next;
- if (p_light->p_next)
- p_light->p_next->p_prev = p_light->p_prev;
- }
- }
- memset(p_light, 0, sizeof(p_light[0]));
- return (TRUE);
- }
- int oe_najdi_volne_stat_svetlo(K_EDITOR * p_cnf)
- {
- int i;
- for (i = 0; i < MAX_EDIT_SVETEL; i++) {
- if (!p_cnf->light[i].akt)
- return (i);
- }
- return (K_CHYBA);
- }
- void oe_prikaz_pridej_staticke_svetlo(K_EDITOR * p_cnf)
- {
- int l = oe_najdi_volne_stat_svetlo(p_cnf);
- byte pom[200];
- int k = p_cnf->vybr_kont;
- STATIC_LIGHT light, *p_light;
- if (!p_cnf->cnf.svetla_sceny) {
- n_kont(k);
- }
- memset(&light, 0, sizeof(light));
- light.dosah = 10000.0f;
- light.index = l;
- light.r = light.g = light.b = 1.0f;
- light.k1 = 1;
- light.uhel = light.utlum = 1;
- light.p_flare = NULL;
- light.akt = TRUE;
- sprintf(light.jmeno, "Svetlo %d", l);
- if (p_cnf->cnf.svetla_sceny) {
- strcpy(pom, "Pridat bodove svetlo sceny...");
- }
- else {
- sprintf(pom, "Pridat bodove svetlo kontejneru %s (%d)",
- p_cnf->p_kont[k]->jmeno, k);
- }
- if (doe_prikaz_bodove_svetlo(hwnd_aplikace, pom, &light)) {
- p_cnf->lightakt = oe_vloz_staticke_bodove_svetlo(p_cnf, &light);
- p_light = p_cnf->light + p_cnf->lightakt;
- if (p_cnf->cnf.svetla_dynamicke) {
- oe_prepocitat_stat_svetla(p_cnf);
- ray_prepocitej_staticke_osvetleni_vertexy(p_cnf);
- }
- if (!p_cnf->cnf.svetla_sceny) {
- p_light->flag2 = SL2_MESH;
- p_light->p_mesh_data = p_cnf->p_kont[k];
- p_light->p_next = p_cnf->p_kont[k]->p_slight;
- p_light->p_prev = NULL;
- p_cnf->p_kont[k]->p_slight = p_light;
- if (p_light->p_next) {
- p_light->p_next->p_prev = p_light;
- }
- }
- }
- }
- void oe_uprav_staticke_svetlo(K_EDITOR * p_cnf, STATIC_LIGHT * p_light)
- {
- STATIC_LIGHT light = *p_light;
- byte pom[200];
- if (p_light->flag2 & SL2_MESH) {
- EDIT_KONTEJNER *p_kont = p_light->p_mesh_data;
- sprintf(pom, "Uprav bodove svetlo kontejneru %s...", p_kont->jmeno);
- }
- else {
- strcpy(pom, "Uprav bodove svetlo sceny...");
- }
- if (doe_prikaz_bodove_svetlo(hwnd_aplikace, pom, &light))
- oe_vloz_staticke_bodove_svetlo(p_cnf, &light);
- }
- void oe_prepocitat_stat_svetla(K_EDITOR * p_cnf)
- {
- STATIC_LIGHT *p_light;
- int i;
- float dist, I, det, a1, a2;
- p_cnf->lightnum = 0;
- for (i = 0; i < MAX_EDIT_SVETEL; i++) {
- if (p_cnf->light[i].akt) {
- p_light = p_cnf->light + i;
- p_cnf->lightnum = i + 1;
- // posledni kontejner&poly je nic
- p_light->last_kont = p_light->last_poly = K_CHYBA;
- // prepocitam dosah podle utlumu
- if (p_light->utlum) {
- dist = p_light->dosah;
- I =
- 1.0f / (p_light->k1 + p_light->k2 * dist +
- p_light->k3 * dist * dist);
- // nastavim dosah podle utlumu
- if (I < MIN_LIGHT) {
- det =
- p_light->k2 * p_light->k2 - 4 * p_light->k3 * (p_light->k1 -
- 1.0f / MIN_LIGHT);
- a1 = (-p_light->k2 + sqrtf(det)) / (2 * p_light->k3);
- a2 = (-p_light->k2 - sqrtf(det)) / (2 * p_light->k3);
- if (a1 > dist || a1 < 0.0f)
- a1 = dist;
- if (a2 > dist || a2 < 0.0f)
- a2 = dist;
- p_light->dosah = (a2 > a1) ? a1 : a2;
- }
- }
- }
- }
- }
- /*******************************
- Ray-Casting
- *******************************
- Motto:
- "To je vec, ktera je dnes uz naprosty standard.
- Vsechny gamesy, pokud vim, to takhle delaji.
- Pekne to popisuje Michael Abrash v Ramblings
- in Realtime (o vyvoji Quaka), posilam ti to PDFko.
- Jde to, ze kazdemu polygonu sceny udelas lightmapu
- tak, ze vytvoris nejakou pravidelnou sit o ne moc
- velkem poctu stejne vzdalenych uzlu, takovy grid
- rovnomerne napamovany na cely polygon. Z kazdeho
- toho uzlu pak vystrelis papresek ke vsem zdrojum
- svetla, kdyz se s nicim neprotne, tak je tam svetlo
- jinak tma. Muzes merit i vzdalenost od svetla a tim
- korigovat mnozstvi energie. Vysledek pak zprumerujes
- s nekolika okolnima uzlama a ziskas tak mekke stiny.
- Kdyz zvolis raster moc veliky, tak jsou mapy kvalitni
- ale zase zabiraji moc mista, takze se tezko rvou do
- akceleratoru. Je dobre zvolit mensi kompromis, pak se
- jsou sice ve vetsi vzdalenosti od svetla videt takove
- rozblurovane ctverce (viz. nektere levely v Quaku),
- ale to je dan pometovym narokum."
- ReDox^Movsd
- */
- void oe_uloz_screen(byte * p_file)
- {
- /* Nacte HDC a ulozi to na disk
- */
- }
- /**************************************************************************
- Optimalizacni kvadratura
- *************************************************************************
- */
- // analizuje scenu a vyplivne rozmery kvadrat. stromu
- #define X_BUNKA 2
- #define Y_BUNKA 2
- #define Z_BUNKA 2
- void ray_analizuj_scenu(K_EDITOR * p_cnf, BOD * p_start, BOD * p_bunek,
- BOD * p_roz)
- {
- EDIT_MESH_POLY *p_poly;
- BOD kon = { -FLT_MAX, -FLT_MAX, -FLT_MAX }, zac = {
- FLT_MAX, FLT_MAX, FLT_MAX}, a;
- int p, f;
- for (p = 0; p < p_cnf->polynum; p++) {
- p_poly = p_cnf->p_poly + p;
- for (f = 0; f < p_poly->facenum; f++) {
- a.x = p_poly->p_koord[f].x;
- a.y = p_poly->p_koord[f].y;
- a.z = p_poly->p_koord[f].z;
- if (a.x < zac.x)
- zac.x = a.x;
- if (a.y < zac.y)
- zac.y = a.y;
- if (a.z < zac.z)
- zac.z = a.z;
- if (a.x > kon.x)
- kon.x = a.x;
- if (a.y > kon.y)
- kon.y = a.y;
- if (a.z > kon.z)
- kon.z = a.z;
- }
- }
- *p_start = zac;
- p_bunek->x =
- (float) ceil((2.0f * ceil(kon.x - zac.x)) / (float) p_roz->x) + 1;
- p_bunek->y =
- (float) ceil((2.0f * ceil(kon.y - zac.y)) / (float) p_roz->y) + 1;
- p_bunek->z =
- (float) ceil((2.0f * ceil(kon.z - zac.z)) / (float) p_roz->z) + 1;
- }
- int ray_bod_do_qbod(QUAD_TREE * p_qtree, QBOD * p_q, BOD * p_b)
- {
- p_q->x = (int) floor((p_b->x - p_qtree->st.x) / p_qtree->bunka.x);
- p_q->y = (int) floor((p_b->y - p_qtree->st.y) / p_qtree->bunka.y);
- p_q->z = (int) floor((p_b->z - p_qtree->st.z) / p_qtree->bunka.z);
- if (p_q->x >= 0 && p_q->x < p_qtree->rad.x &&
- p_q->y >= 0 && p_q->y < p_qtree->rad.y &&
- p_q->z >= 0 && p_q->z < p_qtree->rad.z)
- return (TRUE);
- else
- return (FALSE);
- }
- BOD *ray_interpoluj_face_bodama(BOD * p_face, int *p_bodu)
- {
- BOD q1, q2, h1, h2, hq, *p_list;
- int i, j, bodu, lbodu;
- int cbodu;
- float k1, k2, t, dt, ht, hdt;
- float krok = 0.05f;
- k1 = vzdal_bodu_bod(p_face, p_face + 2);
- k2 = vzdal_bodu_bod(p_face + 1, p_face + 2);
- bodu = (int) ceil((k1 < k2) ? k2 / krok : k1 / krok);
- bodu++;
- p_list = malloc(sizeof(BOD) * bodu * bodu);
- if (!p_list)
- chyba("Pamet!");
- cbodu = 0;
- // t je parametr od 0 do 1
- calc_primku_3d(p_face, p_face + 2, &q1);
- calc_primku_3d(p_face + 1, p_face + 2, &q2);
- // P = d + q*t
- // t = 0-1 -> po k1 krocich
- t = 0;
- dt = 1.0f / (float) (bodu - 1);
- for (i = 0; i < bodu; i++) {
- // d[0] -> d[2]
- h1.x = p_face[0].x + q1.x * t;
- h1.y = p_face[0].y + q1.y * t;
- h1.z = p_face[0].z + q1.z * t;
- h2.x = p_face[1].x + q2.x * t;
- h2.y = p_face[1].y + q2.y * t;
- h2.z = p_face[1].z + q2.z * t;
- t += dt;
- // 2 body a mezi nema interpolovat
- // h1 a h2
- lbodu = (int) ceil(vzdal_bodu_bod(&h1, &h2) / krok);
- lbodu++;
- calc_primku_3d(&h1, &h2, &hq);
- ht = 0.0f;
- hdt = 1.0f / ((float) (lbodu - 1));
- for (j = 0; j < lbodu; j++) {
- p_list[cbodu].x = (h1.x + hq.x * ht);
- p_list[cbodu].y = (h1.y + hq.y * ht);
- p_list[cbodu].z = (h1.z + hq.z * ht);
- ht += hdt;
- cbodu++;
- }
- }
- *p_bodu = cbodu;
- return (p_list);
- }
|