RENDER.C 92 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869
  1. /****************************************************************************
  2. * render.c
  3. *
  4. * This module implements the main raytracing loop.
  5. *
  6. * 08/07/92 lsk Changed the normal antialiasing function to use a loop
  7. * where the number of rays per pixel when antialiasing can
  8. * be specified.
  9. *
  10. * from Persistence of Vision(tm) Ray Tracer
  11. * Copyright 1996,1999 Persistence of Vision Team
  12. *---------------------------------------------------------------------------
  13. * NOTICE: This source code file is provided so that users may experiment
  14. * with enhancements to POV-Ray and to port the software to platforms other
  15. * than those supported by the POV-Ray Team. There are strict rules under
  16. * which you are permitted to use this file. The rules are in the file
  17. * named POVLEGAL.DOC which should be distributed with this file.
  18. * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  19. * Team Coordinator by email to team-coord@povray.org or visit us on the web at
  20. * http://www.povray.org. The latest version of POV-Ray may be found at this site.
  21. *
  22. * This program is based on the popular DKB raytracer version 2.12.
  23. * DKBTrace was originally written by David K. Buck.
  24. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  25. *
  26. ******************************************************************************/
  27. #include <time.h>
  28. #include "frame.h"
  29. #include "vector.h"
  30. #include "povproto.h"
  31. #include "bbox.h"
  32. #include "chi2.h"
  33. #include "colour.h"
  34. #include "interior.h"
  35. #include "lighting.h"
  36. #include "normal.h"
  37. #include "objects.h"
  38. #include "octree.h"
  39. #include "optout.h"
  40. #include "povray.h"
  41. #include "radiosit.h"
  42. #include "ray.h"
  43. #include "render.h"
  44. #include "targa.h"
  45. #include "texture.h"
  46. #include "vbuffer.h"
  47. #include "userio.h"
  48. /*****************************************************************************
  49. * Local preprocessor defines
  50. ******************************************************************************/
  51. #define rand2d(a, b) jitttab[(int)(hashTable[(int)(hashTable[(int)((a)&0xfff)]^(b))&0xfff])&0xff]
  52. /* Grid stuff used by focal blur code. */
  53. #define grid1size 4
  54. #define hexgrid2size 7
  55. #define hexgrid3size 19
  56. #define hexgrid4size 37
  57. /* Grid size (n x n) used while jittering focal blur sub-pixel position. */
  58. #define SUB_PIXEL_GRID_SIZE 16
  59. /*****************************************************************************
  60. * Local typedefs
  61. ******************************************************************************/
  62. typedef struct Pixel_Struct PIXEL;
  63. typedef struct Vec2_Struct VEC2;
  64. struct Vec2_Struct
  65. {
  66. DBL x, y;
  67. };
  68. struct Pixel_Struct
  69. {
  70. int active;
  71. COLOUR Colour;
  72. };
  73. /*****************************************************************************
  74. * Local variables
  75. ******************************************************************************/
  76. int Trace_Level;
  77. int Max_Trace_Level = 5;
  78. int Highest_Trace_Level; /* DMF */
  79. /* ADC stuff by DMF. */
  80. DBL ADC_Bailout = 1.0/255.0;
  81. static COLOUR *Previous_Line, *Current_Line;
  82. static char *Previous_Line_Antialiased_Flags, *Current_Line_Antialiased_Flags;
  83. static RAY Camera_Ray;
  84. static int SuperSampleCount, RadiosityCount;
  85. static DBL maxclr;
  86. /* Jitter values are taken from [-0.5*JitterScale, 0.5*JitterScale]. */
  87. static DBL JitterScale;
  88. /* Jitter ranges unsed during supersampling. */
  89. static unsigned short JRanges[] = {1,1,1,1,3,2,5,3,7,4};
  90. /* variables used by accumulate_histogram() for statistics on the render */
  91. unsigned long *histogram_grid;
  92. unsigned long max_histogram_value;
  93. FILE_HANDLE *Histogram_File_Handle;
  94. /*
  95. * Focal blur stuff.
  96. */
  97. /* Flag telling if focal blur is used. */
  98. static int Focal_Blur_Is_Used;
  99. /* Direction to focal plane. */
  100. static DBL Focal_Distance;
  101. /* Array of threshold for confidence test. */
  102. static DBL *Sample_Threshold;
  103. /* Array giving number of samples to take before next confidence test. */
  104. static int *Current_Number_Of_Samples;
  105. /* Array of sample locations. */
  106. static VEC2 *Sample_Grid;
  107. /* Maximum amount of jitter to use. */
  108. static DBL Max_Jitter;
  109. /* Vectors in the viewing plane. */
  110. static VECTOR XPerp, YPerp;
  111. /* 2*2 grid */
  112. static VEC2 grid1[grid1size] =
  113. {
  114. {-0.25, 0.25},
  115. { 0.25, 0.25},
  116. {-0.25, -0.25},
  117. { 0.25, -0.25}
  118. };
  119. static DBL hexjitter2 = 0.144338;
  120. static int hexgrid2samples[2] = { 7, 0 };
  121. static VEC2 hexgrid2 [hexgrid2size] =
  122. {
  123. {-0.288675, 0.000000},
  124. { 0.000000, 0.000000},
  125. { 0.288675, 0.000000},
  126. {-0.144338, 0.250000},
  127. {-0.144338, -0.250000},
  128. { 0.144338, 0.250000},
  129. { 0.144338, -0.250000}
  130. };
  131. static DBL hexjitter3 = 0.096225;
  132. static int hexgrid3samples[4] = { 7, 6, 6, 0 };
  133. static VEC2 hexgrid3 [hexgrid3size] =
  134. {
  135. {-0.192450, 0.333333},
  136. {-0.192450, -0.333333},
  137. { 0.192450, 0.333333},
  138. { 0.192450, -0.333333},
  139. { 0.384900, 0.000000},
  140. {-0.384900, 0.000000},
  141. { 0.000000, 0.000000},
  142. { 0.000000, 0.333333},
  143. { 0.000000, -0.333333},
  144. {-0.288675, 0.166667},
  145. {-0.288675, -0.166667},
  146. { 0.288675, 0.166667},
  147. { 0.288675, -0.166667},
  148. {-0.096225, 0.166667},
  149. {-0.096225, -0.166667},
  150. { 0.096225, 0.166667},
  151. { 0.096225, -0.166667},
  152. {-0.192450, 0.000000},
  153. { 0.192450, 0.000000}
  154. };
  155. static DBL hexjitter4 = 0.0721688;
  156. static int hexgrid4samples[9] = { 7, 6, 6, 4, 4, 4, 4, 2, 0 };
  157. static VEC2 hexgrid4 [hexgrid4size] =
  158. {
  159. { 0.000000, 0.000000},
  160. {-0.216506, 0.375000},
  161. { 0.216506, -0.375000},
  162. {-0.216506, -0.375000},
  163. { 0.216506, 0.375000},
  164. {-0.433013, 0.000000},
  165. { 0.433013, 0.000000},
  166. {-0.144338, 0.250000},
  167. { 0.144338, -0.250000},
  168. {-0.144338, -0.250000},
  169. { 0.144338, 0.250000},
  170. {-0.288675, 0.000000},
  171. { 0.288675, 0.000000},
  172. {-0.072169, 0.125000},
  173. { 0.072169, -0.125000},
  174. {-0.072169, -0.125000},
  175. { 0.072169, 0.125000},
  176. {-0.144338, 0.000000},
  177. { 0.144338, 0.000000},
  178. {-0.360844, 0.125000},
  179. {-0.360844, -0.125000},
  180. { 0.360844, 0.125000},
  181. { 0.360844, -0.125000},
  182. {-0.288675, 0.250000},
  183. {-0.288675, -0.250000},
  184. { 0.288675, 0.250000},
  185. { 0.288675, -0.250000},
  186. {-0.072169, 0.375000},
  187. {-0.072169, -0.375000},
  188. { 0.072169, 0.375000},
  189. { 0.072169, -0.375000},
  190. {-0.216506, 0.125000},
  191. {-0.216506, -0.125000},
  192. { 0.216506, 0.125000},
  193. { 0.216506, -0.125000},
  194. { 0.000000, 0.250000},
  195. { 0.000000, -0.250000},
  196. };
  197. static float jitttab[256] = {
  198. -0.500000,0.005890,0.011749,-0.490234,0.023468,-0.470703,-0.480469,0.017609,
  199. 0.046906,-0.447266,-0.441406,0.056671,-0.460938,0.044952,0.035187,-0.466797,
  200. 0.093781,-0.400391,-0.394531,0.103546,-0.382813,0.123077,0.113312,-0.388672,
  201. -0.421875,0.084015,0.089874,-0.412109,0.070343,-0.423828,-0.433594,0.064484,
  202. 0.187531,-0.306641,-0.300781,0.197296,-0.289063,0.216827,0.207062,-0.294922,
  203. -0.265625,0.240265,0.246124,-0.255859,0.226593,-0.267578,-0.277344,0.220734,
  204. -0.343750,0.162140,0.167999,-0.333984,0.179718,-0.314453,-0.324219,0.173859,
  205. 0.140656,-0.353516,-0.347656,0.150421,-0.367188,0.138702,0.128937,-0.373047,
  206. 0.375031,-0.119141,-0.113281,0.384796,-0.101563,0.404327,0.394562,-0.107422,
  207. -0.078125,0.427765,0.433624,-0.068359,0.414093,-0.080078,-0.089844,0.408234,
  208. -0.031250,0.474640,0.480499,-0.021484,0.492218,-0.001953,-0.011719,0.486359,
  209. 0.453156,-0.041016,-0.035156,0.462921,-0.054688,0.451202,0.441437,-0.060547,
  210. -0.187500,0.318390,0.324249,-0.177734,0.335968,-0.158203,-0.167969,0.330109,
  211. 0.359406,-0.134766,-0.128906,0.369171,-0.148438,0.357452,0.347687,-0.154297,
  212. 0.281281,-0.212891,-0.207031,0.291046,-0.195313,0.310577,0.300812,-0.201172,
  213. -0.234375,0.271515,0.277374,-0.224609,0.257843,-0.236328,-0.246094,0.251984,
  214. -0.249969,0.255859,0.261719,-0.240204,0.273438,-0.220673,-0.230438,0.267578,
  215. 0.296875,-0.197235,-0.191376,0.306641,-0.210907,0.294922,0.285156,-0.216766,
  216. 0.343750,-0.150360,-0.144501,0.353516,-0.132782,0.373047,0.363281,-0.138641,
  217. -0.171844,0.333984,0.339844,-0.162079,0.320313,-0.173798,-0.183563,0.314453,
  218. 0.437500,-0.056610,-0.050751,0.447266,-0.039032,0.466797,0.457031,-0.044891,
  219. -0.015594,0.490234,0.496094,-0.005829,0.476563,-0.017548,-0.027313,0.470703,
  220. -0.093719,0.412109,0.417969,-0.083954,0.429688,-0.064423,-0.074188,0.423828,
  221. 0.390625,-0.103485,-0.097626,0.400391,-0.117157,0.388672,0.378906,-0.123016,
  222. 0.125000,-0.369110,-0.363251,0.134766,-0.351532,0.154297,0.144531,-0.357391,
  223. -0.328094,0.177734,0.183594,-0.318329,0.164063,-0.330048,-0.339813,0.158203,
  224. -0.281219,0.224609,0.230469,-0.271454,0.242188,-0.251923,-0.261688,0.236328,
  225. 0.203125,-0.290985,-0.285126,0.212891,-0.304657,0.201172,0.191406,-0.310516,
  226. -0.437469,0.068359,0.074219,-0.427704,0.085938,-0.408173,-0.417938,0.080078,
  227. 0.109375,-0.384735,-0.378876,0.119141,-0.398407,0.107422,0.097656,-0.404266,
  228. 0.031250,-0.462860,-0.457001,0.041016,-0.445282,0.060547,0.050781,-0.451141,
  229. -0.484344,0.021484,0.027344,-0.474579,0.007813,-0.486298,-0.496063,0.001953,
  230. };
  231. /* Precomputed ray container values. */
  232. static int Primary_Ray_State_Tested;
  233. static int Containing_Index;
  234. static INTERIOR *Containing_Interiors[MAX_CONTAINING_OBJECTS];
  235. /* Flag wether to compute camera constant that don't change during one frame. */
  236. static int Precompute_Camera_Constants;
  237. static DBL Camera_Aspect_Ratio;
  238. /*****************************************************************************
  239. * Local functions
  240. ******************************************************************************/
  241. static void focal_blur (RAY *Ray, COLOUR Colour, DBL x, DBL y);
  242. static void jitter_camera_ray (RAY *ray, int ray_number);
  243. static void check_stats (int y, int doingMosaic, int pixWidth);
  244. static void do_anti_aliasing (int x, int y, COLOUR Colour);
  245. static void output_line (int y);
  246. static int create_ray (RAY *ray, DBL x, DBL y, int ray_number);
  247. static void supersample (COLOUR result, int x, int y);
  248. static void gamma_correct (COLOUR Colour);
  249. static void extract_colors (COLOUR Colour, unsigned char *Red, unsigned char *Green, unsigned char *Blue, unsigned char *Alpha, DBL *grey);
  250. static void trace_pixel (int x, int y, COLOUR Colour);
  251. static void initialise_histogram (void) ;
  252. static void accumulate_histogram (int x, int y, int on);
  253. static void plot_pixel (int x, int y, COLOUR Colour);
  254. static void jitter_pixel_position (int x, int y, DBL *Jitter_X, DBL *Jitter_Y);
  255. static void trace_sub_pixel (int level, PIXEL **Block, int x, int y, int x1, int y1, int x2, int y2, int size, COLOUR Colour, int antialias);
  256. static void trace_ray_with_offset (int x, int y, DBL dx, DBL dy, COLOUR Colour);
  257. static void initialize_ray_container_state (RAY *Ray, int Compute);
  258. static void initialize_ray_container_state_tree (RAY *Ray, BBOX_TREE *Node);
  259. /*****************************************************************************
  260. *
  261. * FUNCTION
  262. *
  263. * Initialize_Renderer
  264. *
  265. * INPUT
  266. *
  267. * OUTPUT
  268. *
  269. * RETURNS
  270. *
  271. * AUTHOR
  272. *
  273. * POV-Ray Team
  274. *
  275. * DESCRIPTION
  276. *
  277. * Setup renderer. Allocate memory for line storage.
  278. *
  279. * CHANGES
  280. *
  281. * -
  282. *
  283. ******************************************************************************/
  284. void Initialize_Renderer (void)
  285. {
  286. char **Grid;
  287. int i, xi, yi, Grid_Size;
  288. int Standard_Sample_Grid_Size;
  289. size_t size;
  290. DBL x, y, len;
  291. DBL T1;
  292. VEC2 *Standard_Sample_Grid;
  293. maxclr = (DBL)(1 << Color_Bits) - 1.0;
  294. Radiosity_Trace_Level = 1;
  295. size = (Frame.Screen_Width + 1) * sizeof(COLOUR);
  296. Previous_Line = (COLOUR *)POV_MALLOC(size, "previous line buffer");
  297. Current_Line = (COLOUR *)POV_MALLOC(size, "current line buffer");
  298. for (i = 0; i <= Frame.Screen_Width ; i++)
  299. {
  300. Make_ColourA(Previous_Line[i], 0.0, 0.0, 0.0, 0.0, 0.0);
  301. Make_ColourA(Current_Line[i], 0.0, 0.0, 0.0, 0.0, 0.0);
  302. }
  303. if (opts.Options & ANTIALIAS)
  304. {
  305. size = (Frame.Screen_Width + 1) * sizeof(char);
  306. Previous_Line_Antialiased_Flags = (char *)POV_MALLOC(size, "previous line flags");
  307. Current_Line_Antialiased_Flags = (char *)POV_MALLOC(size, "current line flags");
  308. for (i = 0; i <= Frame.Screen_Width ; i++)
  309. {
  310. Previous_Line_Antialiased_Flags[i] = 0;
  311. Current_Line_Antialiased_Flags[i] = 0;
  312. }
  313. }
  314. Assign_Vector(Camera_Ray.Initial, Frame.Camera->Location);
  315. if (opts.histogram_on)
  316. {
  317. initialise_histogram();
  318. }
  319. Focal_Blur_Is_Used = (Frame.Camera->Aperture != 0.0) && (Frame.Camera->Blur_Samples > 0);
  320. /* Init focal blur stuff. */
  321. Sample_Grid = NULL;
  322. Sample_Threshold = NULL;
  323. if (Focal_Blur_Is_Used)
  324. {
  325. /* Create list of thresholds for confidence test. */
  326. Sample_Threshold = (DBL *)POV_MALLOC(Frame.Camera->Blur_Samples*sizeof(DBL), "sample threshold list");
  327. if (Frame.Camera->Blur_Samples > 1)
  328. {
  329. T1 = Frame.Camera->Variance / chdtri((DBL)(Frame.Camera->Blur_Samples-1), Frame.Camera->Confidence);
  330. for (i = 0; i < Frame.Camera->Blur_Samples; i++)
  331. {
  332. Sample_Threshold[i] = T1 * chdtri((DBL)(i+1), Frame.Camera->Confidence);
  333. }
  334. }
  335. else
  336. {
  337. Sample_Threshold[0] = 0.0;
  338. }
  339. /* Create list of sample positions. */
  340. Sample_Grid = (VEC2 *)POV_MALLOC(Frame.Camera->Blur_Samples*sizeof(VEC2), "sample grid");
  341. /*
  342. * Choose sample list and the best standard grid to use.
  343. */
  344. /* Default is 4x4 standard grid. */
  345. Standard_Sample_Grid = &grid1[0];
  346. Standard_Sample_Grid_Size = 4;
  347. Current_Number_Of_Samples = NULL;
  348. /* Check for 7 samples hexgrid. */
  349. if (Frame.Camera->Blur_Samples >= hexgrid2size)
  350. {
  351. Standard_Sample_Grid = &hexgrid2[0];
  352. Standard_Sample_Grid_Size = hexgrid2size;
  353. Current_Number_Of_Samples = &hexgrid2samples[0];
  354. }
  355. /* Check for 19 samples hexgrid. */
  356. if (Frame.Camera->Blur_Samples >= hexgrid3size)
  357. {
  358. Standard_Sample_Grid = &hexgrid3[0];
  359. Standard_Sample_Grid_Size = hexgrid3size;
  360. Current_Number_Of_Samples = &hexgrid3samples[0];
  361. }
  362. /* Check for 37 samples hexgrid. */
  363. if (Frame.Camera->Blur_Samples >= hexgrid4size)
  364. {
  365. Standard_Sample_Grid = &hexgrid4[0];
  366. Standard_Sample_Grid_Size = hexgrid4size;
  367. Current_Number_Of_Samples = &hexgrid4samples[0];
  368. }
  369. /* Get max. jitter. */
  370. switch (Frame.Camera->Blur_Samples)
  371. {
  372. case hexgrid2size :
  373. Max_Jitter = hexjitter2;
  374. break;
  375. case hexgrid3size :
  376. Max_Jitter = hexjitter3;
  377. break;
  378. case hexgrid4size :
  379. Max_Jitter = hexjitter4;
  380. break;
  381. default:
  382. Max_Jitter = 1.0 / (2.0 * sqrt((DBL)Frame.Camera->Blur_Samples));
  383. }
  384. /* Copy standard grid to sample grid. */
  385. for (i = 0; i < min(Standard_Sample_Grid_Size, Frame.Camera->Blur_Samples); i++)
  386. {
  387. Sample_Grid[i] = Standard_Sample_Grid[i];
  388. }
  389. /* Choose remaining samples from a uniform grid to get "best" coverage. */
  390. if (Frame.Camera->Blur_Samples > Standard_Sample_Grid_Size)
  391. {
  392. /* Get sub-pixel grid size (I want it to be odd). */
  393. Grid_Size = (int)sqrt((DBL)Frame.Camera->Blur_Samples) + 1;
  394. if ((Grid_Size & 1) == 0)
  395. {
  396. Grid_Size++;
  397. }
  398. /* Allocate temporary grid. */
  399. Grid = (char **)POV_MALLOC(Grid_Size * sizeof(int *), "temporary sub-pixel grid");
  400. for (i = 0; i < Grid_Size; i++)
  401. {
  402. Grid[i] = (char *)POV_CALLOC((unsigned)Grid_Size, sizeof(int), "temporary sub-pixel grid");
  403. }
  404. /* Mark sub-pixels already covered. */
  405. for (i = 0; i < Standard_Sample_Grid_Size; i++)
  406. {
  407. xi = (int)((Sample_Grid[i].x + 0.5) * (DBL)Grid_Size);
  408. yi = (int)((Sample_Grid[i].y + 0.5) * (DBL)Grid_Size);
  409. Grid[yi][xi] = TRUE;
  410. }
  411. /* Distribute remaining samples. */
  412. for (i = Standard_Sample_Grid_Size; i < Frame.Camera->Blur_Samples; )
  413. {
  414. xi = POV_RAND() % Grid_Size;
  415. yi = POV_RAND() % Grid_Size;
  416. if (!Grid[yi][xi])
  417. {
  418. x = (DBL)(2 * xi + 1) / (DBL)(2 * Grid_Size) - 0.5;
  419. y = (DBL)(2 * yi + 1) / (DBL)(2 * Grid_Size) - 0.5;
  420. Sample_Grid[i].x = x;
  421. Sample_Grid[i].y = y;
  422. Grid[yi][xi] = TRUE;
  423. i++;
  424. }
  425. }
  426. /* Free temporary grid. */
  427. for (i = 0; i < Grid_Size; i++)
  428. {
  429. POV_FREE(Grid[i]);
  430. }
  431. POV_FREE(Grid);
  432. }
  433. /*
  434. * Calculate vectors perpendicular to the current ray
  435. * We're making a "+" (crosshair) on the film plane.
  436. */
  437. /* XPerp = vector perpendicular to y/z plane */
  438. VCross(XPerp, Frame.Camera->Up, Frame.Camera->Direction);
  439. VNormalize(XPerp, XPerp);
  440. /* YPerp = vector perpendicular to x/z plane */
  441. VCross(YPerp, Frame.Camera->Direction, XPerp);
  442. VNormalize(YPerp, YPerp);
  443. /* Get adjusted distance to focal plane. */
  444. VLength(len, Frame.Camera->Direction);
  445. Focal_Distance = Frame.Camera->Focal_Distance / len;
  446. }
  447. /* If a single frame is traced disable field rendering. */
  448. /* Disabled 11/12/95 CEY
  449. if (opts.FrameSeq.FrameType == FT_SINGLE_FRAME)
  450. {
  451. opts.FrameSeq.Field_Render_Flag = FALSE;
  452. }
  453. */
  454. /* We have to precalculate all camera constants. */
  455. Precompute_Camera_Constants = TRUE;
  456. Primary_Ray_State_Tested = FALSE;
  457. }
  458. /*****************************************************************************
  459. *
  460. * FUNCTION
  461. *
  462. * Terminate_Renderer
  463. *
  464. * INPUT
  465. *
  466. * OUTPUT
  467. *
  468. * RETURNS
  469. *
  470. * AUTHOR
  471. *
  472. * POV-Ray Team
  473. *
  474. * DESCRIPTION
  475. *
  476. * -
  477. *
  478. * CHANGES
  479. *
  480. * -
  481. *
  482. ******************************************************************************/
  483. void Terminate_Renderer()
  484. {
  485. if (Previous_Line != NULL)
  486. {
  487. POV_FREE(Previous_Line);
  488. POV_FREE(Current_Line);
  489. Previous_Line = NULL;
  490. Current_Line = NULL;
  491. }
  492. if (Previous_Line_Antialiased_Flags != NULL)
  493. {
  494. POV_FREE(Previous_Line_Antialiased_Flags);
  495. POV_FREE(Current_Line_Antialiased_Flags);
  496. Previous_Line_Antialiased_Flags = NULL;
  497. Current_Line_Antialiased_Flags = NULL;
  498. }
  499. if (Focal_Blur_Is_Used)
  500. {
  501. if (Sample_Threshold != NULL)
  502. {
  503. POV_FREE(Sample_Threshold);
  504. Sample_Threshold = NULL;
  505. }
  506. if (Sample_Grid != NULL)
  507. {
  508. POV_FREE(Sample_Grid);
  509. Sample_Grid = NULL;
  510. }
  511. }
  512. }
  513. /*****************************************************************************
  514. *
  515. * FUNCTION
  516. *
  517. * Read_Rendered_Part
  518. *
  519. * INPUT
  520. *
  521. * OUTPUT
  522. *
  523. * RETURNS
  524. *
  525. * AUTHOR
  526. *
  527. * POV-Ray Team
  528. *
  529. * DESCRIPTION
  530. *
  531. * -
  532. *
  533. * CHANGES
  534. *
  535. * Sep 1994 : Call extract_colors to get pixel's color. [DB]
  536. *
  537. ******************************************************************************/
  538. void Read_Rendered_Part(char *New_Fname)
  539. {
  540. int rc, x, line_number = -1;
  541. unsigned char Red, Green, Blue, Alpha;
  542. DBL grey;
  543. maxclr = (DBL)(1 << Color_Bits) - 1.0;
  544. while ((rc = Read_Line(Output_File_Handle, Previous_Line, &line_number)) == 1)
  545. {
  546. if (opts.Options & DISPLAY)
  547. {
  548. for (x = 0; x < Frame.Screen_Width ; x++)
  549. {
  550. extract_colors(Previous_Line[x], &Red, &Green, &Blue, &Alpha, &grey);
  551. POV_DISPLAY_PLOT(x, line_number, Red, Green, Blue, Alpha);
  552. COOPERATE_1
  553. }
  554. }
  555. }
  556. opts.First_Line = line_number + 1;
  557. if(opts.First_Line < 1)
  558. {
  559. opts.First_Line = 1;
  560. }
  561. Close_File(Output_File_Handle);
  562. if (rc == 0)
  563. {
  564. if (Open_File(Output_File_Handle, New_Fname,
  565. &Frame.Screen_Width, &Frame.Screen_Height, opts.File_Buffer_Size,
  566. APPEND_MODE) != 1)
  567. {
  568. Error("Error opening output file.\n");
  569. }
  570. return;
  571. }
  572. Error("Error reading aborted data file.\n");
  573. }
  574. /*****************************************************************************
  575. *
  576. * FUNCTION
  577. *
  578. * Check_User_Abort
  579. *
  580. * INPUT
  581. *
  582. * Forced -- if FALSE, then check else force user abort
  583. *
  584. * OUTPUT
  585. *
  586. * RETURNS
  587. *
  588. * AUTHOR
  589. *
  590. * POV-Ray Team
  591. *
  592. * DESCRIPTION
  593. *
  594. * Exit with error if image not completed/user abort.
  595. *
  596. * CHANGES
  597. *
  598. * -
  599. *
  600. ******************************************************************************/
  601. void Check_User_Abort(int Forced)
  602. {
  603. if (Forced)
  604. {
  605. Stop_Flag=TRUE;
  606. }
  607. else
  608. {
  609. if (--opts.Abort_Test_Counter <= 0)
  610. {
  611. opts.Abort_Test_Counter = Abort_Test_Every;
  612. TEST_ABORT
  613. }
  614. }
  615. if (Stop_Flag)
  616. {
  617. Render_Info("\nAborting render...\n");
  618. if ((opts.Options & DISPLAY) && Display_Started)
  619. {
  620. POV_DISPLAY_CLOSE
  621. }
  622. if (opts.Do_Stats)
  623. {
  624. PRINT_STATS(stats);
  625. }
  626. Error("User abort.\n");
  627. }
  628. }
  629. /*****************************************************************************
  630. *
  631. * FUNCTION
  632. *
  633. * Start_Tracing_Mosaic_Preview
  634. *
  635. * INPUT
  636. *
  637. * MosaicPixelSize - # of pixels square to start
  638. *
  639. * OUTPUT
  640. *
  641. * RETURNS
  642. *
  643. * AUTHOR
  644. *
  645. * Eduard Schwan
  646. *
  647. * DESCRIPTION
  648. *
  649. * Trace the entire image, but instead of doing it pixel by pixel,
  650. * draw every 8th pixel, then every 4th, then every 2nd, then
  651. * every pixel. This shows the image as a quick chunky preview,
  652. * and the image gets more detailed as each pass redraws it in
  653. * increasing detail. This is a simple subdivision preview method.
  654. * On the first pass, the entire screen is painted. On each subsequent
  655. * pass, smaller squares are painted to fill in more detail. Any
  656. * squares that were already calculated on previous passes are NOT
  657. * redrawn, making this mode just as fast as the non-preview rendering
  658. * mode (ignoring additional time used by rectangle screen painting.)
  659. *
  660. * CHANGES
  661. *
  662. * Aug 1994 : Created from Start_Tracing, by Eduard Schwan
  663. * Dec 1994 : Updated for more regular scanning, by Eduard Schwan
  664. *
  665. ******************************************************************************/
  666. void Start_Tracing_Mosaic_Preview(int StartPixelSize, int EndPixelSize)
  667. {
  668. unsigned char Red, Green, Blue, Alpha;
  669. int x, y, x2, y2, PreviewStep, PixelSize, AlreadyPainted, PreviewPass;
  670. COLOUR Colour;
  671. DBL grey;
  672. /* PreviewStep tracks how many pixels to skip on each square painted */
  673. PreviewStep = StartPixelSize;
  674. /* do each pass of the image */
  675. /* increment pass counter and divide PixelSize & PreviewStep by 2 */
  676. for (PreviewPass = 1, PixelSize = StartPixelSize;
  677. PixelSize >= EndPixelSize;
  678. PreviewPass++, PixelSize >>= 1, PreviewStep >>= 1)
  679. {
  680. /* do each row */
  681. for (y = opts.First_Line; y < opts.Last_Line; y += PreviewStep)
  682. {
  683. /* show some status information */
  684. /* note, this fn should change to show new style for preview */
  685. check_stats(y, 1, PixelSize);
  686. /* do each column/pixel on a row */
  687. for (x = opts.First_Column; x < opts.Last_Column; x += PreviewStep)
  688. {
  689. Check_User_Abort(FALSE);
  690. /*
  691. * Skip any pixels we have done previously. These would be any pixels
  692. * that are on a row AND column that is divisible by the previous
  693. * pass's step-size. On the first pass, however, do ALL pixels, since
  694. * there is nothing to skip.
  695. */
  696. AlreadyPainted = FALSE;
  697. if (PreviewPass > 1)
  698. {
  699. if ( ((x-opts.First_Column) % (PreviewStep*2) == 0) &&
  700. ((y-opts.First_Line) % (PreviewStep*2) == 0) )
  701. {
  702. AlreadyPainted = TRUE;
  703. }
  704. }
  705. if (!AlreadyPainted)
  706. {
  707. /* OK, it is safe to draw this pixel */
  708. trace_pixel(x, y, Colour);
  709. extract_colors(Colour, &Red, &Green, &Blue, &Alpha, &grey);
  710. y2 = min(y + PixelSize - 1, opts.Last_Line-1);
  711. x2 = min(x + PixelSize - 1, opts.Last_Column-1);
  712. POV_DISPLAY_PLOT_RECT(x, y, x2, y2, Red, Green, Blue, Alpha);
  713. }
  714. }
  715. if (opts.Options & VERBOSE)
  716. {
  717. Status_Info("\r");
  718. }
  719. }
  720. }
  721. }
  722. /*****************************************************************************
  723. *
  724. * FUNCTION
  725. *
  726. * Start_Tracing_Mosaic_Smooth
  727. *
  728. * INPUT
  729. *
  730. * MosaicPixelSize - # of pixels square to start
  731. *
  732. * OUTPUT
  733. *
  734. * RETURNS
  735. *
  736. * AUTHOR
  737. *
  738. * Eduard Schwan
  739. *
  740. * DESCRIPTION
  741. *
  742. * See comments for Start_Tracing_Mosaic_Preview.
  743. * Radiosity requires this pass, so it is not optional, and does not
  744. * require you to set Mosaic_Preview_Start and End.
  745. * This function does a smooth interpolation of pixel values, so as
  746. * a result, it re-renders the pixels done on previous passes, so it
  747. * is about 1/16th slower. This function will take any tile size, not
  748. * just powers of two. The smooth interpolation is conditional, since
  749. * on some platforms it is quite slow. When you're doing radiosity,
  750. * life is slow anyway, so the smooth effect is very nice.
  751. * Most important difference is that this function does jittering, so
  752. * that the places at which radiosity tends to be calculated don't lie
  753. * on a grid and produce unpleasant grid artefacts.
  754. * This doesn't really have to be a separate function; the two
  755. * could be merged.
  756. *
  757. * CHANGES
  758. *
  759. * Apr 1995 : Created with first radiosity patches
  760. * Feb 1996 : Made the row buffers dynamically allocated [AED]
  761. *
  762. ******************************************************************************/
  763. void Start_Tracing_Mosaic_Smooth(int StartPixelSize, int EndPixelSize)
  764. {
  765. unsigned char Red, Green, Blue, Alpha;
  766. unsigned char *thisr = NULL, *thisg = NULL, *thisb = NULL, *thisa = NULL;
  767. unsigned char *upr = NULL, *upg = NULL, *upb = NULL, *upa = NULL;
  768. int Smooth_Preview = 0;
  769. int dx, dy, skip,
  770. tr, tg, tb, ta,
  771. lastr, lastg, lastb, lasta,
  772. ulr, urr, llr, lrr,
  773. ulg, urg, llg, lrg,
  774. ulb, urb, llb, lrb,
  775. ula, ura, lla, lra,
  776. lor, log, lob, loa,
  777. hir, hig, hib, hia,
  778. tx, ty, jitter_range, jitter_offset, offset_x, offset_y, first_pass,
  779. x, y, x2, y2;
  780. DBL grey, gather_grey;
  781. COLOUR Colour, avg_gather;
  782. lastr = lastg = lastb = lasta = 0;
  783. opts.Radiosity_Error_Bound *= opts.Radiosity_Low_Error_Factor;
  784. /* Initialize the accumulators which will allow us to set average amb Brightness */
  785. Make_Colour(Radiosity_Gather_Total, 0.0, 0.0, 0.0);
  786. Radiosity_Gather_Total_Count = 0;
  787. /* if radiosity is on, you MUST use preview pass to get reasonable results.
  788. * 8x8 is generally a good size to use if the user didn't specify anything.
  789. */
  790. if ( StartPixelSize == 1 ) StartPixelSize = EndPixelSize = 8;
  791. /* Prevent 2x2 or 1x1 passes - this code is very slow at 2x2 or less */
  792. if ( StartPixelSize < 4) StartPixelSize = 4;
  793. if ( EndPixelSize < 4) EndPixelSize = 4;
  794. /* if there is no visible output, might as well just do one pass, it's faster.
  795. * The last pass is the one which determines the values which get put into
  796. * the radiosity tree, so just do the last (end) pass.
  797. */
  798. if ( !(opts.Options & DISPLAY)) StartPixelSize = EndPixelSize;
  799. /* Finally, end size must always be less than or equal to start size */
  800. if ( EndPixelSize > StartPixelSize ) EndPixelSize = StartPixelSize;
  801. skip = StartPixelSize;
  802. first_pass = TRUE;
  803. if (opts.Options & DISPLAY)
  804. {
  805. upr = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  806. upg = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  807. upb = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  808. upa = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  809. thisr = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  810. thisg = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  811. thisb = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  812. thisa = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  813. }
  814. while ((skip >= 4) && (skip >= EndPixelSize))
  815. {
  816. /* for each pass */
  817. jitter_range = 3;
  818. jitter_offset = skip / 2 - 1; /* add a very small amount of jitter */
  819. if ( skip <= 8 ) Smooth_Preview = 1;
  820. for (y = opts.First_Line; y < opts.Last_Line; y += skip)
  821. {
  822. check_stats(y, 1, skip);
  823. for (x = opts.First_Column; x < opts.Last_Column; x += skip)
  824. {
  825. Check_User_Abort(FALSE);
  826. offset_x = jitter_offset + (POV_RAND() % jitter_range);
  827. offset_y = jitter_offset + (POV_RAND() % jitter_range);
  828. trace_pixel(x + offset_x, y + offset_y, Colour);
  829. extract_colors(Colour, &Red, &Green, &Blue, &Alpha, &grey);
  830. Assign_Colour(Current_Line[x], Colour);
  831. POV_ASSIGN_PIXEL (x, y, Colour)
  832. if (opts.Options & DISPLAY)
  833. {
  834. if ( Smooth_Preview )
  835. {
  836. /* if smooth colour blending desired */
  837. if (y == opts.First_Line)
  838. {
  839. upr[x] = Red;
  840. upg[x] = Green;
  841. upb[x] = Blue;
  842. upa[x] = Alpha;
  843. }
  844. ulr = (x>opts.First_Column) ? upr[x-skip] : Red;
  845. urr = upr[x];
  846. llr = (x>opts.First_Column) ? lastr : Red;
  847. lrr = Red;
  848. ulg = (x>opts.First_Column) ? upg[x-skip] : Green;
  849. urg = upg[x];
  850. llg = (x>opts.First_Column) ? lastg : Green;
  851. lrg = Green;
  852. ulb = (x>opts.First_Column) ? upb[x-skip] : Blue;
  853. urb = upb[x];
  854. llb = (x>opts.First_Column) ? lastb : Blue;
  855. lrb = Blue;
  856. ula = (x>opts.First_Column) ? upa[x-skip] : Alpha;
  857. ura = upa[x];
  858. lla = (x>opts.First_Column) ? lasta : Alpha;
  859. lra = Alpha;
  860. for (ty = y, dy = 0; (dy < skip) && (ty < opts.Last_Line); dy++, ty++)
  861. {
  862. lor = (ulr * (skip-dy) + llr * dy) / skip;
  863. hir = (urr * (skip-dy) + lrr * dy) / skip;
  864. log = (ulg * (skip-dy) + llg * dy) / skip;
  865. hig = (urg * (skip-dy) + lrg * dy) / skip;
  866. lob = (ulb * (skip-dy) + llb * dy) / skip;
  867. hib = (urb * (skip-dy) + lrb * dy) / skip;
  868. loa = (ula * (skip-dy) + lla * dy) / skip;
  869. hia = (ura * (skip-dy) + lra * dy) / skip;
  870. for (tx = x, dx = 0; (dx < skip) && (tx < opts.Last_Column); dx++, tx++)
  871. {
  872. tr = (lor * (skip - dx) + (hir * dx)) / skip;
  873. tg = (log * (skip - dx) + (hig * dx)) / skip;
  874. tb = (lob * (skip - dx) + (hib * dx)) / skip;
  875. ta = (loa * (skip - dx) + (hia * dx)) / skip;
  876. POV_DISPLAY_PLOT (tx, y+dy, tr, tg, tb, ta);
  877. }
  878. }
  879. thisr[x] = Red;
  880. thisg[x] = Green;
  881. thisb[x] = Blue;
  882. thisa[x] = Alpha;
  883. lastr = Red;
  884. lastg = Green;
  885. lastb = Blue;
  886. lasta = Alpha;
  887. }
  888. else
  889. {
  890. y2 = min(y + skip - 1, opts.Last_Line - 1);
  891. x2 = min(x + skip - 1, opts.Last_Column - 1);
  892. POV_DISPLAY_PLOT_RECT(x, y, x2, y2, Red, Green, Blue, Alpha);
  893. }
  894. }
  895. } /* end loop for each block horizontally in a row of blocks */
  896. /* Swap the previous and current row buffers */
  897. if (opts.Options & DISPLAY)
  898. {
  899. unsigned char * temp;
  900. temp = upr;
  901. upr = thisr;
  902. thisr = temp;
  903. temp = upg;
  904. upg = thisg;
  905. thisg = temp;
  906. temp = upb;
  907. upb = thisb;
  908. thisb = temp;
  909. temp = upa;
  910. upa = thisa;
  911. thisa = temp;
  912. }
  913. if (opts.Options & VERBOSE)
  914. {
  915. if (opts.Options & RADIOSITY)
  916. {
  917. Status_Info(" %ld radiosity samples", ra_gather_count - RadiosityCount);
  918. }
  919. Status_Info(". \r");
  920. }
  921. } /* end loop of rows of blocks */
  922. /*
  923. * This adjusts the overall brightness value so that the darkening
  924. * effect of the radiosity calculation is cancelled out.
  925. */
  926. if (first_pass)
  927. {
  928. /* Ensure that the average ambient value returned by compute_ambient() is about
  929. * the same as the average ambient value setting in the scene file
  930. */
  931. if ( Radiosity_Gather_Total_Count )
  932. {
  933. VInverseScale(avg_gather, Radiosity_Gather_Total, (DBL)Radiosity_Gather_Total_Count);
  934. gather_grey = avg_gather[RED] + avg_gather[GREEN] + avg_gather[BLUE];
  935. if ( gather_grey > 0. )
  936. {
  937. opts.Radiosity_Brightness = 3. / gather_grey;
  938. if ( ot_fd != NULL)
  939. {
  940. fprintf(ot_fd, "B%g\n", opts.Radiosity_Brightness);
  941. }
  942. }
  943. }
  944. first_pass = 0;
  945. }
  946. skip /= 2;
  947. } /* end loop of different resolutions */
  948. /* Free our row buffers */
  949. if (opts.Options & DISPLAY)
  950. {
  951. POV_FREE(upr); upr=NULL;
  952. POV_FREE(upg); upg=NULL;
  953. POV_FREE(upb); upb=NULL;
  954. POV_FREE(upa); upa=NULL;
  955. POV_FREE(thisr); thisr=NULL;
  956. POV_FREE(thisg); thisg=NULL;
  957. POV_FREE(thisb); thisb=NULL;
  958. POV_FREE(thisa); thisa=NULL;
  959. }
  960. opts.Radiosity_Error_Bound /= opts.Radiosity_Low_Error_Factor;
  961. if (opts.Options & VERBOSE)
  962. {
  963. Status_Info(" \r");
  964. }
  965. /* Are we in the process of creating a radiosity cache file? */
  966. if ( ot_fd != NULL )
  967. {
  968. fprintf(ot_fd, "P\n"); /* code meaning that preview pass was completed */
  969. }
  970. opts.Radiosity_Preview_Done = 1;
  971. }
  972. /*****************************************************************************
  973. *
  974. * FUNCTION
  975. *
  976. * Start_Non_Adaptive_Tracing
  977. *
  978. * INPUT
  979. *
  980. * OUTPUT
  981. *
  982. * RETURNS
  983. *
  984. * AUTHOR
  985. *
  986. * POV-Ray Team
  987. *
  988. * DESCRIPTION
  989. *
  990. * Trace pixels by shooting rays at the center of each pixel. If the
  991. * colors between a pixel and its left and/or upper neighbor differ
  992. * too much all or some of the pixel are supersampled using a fixed
  993. * number of rays.
  994. *
  995. * CHANGES
  996. *
  997. * Aug 1994 : Modified to call common extract_colors() fn, Eduard Schwan
  998. *
  999. * Sep 1994 : Added code for vista buffer. [DB]
  1000. *
  1001. * Aug 1995 : Added Field Rendering for NTSC/PAL Animations, Jeff Bowermaster
  1002. *
  1003. * Aug 1995 : Added code to jitter pixel location. [DB]
  1004. *
  1005. ******************************************************************************/
  1006. void Start_Non_Adaptive_Tracing()
  1007. {
  1008. int x, y;
  1009. int antialias_line = TRUE;
  1010. int skip_lines;
  1011. int first_line;
  1012. int skip_odd_lines;
  1013. /* Set jitterscale. */
  1014. JitterScale = opts.JitterScale / (DBL)opts.AntialiasDepth;
  1015. /* Odd/even line tracing depends on the frame number. */
  1016. skip_odd_lines = !((opts.FrameSeq.FrameNumber % 2) ^ opts.FrameSeq.Odd_Field_Flag);
  1017. /* Field rendering starts on an odd or even line. */
  1018. skip_lines = (opts.FrameSeq.Field_Render_Flag) && !(opts.Options & ANTIALIAS);
  1019. /* Get first line number. */
  1020. first_line = (opts.Options & ANTIALIAS)?opts.First_Line-1:opts.First_Line;
  1021. /* Loop over all rows. */
  1022. for (y = first_line; y < opts.Last_Line; y++)
  1023. {
  1024. /* Skip odd or even lines depending on the line number. */
  1025. if ((skip_lines) && ((y % 2) == skip_odd_lines))
  1026. {
  1027. /* Write previous line again. */
  1028. if ((opts.Options & DISKWRITE) && (y > opts.First_Line))
  1029. {
  1030. Write_Line(Output_File_Handle, Previous_Line, y);
  1031. }
  1032. POV_WRITE_LINE (Previous_Line, y)
  1033. continue;
  1034. }
  1035. check_stats(y, 0, 1);
  1036. /* Prune vista tree. */
  1037. Prune_Vista_Tree(y);
  1038. /* Precalculate whether to antialias a line. */
  1039. if (opts.FrameSeq.Field_Render_Flag)
  1040. {
  1041. if (y >= opts.First_Line)
  1042. {
  1043. antialias_line = ((y % 2) ^ skip_odd_lines);
  1044. }
  1045. else
  1046. {
  1047. antialias_line = FALSE;
  1048. }
  1049. }
  1050. /* Loop over all columns. */
  1051. for (x = opts.First_Column; x < opts.Last_Column; x++)
  1052. {
  1053. /* Check for user abort. */
  1054. Check_User_Abort(FALSE);
  1055. /* Trace current pixel. */
  1056. /*
  1057. Debug_Info("y = %3d, x = %3d\n", y, x);
  1058. */
  1059. trace_pixel(x, y, Current_Line[x]);
  1060. /* Apply anti-aliasing. */
  1061. if ((opts.Options & ANTIALIAS) && antialias_line)
  1062. {
  1063. do_anti_aliasing(x, y, Current_Line[x]);
  1064. }
  1065. /* Display pixel. */
  1066. plot_pixel(x, y, Current_Line[x]);
  1067. POV_ASSIGN_PIXEL (x, y, Current_Line [x])
  1068. }
  1069. /* Write current row to disk. */
  1070. output_line(y);
  1071. }
  1072. /* Write last row to disk. */
  1073. if (opts.Last_Line != opts.First_Line)
  1074. {
  1075. if (opts.Options & DISKWRITE)
  1076. {
  1077. Write_Line(Output_File_Handle, Previous_Line, opts.Last_Line - 1);
  1078. }
  1079. POV_WRITE_LINE (Previous_Line, opts.Last_Line - 1)
  1080. }
  1081. }
  1082. /*****************************************************************************
  1083. *
  1084. * FUNCTION
  1085. *
  1086. * Start_Adaptive_Tracing
  1087. *
  1088. * INPUT
  1089. *
  1090. * OUTPUT
  1091. *
  1092. * RETURNS
  1093. *
  1094. * AUTHOR
  1095. *
  1096. * Dieter Bayer
  1097. *
  1098. * DESCRIPTION
  1099. *
  1100. * Trace pixels by shooting rays at each corner of a pixel and subdividing
  1101. * if the colors ate the pixel's corenr differ too much. The subdivision
  1102. * is made recursively by further subdividing those sub-pixels whose colors
  1103. * differ too much.
  1104. *
  1105. * Note that is doesn't make any sense to skip line during field tracing
  1106. * because samples are taken at the corners of the pixels and are shared
  1107. * among adjacent lines/pixels. Thus leaving every second line doesn't
  1108. * save anything. The subdivision is only done on the odd/even lines
  1109. * depending on the lines to be traced.
  1110. *
  1111. * CHANGES
  1112. *
  1113. * Jul 1995 : Creation
  1114. *
  1115. * Aug 1995 : Added field rendering support. [DB]
  1116. *
  1117. ******************************************************************************/
  1118. void Start_Adaptive_Tracing()
  1119. {
  1120. int x, y, xx, xxx, yy, skip_odd_lines;
  1121. int sub_pixel_size, antialias_line = TRUE;
  1122. size_t size;
  1123. COLOUR Colour;
  1124. PIXEL *First_Row, *Last_Row, **Block, *TempRow, TempPixel;
  1125. /* If no antialiasing is specified use non-adaptive sampling. */
  1126. if (!(opts.Options & ANTIALIAS))
  1127. {
  1128. Start_Non_Adaptive_Tracing();
  1129. return;
  1130. }
  1131. /* Init color. */
  1132. Make_ColourA(Colour, 0.0, 0.0, 0.0, 0.0, 0.0);
  1133. /* Odd/even line tracing depends on the frame number. */
  1134. skip_odd_lines = !((opts.FrameSeq.FrameNumber % 2) ^ opts.FrameSeq.Odd_Field_Flag);
  1135. /* Set sub-pixel size to 2**(AntialiasDepth) */
  1136. sub_pixel_size = 1 << (opts.AntialiasDepth);
  1137. /* Set jitterscale. */
  1138. JitterScale = opts.JitterScale / (DBL)(sub_pixel_size+1);
  1139. /* Allocate row arrays */
  1140. size = (sub_pixel_size * Frame.Screen_Width + 1) * sizeof(PIXEL);
  1141. First_Row = (PIXEL *)POV_MALLOC(size, "row buffer");
  1142. Last_Row = (PIXEL *)POV_MALLOC(size, "row buffer");
  1143. /* Allocate block array */
  1144. Block = (PIXEL **)POV_MALLOC((sub_pixel_size+1) * sizeof(PIXEL *), "block buffer");
  1145. for (y = 0; y < sub_pixel_size + 1; y++)
  1146. {
  1147. Block[y] = (PIXEL *)POV_MALLOC((sub_pixel_size+1) * sizeof(PIXEL), "block buffer");
  1148. }
  1149. /**************************************************************************
  1150. * Init row and block buffer
  1151. **************************************************************************/
  1152. for (x = 0; x < sub_pixel_size * Frame.Screen_Width + 1; x++)
  1153. {
  1154. First_Row[x].active = FALSE;
  1155. Last_Row[x].active = FALSE;
  1156. Make_ColourA(First_Row[x].Colour, 0.0, 0.0, 0.0, 0.0, 0.0);
  1157. Make_ColourA(Last_Row[x].Colour, 0.0, 0.0, 0.0, 0.0, 0.0);
  1158. }
  1159. for (y = 0; y < sub_pixel_size + 1; y++)
  1160. {
  1161. for (x = 0; x < sub_pixel_size + 1; x++)
  1162. {
  1163. Block[y][x].active = FALSE;
  1164. Make_ColourA(Block[y][x].Colour, 0.0, 0.0, 0.0, 0.0, 0.0);
  1165. }
  1166. }
  1167. /**************************************************************************
  1168. * Trace all lines, i.e. the image
  1169. **************************************************************************/
  1170. for (y = opts.First_Line; y < opts.Last_Line; y++)
  1171. {
  1172. check_stats(y, 0, 1);
  1173. if (opts.Options & USE_VISTA_BUFFER)
  1174. {
  1175. Prune_Vista_Tree(y);
  1176. }
  1177. /* Set last row inactive */
  1178. for (xx = 0; xx < sub_pixel_size * Frame.Screen_Width + 1; xx++)
  1179. {
  1180. Last_Row[xx].active = FALSE;
  1181. }
  1182. /* Set first column inactive */
  1183. for (yy = 0; yy < sub_pixel_size + 1; yy++)
  1184. {
  1185. Block[yy][0].active = FALSE;
  1186. }
  1187. /* Precalculate whether to antialias a line. */
  1188. if (opts.FrameSeq.Field_Render_Flag)
  1189. {
  1190. antialias_line = (y % 2) ^ skip_odd_lines;
  1191. }
  1192. /************************************************************************
  1193. * Trace all pixels on the current line
  1194. ************************************************************************/
  1195. for (x = opts.First_Column; x < opts.Last_Column; x++)
  1196. {
  1197. Check_User_Abort(FALSE);
  1198. Increase_Counter(stats[Number_Of_Pixels]);
  1199. /* Initialize current block */
  1200. for (yy = 1; yy < sub_pixel_size + 1; yy++)
  1201. {
  1202. for (xx = 1; xx < sub_pixel_size + 1; xx++)
  1203. {
  1204. Block[yy][xx].active = FALSE;
  1205. }
  1206. }
  1207. for (xxx = 0, xx = x * sub_pixel_size; xx < (x+1) * sub_pixel_size + 1; xxx++, xx++)
  1208. {
  1209. Block[0][xxx] = First_Row[xx];
  1210. }
  1211. /* Do histogram stuff. */
  1212. if (opts.histogram_on)
  1213. {
  1214. accumulate_histogram(x, y, TRUE);
  1215. }
  1216. /* Trace pixel centered on (x, y) */
  1217. POV_PRE_PIXEL (x, y, Colour)
  1218. trace_sub_pixel(1, Block, x, y, 0, 0, sub_pixel_size, sub_pixel_size, sub_pixel_size, Colour, antialias_line);
  1219. POV_POST_PIXEL (x, y, Colour)
  1220. /* Do histogram stuff. */
  1221. if (opts.histogram_on)
  1222. {
  1223. accumulate_histogram(x, y, FALSE);
  1224. }
  1225. /* Store colour in current line */
  1226. Assign_Colour(Current_Line[x], Colour);
  1227. POV_ASSIGN_PIXEL (x, y, Colour)
  1228. /* Display pixel */
  1229. plot_pixel(x, y, Colour);
  1230. /* Store current block in rows */
  1231. for (xxx = 0, xx = x * sub_pixel_size; xx < (x+1) * sub_pixel_size + 1; xxx++, xx++)
  1232. {
  1233. First_Row[xx] = Block[0][xxx];
  1234. Last_Row[xx] = Block[sub_pixel_size][xxx];
  1235. }
  1236. /* Swap first and last block column */
  1237. for (yy = 0; yy < sub_pixel_size + 1; yy++)
  1238. {
  1239. TempPixel = Block[yy][0];
  1240. Block[yy][0] = Block[yy][sub_pixel_size];
  1241. Block[yy][sub_pixel_size] = TempPixel;
  1242. }
  1243. }
  1244. output_line(y);
  1245. /* Swap first and last row */
  1246. TempRow = Last_Row;
  1247. Last_Row = First_Row;
  1248. First_Row = TempRow;
  1249. }
  1250. /* We've come to the end ... at last! */
  1251. if (opts.Last_Line != opts.First_Line)
  1252. {
  1253. if (opts.Options & DISKWRITE)
  1254. {
  1255. Write_Line (Output_File_Handle, Previous_Line, opts.Last_Line - 1);
  1256. }
  1257. POV_WRITE_LINE (Previous_Line, opts.Last_Line - 1)
  1258. }
  1259. /* Free memory. */
  1260. for (y = 0; y < sub_pixel_size + 1; y++)
  1261. {
  1262. POV_FREE(Block[y]);
  1263. }
  1264. POV_FREE(Block);
  1265. POV_FREE(First_Row);
  1266. POV_FREE(Last_Row);
  1267. }
  1268. /*****************************************************************************
  1269. *
  1270. * FUNCTION
  1271. *
  1272. * Trace
  1273. *
  1274. * INPUT
  1275. *
  1276. * OUTPUT
  1277. *
  1278. * RETURNS
  1279. *
  1280. * distance to nearest intersection, or BOUND_HUGE on miss
  1281. *
  1282. * AUTHOR
  1283. *
  1284. * POV-Ray Team
  1285. *
  1286. * DESCRIPTION
  1287. *
  1288. * -
  1289. *
  1290. * CHANGES
  1291. *
  1292. * Nov 1994 : Rearranged calls to Fog, Rainbow and Skyblend.
  1293. * Added call to Atmosphere for atmospheric effects. [DB]
  1294. * Jan 1995 : Set intersection depth to Max_Distance for infinite rays. [DB]
  1295. * Mar 1995 : Added return value for radiosity work [JDM]
  1296. * Jul 1995 : Added code to support alpha channel. [DB]
  1297. *
  1298. ******************************************************************************/
  1299. DBL Trace(RAY *Ray, COLOUR Colour, DBL Weight)
  1300. {
  1301. int i, Intersection_Found, all_hollow;
  1302. OBJECT *Object;
  1303. INTERSECTION Best_Intersection, New_Intersection;
  1304. COOPERATE_0
  1305. Increase_Counter(stats[Number_Of_Rays]);
  1306. /* Transmittance has to be 1 to make alpha channel output to work. [DB] */
  1307. Make_ColourA(Colour, 0.0, 0.0, 0.0, 0.0, 1.0);
  1308. /* Check for max. trace level or ADC bailout. */
  1309. if ((Trace_Level > Max_Trace_Level) || (Weight < ADC_Bailout))
  1310. {
  1311. if (Weight < ADC_Bailout)
  1312. {
  1313. Increase_Counter(stats[ADC_Saves]);
  1314. }
  1315. return (BOUND_HUGE);
  1316. }
  1317. /* Set highest level traced. */
  1318. if (Trace_Level > Highest_Trace_Level)
  1319. {
  1320. Highest_Trace_Level = Trace_Level;
  1321. }
  1322. /* What objects does this ray intersect? */
  1323. Intersection_Found = FALSE;
  1324. Best_Intersection.Depth = BOUND_HUGE;
  1325. if (!opts.Use_Slabs)
  1326. {
  1327. for (Object = Frame.Objects; Object != NULL; Object = Object -> Sibling)
  1328. {
  1329. if (Intersection(&New_Intersection, Object, Ray))
  1330. {
  1331. if (New_Intersection.Depth < Best_Intersection.Depth)
  1332. {
  1333. Best_Intersection = New_Intersection;
  1334. Intersection_Found = TRUE;
  1335. }
  1336. }
  1337. }
  1338. }
  1339. else
  1340. {
  1341. Intersection_Found = Intersect_BBox_Tree(Root_Object, Ray,
  1342. &Best_Intersection, &Object);
  1343. }
  1344. /* Get color for this ray. */
  1345. if (Intersection_Found)
  1346. {
  1347. /* Determine colour of object hit. */
  1348. Determine_Apparent_Colour(&Best_Intersection, Colour, Ray, Weight);
  1349. }
  1350. else
  1351. {
  1352. /* Infinite ray, set intersecton distance. */
  1353. Best_Intersection.Depth = Max_Distance;
  1354. /* Apply infinite atmospheric effects. */
  1355. Do_Infinite_Atmosphere(Ray, Colour);
  1356. }
  1357. /* Test if all contained objects are hollow. */
  1358. all_hollow = TRUE;
  1359. if (Ray->Index > -1)
  1360. {
  1361. for (i = 0; i <= Ray->Index; i++)
  1362. {
  1363. if (!Ray->Interiors[i]->hollow)
  1364. {
  1365. all_hollow = FALSE;
  1366. break;
  1367. }
  1368. }
  1369. }
  1370. /* Apply finite atmospheric effects. */
  1371. if (all_hollow && (opts.Quality_Flags & Q_VOLUME))
  1372. {
  1373. Do_Finite_Atmosphere(Ray, &Best_Intersection, Colour, FALSE);
  1374. }
  1375. return (Best_Intersection.Depth);
  1376. }
  1377. /*****************************************************************************
  1378. *
  1379. * FUNCTION
  1380. *
  1381. * do_anti_aliasing
  1382. *
  1383. * INPUT
  1384. *
  1385. * OUTPUT
  1386. *
  1387. * RETURNS
  1388. *
  1389. * AUTHOR
  1390. *
  1391. * POV-Ray Team
  1392. *
  1393. * DESCRIPTION
  1394. *
  1395. * -
  1396. *
  1397. * CHANGES
  1398. *
  1399. * Aug 1995 : Modified to avoid unnecessary pixel output. [DB]
  1400. *
  1401. * Aug 1995 : Modified to avoid supersampling of unused lines
  1402. * when using field tracing. [DB]
  1403. *
  1404. ******************************************************************************/
  1405. static void do_anti_aliasing(register int x, register int y, COLOUR Colour)
  1406. {
  1407. char Antialias_Center_Flag = FALSE;
  1408. Current_Line_Antialiased_Flags[x] = FALSE;
  1409. /* Test difference to pixel left of current pixel. */
  1410. if (x != 0)
  1411. {
  1412. if (Colour_Distance(Current_Line[x-1],Current_Line[x]) >= Frame.Antialias_Threshold)
  1413. {
  1414. Antialias_Center_Flag = TRUE;
  1415. if (!(Current_Line_Antialiased_Flags[x-1]))
  1416. {
  1417. supersample(Current_Line[x-1], x-1, y);
  1418. Current_Line_Antialiased_Flags[x-1] = TRUE;
  1419. SuperSampleCount++;
  1420. plot_pixel(x-1, y, Current_Line[x-1]);
  1421. COOPERATE_1
  1422. }
  1423. }
  1424. }
  1425. /* Test difference to pixel above current pixel. */
  1426. if ((y != opts.First_Line-1) && (!opts.FrameSeq.Field_Render_Flag))
  1427. {
  1428. if (Colour_Distance(Previous_Line[x],Current_Line[x]) >= Frame.Antialias_Threshold)
  1429. {
  1430. Antialias_Center_Flag = TRUE;
  1431. if (!(Previous_Line_Antialiased_Flags[x]))
  1432. {
  1433. supersample(Previous_Line[x], x, y-1);
  1434. Previous_Line_Antialiased_Flags[x] = TRUE;
  1435. SuperSampleCount++;
  1436. plot_pixel(x, y, Previous_Line[x]);
  1437. COOPERATE_1
  1438. }
  1439. }
  1440. }
  1441. /* Supersample current pixel if necessary. */
  1442. if (Antialias_Center_Flag)
  1443. {
  1444. supersample(Current_Line[x], x, y);
  1445. Current_Line_Antialiased_Flags[x] = TRUE;
  1446. Assign_Colour(Colour, Current_Line[x]);
  1447. POV_ASSIGN_PIXEL (x, y, Colour)
  1448. SuperSampleCount++;
  1449. COOPERATE_1
  1450. }
  1451. }
  1452. /*****************************************************************************
  1453. *
  1454. * FUNCTION
  1455. *
  1456. * supersample
  1457. *
  1458. * INPUT
  1459. *
  1460. * OUTPUT
  1461. *
  1462. * RETURNS
  1463. *
  1464. * AUTHOR
  1465. *
  1466. * POV-Ray Team
  1467. *
  1468. * DESCRIPTION
  1469. *
  1470. * Standard sampling in loop
  1471. *
  1472. * CHANGES
  1473. *
  1474. * Aug 1995 : Modified to avoid resampling of center sub-pixel. [DB]
  1475. *
  1476. * Sep 1995 : Weight of a primary ray has to be 1 regardless of its
  1477. * contribution to a supersampled pixel! [DB]
  1478. *
  1479. ******************************************************************************/
  1480. static void supersample(COLOUR result, int x, int y)
  1481. {
  1482. int i, j, samples;
  1483. int JRange, JSteps;
  1484. DBL JSize, JScale;
  1485. DBL Jitter_X, Jitter_Y;
  1486. DBL dx, dy;
  1487. DBL save_radiosity_error_bound;
  1488. COLOUR colour;
  1489. /* Why are we here? */
  1490. if (opts.AntialiasDepth <= 1)
  1491. {
  1492. return;
  1493. }
  1494. Increase_Counter(stats[Number_Of_Pixels_Supersampled]);
  1495. /* Number of samples in pixel (used to scale resulting color). */
  1496. samples = 1;
  1497. /* Substantially reduces chances of doing new samples. */
  1498. save_radiosity_error_bound = opts.Radiosity_Error_Bound;
  1499. opts.Radiosity_Error_Bound *= 2.0;
  1500. /* JSize is the size of the jitter scattering area */
  1501. JSize = 1.0 / opts.AntialiasDepth;
  1502. /*
  1503. * JSteps is either 1 or 2 depending on whether the number of samples
  1504. * is odd or even. This is because the loop need to either run through
  1505. * or over 0.
  1506. */
  1507. JSteps = 2 - (opts.AntialiasDepth % 2);
  1508. /*
  1509. * JRange is the range that the loop will run through. I couldn't
  1510. * come up with a function describing the values, so I used an array
  1511. * for 2x2 up to 9x9.
  1512. */
  1513. JRange = JRanges[opts.AntialiasDepth];
  1514. /*
  1515. * JScale is the value with which the current sub-pixel indices
  1516. * (i,j) have to be scaled to get the real sub-pixel positions.
  1517. */
  1518. JScale = JSize / (DBL)JSteps;
  1519. /* Loop over all sub-pixels. */
  1520. for (i = -JRange; i <= JRange; i += JSteps)
  1521. {
  1522. for (j = -JRange; j <= JRange; j += JSteps)
  1523. {
  1524. /* Skip center sub-pixel because we already traced it. */
  1525. if ((i == 0) && (j == 0))
  1526. {
  1527. continue;
  1528. }
  1529. /* Increase number of samples. */
  1530. samples++;
  1531. /* Jitter grid location. */
  1532. jitter_pixel_position(x, y, &Jitter_X, &Jitter_Y);
  1533. /* Trace ray through current sub-pixel. */
  1534. dx = Jitter_X + i * JScale;
  1535. dy = Jitter_Y + j * JScale;
  1536. if (create_ray(&Camera_Ray, (DBL)x+dx, (DBL)y+dy, 0))
  1537. {
  1538. Trace_Level = 1;
  1539. Increase_Counter(stats[Number_Of_Samples]);
  1540. if (opts.Options & USE_VISTA_BUFFER)
  1541. {
  1542. Trace_Primary_Ray(&Camera_Ray, colour, 1.0, x);
  1543. }
  1544. else
  1545. {
  1546. Trace(&Camera_Ray, colour, 1.0);
  1547. }
  1548. Clip_Colour(colour, colour);
  1549. gamma_correct(colour);
  1550. Add_Colour(result, result, colour);
  1551. }
  1552. else
  1553. {
  1554. Make_ColourA(colour, 0.0, 0.0, 0.0, 0.0, 1.0);
  1555. }
  1556. }
  1557. }
  1558. /* Average pixel's color. */
  1559. Scale_Colour(result, result, 1.0 / (DBL)samples);
  1560. opts.Radiosity_Error_Bound = save_radiosity_error_bound;
  1561. }
  1562. /*****************************************************************************
  1563. *
  1564. * FUNCTION
  1565. *
  1566. * trace_sub_pixel
  1567. *
  1568. * INPUT
  1569. *
  1570. * level - current subdivision level
  1571. * Block - sub-pixel information of current pixel
  1572. * x, y - current pixel
  1573. * x1, y1 - upper left corner of current sub-pixel
  1574. * x3, y3 - lower right corner of current sub-pixel
  1575. * size - sub-pixel size
  1576. * antialias - TRUE if antialiasing is allowed
  1577. *
  1578. * OUTPUT
  1579. *
  1580. * Colour - (sub-)pixels color
  1581. *
  1582. * RETURNS
  1583. *
  1584. * AUTHOR
  1585. *
  1586. * Dieter Bayer
  1587. *
  1588. * DESCRIPTION
  1589. *
  1590. * Trace rays at the corners of the (sub-)pixel. If the colors differ
  1591. * too much and the max. recursion level isn't reached yet subdivide
  1592. * pixel into four sub-pixel and trace those.
  1593. *
  1594. * CHANGES
  1595. *
  1596. * Jul 1995 : Creation.
  1597. *
  1598. ******************************************************************************/
  1599. static void trace_sub_pixel(int level, PIXEL **Block, int x, int y, int x1, int y1, int x3, int y3, int size, COLOUR Colour, int antialias)
  1600. {
  1601. int x2, y2; /* Coordinates of center sub-pixel of current block. */
  1602. DBL dx1, dy1; /* coord. of upper left corner relative to pixel coord. */
  1603. DBL dx3, dy3; /* coord. of lower right corner relative to pixel coord. */
  1604. COLOUR C1, C2, C3, C4;
  1605. /* Get offsets for corner pixels. */
  1606. dx1 = (DBL)(x1 - size / 2) / (DBL)size;
  1607. dx3 = (DBL)(x3 - size / 2) / (DBL)size;
  1608. dy1 = (DBL)(y1 - size / 2) / (DBL)size;
  1609. dy3 = (DBL)(y3 - size / 2) / (DBL)size;
  1610. /* Trace upper left corner pixel. */
  1611. if (!Block[y1][x1].active)
  1612. {
  1613. trace_ray_with_offset(x, y, dx1, dy1, C1);
  1614. Block[y1][x1].active = TRUE;
  1615. Assign_Colour(Block[y1][x1].Colour, C1);
  1616. }
  1617. else
  1618. {
  1619. Assign_Colour(C1, Block[y1][x1].Colour);
  1620. }
  1621. /* Trace lower left corner pixel. */
  1622. if (!Block[y3][x1].active)
  1623. {
  1624. trace_ray_with_offset(x, y, dx1, dy3, C2);
  1625. Block[y3][x1].active = TRUE;
  1626. Assign_Colour(Block[y3][x1].Colour, C2);
  1627. }
  1628. else
  1629. {
  1630. Assign_Colour(C2, Block[y3][x1].Colour);
  1631. }
  1632. /* Trace upper right corner pixel. */
  1633. if (!Block[y1][x3].active)
  1634. {
  1635. trace_ray_with_offset(x, y, dx3, dy1, C3);
  1636. Block[y1][x3].active = TRUE;
  1637. Assign_Colour(Block[y1][x3].Colour, C3);
  1638. }
  1639. else
  1640. {
  1641. Assign_Colour(C3, Block[y1][x3].Colour);
  1642. }
  1643. /* Trace lower right corner pixel. */
  1644. if (!Block[y3][x3].active)
  1645. {
  1646. trace_ray_with_offset(x, y, dx3, dy3, C4);
  1647. Block[y3][x3].active = TRUE;
  1648. Assign_Colour(Block[y3][x3].Colour, C4);
  1649. }
  1650. else
  1651. {
  1652. Assign_Colour(C4, Block[y3][x3].Colour);
  1653. }
  1654. /* Do we have to check for supersampling? */
  1655. if (antialias && (level <= opts.AntialiasDepth))
  1656. {
  1657. /* Check if upper left sub-block should be supersampled. */
  1658. if ((Colour_Distance(C1, C2) >= Frame.Antialias_Threshold) ||
  1659. (Colour_Distance(C2, C4) >= Frame.Antialias_Threshold) ||
  1660. (Colour_Distance(C3, C4) >= Frame.Antialias_Threshold) ||
  1661. (Colour_Distance(C1, C3) >= Frame.Antialias_Threshold) ||
  1662. (Colour_Distance(C1, C4) >= Frame.Antialias_Threshold) ||
  1663. (Colour_Distance(C2, C3) >= Frame.Antialias_Threshold))
  1664. {
  1665. /* Get coordinates of center sub-pixel. */
  1666. x2 = (x1 + x3) / 2;
  1667. y2 = (y1 + y3) / 2;
  1668. /* Trace the four sub-blocks. */
  1669. trace_sub_pixel(level+1, Block, x, y, x1, y1, x2, y2, size, C1, antialias);
  1670. trace_sub_pixel(level+1, Block, x, y, x1, y2, x2, y3, size, C2, antialias);
  1671. trace_sub_pixel(level+1, Block, x, y, x2, y1, x3, y2, size, C3, antialias);
  1672. trace_sub_pixel(level+1, Block, x, y, x2, y2, x3, y3, size, C4, antialias);
  1673. if (level == 1)
  1674. {
  1675. SuperSampleCount++;
  1676. }
  1677. }
  1678. }
  1679. /* Average sub-block colors. */
  1680. Colour[RED] = 0.25 * (C1[RED] + C2[RED] + C3[RED] + C4[RED]);
  1681. Colour[GREEN] = 0.25 * (C1[GREEN] + C2[GREEN] + C3[GREEN] + C4[GREEN]);
  1682. Colour[BLUE] = 0.25 * (C1[BLUE] + C2[BLUE] + C3[BLUE] + C4[BLUE]);
  1683. Colour[TRANSM] = 0.25 * (C1[TRANSM] + C2[TRANSM] + C3[TRANSM] + C4[TRANSM]);
  1684. }
  1685. /*****************************************************************************
  1686. *
  1687. * FUNCTION
  1688. *
  1689. * trace_ray_with_offset
  1690. *
  1691. * INPUT
  1692. *
  1693. * OUTPUT
  1694. *
  1695. * RETURNS
  1696. *
  1697. * AUTHOR
  1698. *
  1699. * Dieter Bayer
  1700. *
  1701. * DESCRIPTION
  1702. *
  1703. * Trace a ray through the pixel at (x,y) with an offset (dx,dy)
  1704. *
  1705. * CHANGES
  1706. *
  1707. * May 1994 : Creation.
  1708. *
  1709. * Sep 1995 : Weight of a primary ray has to be 1 regardless of its
  1710. * contribution to a supersampled pixel! [DB]
  1711. *
  1712. ******************************************************************************/
  1713. static void trace_ray_with_offset(int x, int y, DBL dx, DBL dy, COLOUR Colour)
  1714. {
  1715. DBL Jitter_X, Jitter_Y;
  1716. if (Focal_Blur_Is_Used)
  1717. {
  1718. focal_blur(&Camera_Ray, Colour, (DBL)x, (DBL)y);
  1719. }
  1720. else
  1721. {
  1722. /* Jitter the ray */
  1723. if (opts.Options & ANTIALIAS)
  1724. {
  1725. jitter_pixel_position(x, y, &Jitter_X, &Jitter_Y);
  1726. }
  1727. else
  1728. {
  1729. Jitter_X = Jitter_Y = 0.0;
  1730. }
  1731. if (create_ray (&Camera_Ray, (DBL)x+dx+Jitter_X, (DBL)y+dy+Jitter_Y, 0))
  1732. {
  1733. Trace_Level = 1;
  1734. Increase_Counter(stats[Number_Of_Samples]);
  1735. if (opts.Options & USE_VISTA_BUFFER)
  1736. {
  1737. Trace_Primary_Ray(&Camera_Ray, Colour, 1.0, x);
  1738. }
  1739. else
  1740. {
  1741. Trace(&Camera_Ray, Colour, 1.0);
  1742. }
  1743. Clip_Colour(Colour, Colour);
  1744. gamma_correct(Colour);
  1745. }
  1746. else
  1747. {
  1748. Make_ColourA(Colour, 0.0, 0.0, 0.0, 0.0, 1.0);
  1749. }
  1750. }
  1751. }
  1752. /*****************************************************************************
  1753. *
  1754. * FUNCTION
  1755. *
  1756. * focal_blur
  1757. *
  1758. * INPUT
  1759. *
  1760. * OUTPUT
  1761. *
  1762. * RETURNS
  1763. *
  1764. * AUTHOR
  1765. *
  1766. * POV-Ray Team
  1767. *
  1768. * DESCRIPTION
  1769. *
  1770. * Calls create_ray(), which calls jitter_camera_ray() to apply the
  1771. * correct amount of jitter to the ray. This routine merely sends out
  1772. * the correct number of rays and averages them into Colour.
  1773. *
  1774. * CHANGES
  1775. *
  1776. * Jul 1995 : Added code to use a different sub-pixel location for
  1777. * each sample. Added code to do a statistic confident
  1778. * test to make early exists possible. [DB]
  1779. *
  1780. ******************************************************************************/
  1781. static void focal_blur(RAY *Ray, COLOUR Colour, DBL x, DBL y)
  1782. {
  1783. int nr; /* Number of current samples. */
  1784. int level; /* Index into number of samples list. */
  1785. int max_s; /* Number of samples to take before next confidence test. */
  1786. int dxi, dyi;
  1787. int i;
  1788. DBL dx, dy, n;
  1789. COLOUR C, V1, S1, S2;
  1790. Make_ColourA(Colour, 0.0, 0.0, 0.0, 0.0, 0.0);
  1791. Make_ColourA(V1, 0.0, 0.0, 0.0, 0.0, 0.0);
  1792. Make_ColourA(S1, 0.0, 0.0, 0.0, 0.0, 0.0);
  1793. Make_ColourA(S2, 0.0, 0.0, 0.0, 0.0, 0.0);
  1794. nr = 0;
  1795. level = 0;
  1796. do
  1797. {
  1798. /* Trace number of rays given by the list Current_Number_Of_Samples[]. */
  1799. max_s = 4;
  1800. if (Current_Number_Of_Samples != NULL)
  1801. {
  1802. if (Current_Number_Of_Samples[level] > 0)
  1803. {
  1804. max_s = Current_Number_Of_Samples[level];
  1805. level++;
  1806. }
  1807. }
  1808. for (i = 0; (i < max_s) && (nr < Frame.Camera->Blur_Samples); i++)
  1809. {
  1810. /* Choose sub-pixel location. */
  1811. dxi = POV_RAND() % SUB_PIXEL_GRID_SIZE;
  1812. dyi = POV_RAND() % SUB_PIXEL_GRID_SIZE;
  1813. dx = (DBL)(2 * dxi + 1) / (DBL)(2 * SUB_PIXEL_GRID_SIZE) - 0.5;
  1814. dy = (DBL)(2 * dyi + 1) / (DBL)(2 * SUB_PIXEL_GRID_SIZE) - 0.5;
  1815. /* Add jitter to sub-pixel location. */
  1816. dx += (FRAND() - 0.5) / (DBL)(SUB_PIXEL_GRID_SIZE);
  1817. dy += (FRAND() - 0.5) / (DBL)(SUB_PIXEL_GRID_SIZE);
  1818. /* Create and trace ray. */
  1819. if (create_ray(Ray, x+dx, y+dy, nr))
  1820. {
  1821. Trace_Level = 1;
  1822. Increase_Counter(stats[Number_Of_Samples]);
  1823. Trace(Ray, C, 1.0);
  1824. Clip_Colour(C, C);
  1825. Add_Colour(Colour, Colour, C);
  1826. }
  1827. else
  1828. {
  1829. Make_ColourA(C, 0.0, 0.0, 0.0, 0.0, 1.0);
  1830. }
  1831. /* Add color to color sum. */
  1832. S1[RED] += C[RED];
  1833. S1[GREEN] += C[GREEN];
  1834. S1[BLUE] += C[BLUE];
  1835. S1[TRANSM] += C[TRANSM];
  1836. /* Add color to squared color sum. */
  1837. S2[RED] += Sqr(C[RED]);
  1838. S2[GREEN] += Sqr(C[GREEN]);
  1839. S2[BLUE] += Sqr(C[BLUE]);
  1840. S2[TRANSM] += Sqr(C[TRANSM]);
  1841. nr++;
  1842. }
  1843. /* Get variance of samples. */
  1844. n = (DBL)nr;
  1845. V1[RED] = (S2[RED] / n - Sqr(S1[RED] / n)) / n;
  1846. V1[GREEN] = (S2[GREEN] / n - Sqr(S1[GREEN] / n)) / n;
  1847. V1[BLUE] = (S2[BLUE] / n - Sqr(S1[BLUE] / n)) / n;
  1848. V1[TRANSM] = (S2[TRANSM] / n - Sqr(S1[TRANSM] / n)) / n;
  1849. /* Exit if samples are likely too be good enough. */
  1850. if ((V1[RED] < Sample_Threshold[nr-1]) && (V1[GREEN] < Sample_Threshold[nr-1]) &&
  1851. (V1[BLUE] < Sample_Threshold[nr-1]) && (V1[TRANSM] < Sample_Threshold[nr-1]))
  1852. {
  1853. break;
  1854. }
  1855. }
  1856. while (nr < Frame.Camera->Blur_Samples);
  1857. Scale_Colour(Colour, Colour, 1.0 / (DBL)nr);
  1858. gamma_correct(Colour);
  1859. }
  1860. /*****************************************************************************
  1861. *
  1862. * FUNCTION
  1863. *
  1864. * jitter_camera_ray
  1865. *
  1866. * INPUT
  1867. *
  1868. * OUTPUT
  1869. *
  1870. * RETURNS
  1871. *
  1872. * AUTHOR
  1873. *
  1874. * POV-Ray Team
  1875. *
  1876. * DESCRIPTION
  1877. *
  1878. * This routine will deflect eye rays only, since it relies on picking
  1879. * up viewpoint information from the "Frame" variable.
  1880. *
  1881. * A hexagonal jitter grid is used if number of blur rays is one of
  1882. * 7, 19, or 37, although this should probably be done differently.
  1883. *
  1884. * CHANGES
  1885. *
  1886. * -
  1887. *
  1888. ******************************************************************************/
  1889. static void jitter_camera_ray(RAY *ray, int ray_number)
  1890. {
  1891. DBL xjit, yjit, xlen, ylen, r;
  1892. VECTOR temp_xperp, temp_yperp, deflection;
  1893. r = Frame.Camera->Aperture * 0.5;
  1894. xjit = Max_Jitter * ((FRAND() * 2.0) - 1.0);
  1895. yjit = Max_Jitter * ((FRAND() * 2.0) - 1.0);
  1896. xlen = r * (Sample_Grid[ray_number].x + xjit);
  1897. ylen = r * (Sample_Grid[ray_number].y + yjit);
  1898. /*
  1899. * Deflect the position of the eye by the size of the aperture, and in
  1900. * a direction perpendicular to the current direction of view.
  1901. */
  1902. VScale(temp_xperp, XPerp, xlen);
  1903. VScale(temp_yperp, YPerp, ylen);
  1904. VSub(deflection, temp_xperp, temp_yperp);
  1905. VAdd(ray->Initial, Frame.Camera->Location, deflection);
  1906. /*
  1907. * Deflect the direction of the ray in the opposite direction we deflected
  1908. * the eye position. This makes sure that we are looking at the same place
  1909. * when the distance from the eye is equal to "Focal_Distance".
  1910. */
  1911. VScale(ray->Direction, ray->Direction, Focal_Distance);
  1912. VSub(ray->Direction, ray->Direction, deflection);
  1913. VNormalize(ray->Direction, ray->Direction);
  1914. }
  1915. /*****************************************************************************
  1916. *
  1917. * FUNCTION
  1918. *
  1919. * trace_pixel
  1920. *
  1921. * INPUT
  1922. *
  1923. * OUTPUT
  1924. *
  1925. * RETURNS
  1926. *
  1927. * AUTHOR
  1928. *
  1929. * POV-Ray Team
  1930. *
  1931. * DESCRIPTION
  1932. *
  1933. * Trace a primary ray regarding focal blur and vista buffer.
  1934. * The color of the pixel is clipped and the number of pixels is increased.
  1935. *
  1936. * CHANGES
  1937. *
  1938. * Sep 1994 : Extracted common code. [DB]
  1939. * Jan 1995 : Added call to accumulate_histogram() - Chris Cason
  1940. *
  1941. ******************************************************************************/
  1942. static void trace_pixel(int x, int y, COLOUR Colour)
  1943. {
  1944. Increase_Counter(stats[Number_Of_Pixels]);
  1945. Trace_Level = 1;
  1946. POV_PRE_PIXEL (x, y, Colour)
  1947. COOPERATE_0
  1948. /* Do histogram stuff. */
  1949. if (opts.histogram_on)
  1950. {
  1951. accumulate_histogram(x, y, TRUE);
  1952. }
  1953. if (Focal_Blur_Is_Used)
  1954. {
  1955. /* Use focal blur tracing. */
  1956. focal_blur(&Camera_Ray, Colour, (DBL)x, (DBL)y);
  1957. }
  1958. else
  1959. {
  1960. /* Create and trace ray. */
  1961. if (create_ray(&Camera_Ray, (DBL)x, (DBL)y, 0))
  1962. {
  1963. Increase_Counter(stats[Number_Of_Samples]);
  1964. if (opts.Options & USE_VISTA_BUFFER)
  1965. {
  1966. Trace_Primary_Ray(&Camera_Ray, Colour, 1.0, x);
  1967. }
  1968. else
  1969. {
  1970. Trace(&Camera_Ray, Colour, 1.0);
  1971. }
  1972. }
  1973. else
  1974. {
  1975. Make_ColourA(Colour, 0.0, 0.0, 0.0, 0.0, 1.0);
  1976. }
  1977. }
  1978. Clip_Colour(Colour, Colour);
  1979. gamma_correct(Colour);
  1980. /* Do histogram stuff. */
  1981. if (opts.histogram_on)
  1982. {
  1983. accumulate_histogram(x, y, FALSE);
  1984. }
  1985. POV_POST_PIXEL (x, y, Colour)
  1986. }
  1987. /*****************************************************************************
  1988. *
  1989. * FUNCTION
  1990. *
  1991. * create_ray
  1992. *
  1993. * INPUT
  1994. *
  1995. * ray - Primary ray for given screen point
  1996. * x, y - Coordinates of current pixel
  1997. * ray_number - number of ray used by jitter_camera_ray()
  1998. *
  1999. * OUTPUT
  2000. *
  2001. * ray
  2002. *
  2003. * RETURNS
  2004. *
  2005. * int - TRUE, if a ray was created
  2006. *
  2007. * AUTHOR
  2008. *
  2009. * Dieter Bayer
  2010. * Dan Farmer (focal blur, 'ultra wide angle camera')
  2011. *
  2012. * DESCRIPTION
  2013. *
  2014. * Create a primary ray depending on the camera model used.
  2015. *
  2016. * Ideas for the camera models were taken from:
  2017. *
  2018. * Geoff Wyvill and Craig McNaughton, "Optical Models",
  2019. * CG International '90, Springer, 1990, p. 83-93
  2020. *
  2021. * F. Kenton Musgrave, "A panoramic virtual screen for ray tracing",
  2022. * Graphics Gems III, David Kirk (eds.), p. 288-294
  2023. *
  2024. * CHANGES
  2025. *
  2026. * May 1994 : Creation.
  2027. *
  2028. * Aug 1996 : Removed unnecessary width/height parameters. [DB]
  2029. *
  2030. ******************************************************************************/
  2031. static int create_ray(RAY *Ray, DBL x, DBL y, int ray_number)
  2032. {
  2033. /* Just some shortcuts. */
  2034. #define FCD Frame.Camera->Direction
  2035. #define FCR Frame.Camera->Right
  2036. #define FCU Frame.Camera->Up
  2037. #define FCL Frame.Camera->Location
  2038. DBL x0 = 0.0, y0 = 0.0;
  2039. DBL cx, sx, cy, sy, ty, rad, phi, lx, ly;
  2040. VECTOR V1;
  2041. /* Create primary ray according to the camera used. */
  2042. Assign_Vector(Ray->Initial, FCL);
  2043. Initialize_Ray_Containers(Ray);
  2044. switch (Frame.Camera->Type)
  2045. {
  2046. /*
  2047. * Perspective projection (Pinhole camera; POV standard).
  2048. */
  2049. case PERSPECTIVE_CAMERA:
  2050. /* Convert the x coordinate to be a DBL from -0.5 to 0.5. */
  2051. x0 = x / (DBL)Frame.Screen_Width - 0.5;
  2052. /* Convert the y coordinate to be a DBL from -0.5 to 0.5. */
  2053. y0 = ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 0.5;
  2054. /* Create primary ray. */
  2055. VLinComb3(Ray->Direction, 1.0, FCD, x0, FCR, y0, FCU);
  2056. /* Do focal blurring (by Dan Farmer). */
  2057. if (Focal_Blur_Is_Used)
  2058. {
  2059. jitter_camera_ray(Ray, ray_number);
  2060. initialize_ray_container_state(Ray, TRUE);
  2061. }
  2062. else
  2063. {
  2064. initialize_ray_container_state(Ray, Precompute_Camera_Constants);
  2065. Precompute_Camera_Constants = FALSE;
  2066. }
  2067. break;
  2068. /*
  2069. * Orthographic projection.
  2070. */
  2071. case ORTHOGRAPHIC_CAMERA:
  2072. /* Convert the x coordinate to be a DBL from -0.5 to 0.5. */
  2073. x0 = x / (DBL)Frame.Screen_Width - 0.5;
  2074. /* Convert the y coordinate to be a DBL from -0.5 to 0.5. */
  2075. y0 = ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 0.5;
  2076. /* Create primary ray. */
  2077. Assign_Vector(Ray->Direction, FCD);
  2078. VLinComb3(Ray->Initial, 1.0, FCL, x0, FCR, y0, FCU);
  2079. initialize_ray_container_state(Ray, TRUE);
  2080. break;
  2081. /*
  2082. * Fisheye camera.
  2083. */
  2084. case FISHEYE_CAMERA:
  2085. /* Convert the x coordinate to be a DBL from -1.0 to 1.0. */
  2086. x0 = 2.0 * x / (DBL)Frame.Screen_Width - 1.0;
  2087. /* Convert the y coordinate to be a DBL from -1.0 to 1.0. */
  2088. y0 = 2.0 * ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 1.0;
  2089. /* Get aspect ratio --> we want a circle (do this only once). */
  2090. if (Precompute_Camera_Constants)
  2091. {
  2092. VLength(lx, FCR);
  2093. VLength(ly, FCU);
  2094. Camera_Aspect_Ratio = lx / ly;
  2095. VNormalize(FCR, FCR);
  2096. VNormalize(FCU, FCU);
  2097. VNormalize(FCD, FCD);
  2098. }
  2099. /* Get polar coordinates. */
  2100. x0 *= Camera_Aspect_Ratio;
  2101. rad = sqrt(x0 * x0 + y0 * y0);
  2102. /* If the pixel lies outside the unit circle no ray is traced. */
  2103. if (rad > 1.0)
  2104. {
  2105. return(FALSE);
  2106. }
  2107. if (rad == 0.0)
  2108. {
  2109. phi = 0.0;
  2110. }
  2111. else
  2112. {
  2113. if (x0 < 0.0)
  2114. {
  2115. phi = M_PI - asin(y0 / rad);
  2116. }
  2117. else
  2118. {
  2119. phi = asin(y0 / rad);
  2120. }
  2121. }
  2122. /* Get spherical coordinates. */
  2123. x0 = phi;
  2124. /* Set vertical angle to half viewing angle. */
  2125. y0 = rad * Frame.Camera->Angle * M_PI_360;
  2126. /* Create primary ray. */
  2127. cx = cos(x0); sx = sin(x0);
  2128. cy = cos(y0); sy = sin(y0);
  2129. VLinComb3(Ray->Direction, cx * sy, FCR, sx * sy, FCU, cy, FCD);
  2130. initialize_ray_container_state(Ray, Precompute_Camera_Constants);
  2131. Precompute_Camera_Constants = FALSE;
  2132. break;
  2133. /*
  2134. * Omnimax camera.
  2135. */
  2136. case OMNIMAX_CAMERA:
  2137. /* Convert the x coordinate to be a DBL from -1.0 to 1.0. */
  2138. x0 = 2.0 * x / (DBL)Frame.Screen_Width - 1.0;
  2139. /* Convert the y coordinate to be a DBL from -1.0 to 1.0. */
  2140. y0 = 2.0 * ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 1.0;
  2141. /* Get aspect ratio --> we want a circle (do this only once). */
  2142. if (Precompute_Camera_Constants)
  2143. {
  2144. VLength(lx, FCR);
  2145. VLength(ly, FCU);
  2146. Camera_Aspect_Ratio = lx / ly;
  2147. VNormalize(FCR, FCR);
  2148. VNormalize(FCU, FCU);
  2149. VNormalize(FCD, FCD);
  2150. }
  2151. /* Get polar coordinates. */
  2152. x0 *= Camera_Aspect_Ratio;
  2153. rad = sqrt(x0 * x0 + y0 * y0);
  2154. /* If the pixel lies outside the unit circle no ray is traced. */
  2155. if (rad > 1.0)
  2156. {
  2157. return(FALSE);
  2158. }
  2159. if (rad == 0.0)
  2160. {
  2161. phi = 0.0;
  2162. }
  2163. else
  2164. {
  2165. if (x0 < 0.0)
  2166. {
  2167. phi = M_PI - asin(y0 / rad);
  2168. }
  2169. else
  2170. {
  2171. phi = asin(y0 / rad);
  2172. }
  2173. }
  2174. /* Get spherical coordinates. */
  2175. x0 = phi;
  2176. y0 = 1.411269 * rad - 0.09439 * rad * rad * rad + 0.25674 * rad * rad * rad * rad * rad;
  2177. cx = cos(x0); sx = sin(x0);
  2178. cy = cos(y0); sy = sin(y0);
  2179. /* We can't see below 45 degrees under the projection axis. */
  2180. if (sx * sy < tan(135.0 * M_PI_180) * cy)
  2181. {
  2182. return(FALSE);
  2183. }
  2184. /* Create primary ray. */
  2185. VLinComb3(Ray->Direction, cx * sy, FCR, sx * sy, FCU, cy, FCD);
  2186. initialize_ray_container_state(Ray, Precompute_Camera_Constants);
  2187. Precompute_Camera_Constants = FALSE;
  2188. break;
  2189. /*
  2190. * Panoramic camera from Graphic Gems III.
  2191. */
  2192. case PANORAMIC_CAMERA:
  2193. /* Convert the x coordinate to be a DBL from 0.0 to 1.0. */
  2194. x0 = x / (DBL)Frame.Screen_Width;
  2195. /* Convert the y coordinate to be a DBL from -1.0 to 1.0. */
  2196. y0 = 2.0 * ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 1.0;
  2197. /* Get cylindrical coordinates. */
  2198. x0 = (1.0 - x0) * M_PI;
  2199. y0 = M_PI_2 * y0;
  2200. cx = cos(x0);
  2201. sx = sin(x0);
  2202. if (fabs(M_PI_2 - fabs(y0)) < EPSILON)
  2203. {
  2204. if (y0 > 0.0)
  2205. {
  2206. ty = BOUND_HUGE;
  2207. }
  2208. else
  2209. {
  2210. ty = - BOUND_HUGE;
  2211. }
  2212. }
  2213. else
  2214. {
  2215. ty = tan(y0);
  2216. }
  2217. /* Create primary ray. */
  2218. VLinComb3(Ray->Direction, cx, FCR, ty, FCU, sx, FCD);
  2219. initialize_ray_container_state(Ray, Precompute_Camera_Constants);
  2220. Precompute_Camera_Constants = FALSE;
  2221. break;
  2222. /*
  2223. * Ultra wide angle camera written by Dan Farmer.
  2224. */
  2225. case ULTRA_WIDE_ANGLE_CAMERA:
  2226. /* Convert the x coordinate to be a DBL from -0.5 to 0.5. */
  2227. x0 = x / (DBL)Frame.Screen_Width - 0.5;
  2228. /* Convert the y coordinate to be a DBL from -0.5 to 0.5. */
  2229. y0 = ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 0.5;
  2230. /* Create primary ray. */
  2231. x0 *= Frame.Camera->Angle / 180.0;
  2232. y0 *= Frame.Camera->Angle / 180.0;
  2233. cx = cos(x0); sx = sin(x0);
  2234. cy = cos(y0); sy = sin(y0);
  2235. VLinComb3(Ray->Direction, sx, FCR, sy, FCU, cx * cy, FCD);
  2236. initialize_ray_container_state(Ray, Precompute_Camera_Constants);
  2237. Precompute_Camera_Constants = FALSE;
  2238. break;
  2239. /*
  2240. * Cylinder camera 1. Axis in "up" direction
  2241. */
  2242. case CYL_1_CAMERA:
  2243. /* Convert the x coordinate to be a DBL from -0.5 to 0.5. */
  2244. x0 = x / (DBL)Frame.Screen_Width - 0.5;
  2245. /* Convert the y coordinate to be a DBL from -0.5 to 0.5. */
  2246. y0 = ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 0.5;
  2247. /* Create primary ray. */
  2248. x0 *= Frame.Camera->Angle * M_PI_180;
  2249. cx = cos(x0);
  2250. sx = sin(x0);
  2251. VLinComb3(Ray->Direction, sx, FCR, y0, FCU, cx, FCD);
  2252. initialize_ray_container_state(Ray, Precompute_Camera_Constants);
  2253. Precompute_Camera_Constants = FALSE;
  2254. break;
  2255. /*
  2256. * Cylinder camera 2. Axis in "right" direction
  2257. */
  2258. case CYL_2_CAMERA:
  2259. /* Convert the x coordinate to be a DBL from -0.5 to 0.5. */
  2260. x0 = x / (DBL)Frame.Screen_Width - 0.5;
  2261. /* Convert the y coordinate to be a DBL from -0.5 to 0.5. */
  2262. y0 = ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 0.5;
  2263. /* Create primary ray. */
  2264. y0 *= Frame.Camera->Angle * M_PI_180;
  2265. cy = cos(y0);
  2266. sy = sin(y0);
  2267. VLinComb3(Ray->Direction, x0, FCR, sy, FCU, cy, FCD);
  2268. initialize_ray_container_state(Ray, Precompute_Camera_Constants);
  2269. Precompute_Camera_Constants = FALSE;
  2270. break;
  2271. /*
  2272. * Cylinder camera 3. Axis in "up" direction, orthogonal in "right"
  2273. */
  2274. case CYL_3_CAMERA:
  2275. /* Convert the x coordinate to be a DBL from -0.5 to 0.5. */
  2276. x0 = x / (DBL)Frame.Screen_Width - 0.5;
  2277. /* Convert the y coordinate to be a DBL from -0.5 to 0.5. */
  2278. y0 = ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 0.5;
  2279. /* Create primary ray. */
  2280. x0 *= Frame.Camera->Angle * M_PI_180;
  2281. cx = cos(x0);
  2282. sx = sin(x0);
  2283. VLinComb2(Ray->Direction, sx, FCR, cx, FCD);
  2284. VLinComb2(Ray->Initial, 1.0, FCL, y0, FCU);
  2285. initialize_ray_container_state(Ray, TRUE);
  2286. break;
  2287. /*
  2288. * Cylinder camera 4. Axis in "right" direction, orthogonal in "up"
  2289. */
  2290. case CYL_4_CAMERA:
  2291. /* Convert the x coordinate to be a DBL from -0.5 to 0.5. */
  2292. x0 = x / (DBL)Frame.Screen_Width - 0.5;
  2293. /* Convert the y coordinate to be a DBL from -0.5 to 0.5. */
  2294. y0 = ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 0.5;
  2295. /* Create primary ray. */
  2296. y0 *= Frame.Camera->Angle * M_PI_180;
  2297. cy = cos(y0);
  2298. sy = sin(y0);
  2299. VLinComb2(Ray->Direction, sy, FCU, cy, FCD);
  2300. VLinComb2(Ray->Initial, 1.0, FCL, x0, FCR);
  2301. initialize_ray_container_state(Ray, TRUE);
  2302. break;
  2303. default:
  2304. Error("Unknown camera type in create_ray().\n");
  2305. }
  2306. if (Frame.Camera->Tnormal != NULL)
  2307. {
  2308. VNormalize(Ray->Direction, Ray->Direction);
  2309. Make_Vector(V1, x0, y0, 0.0);
  2310. Perturb_Normal(Ray->Direction, Frame.Camera->Tnormal, V1);
  2311. }
  2312. VNormalize(Ray->Direction, Ray->Direction);
  2313. return(TRUE);
  2314. #undef FCD
  2315. #undef FCR
  2316. #undef FCU
  2317. #undef FCL
  2318. }
  2319. /*****************************************************************************
  2320. *
  2321. * FUNCTION
  2322. *
  2323. * gamma_correct
  2324. *
  2325. * INPUT
  2326. *
  2327. * Colour (an array of DBL's)
  2328. *
  2329. * OUTPUT
  2330. *
  2331. * The colour array
  2332. *
  2333. * RETURNS
  2334. *
  2335. * AUTHOR
  2336. *
  2337. * POV-Ray Team
  2338. *
  2339. * DESCRIPTION
  2340. *
  2341. * Adjust RGB values for overall brightness and gamma curve so that the
  2342. * image appears a constant brightness regardless of the hardware that
  2343. * is being used. This can't be part of extract_colors, since
  2344. * extract_colors is used multiple times in anti aliasing, and this has
  2345. * to be called exactly once per pixel output.
  2346. *
  2347. * If gamma correction is enabled, then file and display pixel values
  2348. * will be corrected for the current assumed_gamma, which has default
  2349. * value 1.00, but can be set by a global_settings {assumed_gamma} in the
  2350. * source file, and the DisplayGamma value, which can be set in the INI
  2351. * file via Display_Gamma=n.n or defaults to DEFAULT_DISPLAY_GAMMA
  2352. * (2.2 unless another value set in the system specific config.h files.)
  2353. *
  2354. * If gamma correction is turned off (if no global_settings {assumed_gamma}
  2355. * line occurrs in the scene file) then no gamma correction will be done
  2356. * on the pixel values. If gamma correction is turned off, the
  2357. * DisplayGamma value is still relevant for PNG output files, since if
  2358. * gamma correction is disabled, it is presumed that the scene is
  2359. * "pre-corrected" for the current hardware, and a gAMA chunk with the
  2360. * current 1/DisplayGamma value will be output.
  2361. *
  2362. * When DisplayGamma approximately equals assumed_gamma, it means that we
  2363. * don't need to do any gamma correction since it is already the correct
  2364. * brightness. opts.GammaFactor is calculated once in tokenize.c to
  2365. * be assumed_gamma/DisplayGamma to avoid re-calculation for each pixel.
  2366. *
  2367. * CHANGES
  2368. *
  2369. * Apr 1995 : Created function - Jim McElhiney
  2370. * Oct 1995 : Modified to do proper system gamma correction [AED]
  2371. *
  2372. ******************************************************************************/
  2373. static void gamma_correct(COLOUR Colour)
  2374. {
  2375. if (opts.Options & GAMMA_CORRECT)
  2376. {
  2377. Colour[RED] = pow(Colour[RED], opts.GammaFactor);
  2378. Colour[GREEN] = pow(Colour[GREEN],opts.GammaFactor);
  2379. Colour[BLUE] = pow(Colour[BLUE], opts.GammaFactor);
  2380. }
  2381. }
  2382. /*****************************************************************************
  2383. *
  2384. * FUNCTION
  2385. *
  2386. * extract_colors
  2387. *
  2388. * INPUT
  2389. *
  2390. * Colour, Red, Green, Blue, Alpha, grey
  2391. *
  2392. * OUTPUT
  2393. *
  2394. * Red, Green, Blue, Alpha, grey
  2395. *
  2396. * RETURNS
  2397. *
  2398. * AUTHOR
  2399. *
  2400. * POV-Ray Team
  2401. *
  2402. * DESCRIPTION
  2403. *
  2404. * Create appropriate rgba values.
  2405. *
  2406. * CHANGES
  2407. *
  2408. * Aug 1994 : Extracted common code from Start_Tracing - Eduard Schwan
  2409. * Jun 1995 : Alpha channel support -CEY
  2410. *
  2411. ******************************************************************************/
  2412. static void extract_colors(COLOUR Colour, unsigned char *Red, unsigned char *Green, unsigned char *Blue, unsigned char *Alpha, DBL *grey)
  2413. {
  2414. if (opts.PaletteOption == GREY)
  2415. {
  2416. *grey = Colour[RED] * 0.287 + Colour[GREEN] * 0.589 + Colour[BLUE] * 0.114;
  2417. *Red = *Green = *Blue = (unsigned char)((*grey) * maxclr);
  2418. }
  2419. else
  2420. {
  2421. *Red = (unsigned char)(Colour[RED] * maxclr);
  2422. *Green = (unsigned char)(Colour[GREEN] * maxclr);
  2423. *Blue = (unsigned char)(Colour[BLUE] * maxclr);
  2424. *Alpha = (unsigned char)(Colour[TRANSM] * maxclr);
  2425. }
  2426. }
  2427. /*****************************************************************************
  2428. *
  2429. * FUNCTION
  2430. *
  2431. * plot_pixel
  2432. *
  2433. * INPUT
  2434. *
  2435. * x, y - pixel location
  2436. * Colour - pixel color
  2437. *
  2438. * OUTPUT
  2439. *
  2440. * RETURNS
  2441. *
  2442. * AUTHOR
  2443. *
  2444. * Dieter Bayer
  2445. *
  2446. * DESCRIPTION
  2447. *
  2448. * Display a pixel on the screen.
  2449. *
  2450. * CHANGES
  2451. *
  2452. * Aug 1995 : Creation. Extracted from common code.
  2453. *
  2454. ******************************************************************************/
  2455. static void plot_pixel(int x, int y, COLOUR Colour)
  2456. {
  2457. unsigned char Red, Green, Blue, Alpha;
  2458. DBL grey;
  2459. if ((opts.Options & DISPLAY) && (y != opts.First_Line - 1))
  2460. {
  2461. extract_colors(Colour, &Red, &Green, &Blue, &Alpha, &grey);
  2462. POV_DISPLAY_PLOT(x, y, Red, Green, Blue, Alpha);
  2463. }
  2464. }
  2465. /*****************************************************************************
  2466. *
  2467. * FUNCTION
  2468. *
  2469. * jitter_pixel_position
  2470. *
  2471. * INPUT
  2472. *
  2473. * x, y - pixel location
  2474. *
  2475. * OUTPUT
  2476. *
  2477. * Jitter_X - pseudo-random offset to x-coordinate
  2478. * Jitter_Y - pseudo-random offset to y-coordinate
  2479. *
  2480. * RETURNS
  2481. *
  2482. * AUTHOR
  2483. *
  2484. * Dieter Bayer
  2485. *
  2486. * DESCRIPTION
  2487. *
  2488. * Apply jitter to a pixel location.
  2489. *
  2490. * CHANGES
  2491. *
  2492. * Aug 1995 : Creation. Extracted from common code.
  2493. *
  2494. ******************************************************************************/
  2495. static void jitter_pixel_position(int x, int y, DBL *Jitter_X, DBL *Jitter_Y)
  2496. {
  2497. static int Jitt_Offset = 10;
  2498. if (opts.Options & JITTER)
  2499. {
  2500. *Jitter_X = rand2d(x + Jitt_Offset, y);
  2501. Jitt_Offset++;
  2502. *Jitter_Y = rand2d(x + Jitt_Offset, y);
  2503. Jitt_Offset++;
  2504. *Jitter_X *= JitterScale;
  2505. *Jitter_Y *= JitterScale;
  2506. }
  2507. else
  2508. {
  2509. *Jitter_X = *Jitter_Y = 0.0;
  2510. }
  2511. }
  2512. /*****************************************************************************
  2513. *
  2514. * FUNCTION
  2515. *
  2516. * output_line
  2517. *
  2518. * INPUT
  2519. *
  2520. * y - current line number
  2521. *
  2522. * OUTPUT
  2523. *
  2524. * RETURNS
  2525. *
  2526. * AUTHOR
  2527. *
  2528. * POV-Ray Team
  2529. *
  2530. * DESCRIPTION
  2531. *
  2532. * -
  2533. *
  2534. * CHANGES
  2535. *
  2536. * -
  2537. *
  2538. ******************************************************************************/
  2539. static void output_line(int y)
  2540. {
  2541. COLOUR *Temp_Colour_Ptr;
  2542. char *Temp_Char_Ptr;
  2543. if (y > opts.First_Line)
  2544. {
  2545. if (opts.Options & DISKWRITE)
  2546. {
  2547. Write_Line(Output_File_Handle, Previous_Line, y - 1);
  2548. }
  2549. POV_WRITE_LINE (Previous_Line, y - 1)
  2550. }
  2551. if (opts.Options & VERBOSE)
  2552. {
  2553. if (opts.Options & ANTIALIAS)
  2554. {
  2555. if (opts.Options & RADIOSITY)
  2556. {
  2557. Status_Info(" supersampled %d, %ld radiosity.",
  2558. SuperSampleCount, ra_gather_count - RadiosityCount);
  2559. }
  2560. else
  2561. {
  2562. Status_Info(" supersampled %d times.", SuperSampleCount);
  2563. }
  2564. }
  2565. else
  2566. {
  2567. if (opts.Options & RADIOSITY)
  2568. {
  2569. Status_Info(" %ld radiosity samples.", ra_gather_count - RadiosityCount);
  2570. }
  2571. }
  2572. Status_Info(" \r");
  2573. }
  2574. Temp_Colour_Ptr = Previous_Line;
  2575. Previous_Line = Current_Line;
  2576. Current_Line = Temp_Colour_Ptr;
  2577. Temp_Char_Ptr = Previous_Line_Antialiased_Flags;
  2578. Previous_Line_Antialiased_Flags = Current_Line_Antialiased_Flags;
  2579. Current_Line_Antialiased_Flags = Temp_Char_Ptr;
  2580. }
  2581. /*****************************************************************************
  2582. *
  2583. * FUNCTION
  2584. *
  2585. * initialise_histogram
  2586. *
  2587. * INPUT
  2588. *
  2589. * OUTPUT
  2590. *
  2591. * RETURNS
  2592. *
  2593. * AUTHOR
  2594. *
  2595. * Chris Cason
  2596. *
  2597. * DESCRIPTION
  2598. *
  2599. * Initialise histogram collation if available, otherwise force histogram off.
  2600. *
  2601. * CHANGES
  2602. *
  2603. ******************************************************************************/
  2604. static void initialise_histogram ()
  2605. {
  2606. #if PRECISION_TIMER_AVAILABLE
  2607. if (opts.histogram_on)
  2608. {
  2609. PRECISION_TIMER_INIT
  2610. histogram_grid = (unsigned long *)POV_CALLOC (opts.histogram_x * opts.histogram_y,
  2611. sizeof(unsigned long), "histogram grid");
  2612. }
  2613. #else
  2614. opts.histogram_on = FALSE ;
  2615. #endif
  2616. }
  2617. /*****************************************************************************
  2618. *
  2619. * FUNCTION
  2620. *
  2621. * destroy_histogram
  2622. *
  2623. * INPUT
  2624. *
  2625. * OUTPUT
  2626. *
  2627. * RETURNS
  2628. *
  2629. * AUTHOR
  2630. *
  2631. * Andreas Dilger
  2632. *
  2633. * DESCRIPTION
  2634. *
  2635. * CHANGES
  2636. *
  2637. ******************************************************************************/
  2638. void destroy_histogram ()
  2639. {
  2640. #if PRECISION_TIMER_AVAILABLE
  2641. if (Histogram_File_Handle != NULL)
  2642. {
  2643. Close_File(Histogram_File_Handle);
  2644. POV_FREE(Histogram_File_Handle);
  2645. Histogram_File_Handle = NULL;
  2646. }
  2647. if (histogram_grid != NULL)
  2648. {
  2649. POV_FREE (histogram_grid) ;
  2650. histogram_grid = NULL;
  2651. }
  2652. #endif
  2653. }
  2654. /*****************************************************************************
  2655. *
  2656. * FUNCTION
  2657. *
  2658. * accumulate_histogram
  2659. *
  2660. * INPUT
  2661. *
  2662. * int x, y - pixel position on screen, on - starting pixel
  2663. *
  2664. * OUTPUT
  2665. *
  2666. * RETURNS
  2667. *
  2668. * AUTHOR
  2669. *
  2670. * Chris Cason
  2671. *
  2672. * DESCRIPTION
  2673. *
  2674. * Accumulate statistics on the histogram grid given on the command line.
  2675. * The total amount of time that the program spends in tracing pixels in the
  2676. * particular grid section that the pixel lies in is eventually written to an
  2677. * output file.
  2678. *
  2679. * CHANGES
  2680. *
  2681. * Oct 1995: Modified to return if PRECISION_TIMER_AVAILABLE == 0 [CJC]
  2682. *
  2683. ******************************************************************************/
  2684. static void accumulate_histogram(int x, int y, int on)
  2685. {
  2686. #if PRECISION_TIMER_AVAILABLE
  2687. int loc_x, loc_y;
  2688. unsigned long *p;
  2689. if (y < 0)
  2690. {
  2691. return;
  2692. }
  2693. if (!on)
  2694. {
  2695. PRECISION_TIMER_STOP
  2696. /* determine which grid section the pixel lies in */
  2697. loc_x = x * opts.histogram_x / Frame.Screen_Width;
  2698. loc_y = y * opts.histogram_y / Frame.Screen_Height;
  2699. p = histogram_grid + (long) loc_y * opts.histogram_x + loc_x;
  2700. *p += PRECISION_TIMER_COUNT;
  2701. if (*p > max_histogram_value)
  2702. {
  2703. max_histogram_value = *p;
  2704. }
  2705. }
  2706. else
  2707. {
  2708. PRECISION_TIMER_START
  2709. }
  2710. #endif
  2711. }
  2712. /*****************************************************************************
  2713. *
  2714. * FUNCTION
  2715. *
  2716. * write_histogram
  2717. *
  2718. * INPUT
  2719. *
  2720. * filename - file to output the data to.
  2721. *
  2722. * OUTPUT
  2723. *
  2724. * RETURNS
  2725. *
  2726. * AUTHOR
  2727. *
  2728. * Chris Cason
  2729. *
  2730. * DESCRIPTION
  2731. *
  2732. * Processes and then writes the accumulated histogram statistics to a CSV
  2733. * (comma separated value) file. Programs such as Microsoft Excel can read CSV.
  2734. * Also accomodates image file output, such as Targa, for height field usage.
  2735. *
  2736. * CHANGES
  2737. *
  2738. * Sep 1995: Added support for grayscale PNG histogram output [AED]
  2739. * Oct 1995: Fixed TGA, PPM output for 0 - 1 range and use HF_GRAY_16 [AED]
  2740. * Oct 1995: Modified to return if PRECISION_TIMER_AVAILABLE == 0 [CJC]
  2741. *
  2742. ******************************************************************************/
  2743. void write_histogram(char *filename)
  2744. {
  2745. #if PRECISION_TIMER_AVAILABLE
  2746. int x, y, x_step, y_step;
  2747. unsigned long OptionsSave;
  2748. int OutputQualitySave;
  2749. unsigned long *p;
  2750. FILE *f;
  2751. COLOUR *line, *l;
  2752. Status_Info ("\nWriting histogram file '%s'", filename);
  2753. switch (opts.histogram_type)
  2754. {
  2755. case CSV :
  2756. if ((f = fopen (filename, WRITE_TXTFILE_STRING)) == NULL)
  2757. {
  2758. Warning (0.0, "Cannot open file %s for histogram output.", filename);
  2759. return;
  2760. }
  2761. for (y = 0, p = histogram_grid; y < opts.histogram_y ; y++)
  2762. {
  2763. for (x = 0; x < opts.histogram_x ; x++)
  2764. {
  2765. fprintf (f, "%s%010lu", x ? ", " : "", *p++);
  2766. }
  2767. fprintf (f, "\n");
  2768. }
  2769. fclose (f);
  2770. break;
  2771. case PPM :
  2772. case SYS :
  2773. case TARGA :
  2774. case PNG:
  2775. OptionsSave = opts.Options;
  2776. OutputQualitySave = opts.OutputQuality;
  2777. opts.Options = HF_GRAY_16;
  2778. opts.OutputQuality = 12;
  2779. Histogram_File_Handle->file_type = HIST_FTYPE;
  2780. if (Open_File (Histogram_File_Handle, filename,
  2781. &Frame.Screen_Width, &Frame.Screen_Height, 0, WRITE_MODE) != 1)
  2782. {
  2783. Warning (0.0, "Cannot open file %s for histogram output.", filename);
  2784. return;
  2785. }
  2786. line = (COLOUR *)POV_CALLOC(Frame.Screen_Width, sizeof(COLOUR), "histogram buffer");
  2787. y_step = Frame.Screen_Height / opts.histogram_y;
  2788. x_step = Frame.Screen_Width / opts.histogram_x;
  2789. for (y = 0; y < Frame.Screen_Height ; y++)
  2790. {
  2791. p = histogram_grid + (long) (y / y_step) * opts.histogram_x;
  2792. for (x = 0, l = line; x < Frame.Screen_Width ; x++, l++)
  2793. {
  2794. (*l) [RED] =
  2795. (*l) [GREEN] =
  2796. (*l) [BLUE] = (COLC)*(p + x / x_step) / max_histogram_value;
  2797. }
  2798. Write_Line (Histogram_File_Handle, line, y);
  2799. }
  2800. POV_FREE (line);
  2801. Close_File (Histogram_File_Handle);
  2802. POV_FREE (Histogram_File_Handle);
  2803. Histogram_File_Handle=NULL;
  2804. opts.Options = OptionsSave;
  2805. opts.OutputQuality = OutputQualitySave;
  2806. break;
  2807. case NONE: /* Just to quiet warnings */
  2808. default:
  2809. break;
  2810. }
  2811. #endif
  2812. }
  2813. /*****************************************************************************
  2814. *
  2815. * FUNCTION
  2816. *
  2817. * check_stats
  2818. *
  2819. * INPUT
  2820. * y = current row
  2821. * doingMosaic = 1 if doing mosaic preview (show pixWidth)
  2822. * pixWidth = size of pixel
  2823. * OUTPUT
  2824. *
  2825. * RETURNS
  2826. *
  2827. * AUTHOR
  2828. *
  2829. * POV-Ray Team
  2830. *
  2831. * DESCRIPTION
  2832. *
  2833. * -
  2834. *
  2835. * CHANGES
  2836. *
  2837. * 6/17/95 esp Added display of mosaic pixWidth
  2838. *
  2839. ******************************************************************************/
  2840. static void check_stats(register int y, register int doingMosaic, register int pixWidth)
  2841. {
  2842. DBL time_dif;
  2843. unsigned long hrs, mins;
  2844. DBL secs;
  2845. /* New verbose options CdW */
  2846. if (opts.Options & VERBOSE)
  2847. {
  2848. STOP_TIME
  2849. time_dif = TIME_ELAPSED
  2850. if (time_dif > 0.0)
  2851. {
  2852. SPLIT_TIME(time_dif, &hrs, &mins, &secs);
  2853. Status_Info("%3ld:%02ld:%02ld ", hrs, mins, (long)secs);
  2854. }
  2855. else
  2856. {
  2857. Status_Info(" -:--:-- ");
  2858. }
  2859. Status_Info("Rendering line %4d of %4d", y-opts.First_Line+1, opts.Last_Line-opts.First_Line);
  2860. if (doingMosaic)
  2861. {
  2862. Status_Info(" at %dx%d \b\b", pixWidth, pixWidth);
  2863. }
  2864. if (opts.Options & ANTIALIAS)
  2865. {
  2866. SuperSampleCount = 0;
  2867. }
  2868. else
  2869. {
  2870. Status_Info(". ");
  2871. }
  2872. RadiosityCount = ra_gather_count;
  2873. }
  2874. }
  2875. /*****************************************************************************
  2876. *
  2877. * FUNCTION
  2878. *
  2879. * initialize_ray_container_state
  2880. *
  2881. * INPUT
  2882. *
  2883. * OUTPUT
  2884. *
  2885. * RETURNS
  2886. *
  2887. * AUTHOR
  2888. *
  2889. * Dieter Bayer
  2890. *
  2891. * DESCRIPTION
  2892. *
  2893. * Initialize the containing lists of a primary ray by testing wether
  2894. * the ray's starting point is inside any object. All objects that the
  2895. * ray's origin is currently inside will be added to the containing
  2896. * lists.
  2897. *
  2898. * This is neccessary to make participating media work if the camera
  2899. * is inside the medium. It is also neccessary to make refraction work
  2900. * correctly if the camera is inside this object.
  2901. *
  2902. * CHANGES
  2903. *
  2904. * Mar 1996 : Creation.
  2905. *
  2906. ******************************************************************************/
  2907. static void initialize_ray_container_state(RAY *Ray, int Compute)
  2908. {
  2909. int i, solid;
  2910. OBJECT *Object;
  2911. if (Compute)
  2912. {
  2913. Containing_Index = -1;
  2914. if (!opts.Use_Slabs)
  2915. {
  2916. for (Object = Frame.Objects; Object != NULL; Object = Object -> Sibling)
  2917. {
  2918. if (Inside(Ray->Initial, Object) && (Object->Interior != NULL))
  2919. {
  2920. if ((++Containing_Index) >= MAX_CONTAINING_OBJECTS)
  2921. {
  2922. Error("Too many nested objects\n");
  2923. }
  2924. Containing_Interiors[Containing_Index] = Object->Interior;
  2925. }
  2926. }
  2927. }
  2928. else
  2929. {
  2930. initialize_ray_container_state_tree(Ray, Root_Object);
  2931. }
  2932. }
  2933. for (i = 0; i <= Containing_Index; i++)
  2934. {
  2935. Ray->Interiors[i] = Containing_Interiors[i];
  2936. }
  2937. Ray->Index = Containing_Index;
  2938. /* Test if we are in a hollow object (do this only once). */
  2939. if (!Primary_Ray_State_Tested)
  2940. {
  2941. solid = FALSE;
  2942. for (i = 0; i <= Containing_Index; i++)
  2943. {
  2944. if (!Containing_Interiors[i]->hollow)
  2945. {
  2946. solid = TRUE;
  2947. break;
  2948. }
  2949. }
  2950. if (solid)
  2951. {
  2952. Warning(0.0, "Camera is inside a non-hollow object.\nFog and participating media may not work as expected.\n");
  2953. }
  2954. Primary_Ray_State_Tested = TRUE;
  2955. }
  2956. }
  2957. /*****************************************************************************
  2958. *
  2959. * FUNCTION
  2960. *
  2961. * initialize_ray_container_state_tree
  2962. *
  2963. * INPUT
  2964. *
  2965. * OUTPUT
  2966. *
  2967. * RETURNS
  2968. *
  2969. * AUTHOR
  2970. *
  2971. * Dieter Bayer
  2972. *
  2973. * DESCRIPTION
  2974. *
  2975. * Step down the bounding box hierarchy and test for all node wether
  2976. * the ray's origin is inside or not. If it's inside a node descend
  2977. * further. If a leaf is reached and the ray's origin is inside the
  2978. * leaf object insert the objects data into the ray's containing lists.
  2979. *
  2980. * CHANGES
  2981. *
  2982. * Mar 1996 : Creation.
  2983. *
  2984. ******************************************************************************/
  2985. static void initialize_ray_container_state_tree(RAY *Ray, BBOX_TREE *Node)
  2986. {
  2987. int i;
  2988. OBJECT *Object;
  2989. /* Check current node. */
  2990. if ((Ray->Initial[X] < (DBL)Node->BBox.Lower_Left[X]) ||
  2991. (Ray->Initial[Y] < (DBL)Node->BBox.Lower_Left[Y]) ||
  2992. (Ray->Initial[Z] < (DBL)Node->BBox.Lower_Left[Z]) ||
  2993. (Ray->Initial[X] > (DBL)Node->BBox.Lower_Left[X] + (DBL)Node->BBox.Lengths[X]) ||
  2994. (Ray->Initial[Y] > (DBL)Node->BBox.Lower_Left[Y] + (DBL)Node->BBox.Lengths[Y]) ||
  2995. (Ray->Initial[Z] > (DBL)Node->BBox.Lower_Left[Z] + (DBL)Node->BBox.Lengths[Z]))
  2996. {
  2997. return;
  2998. }
  2999. if (Node->Entries)
  3000. {
  3001. /* This is a node containing leaves to be checked. */
  3002. for (i = 0; i < Node->Entries; i++)
  3003. {
  3004. initialize_ray_container_state_tree(Ray, Node->Node[i]);
  3005. }
  3006. }
  3007. else
  3008. {
  3009. /* This is a leaf so test contained object. */
  3010. Object = (OBJECT *)Node->Node;
  3011. if (Inside(Ray->Initial, Object) && (Object->Interior != NULL))
  3012. {
  3013. if ((++Containing_Index) >= MAX_CONTAINING_OBJECTS)
  3014. {
  3015. Error("Too many nested objects\n");
  3016. }
  3017. Containing_Interiors[Containing_Index] = Object->Interior;
  3018. }
  3019. }
  3020. }