lightv.c 145 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "cmdlib.h"
  19. #include "mathlib.h"
  20. #include "bspfile.h"
  21. #include "imagelib.h"
  22. #include "threads.h"
  23. #include "mutex.h"
  24. #include "scriplib.h"
  25. #include "shaders.h"
  26. #include "mesh.h"
  27. #ifdef _WIN32
  28. //Improve floating-point consistency.
  29. #pragma optimize( "p", on )
  30. #endif
  31. #ifdef _WIN32
  32. #include "../libs/pakstuff.h"
  33. #endif
  34. #define MAX_CLUSTERS 16384
  35. #define MAX_PORTALS 32768
  36. #define MAX_FACETS 65536
  37. #define MAX_LIGHTS 16384
  38. #define LIGHTMAP_SIZE 128
  39. #define LIGHTMAP_PIXELSHIFT 0.5
  40. //#define LIGHTMAP_PATCHSHIFT
  41. #define PORTALFILE "PRT1"
  42. #define ON_EPSILON 0.1
  43. #define VectorSet(v, x, y, z) v[0] = x;v[1] = y;v[2] = z;
  44. typedef struct
  45. {
  46. vec3_t normal;
  47. float dist;
  48. } plane_t;
  49. #define MAX_POINTS_ON_WINDING 64
  50. //NOTE: whenever this is overflowed parts of lightmaps might end up not being lit
  51. #define MAX_POINTS_ON_FIXED_WINDING 48
  52. typedef struct
  53. {
  54. int numpoints;
  55. vec3_t points[MAX_POINTS_ON_FIXED_WINDING]; // variable sized
  56. } winding_t;
  57. typedef struct
  58. {
  59. plane_t plane; // normal pointing into neighbor
  60. int leaf; // neighbor
  61. winding_t *winding;
  62. vec3_t origin; // for fast clip testing
  63. float radius;
  64. } lportal_t;
  65. #define MAX_PORTALS_ON_LEAF 128
  66. typedef struct lleaf_s
  67. {
  68. int numportals;
  69. lportal_t *portals[MAX_PORTALS_ON_LEAF];
  70. //
  71. int numSurfaces;
  72. int firstSurface;
  73. } lleaf_t;
  74. typedef struct lFacet_s
  75. {
  76. int num;
  77. plane_t plane;
  78. vec3_t points[4]; //
  79. int numpoints;
  80. float lightmapCoords[4][2];
  81. plane_t boundaries[4]; // negative is outside the bounds
  82. float textureMatrix[2][4]; // texture coordinates for translucency
  83. float lightmapMatrix[2][4]; // lightmap texture coordinates
  84. vec3_t mins;
  85. int x, y, width, height;
  86. } lFacet_t;
  87. typedef struct lsurfaceTest_s
  88. {
  89. vec3_t mins, maxs;
  90. vec3_t origin;
  91. float radius;
  92. qboolean patch; // true if this is a patch
  93. qboolean trisoup; // true if this is a triangle soup
  94. int numFacets;
  95. lFacet_t *facets;
  96. mesh_t *detailMesh; // detailed mesh with points for each lmp
  97. shaderInfo_t *shader; // for translucency
  98. mutex_t *mutex;
  99. int numvolumes; // number of volumes casted at this surface
  100. //
  101. int always_tracelight;
  102. int always_vlight;
  103. } lsurfaceTest_t;
  104. //volume types
  105. #define VOLUME_NORMAL 0
  106. #define VOLUME_DIRECTED 1
  107. #define MAX_TRANSLUCENTFACETS 32
  108. typedef struct lightvolume_s
  109. {
  110. int num;
  111. int cluster; //cluster this light volume started in
  112. plane_t endplane; //end plane
  113. plane_t farplane; //original end plane
  114. vec3_t points[MAX_POINTS_ON_WINDING]; //end winding points
  115. plane_t planes[MAX_POINTS_ON_WINDING]; //volume bounding planes
  116. int numplanes; //number of volume bounding planes
  117. int type; //light volume type
  118. //list with translucent surfaces the volume went through
  119. int transFacets[MAX_TRANSLUCENTFACETS];
  120. int transSurfaces[MAX_TRANSLUCENTFACETS];
  121. int numtransFacets;
  122. //clusters already tested
  123. byte clusterTested[MAX_CLUSTERS/8];
  124. //facets already tested
  125. byte facetTested[MAX_FACETS/8];
  126. int facetNum; //number of the facet blocking the light in this volume
  127. int surfaceNum; //number of the surface blocking the light in this volume
  128. } lightvolume_t;
  129. //light types
  130. #define LIGHT_POINTRADIAL 1
  131. #define LIGHT_POINTSPOT 2
  132. #define LIGHT_POINTFAKESURFACE 3
  133. #define LIGHT_SURFACEDIRECTED 4
  134. #define LIGHT_SURFACERADIAL 5
  135. #define LIGHT_SURFACESPOT 6
  136. //light distance attenuation types
  137. #define LDAT_QUADRATIC 0
  138. #define LDAT_LINEAR 1
  139. #define LDAT_NOSCALE 2
  140. //light angle attenuation types
  141. #define LAAT_NORMAL 0
  142. #define LAAT_QUADRATIC 1
  143. #define LAAT_DOUBLEQUADRATIC 2
  144. typedef struct vlight_s
  145. {
  146. vec3_t origin; //light origin, for point lights
  147. winding_t w; //light winding, for area lights
  148. vec4_t plane; //light winding plane
  149. vec3_t normal; //direction of the light
  150. int type; //light type
  151. vec3_t color; //light color
  152. qboolean twosided; //radiates light at both sides of the winding
  153. int style; //light style (not used)
  154. int atten_disttype; //light distance attenuation type
  155. int atten_angletype; //light angle attenuation type
  156. float atten_distscale; //distance attenuation scale
  157. float atten_anglescale; //angle attenuation scale
  158. float radiusByDist; //radius by distance for spot lights
  159. float photons; //emitted photons
  160. float intensity; //intensity
  161. vec3_t emitColor; //full out-of-gamut value (not used)
  162. struct shaderInfo_s *si; //shader info
  163. int insolid; //set when light is in solid
  164. } vlight_t;
  165. float lightLinearScale = 1.0 / 8000;
  166. float lightPointScale = 7500;
  167. float lightAreaScale = 0.25;
  168. float lightFormFactorValueScale = 3;
  169. int lightDefaultSubdivide = 999; // vary by surface size?
  170. vec3_t lightAmbientColor;
  171. int portalclusters, numportals, numfaces;
  172. lleaf_t *leafs;
  173. lportal_t *portals;
  174. int numvlights = 0;
  175. vlight_t *vlights[MAX_LIGHTS];
  176. int nostitching = 0;
  177. int noalphashading = 0;
  178. int nocolorshading = 0;
  179. int nobackfaceculling = 0;
  180. int defaulttracelight = 0;
  181. int radiosity = 0;
  182. int radiosity_scale;
  183. int clustersurfaces[MAX_MAP_LEAFFACES];
  184. int numclustersurfaces = 0;
  185. lsurfaceTest_t *lsurfaceTest[MAX_MAP_DRAW_SURFS];
  186. int numfacets;
  187. float lightmappixelarea[MAX_MAP_LIGHTING/3];
  188. float *lightFloats;//[MAX_MAP_LIGHTING];
  189. // from polylib.c
  190. winding_t *AllocWinding (int points);
  191. void FreeWinding (winding_t *w);
  192. void WindingCenter (winding_t *w, vec3_t center);
  193. void WindingBounds (winding_t *w, vec3_t mins, vec3_t maxs);
  194. vec_t WindingArea (winding_t *w);
  195. winding_t *BaseWindingForPlane (vec3_t normal, vec_t dist);
  196. void ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist,
  197. vec_t epsilon, winding_t **front, winding_t **back);
  198. winding_t *ReverseWinding (winding_t *w);
  199. // from light.c
  200. extern char source[1024];
  201. extern vec3_t surfaceOrigin[ MAX_MAP_DRAW_SURFS ];
  202. extern int entitySurface[ MAX_MAP_DRAW_SURFS ];
  203. extern int samplesize;
  204. extern int novertexlighting;
  205. extern int nogridlighting;
  206. extern qboolean patchshadows;
  207. extern vec3_t gridSize;
  208. float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const winding_t *w );
  209. void ColorToBytes( const float *color, byte *colorBytes );
  210. void CountLightmaps( void );
  211. void GridAndVertexLighting( void );
  212. void SetEntityOrigins( void );
  213. //#define DEBUGNET
  214. #ifdef DEBUGNET
  215. #include "l_net.h"
  216. socket_t *debug_socket;
  217. /*
  218. =====================
  219. DebugNet_Setup
  220. =====================
  221. */
  222. void DebugNet_Setup(void)
  223. {
  224. address_t address;
  225. int i;
  226. Net_Setup();
  227. Net_StringToAddress("127.0.0.1:28000", &address);
  228. for (i = 0; i < 10; i++)
  229. {
  230. debug_socket = Net_Connect(&address, 28005 + i);
  231. if (debug_socket)
  232. break;
  233. }
  234. }
  235. /*
  236. =====================
  237. DebugNet_Shutdown
  238. =====================
  239. */
  240. void DebugNet_Shutdown(void)
  241. {
  242. netmessage_t msg;
  243. if (debug_socket)
  244. {
  245. NMSG_Clear(&msg);
  246. NMSG_WriteByte(&msg, 1);
  247. Net_Send(debug_socket, &msg);
  248. Net_Disconnect(debug_socket);
  249. }
  250. debug_socket = NULL;
  251. Net_Shutdown();
  252. }
  253. /*
  254. =====================
  255. DebugNet_RemoveAllPolys
  256. =====================
  257. */
  258. void DebugNet_RemoveAllPolys(void)
  259. {
  260. netmessage_t msg;
  261. if (!debug_socket)
  262. return;
  263. NMSG_Clear(&msg);
  264. NMSG_WriteByte(&msg, 2); //remove all debug polys
  265. Net_Send(debug_socket, &msg);
  266. }
  267. /*
  268. ====================
  269. DebugNet_DrawWinding
  270. =====================
  271. */
  272. void DebugNet_DrawWinding(winding_t *w, int color)
  273. {
  274. netmessage_t msg;
  275. int i;
  276. if (!debug_socket)
  277. return;
  278. NMSG_Clear(&msg);
  279. NMSG_WriteByte(&msg, 0); //draw a winding
  280. NMSG_WriteByte(&msg, w->numpoints); //number of points
  281. NMSG_WriteLong(&msg, color); //color
  282. for (i = 0; i < w->numpoints; i++)
  283. {
  284. NMSG_WriteFloat(&msg, w->points[i][0]);
  285. NMSG_WriteFloat(&msg, w->points[i][1]);
  286. NMSG_WriteFloat(&msg, w->points[i][2]);
  287. }
  288. Net_Send(debug_socket, &msg);
  289. }
  290. /*
  291. =====================
  292. DebugNet_DrawLine
  293. =====================
  294. */
  295. void DebugNet_DrawLine(vec3_t p1, vec3_t p2, int color)
  296. {
  297. netmessage_t msg;
  298. if (!debug_socket)
  299. return;
  300. NMSG_Clear(&msg);
  301. NMSG_WriteByte(&msg, 1); //draw a line
  302. NMSG_WriteLong(&msg, color); //color
  303. NMSG_WriteFloat(&msg, p1[0]);
  304. NMSG_WriteFloat(&msg, p1[1]);
  305. NMSG_WriteFloat(&msg, p1[2]);
  306. NMSG_WriteFloat(&msg, p2[0]);
  307. NMSG_WriteFloat(&msg, p2[1]);
  308. NMSG_WriteFloat(&msg, p2[2]);
  309. Net_Send(debug_socket, &msg);
  310. }
  311. /*
  312. =====================
  313. DebugNet_DrawMesh
  314. =====================
  315. */
  316. void DebugNet_DrawMesh(mesh_t *mesh)
  317. {
  318. int i, j;
  319. float dot;
  320. drawVert_t *v1, *v2, *v3, *v4;
  321. winding_t winding;
  322. plane_t plane;
  323. vec3_t d1, d2;
  324. for ( i = 0 ; i < mesh->width - 1 ; i++ ) {
  325. for ( j = 0 ; j < mesh->height - 1 ; j++ ) {
  326. v1 = mesh->verts + j * mesh->width + i;
  327. v2 = v1 + 1;
  328. v3 = v1 + mesh->width + 1;
  329. v4 = v1 + mesh->width;
  330. VectorSubtract( v4->xyz, v1->xyz, d1 );
  331. VectorSubtract( v3->xyz, v1->xyz, d2 );
  332. CrossProduct( d2, d1, plane.normal );
  333. if ( VectorNormalize( plane.normal, plane.normal ) != 0 )
  334. {
  335. plane.dist = DotProduct( v1->xyz, plane.normal );
  336. dot = DotProduct(plane.normal, v2->xyz) - plane.dist;
  337. if (fabs(dot) < 0.1)
  338. {
  339. VectorCopy(v1->xyz, winding.points[0]);
  340. VectorCopy(v4->xyz, winding.points[1]);
  341. VectorCopy(v3->xyz, winding.points[2]);
  342. VectorCopy(v2->xyz, winding.points[3]);
  343. winding.numpoints = 4;
  344. DebugNet_DrawWinding(&winding, 2);
  345. continue;
  346. }
  347. }
  348. winding.numpoints = 3;
  349. VectorCopy(v1->xyz, winding.points[0]);
  350. VectorCopy(v4->xyz, winding.points[1]);
  351. VectorCopy(v3->xyz, winding.points[2]);
  352. DebugNet_DrawWinding(&winding, 2);
  353. VectorCopy(v1->xyz, winding.points[0]);
  354. VectorCopy(v3->xyz, winding.points[1]);
  355. VectorCopy(v2->xyz, winding.points[2]);
  356. DebugNet_DrawWinding(&winding, 2);
  357. }
  358. }
  359. }
  360. /*
  361. =====================
  362. VL_DrawLightVolume
  363. =====================
  364. */
  365. int VL_ChopWinding (winding_t *in, plane_t *split, float epsilon);
  366. void VL_DrawLightVolume(vlight_t *light, lightvolume_t *volume)
  367. {
  368. winding_t w;
  369. int i;
  370. vec3_t p2, invlight;
  371. memcpy(w.points, volume->points, volume->numplanes * sizeof(vec3_t));
  372. w.numpoints = volume->numplanes;
  373. DebugNet_DrawWinding(&w, 2);
  374. if (volume->type == VOLUME_DIRECTED)
  375. {
  376. VectorCopy(light->normal, invlight);
  377. VectorInverse(invlight);
  378. for (i = 0; i < volume->numplanes; i++)
  379. {
  380. VectorCopy(volume->points[i], w.points[0]);
  381. VectorCopy(volume->points[(i+1) % volume->numplanes], w.points[1]);
  382. VectorMA(w.points[1], MAX_WORLD_COORD, invlight, w.points[2]);
  383. VectorMA(w.points[0], MAX_WORLD_COORD, invlight, w.points[3]);
  384. w.numpoints = 4;
  385. DebugNet_DrawWinding(&w, 2);
  386. VectorMA(volume->points[i], 8, volume->planes[i].normal, p2);
  387. DebugNet_DrawLine(volume->points[i], p2, 3);
  388. }
  389. }
  390. else
  391. {
  392. //
  393. VectorCopy(light->origin, w.points[0]);
  394. w.numpoints = 3;
  395. for (i = 0; i < volume->numplanes; i++)
  396. {
  397. VectorCopy(volume->points[i], w.points[1]);
  398. VectorCopy(volume->points[(i+1) % volume->numplanes], w.points[2]);
  399. VL_ChopWinding(&w, &volume->endplane, 0);
  400. DebugNet_DrawWinding(&w, 2);
  401. VectorMA(volume->points[i], 8, volume->planes[i].normal, p2);
  402. DebugNet_DrawLine(volume->points[i], p2, 3);
  403. }
  404. }
  405. }
  406. /*
  407. =============
  408. VL_DrawLightmapPixel
  409. =============
  410. */
  411. void VL_DrawLightmapPixel(int surfaceNum, int x, int y, int color)
  412. {
  413. winding_t w;
  414. dsurface_t *ds;
  415. mesh_t *mesh;
  416. ds = &drawSurfaces[surfaceNum];
  417. if (ds->surfaceType == MST_PATCH)
  418. {
  419. mesh = lsurfaceTest[surfaceNum]->detailMesh;
  420. VectorCopy( mesh->verts[(y-ds->lightmapY)*mesh->width+x-ds->lightmapX].xyz, w.points[0]);
  421. VectorCopy( mesh->verts[(y+1-ds->lightmapY)*mesh->width+x-ds->lightmapX].xyz, w.points[1]);
  422. VectorCopy( mesh->verts[(y+1-ds->lightmapY)*mesh->width+x+1-ds->lightmapX].xyz, w.points[2]);
  423. VectorCopy( mesh->verts[(y-ds->lightmapY)*mesh->width+x+1-ds->lightmapX].xyz, w.points[3]);
  424. w.numpoints = 4;
  425. }
  426. else
  427. {
  428. VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT - ds->lightmapX, ds->lightmapVecs[0], w.points[0]);
  429. VectorMA(w.points[0], (float) y - LIGHTMAP_PIXELSHIFT - ds->lightmapY, ds->lightmapVecs[1], w.points[0]);
  430. VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT - ds->lightmapX, ds->lightmapVecs[0], w.points[1]);
  431. VectorMA(w.points[1], (float) y - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapY, ds->lightmapVecs[1], w.points[1]);
  432. VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapX, ds->lightmapVecs[0], w.points[2]);
  433. VectorMA(w.points[2], (float) y - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapY, ds->lightmapVecs[1], w.points[2]);
  434. VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapX, ds->lightmapVecs[0], w.points[3]);
  435. VectorMA(w.points[3], (float) y - LIGHTMAP_PIXELSHIFT - ds->lightmapY, ds->lightmapVecs[1], w.points[3]);
  436. w.numpoints = 4;
  437. }
  438. DebugNet_DrawWinding(&w, color);
  439. }
  440. /*
  441. ============
  442. VL_DrawPortals
  443. ============
  444. */
  445. void VL_DrawPortals(void)
  446. {
  447. int j;
  448. lportal_t *p;
  449. for (j = 0; j < numportals * 2; j++)
  450. {
  451. p = portals + j;
  452. DebugNet_DrawWinding(p->winding, 1);
  453. }
  454. }
  455. /*
  456. ============
  457. VL_DrawLeaf
  458. ============
  459. */
  460. void VL_DrawLeaf(int cluster)
  461. {
  462. int i;
  463. lleaf_t *leaf;
  464. lportal_t *p;
  465. leaf = &leafs[cluster];
  466. for (i = 0; i < leaf->numportals; i++)
  467. {
  468. p = leaf->portals[i];
  469. DebugNet_DrawWinding(p->winding, 1);
  470. }
  471. }
  472. #endif //DEBUGNET
  473. /*
  474. =============
  475. VL_SplitWinding
  476. =============
  477. */
  478. int VL_SplitWinding (winding_t *in, winding_t *back, plane_t *split, float epsilon)
  479. {
  480. vec_t dists[128];
  481. int sides[128];
  482. int counts[3];
  483. vec_t dot;
  484. int i, j;
  485. vec_t *p1, *p2;
  486. vec3_t mid;
  487. winding_t out;
  488. winding_t *neww;
  489. counts[0] = counts[1] = counts[2] = 0;
  490. // determine sides for each point
  491. for (i=0 ; i<in->numpoints ; i++)
  492. {
  493. dot = DotProduct (in->points[i], split->normal);
  494. dot -= split->dist;
  495. dists[i] = dot;
  496. if (dot > epsilon)
  497. sides[i] = SIDE_FRONT;
  498. else if (dot < -epsilon)
  499. sides[i] = SIDE_BACK;
  500. else
  501. {
  502. sides[i] = SIDE_ON;
  503. }
  504. counts[sides[i]]++;
  505. }
  506. if (!counts[SIDE_BACK])
  507. {
  508. if (!counts[SIDE_FRONT])
  509. return SIDE_ON;
  510. else
  511. return SIDE_FRONT;
  512. }
  513. if (!counts[SIDE_FRONT])
  514. {
  515. return SIDE_BACK;
  516. }
  517. sides[i] = sides[0];
  518. dists[i] = dists[0];
  519. neww = &out;
  520. neww->numpoints = 0;
  521. back->numpoints = 0;
  522. for (i=0 ; i<in->numpoints ; i++)
  523. {
  524. p1 = in->points[i];
  525. if (neww->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
  526. {
  527. _printf("WARNING: VL_SplitWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
  528. return SIDE_FRONT; // can't chop -- fall back to original
  529. }
  530. if (back->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
  531. {
  532. _printf("WARNING: VL_SplitWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
  533. return SIDE_FRONT;
  534. }
  535. if (sides[i] == SIDE_ON)
  536. {
  537. VectorCopy (p1, neww->points[neww->numpoints]);
  538. neww->numpoints++;
  539. VectorCopy (p1, back->points[back->numpoints]);
  540. back->numpoints++;
  541. continue;
  542. }
  543. if (sides[i] == SIDE_FRONT)
  544. {
  545. VectorCopy (p1, neww->points[neww->numpoints]);
  546. neww->numpoints++;
  547. }
  548. if (sides[i] == SIDE_BACK)
  549. {
  550. VectorCopy (p1, back->points[back->numpoints]);
  551. back->numpoints++;
  552. }
  553. if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
  554. continue;
  555. if (neww->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
  556. {
  557. _printf("WARNING: VL_SplitWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
  558. return SIDE_FRONT; // can't chop -- fall back to original
  559. }
  560. if (back->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
  561. {
  562. _printf("WARNING: VL_SplitWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
  563. return SIDE_FRONT; // can't chop -- fall back to original
  564. }
  565. // generate a split point
  566. p2 = in->points[(i+1)%in->numpoints];
  567. dot = dists[i] / (dists[i]-dists[i+1]);
  568. for (j=0 ; j<3 ; j++)
  569. { // avoid round off error when possible
  570. if (split->normal[j] == 1)
  571. mid[j] = split->dist;
  572. else if (split->normal[j] == -1)
  573. mid[j] = -split->dist;
  574. else
  575. mid[j] = p1[j] + dot*(p2[j]-p1[j]);
  576. }
  577. VectorCopy (mid, neww->points[neww->numpoints]);
  578. neww->numpoints++;
  579. VectorCopy (mid, back->points[back->numpoints]);
  580. back->numpoints++;
  581. }
  582. memcpy(in, &out, sizeof(winding_t));
  583. return SIDE_CROSS;
  584. }
  585. /*
  586. =====================
  587. VL_LinkSurfaceIntoCluster
  588. =====================
  589. */
  590. void VL_LinkSurfaceIntoCluster(int cluster, int surfaceNum)
  591. {
  592. lleaf_t *leaf;
  593. int i;
  594. leaf = &leafs[cluster];
  595. for (i = 0; i < leaf->numSurfaces; i++)
  596. {
  597. if (clustersurfaces[leaf->firstSurface + i] == surfaceNum)
  598. return;
  599. }
  600. for (i = numclustersurfaces; i > leaf->firstSurface + leaf->numSurfaces; i--)
  601. clustersurfaces[i] = clustersurfaces[i-1];
  602. for (i = 0; i < portalclusters; i++)
  603. {
  604. if (i == cluster)
  605. continue;
  606. if (leafs[i].firstSurface >= leaf->firstSurface + leaf->numSurfaces)
  607. leafs[i].firstSurface++;
  608. }
  609. clustersurfaces[leaf->firstSurface + leaf->numSurfaces] = surfaceNum;
  610. leaf->numSurfaces++;
  611. numclustersurfaces++;
  612. if (numclustersurfaces >= MAX_MAP_LEAFFACES)
  613. Error("MAX_MAP_LEAFFACES");
  614. }
  615. /*
  616. =====================
  617. VL_R_LinkSurface
  618. =====================
  619. */
  620. void VL_R_LinkSurface(int nodenum, int surfaceNum, winding_t *w)
  621. {
  622. int leafnum, cluster, res;
  623. dnode_t *node;
  624. dplane_t *plane;
  625. winding_t back;
  626. plane_t split;
  627. while(nodenum >= 0)
  628. {
  629. node = &dnodes[nodenum];
  630. plane = &dplanes[node->planeNum];
  631. VectorCopy(plane->normal, split.normal);
  632. split.dist = plane->dist;
  633. res = VL_SplitWinding (w, &back, &split, 0.1);
  634. if (res == SIDE_FRONT)
  635. {
  636. nodenum = node->children[0];
  637. }
  638. else if (res == SIDE_BACK)
  639. {
  640. nodenum = node->children[1];
  641. }
  642. else if (res == SIDE_ON)
  643. {
  644. memcpy(&back, w, sizeof(winding_t));
  645. VL_R_LinkSurface(node->children[1], surfaceNum, &back);
  646. nodenum = node->children[0];
  647. }
  648. else
  649. {
  650. VL_R_LinkSurface(node->children[1], surfaceNum, &back);
  651. nodenum = node->children[0];
  652. }
  653. }
  654. leafnum = -nodenum - 1;
  655. cluster = dleafs[leafnum].cluster;
  656. if (cluster != -1)
  657. {
  658. VL_LinkSurfaceIntoCluster(cluster, surfaceNum);
  659. }
  660. }
  661. /*
  662. =====================
  663. VL_LinkSurfaces
  664. maybe link each facet seperately instead of the test surfaces?
  665. =====================
  666. */
  667. void VL_LinkSurfaces(void)
  668. {
  669. int i, j;
  670. lsurfaceTest_t *test;
  671. lFacet_t *facet;
  672. winding_t winding;
  673. for ( i = 0 ; i < numDrawSurfaces ; i++ )
  674. {
  675. test = lsurfaceTest[ i ];
  676. if (!test)
  677. continue;
  678. for (j = 0; j < test->numFacets; j++)
  679. {
  680. facet = &test->facets[j];
  681. memcpy(winding.points, facet->points, facet->numpoints * sizeof(vec3_t));
  682. winding.numpoints = facet->numpoints;
  683. VL_R_LinkSurface(0, i, &winding);
  684. }
  685. }
  686. }
  687. /*
  688. =====================
  689. VL_TextureMatrixFromPoints
  690. =====================
  691. */
  692. void VL_TextureMatrixFromPoints( lFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c ) {
  693. int i, j;
  694. float t;
  695. float m[3][4];
  696. float s;
  697. // This is an incredibly stupid way of solving a three variable equation
  698. for ( i = 0 ; i < 2 ; i++ ) {
  699. m[0][0] = a->xyz[0];
  700. m[0][1] = a->xyz[1];
  701. m[0][2] = a->xyz[2];
  702. m[0][3] = a->st[i];
  703. m[1][0] = b->xyz[0];
  704. m[1][1] = b->xyz[1];
  705. m[1][2] = b->xyz[2];
  706. m[1][3] = b->st[i];
  707. m[2][0] = c->xyz[0];
  708. m[2][1] = c->xyz[1];
  709. m[2][2] = c->xyz[2];
  710. m[2][3] = c->st[i];
  711. if ( fabs(m[1][0]) > fabs(m[0][0]) && fabs(m[1][0]) > fabs(m[2][0]) ) {
  712. for ( j = 0 ; j < 4 ; j ++ ) {
  713. t = m[0][j];
  714. m[0][j] = m[1][j];
  715. m[1][j] = t;
  716. }
  717. } else if ( fabs(m[2][0]) > fabs(m[0][0]) && fabs(m[2][0]) > fabs(m[1][0]) ) {
  718. for ( j = 0 ; j < 4 ; j ++ ) {
  719. t = m[0][j];
  720. m[0][j] = m[2][j];
  721. m[2][j] = t;
  722. }
  723. }
  724. s = 1.0 / m[0][0];
  725. m[0][0] *= s;
  726. m[0][1] *= s;
  727. m[0][2] *= s;
  728. m[0][3] *= s;
  729. s = m[1][0];
  730. m[1][0] -= m[0][0] * s;
  731. m[1][1] -= m[0][1] * s;
  732. m[1][2] -= m[0][2] * s;
  733. m[1][3] -= m[0][3] * s;
  734. s = m[2][0];
  735. m[2][0] -= m[0][0] * s;
  736. m[2][1] -= m[0][1] * s;
  737. m[2][2] -= m[0][2] * s;
  738. m[2][3] -= m[0][3] * s;
  739. if ( fabs(m[2][1]) > fabs(m[1][1]) ) {
  740. for ( j = 0 ; j < 4 ; j ++ ) {
  741. t = m[1][j];
  742. m[1][j] = m[2][j];
  743. m[2][j] = t;
  744. }
  745. }
  746. s = 1.0 / m[1][1];
  747. m[1][0] *= s;
  748. m[1][1] *= s;
  749. m[1][2] *= s;
  750. m[1][3] *= s;
  751. s = m[2][1];// / m[1][1];
  752. m[2][0] -= m[1][0] * s;
  753. m[2][1] -= m[1][1] * s;
  754. m[2][2] -= m[1][2] * s;
  755. m[2][3] -= m[1][3] * s;
  756. s = 1.0 / m[2][2];
  757. m[2][0] *= s;
  758. m[2][1] *= s;
  759. m[2][2] *= s;
  760. m[2][3] *= s;
  761. f->textureMatrix[i][2] = m[2][3];
  762. f->textureMatrix[i][1] = m[1][3] - f->textureMatrix[i][2] * m[1][2];
  763. f->textureMatrix[i][0] = m[0][3] - f->textureMatrix[i][2] * m[0][2] - f->textureMatrix[i][1] * m[0][1];
  764. f->textureMatrix[i][3] = 0;
  765. /*
  766. s = fabs( DotProduct( a->xyz, f->textureMatrix[i] ) - a->st[i] );
  767. if ( s > 0.01 ) {
  768. Error( "Bad textureMatrix" );
  769. }
  770. s = fabs( DotProduct( b->xyz, f->textureMatrix[i] ) - b->st[i] );
  771. if ( s > 0.01 ) {
  772. Error( "Bad textureMatrix" );
  773. }
  774. s = fabs( DotProduct( c->xyz, f->textureMatrix[i] ) - c->st[i] );
  775. if ( s > 0.01 ) {
  776. Error( "Bad textureMatrix" );
  777. }
  778. */
  779. }
  780. }
  781. /*
  782. =====================
  783. VL_LightmapMatrixFromPoints
  784. =====================
  785. */
  786. void VL_LightmapMatrixFromPoints( dsurface_t *dsurf, shaderInfo_t *si, lFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c ) {
  787. int i, j;
  788. float t;
  789. float m[3][4], al, bl, cl;
  790. float s;
  791. int h, w, ssize;
  792. vec3_t mins, maxs, delta, size, planeNormal;
  793. drawVert_t *verts;
  794. static int message;
  795. // vertex-lit triangle model
  796. if ( dsurf->surfaceType == MST_TRIANGLE_SOUP ) {
  797. return;
  798. }
  799. if ( dsurf->lightmapNum < 0 ) {
  800. return; // doesn't need lighting
  801. }
  802. VectorClear(f->mins);
  803. if (dsurf->surfaceType != MST_PATCH)
  804. {
  805. ssize = samplesize;
  806. if (si->lightmapSampleSize)
  807. ssize = si->lightmapSampleSize;
  808. ClearBounds( mins, maxs );
  809. verts = &drawVerts[dsurf->firstVert];
  810. for ( i = 0 ; i < dsurf->numVerts ; i++ ) {
  811. AddPointToBounds( verts[i].xyz, mins, maxs );
  812. }
  813. // round to the lightmap resolution
  814. for ( i = 0 ; i < 3 ; i++ ) {
  815. mins[i] = ssize * floor( mins[i] / ssize );
  816. maxs[i] = ssize * ceil( maxs[i] / ssize );
  817. f->mins[i] = mins[i];
  818. size[i] = (maxs[i] - mins[i]) / ssize + 1;
  819. }
  820. // the two largest axis will be the lightmap size
  821. VectorClear(f->lightmapMatrix[0]);
  822. f->lightmapMatrix[0][3] = 0;
  823. VectorClear(f->lightmapMatrix[1]);
  824. f->lightmapMatrix[1][3] = 0;
  825. planeNormal[0] = fabs( dsurf->lightmapVecs[2][0] );
  826. planeNormal[1] = fabs( dsurf->lightmapVecs[2][1] );
  827. planeNormal[2] = fabs( dsurf->lightmapVecs[2][2] );
  828. if ( planeNormal[0] >= planeNormal[1] && planeNormal[0] >= planeNormal[2] ) {
  829. w = size[1];
  830. h = size[2];
  831. f->lightmapMatrix[0][1] = 1.0 / ssize;
  832. f->lightmapMatrix[1][2] = 1.0 / ssize;
  833. } else if ( planeNormal[1] >= planeNormal[0] && planeNormal[1] >= planeNormal[2] ) {
  834. w = size[0];
  835. h = size[2];
  836. f->lightmapMatrix[0][0] = 1.0 / ssize;
  837. f->lightmapMatrix[1][2] = 1.0 / ssize;
  838. } else {
  839. w = size[0];
  840. h = size[1];
  841. f->lightmapMatrix[0][0] = 1.0 / ssize;
  842. f->lightmapMatrix[1][1] = 1.0 / ssize;
  843. }
  844. if ( w > LIGHTMAP_WIDTH ) {
  845. VectorScale ( f->lightmapMatrix[0], (float)LIGHTMAP_SIZE/w, f->lightmapMatrix[0] );
  846. }
  847. if ( h > LIGHTMAP_HEIGHT ) {
  848. VectorScale ( f->lightmapMatrix[1], (float)LIGHTMAP_SIZE/h, f->lightmapMatrix[1] );
  849. }
  850. VectorSubtract(a->xyz, f->mins, delta);
  851. s = (DotProduct( delta, f->lightmapMatrix[0] ) + dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
  852. if ( fabs(s - a->lightmap[0]) > 0.01 ) {
  853. _printf( "Bad lightmapMatrix" );
  854. }
  855. t = (DotProduct( delta, f->lightmapMatrix[1] ) + dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
  856. if ( fabs(t - a->lightmap[1]) > 0.01 ) {
  857. _printf( "Bad lightmapMatrix" );
  858. }
  859. VectorSubtract(b->xyz, f->mins, delta);
  860. s = (DotProduct( delta, f->lightmapMatrix[0] ) + dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
  861. if ( fabs(s - b->lightmap[0]) > 0.01 ) {
  862. _printf( "Bad lightmapMatrix" );
  863. }
  864. t = (DotProduct( delta, f->lightmapMatrix[1] ) + dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
  865. if ( fabs(t - b->lightmap[1]) > 0.01 ) {
  866. _printf( "Bad lightmapMatrix" );
  867. }
  868. VectorSubtract(c->xyz, f->mins, delta);
  869. s = (DotProduct( delta, f->lightmapMatrix[0] ) + dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
  870. if ( fabs(s - c->lightmap[0]) > 0.01 ) {
  871. _printf( "Bad lightmapMatrix" );
  872. }
  873. t = (DotProduct( delta, f->lightmapMatrix[1] ) + dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
  874. if ( fabs(t - c->lightmap[1]) > 0.01 ) {
  875. _printf( "Bad lightmapMatrix" );
  876. }
  877. VectorAdd(f->mins, surfaceOrigin[dsurf - drawSurfaces], f->mins);
  878. return;
  879. }
  880. // This is an incredibly stupid way of solving a three variable equation
  881. for ( i = 0 ; i < 2 ; i++ ) {
  882. if (i)
  883. al = a->lightmap[i] - ((float) dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
  884. else
  885. al = a->lightmap[i] - ((float) dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
  886. m[0][0] = a->xyz[0] - f->mins[0];
  887. m[0][1] = a->xyz[1] - f->mins[1];
  888. m[0][2] = a->xyz[2] - f->mins[2];
  889. m[0][3] = al;
  890. if (i)
  891. bl = b->lightmap[i] - ((float) dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
  892. else
  893. bl = b->lightmap[i] - ((float) dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
  894. m[1][0] = b->xyz[0] - f->mins[0];
  895. m[1][1] = b->xyz[1] - f->mins[1];
  896. m[1][2] = b->xyz[2] - f->mins[2];
  897. m[1][3] = bl;
  898. if (i)
  899. cl = c->lightmap[i] - ((float) dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
  900. else
  901. cl = c->lightmap[i] - ((float) dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
  902. m[2][0] = c->xyz[0] - f->mins[0];
  903. m[2][1] = c->xyz[1] - f->mins[1];
  904. m[2][2] = c->xyz[2] - f->mins[2];
  905. m[2][3] = cl;
  906. if ( fabs(m[1][0]) > fabs(m[0][0]) && fabs(m[1][0]) >= fabs(m[2][0]) ) {
  907. for ( j = 0 ; j < 4 ; j ++ ) {
  908. t = m[0][j];
  909. m[0][j] = m[1][j];
  910. m[1][j] = t;
  911. }
  912. } else if ( fabs(m[2][0]) > fabs(m[0][0]) && fabs(m[2][0]) >= fabs(m[1][0]) ) {
  913. for ( j = 0 ; j < 4 ; j ++ ) {
  914. t = m[0][j];
  915. m[0][j] = m[2][j];
  916. m[2][j] = t;
  917. }
  918. }
  919. if (m[0][0])
  920. {
  921. s = 1.0 / m[0][0];
  922. m[0][0] *= s;
  923. m[0][1] *= s;
  924. m[0][2] *= s;
  925. m[0][3] *= s;
  926. s = m[1][0];
  927. m[1][0] -= m[0][0] * s;
  928. m[1][1] -= m[0][1] * s;
  929. m[1][2] -= m[0][2] * s;
  930. m[1][3] -= m[0][3] * s;
  931. s = m[2][0];
  932. m[2][0] -= m[0][0] * s;
  933. m[2][1] -= m[0][1] * s;
  934. m[2][2] -= m[0][2] * s;
  935. m[2][3] -= m[0][3] * s;
  936. }
  937. if ( fabs(m[2][1]) > fabs(m[1][1]) ) {
  938. for ( j = 0 ; j < 4 ; j ++ ) {
  939. t = m[1][j];
  940. m[1][j] = m[2][j];
  941. m[2][j] = t;
  942. }
  943. }
  944. if (m[1][1])
  945. {
  946. s = 1.0 / m[1][1];
  947. m[1][0] *= s;
  948. m[1][1] *= s;
  949. m[1][2] *= s;
  950. m[1][3] *= s;
  951. s = m[2][1];
  952. m[2][0] -= m[1][0] * s;
  953. m[2][1] -= m[1][1] * s;
  954. m[2][2] -= m[1][2] * s;
  955. m[2][3] -= m[1][3] * s;
  956. }
  957. if (m[2][2])
  958. {
  959. s = 1.0 / m[2][2];
  960. m[2][0] *= s;
  961. m[2][1] *= s;
  962. m[2][2] *= s;
  963. m[2][3] *= s;
  964. }
  965. f->lightmapMatrix[i][2] = m[2][3];
  966. f->lightmapMatrix[i][1] = m[1][3] - f->lightmapMatrix[i][2] * m[1][2];
  967. f->lightmapMatrix[i][0] = m[0][3] - f->lightmapMatrix[i][2] * m[0][2] - f->lightmapMatrix[i][1] * m[0][1];
  968. f->lightmapMatrix[i][3] = 0;
  969. VectorSubtract(a->xyz, f->mins, delta);
  970. s = fabs( DotProduct( delta, f->lightmapMatrix[i] ) - al );
  971. if ( s > 0.01 ) {
  972. if (!message)
  973. _printf( "Bad lightmapMatrix\n" );
  974. message = qtrue;
  975. }
  976. VectorSubtract(b->xyz, f->mins, delta);
  977. s = fabs( DotProduct( delta, f->lightmapMatrix[i] ) - bl );
  978. if ( s > 0.01 ) {
  979. if (!message)
  980. _printf( "Bad lightmapMatrix\n" );
  981. message = qtrue;
  982. }
  983. VectorSubtract(c->xyz, f->mins, delta);
  984. s = fabs( DotProduct( delta, f->lightmapMatrix[i] ) - cl );
  985. if ( s > 0.01 ) {
  986. if (!message)
  987. _printf( "Bad lightmapMatrix\n" );
  988. message = qtrue;
  989. }
  990. VectorAdd(f->mins, surfaceOrigin[dsurf - drawSurfaces], f->mins);
  991. }
  992. }
  993. /*
  994. =============
  995. Plane_Equal
  996. =============
  997. */
  998. #define NORMAL_EPSILON 0.0001
  999. #define DIST_EPSILON 0.02
  1000. int Plane_Equal(plane_t *a, plane_t *b, int flip)
  1001. {
  1002. vec3_t normal;
  1003. float dist;
  1004. if (flip) {
  1005. normal[0] = - b->normal[0];
  1006. normal[1] = - b->normal[1];
  1007. normal[2] = - b->normal[2];
  1008. dist = - b->dist;
  1009. }
  1010. else {
  1011. normal[0] = b->normal[0];
  1012. normal[1] = b->normal[1];
  1013. normal[2] = b->normal[2];
  1014. dist = b->dist;
  1015. }
  1016. if (
  1017. fabs(a->normal[0] - normal[0]) < NORMAL_EPSILON
  1018. && fabs(a->normal[1] - normal[1]) < NORMAL_EPSILON
  1019. && fabs(a->normal[2] - normal[2]) < NORMAL_EPSILON
  1020. && fabs(a->dist - dist) < DIST_EPSILON )
  1021. return qtrue;
  1022. return qfalse;
  1023. }
  1024. /*
  1025. =============
  1026. VL_PlaneFromPoints
  1027. =============
  1028. */
  1029. qboolean VL_PlaneFromPoints( plane_t *plane, const vec3_t a, const vec3_t b, const vec3_t c ) {
  1030. vec3_t d1, d2;
  1031. VectorSubtract( b, a, d1 );
  1032. VectorSubtract( c, a, d2 );
  1033. CrossProduct( d2, d1, plane->normal );
  1034. if ( VectorNormalize( plane->normal, plane->normal ) == 0 ) {
  1035. return qfalse;
  1036. }
  1037. plane->dist = DotProduct( a, plane->normal );
  1038. return qtrue;
  1039. }
  1040. /*
  1041. =====================
  1042. VL_GenerateBoundaryForPoints
  1043. =====================
  1044. */
  1045. void VL_GenerateBoundaryForPoints( plane_t *boundary, plane_t *plane, vec3_t a, vec3_t b ) {
  1046. vec3_t d1;
  1047. // make a perpendicular vector to the edge and the surface
  1048. VectorSubtract( a, b, d1 );
  1049. CrossProduct( plane->normal, d1, boundary->normal );
  1050. VectorNormalize( boundary->normal, boundary->normal );
  1051. boundary->dist = DotProduct( a, boundary->normal );
  1052. }
  1053. /*
  1054. =====================
  1055. VL_GenerateFacetFor3Points
  1056. =====================
  1057. */
  1058. qboolean VL_GenerateFacetFor3Points( dsurface_t *dsurf, shaderInfo_t *si, lFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c ) {
  1059. //
  1060. vec3_t dir;
  1061. int i;
  1062. // if we can't generate a valid plane for the points, ignore the facet
  1063. if ( !VL_PlaneFromPoints( &f->plane, a->xyz, b->xyz, c->xyz ) ) {
  1064. f->numpoints = 0;
  1065. return qfalse;
  1066. }
  1067. f->num = numfacets++;
  1068. VectorAdd( a->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[0] );
  1069. VectorAdd( b->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[1] );
  1070. VectorAdd( c->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[2] );
  1071. f->lightmapCoords[0][0] = a->lightmap[0];
  1072. f->lightmapCoords[0][1] = a->lightmap[1];
  1073. f->lightmapCoords[1][0] = b->lightmap[0];
  1074. f->lightmapCoords[1][1] = b->lightmap[1];
  1075. f->lightmapCoords[2][0] = c->lightmap[0];
  1076. f->lightmapCoords[2][1] = c->lightmap[1];
  1077. VL_GenerateBoundaryForPoints( &f->boundaries[0], &f->plane, f->points[0], f->points[1] );
  1078. VL_GenerateBoundaryForPoints( &f->boundaries[1], &f->plane, f->points[1], f->points[2] );
  1079. VL_GenerateBoundaryForPoints( &f->boundaries[2], &f->plane, f->points[2], f->points[0] );
  1080. for (i = 0; i < 3; i++)
  1081. {
  1082. VectorSubtract(f->points[(i+1)%3], f->points[i], dir);
  1083. if (VectorLength(dir) < 0.1)
  1084. return qfalse;
  1085. }
  1086. VL_TextureMatrixFromPoints( f, a, b, c );
  1087. VL_LightmapMatrixFromPoints( dsurf, si, f, a, b, c );
  1088. f->numpoints = 3;
  1089. return qtrue;
  1090. }
  1091. /*
  1092. =====================
  1093. VL_GenerateFacetFor4Points
  1094. Attempts to use four points as a planar quad
  1095. =====================
  1096. */
  1097. #define PLANAR_EPSILON 0.1
  1098. qboolean VL_GenerateFacetFor4Points( dsurface_t *dsurf, shaderInfo_t *si, lFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c, drawVert_t *d ) {
  1099. float dist;
  1100. vec3_t dir;
  1101. int i;
  1102. plane_t plane;
  1103. // if we can't generate a valid plane for the points, ignore the facet
  1104. if ( !VL_PlaneFromPoints( &f->plane, a->xyz, b->xyz, c->xyz ) ) {
  1105. f->numpoints = 0;
  1106. return qfalse;
  1107. }
  1108. // if the fourth point is also on the plane, we can make a quad facet
  1109. dist = DotProduct( d->xyz, f->plane.normal ) - f->plane.dist;
  1110. if ( fabs( dist ) > PLANAR_EPSILON ) {
  1111. f->numpoints = 0;
  1112. return qfalse;
  1113. }
  1114. VectorAdd( a->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[0] );
  1115. VectorAdd( b->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[1] );
  1116. VectorAdd( c->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[2] );
  1117. VectorAdd( d->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[3] );
  1118. for (i = 1; i < 4; i++)
  1119. {
  1120. if ( !VL_PlaneFromPoints( &plane, f->points[i], f->points[(i+1) % 4], f->points[(i+2) % 4]) ) {
  1121. f->numpoints = 0;
  1122. return qfalse;
  1123. }
  1124. if (!Plane_Equal(&f->plane, &plane, qfalse)) {
  1125. f->numpoints = 0;
  1126. return qfalse;
  1127. }
  1128. }
  1129. f->lightmapCoords[0][0] = a->lightmap[0];
  1130. f->lightmapCoords[0][1] = a->lightmap[1];
  1131. f->lightmapCoords[1][0] = b->lightmap[0];
  1132. f->lightmapCoords[1][1] = b->lightmap[1];
  1133. f->lightmapCoords[2][0] = c->lightmap[0];
  1134. f->lightmapCoords[2][1] = c->lightmap[1];
  1135. f->lightmapCoords[3][0] = d->lightmap[0];
  1136. f->lightmapCoords[3][1] = d->lightmap[1];
  1137. VL_GenerateBoundaryForPoints( &f->boundaries[0], &f->plane, f->points[0], f->points[1] );
  1138. VL_GenerateBoundaryForPoints( &f->boundaries[1], &f->plane, f->points[1], f->points[2] );
  1139. VL_GenerateBoundaryForPoints( &f->boundaries[2], &f->plane, f->points[2], f->points[3] );
  1140. VL_GenerateBoundaryForPoints( &f->boundaries[3], &f->plane, f->points[3], f->points[0] );
  1141. for (i = 0; i < 4; i++)
  1142. {
  1143. VectorSubtract(f->points[(i+1)%4], f->points[i], dir);
  1144. if (VectorLength(dir) < 0.1)
  1145. return qfalse;
  1146. }
  1147. VL_TextureMatrixFromPoints( f, a, b, c );
  1148. VL_LightmapMatrixFromPoints( dsurf, si, f, a, b, c );
  1149. f->num = numfacets++;
  1150. f->numpoints = 4;
  1151. return qtrue;
  1152. }
  1153. /*
  1154. ===============
  1155. VL_SphereFromBounds
  1156. ===============
  1157. */
  1158. void VL_SphereFromBounds( vec3_t mins, vec3_t maxs, vec3_t origin, float *radius ) {
  1159. vec3_t temp;
  1160. VectorAdd( mins, maxs, origin );
  1161. VectorScale( origin, 0.5, origin );
  1162. VectorSubtract( maxs, origin, temp );
  1163. *radius = VectorLength( temp );
  1164. }
  1165. /*
  1166. ====================
  1167. VL_FacetsForTriangleSurface
  1168. ====================
  1169. */
  1170. void VL_FacetsForTriangleSurface( dsurface_t *dsurf, shaderInfo_t *si, lsurfaceTest_t *test ) {
  1171. int i;
  1172. drawVert_t *v1, *v2, *v3, *v4;
  1173. int count;
  1174. int i1, i2, i3, i4, i5, i6;
  1175. test->patch = qfalse;
  1176. if (dsurf->surfaceType == MST_TRIANGLE_SOUP)
  1177. test->trisoup = qtrue;
  1178. else
  1179. test->trisoup = qfalse;
  1180. test->numFacets = dsurf->numIndexes / 3;
  1181. test->facets = malloc( sizeof( test->facets[0] ) * test->numFacets );
  1182. test->shader = si;
  1183. count = 0;
  1184. for ( i = 0 ; i < test->numFacets ; i++ ) {
  1185. i1 = drawIndexes[ dsurf->firstIndex + i*3 ];
  1186. i2 = drawIndexes[ dsurf->firstIndex + i*3 + 1 ];
  1187. i3 = drawIndexes[ dsurf->firstIndex + i*3 + 2 ];
  1188. v1 = &drawVerts[ dsurf->firstVert + i1 ];
  1189. v2 = &drawVerts[ dsurf->firstVert + i2 ];
  1190. v3 = &drawVerts[ dsurf->firstVert + i3 ];
  1191. // try and make a quad out of two triangles
  1192. if ( i != test->numFacets - 1 ) {
  1193. i4 = drawIndexes[ dsurf->firstIndex + i*3 + 3 ];
  1194. i5 = drawIndexes[ dsurf->firstIndex + i*3 + 4 ];
  1195. i6 = drawIndexes[ dsurf->firstIndex + i*3 + 5 ];
  1196. if ( i4 == i3 && i5 == i2 ) {
  1197. v4 = &drawVerts[ dsurf->firstVert + i6 ];
  1198. if ( VL_GenerateFacetFor4Points( dsurf, si, &test->facets[count], v1, v2, v4, v3 ) ) {
  1199. count++;
  1200. i++; // skip next tri
  1201. continue;
  1202. }
  1203. }
  1204. }
  1205. if (VL_GenerateFacetFor3Points( dsurf, si, &test->facets[count], v1, v2, v3 )) {
  1206. count++;
  1207. }
  1208. }
  1209. // we may have turned some pairs into quads
  1210. test->numFacets = count;
  1211. }
  1212. /*
  1213. ====================
  1214. VL_FacetsForPatch
  1215. ====================
  1216. */
  1217. void VL_FacetsForPatch( dsurface_t *dsurf, int surfaceNum, shaderInfo_t *si, lsurfaceTest_t *test ) {
  1218. int i, j, x, y;
  1219. drawVert_t *v1, *v2, *v3, *v4;
  1220. int count, ssize;
  1221. mesh_t mesh;
  1222. mesh_t *subdivided, *detailmesh, *newmesh;
  1223. int widthtable[LIGHTMAP_SIZE], heighttable[LIGHTMAP_SIZE];
  1224. mesh.width = dsurf->patchWidth;
  1225. mesh.height = dsurf->patchHeight;
  1226. mesh.verts = &drawVerts[ dsurf->firstVert ];
  1227. newmesh = SubdivideMesh( mesh, 8, 999 );
  1228. PutMeshOnCurve( *newmesh );
  1229. MakeMeshNormals( *newmesh );
  1230. subdivided = RemoveLinearMeshColumnsRows( newmesh );
  1231. FreeMesh(newmesh);
  1232. // DebugNet_RemoveAllPolys();
  1233. // DebugNet_DrawMesh(subdivided);
  1234. ssize = samplesize;
  1235. if (si->lightmapSampleSize)
  1236. ssize = si->lightmapSampleSize;
  1237. if ( dsurf->lightmapNum >= 0 ) {
  1238. detailmesh = SubdivideMeshQuads( subdivided, ssize, LIGHTMAP_SIZE, widthtable, heighttable);
  1239. test->detailMesh = detailmesh;
  1240. // DebugNet_RemoveAllPolys();
  1241. // DebugNet_DrawMesh(detailmesh);
  1242. if ( detailmesh->width != dsurf->lightmapWidth || detailmesh->height != dsurf->lightmapHeight ) {
  1243. Error( "Mesh lightmap miscount");
  1244. }
  1245. }
  1246. else {
  1247. test->detailMesh = NULL;
  1248. memset(widthtable, 0, sizeof(widthtable));
  1249. memset(heighttable, 0, sizeof(heighttable));
  1250. }
  1251. test->patch = qtrue;
  1252. test->trisoup = qfalse;
  1253. test->numFacets = ( subdivided->width - 1 ) * ( subdivided->height - 1 ) * 2;
  1254. test->facets = malloc( sizeof( test->facets[0] ) * test->numFacets );
  1255. test->shader = si;
  1256. count = 0;
  1257. x = 0;
  1258. for ( i = 0 ; i < subdivided->width - 1 ; i++ ) {
  1259. y = 0;
  1260. for ( j = 0 ; j < subdivided->height - 1 ; j++ ) {
  1261. v1 = subdivided->verts + j * subdivided->width + i;
  1262. v2 = v1 + 1;
  1263. v3 = v1 + subdivided->width + 1;
  1264. v4 = v1 + subdivided->width;
  1265. if ( VL_GenerateFacetFor4Points( dsurf, si, &test->facets[count], v1, v4, v3, v2 ) ) {
  1266. test->facets[count].x = x;
  1267. test->facets[count].y = y;
  1268. test->facets[count].width = widthtable[i];
  1269. test->facets[count].height = heighttable[j];
  1270. count++;
  1271. } else {
  1272. if (VL_GenerateFacetFor3Points( dsurf, si, &test->facets[count], v1, v4, v3 )) {
  1273. test->facets[count].x = x;
  1274. test->facets[count].y = y;
  1275. test->facets[count].width = widthtable[i];
  1276. test->facets[count].height = heighttable[j];
  1277. count++;
  1278. }
  1279. if (VL_GenerateFacetFor3Points( dsurf, si, &test->facets[count], v1, v3, v2 )) {
  1280. test->facets[count].x = x;
  1281. test->facets[count].y = y;
  1282. test->facets[count].width = widthtable[i];
  1283. test->facets[count].height = heighttable[j];
  1284. count++;
  1285. }
  1286. }
  1287. y += heighttable[j];
  1288. }
  1289. x += widthtable[i];
  1290. }
  1291. test->numFacets = count;
  1292. FreeMesh(subdivided);
  1293. }
  1294. /*
  1295. =====================
  1296. VL_InitSurfacesForTesting
  1297. =====================
  1298. */
  1299. void VL_InitSurfacesForTesting( void ) {
  1300. int i, j, k;
  1301. dsurface_t *dsurf;
  1302. lsurfaceTest_t *test;
  1303. shaderInfo_t *si;
  1304. lFacet_t *facet;
  1305. for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
  1306. // don't light the entity surfaces with vlight
  1307. if ( entitySurface[i] )
  1308. continue;
  1309. //
  1310. dsurf = &drawSurfaces[ i ];
  1311. if ( !dsurf->numIndexes && !dsurf->patchWidth ) {
  1312. continue;
  1313. }
  1314. si = ShaderInfoForShader( dshaders[ dsurf->shaderNum].shader );
  1315. // if the surface is translucent and does not cast an alpha shadow
  1316. if ( (si->contents & CONTENTS_TRANSLUCENT) && !(si->surfaceFlags & SURF_ALPHASHADOW) ) {
  1317. // if the surface has no lightmap
  1318. if ( dsurf->lightmapNum < 0 )
  1319. continue;
  1320. }
  1321. test = malloc( sizeof( *test ) );
  1322. memset(test, 0, sizeof( *test ));
  1323. test->mutex = MutexAlloc();
  1324. test->numvolumes = 0;
  1325. if (si->forceTraceLight)
  1326. test->always_tracelight = qtrue;
  1327. else if (si->forceVLight)
  1328. test->always_vlight = qtrue;
  1329. lsurfaceTest[i] = test;
  1330. if ( dsurf->surfaceType == MST_TRIANGLE_SOUP || dsurf->surfaceType == MST_PLANAR ) {
  1331. VL_FacetsForTriangleSurface( dsurf, si, test );
  1332. } else if ( dsurf->surfaceType == MST_PATCH ) {
  1333. VL_FacetsForPatch( dsurf, i, si, test );
  1334. }
  1335. if (numfacets >= MAX_FACETS)
  1336. Error("numfacets >= MAX_FACETS (%d)", MAX_FACETS);
  1337. ClearBounds( test->mins, test->maxs );
  1338. for (j = 0; j < test->numFacets; j++)
  1339. {
  1340. facet = &test->facets[j];
  1341. for ( k = 0 ; k < facet->numpoints; k++) {
  1342. AddPointToBounds( facet->points[k], test->mins, test->maxs );
  1343. }
  1344. }
  1345. VL_SphereFromBounds( test->mins, test->maxs, test->origin, &test->radius );
  1346. }
  1347. _printf("%6d facets\n", numfacets);
  1348. _printf("linking surfaces...\n");
  1349. VL_LinkSurfaces();
  1350. }
  1351. /*
  1352. =============
  1353. VL_ChopWinding
  1354. =============
  1355. */
  1356. int VL_ChopWinding (winding_t *in, plane_t *split, float epsilon)
  1357. {
  1358. vec_t dists[128];
  1359. int sides[128];
  1360. int counts[3];
  1361. vec_t dot;
  1362. int i, j;
  1363. vec_t *p1, *p2;
  1364. vec3_t mid;
  1365. winding_t out;
  1366. winding_t *neww;
  1367. counts[0] = counts[1] = counts[2] = 0;
  1368. // determine sides for each point
  1369. for (i=0 ; i<in->numpoints ; i++)
  1370. {
  1371. dot = DotProduct (in->points[i], split->normal);
  1372. dot -= split->dist;
  1373. dists[i] = dot;
  1374. if (dot > epsilon)
  1375. sides[i] = SIDE_FRONT;
  1376. else if (dot < -epsilon)
  1377. sides[i] = SIDE_BACK;
  1378. else
  1379. {
  1380. sides[i] = SIDE_ON;
  1381. }
  1382. counts[sides[i]]++;
  1383. }
  1384. if (!counts[SIDE_BACK])
  1385. {
  1386. if (!counts[SIDE_FRONT])
  1387. return SIDE_ON;
  1388. else
  1389. return SIDE_FRONT;
  1390. }
  1391. if (!counts[SIDE_FRONT])
  1392. {
  1393. return SIDE_BACK;
  1394. }
  1395. sides[i] = sides[0];
  1396. dists[i] = dists[0];
  1397. neww = &out;
  1398. neww->numpoints = 0;
  1399. for (i=0 ; i<in->numpoints ; i++)
  1400. {
  1401. p1 = in->points[i];
  1402. if (neww->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
  1403. {
  1404. _printf("WARNING: VL_ChopWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
  1405. return SIDE_FRONT; // can't chop -- fall back to original
  1406. }
  1407. if (sides[i] == SIDE_ON)
  1408. {
  1409. VectorCopy (p1, neww->points[neww->numpoints]);
  1410. neww->numpoints++;
  1411. continue;
  1412. }
  1413. if (sides[i] == SIDE_FRONT)
  1414. {
  1415. VectorCopy (p1, neww->points[neww->numpoints]);
  1416. neww->numpoints++;
  1417. }
  1418. if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
  1419. continue;
  1420. if (neww->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
  1421. {
  1422. _printf("WARNING: VL_ChopWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
  1423. return SIDE_FRONT; // can't chop -- fall back to original
  1424. }
  1425. // generate a split point
  1426. p2 = in->points[(i+1)%in->numpoints];
  1427. dot = dists[i] / (dists[i]-dists[i+1]);
  1428. for (j=0 ; j<3 ; j++)
  1429. { // avoid round off error when possible
  1430. if (split->normal[j] == 1)
  1431. mid[j] = split->dist;
  1432. else if (split->normal[j] == -1)
  1433. mid[j] = -split->dist;
  1434. else
  1435. mid[j] = p1[j] + dot*(p2[j]-p1[j]);
  1436. }
  1437. VectorCopy (mid, neww->points[neww->numpoints]);
  1438. neww->numpoints++;
  1439. }
  1440. memcpy(in, &out, sizeof(winding_t));
  1441. return SIDE_CROSS;
  1442. }
  1443. /*
  1444. =============
  1445. VL_ChopWindingWithBrush
  1446. returns all winding fragments outside the brush
  1447. =============
  1448. */
  1449. int VL_ChopWindingWithBrush(winding_t *w, dbrush_t *brush, winding_t *outwindings, int maxout)
  1450. {
  1451. int i, res, numout;
  1452. winding_t front, back;
  1453. plane_t plane;
  1454. numout = 0;
  1455. memcpy(front.points, w->points, w->numpoints * sizeof(vec3_t));
  1456. front.numpoints = w->numpoints;
  1457. for (i = 0; i < brush->numSides; i++)
  1458. {
  1459. VectorCopy(dplanes[ dbrushsides[ brush->firstSide + i ].planeNum ].normal, plane.normal);
  1460. VectorInverse(plane.normal);
  1461. plane.dist = -dplanes[ dbrushsides[ brush->firstSide + i ].planeNum ].dist;
  1462. res = VL_SplitWinding(&front, &back, &plane, 0.1);
  1463. if (res == SIDE_BACK || res == SIDE_ON)
  1464. {
  1465. memcpy(outwindings[0].points, w->points, w->numpoints * sizeof(vec3_t));
  1466. outwindings[0].numpoints = w->numpoints;
  1467. return 1; //did not intersect
  1468. }
  1469. if (res != SIDE_FRONT)
  1470. {
  1471. if (numout >= maxout)
  1472. {
  1473. _printf("WARNING: VL_ChopWindingWithBrush: more than %d windings\n", maxout);
  1474. return 0;
  1475. }
  1476. memcpy(outwindings[numout].points, back.points, back.numpoints * sizeof(vec3_t));
  1477. outwindings[numout].numpoints = back.numpoints;
  1478. numout++;
  1479. }
  1480. }
  1481. return numout;
  1482. }
  1483. /*
  1484. =============
  1485. VL_WindingAreaOutsideBrushes
  1486. =============
  1487. */
  1488. float VL_WindingAreaOutsideBrushes(winding_t *w, int *brushnums, int numbrushes)
  1489. {
  1490. int i, j, numwindings[2], n;
  1491. winding_t windingsbuf[2][64];
  1492. dbrush_t *brush;
  1493. float area;
  1494. memcpy(windingsbuf[0][0].points, w->points, w->numpoints * sizeof(vec3_t));
  1495. windingsbuf[0][0].numpoints = w->numpoints;
  1496. numwindings[0] = 1;
  1497. for (i = 0; i < numbrushes; i++)
  1498. {
  1499. brush = &dbrushes[brushnums[i]];
  1500. if (!(dshaders[brush->shaderNum].contentFlags & (
  1501. CONTENTS_LAVA
  1502. | CONTENTS_SLIME
  1503. | CONTENTS_WATER
  1504. | CONTENTS_FOG
  1505. | CONTENTS_AREAPORTAL
  1506. | CONTENTS_PLAYERCLIP
  1507. | CONTENTS_MONSTERCLIP
  1508. | CONTENTS_CLUSTERPORTAL
  1509. | CONTENTS_DONOTENTER
  1510. | CONTENTS_BODY
  1511. | CONTENTS_CORPSE
  1512. | CONTENTS_TRANSLUCENT
  1513. | CONTENTS_TRIGGER
  1514. | CONTENTS_NODROP) ) &&
  1515. (dshaders[brush->shaderNum].contentFlags & CONTENTS_SOLID) )
  1516. {
  1517. numwindings[!(i & 1)] = 0;
  1518. for (j = 0; j < numwindings[i&1]; j++)
  1519. {
  1520. n = VL_ChopWindingWithBrush(&windingsbuf[i&1][j], brush,
  1521. &windingsbuf[!(i&1)][numwindings[!(i&1)]],
  1522. 64 - numwindings[!(i&1)]);
  1523. numwindings[!(i&1)] += n;
  1524. }
  1525. if (!numwindings[!(i&1)])
  1526. return 0;
  1527. }
  1528. else
  1529. {
  1530. for (j = 0; j < numwindings[i&1]; j++)
  1531. {
  1532. windingsbuf[!(i&1)][j] = windingsbuf[i&1][j];
  1533. }
  1534. numwindings[!(i&1)] = numwindings[i&1];
  1535. }
  1536. }
  1537. area = 0;
  1538. for (j = 0; j < numwindings[i&1]; j++)
  1539. {
  1540. area += WindingArea(&windingsbuf[i&1][j]);
  1541. }
  1542. return area;
  1543. }
  1544. /*
  1545. =============
  1546. VL_R_WindingAreaOutsideSolid
  1547. =============
  1548. */
  1549. float VL_R_WindingAreaOutsideSolid(winding_t *w, vec3_t normal, int nodenum)
  1550. {
  1551. int leafnum, res;
  1552. float area;
  1553. dnode_t *node;
  1554. dleaf_t *leaf;
  1555. dplane_t *plane;
  1556. winding_t back;
  1557. plane_t split;
  1558. area = 0;
  1559. while(nodenum >= 0)
  1560. {
  1561. node = &dnodes[nodenum];
  1562. plane = &dplanes[node->planeNum];
  1563. VectorCopy(plane->normal, split.normal);
  1564. split.dist = plane->dist;
  1565. res = VL_SplitWinding (w, &back, &split, 0.1);
  1566. if (res == SIDE_FRONT)
  1567. {
  1568. nodenum = node->children[0];
  1569. }
  1570. else if (res == SIDE_BACK)
  1571. {
  1572. nodenum = node->children[1];
  1573. }
  1574. else if (res == SIDE_ON)
  1575. {
  1576. if (DotProduct(normal, plane->normal) > 0)
  1577. nodenum = node->children[0];
  1578. else
  1579. nodenum = node->children[1];
  1580. }
  1581. else
  1582. {
  1583. area += VL_R_WindingAreaOutsideSolid(&back, normal, node->children[1]);
  1584. nodenum = node->children[0];
  1585. }
  1586. }
  1587. leafnum = -nodenum - 1;
  1588. leaf = &dleafs[leafnum];
  1589. if (leaf->cluster != -1)
  1590. {
  1591. area += VL_WindingAreaOutsideBrushes(w, &dleafbrushes[leaf->firstLeafBrush], leaf->numLeafBrushes);
  1592. }
  1593. return area;
  1594. }
  1595. /*
  1596. =============
  1597. VL_WindingAreaOutsideSolid
  1598. =============
  1599. */
  1600. float VL_WindingAreaOutsideSolid(winding_t *w, vec3_t normal)
  1601. {
  1602. return VL_R_WindingAreaOutsideSolid(w, normal, 0);
  1603. }
  1604. /*
  1605. =============
  1606. VL_ChopWindingWithFacet
  1607. =============
  1608. */
  1609. float VL_ChopWindingWithFacet(winding_t *w, lFacet_t *facet)
  1610. {
  1611. int i;
  1612. for (i = 0; i < facet->numpoints; i++)
  1613. {
  1614. if (VL_ChopWinding(w, &facet->boundaries[i], 0) == SIDE_BACK)
  1615. return 0;
  1616. }
  1617. if (nostitching)
  1618. return WindingArea(w);
  1619. else
  1620. return VL_WindingAreaOutsideSolid(w, facet->plane.normal);
  1621. }
  1622. /*
  1623. =============
  1624. VL_CalcVisibleLightmapPixelArea
  1625. nice brute force ;)
  1626. =============
  1627. */
  1628. void VL_CalcVisibleLightmapPixelArea(void)
  1629. {
  1630. int i, j, x, y, k;
  1631. dsurface_t *ds;
  1632. lsurfaceTest_t *test;
  1633. mesh_t *mesh;
  1634. winding_t w, tmpw;
  1635. float area;
  1636. _printf("calculating visible lightmap pixel area...\n");
  1637. for ( i = 0 ; i < numDrawSurfaces ; i++ )
  1638. {
  1639. test = lsurfaceTest[ i ];
  1640. if (!test)
  1641. continue;
  1642. ds = &drawSurfaces[ i ];
  1643. if ( ds->lightmapNum < 0 )
  1644. continue;
  1645. for (y = 0; y < ds->lightmapHeight; y++)
  1646. {
  1647. for (x = 0; x < ds->lightmapWidth; x++)
  1648. {
  1649. if (ds->surfaceType == MST_PATCH)
  1650. {
  1651. if (y == ds->lightmapHeight-1)
  1652. continue;
  1653. if (x == ds->lightmapWidth-1)
  1654. continue;
  1655. mesh = lsurfaceTest[i]->detailMesh;
  1656. VectorCopy( mesh->verts[y*mesh->width+x].xyz, w.points[0]);
  1657. VectorCopy( mesh->verts[(y+1)*mesh->width+x].xyz, w.points[1]);
  1658. VectorCopy( mesh->verts[(y+1)*mesh->width+x+1].xyz, w.points[2]);
  1659. VectorCopy( mesh->verts[y*mesh->width+x+1].xyz, w.points[3]);
  1660. w.numpoints = 4;
  1661. if (nostitching)
  1662. area = WindingArea(&w);
  1663. else
  1664. area = VL_WindingAreaOutsideSolid(&w, mesh->verts[y*mesh->width+x].normal);
  1665. }
  1666. else
  1667. {
  1668. VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT, ds->lightmapVecs[0], w.points[0]);
  1669. VectorMA(w.points[0], (float) y - LIGHTMAP_PIXELSHIFT, ds->lightmapVecs[1], w.points[0]);
  1670. VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT, ds->lightmapVecs[0], w.points[3]);
  1671. VectorMA(w.points[3], (float) y - LIGHTMAP_PIXELSHIFT + 1, ds->lightmapVecs[1], w.points[3]);
  1672. VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1, ds->lightmapVecs[0], w.points[2]);
  1673. VectorMA(w.points[2], (float) y - LIGHTMAP_PIXELSHIFT + 1, ds->lightmapVecs[1], w.points[2]);
  1674. VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1, ds->lightmapVecs[0], w.points[1]);
  1675. VectorMA(w.points[1], (float) y - LIGHTMAP_PIXELSHIFT, ds->lightmapVecs[1], w.points[1]);
  1676. w.numpoints = 4;
  1677. area = 0;
  1678. for (j = 0; j < test->numFacets; j++)
  1679. {
  1680. memcpy(&tmpw, &w, sizeof(winding_t));
  1681. area += VL_ChopWindingWithFacet(&tmpw, &test->facets[j]);
  1682. }
  1683. }
  1684. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  1685. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  1686. lightmappixelarea[k] = area;
  1687. }
  1688. }
  1689. }
  1690. }
  1691. /*
  1692. =============
  1693. VL_FindAdjacentSurface
  1694. =============
  1695. */
  1696. int VL_FindAdjacentSurface(int surfaceNum, int facetNum, vec3_t p1, vec3_t p2, int *sNum, int *fNum, int *point)
  1697. {
  1698. int i, j, k;
  1699. lsurfaceTest_t *test;
  1700. lFacet_t *facet;
  1701. dsurface_t *ds;
  1702. float *fp1, *fp2;
  1703. vec3_t dir;
  1704. plane_t *facetplane;
  1705. // winding_t w;
  1706. facetplane = &lsurfaceTest[surfaceNum]->facets[facetNum].plane;
  1707. // DebugNet_RemoveAllPolys();
  1708. // memcpy(w.points, lsurfaceTest[surfaceNum]->facets[facetNum].points,
  1709. // lsurfaceTest[surfaceNum]->facets[facetNum].numpoints * sizeof(vec3_t));
  1710. // w.numpoints = lsurfaceTest[surfaceNum]->facets[facetNum].numpoints;
  1711. // DebugNet_DrawWinding(&w, 2);
  1712. for ( i = 0 ; i < numDrawSurfaces ; i++ )
  1713. {
  1714. if (i == surfaceNum)
  1715. continue;
  1716. test = lsurfaceTest[ i ];
  1717. if (!test)
  1718. continue;
  1719. if (test->trisoup)// || test->patch)
  1720. continue;
  1721. ds = &drawSurfaces[i];
  1722. if ( ds->lightmapNum < 0 )
  1723. continue;
  1724. //if this surface is not even near the edge
  1725. VectorSubtract(p1, test->origin, dir);
  1726. if (fabs(dir[0]) > test->radius ||
  1727. fabs(dir[1]) > test->radius ||
  1728. fabs(dir[1]) > test->radius)
  1729. {
  1730. VectorSubtract(p2, test->origin, dir);
  1731. if (fabs(dir[0]) > test->radius ||
  1732. fabs(dir[1]) > test->radius ||
  1733. fabs(dir[1]) > test->radius)
  1734. {
  1735. continue;
  1736. }
  1737. }
  1738. //
  1739. for (j = 0; j < test->numFacets; j++)
  1740. {
  1741. facet = &test->facets[j];
  1742. //
  1743. //if (!Plane_Equal(&facet->plane, facetplane, qfalse))
  1744. if (DotProduct(facet->plane.normal, facetplane->normal) < 0.9)
  1745. {
  1746. if (!test->trisoup && !test->patch)
  1747. break;
  1748. continue;
  1749. }
  1750. //
  1751. for (k = 0; k < facet->numpoints; k++)
  1752. {
  1753. fp1 = facet->points[k];
  1754. if (fabs(p2[0] - fp1[0]) < 0.1 &&
  1755. fabs(p2[1] - fp1[1]) < 0.1 &&
  1756. fabs(p2[2] - fp1[2]) < 0.1)
  1757. {
  1758. fp2 = facet->points[(k+1) % facet->numpoints];
  1759. if (fabs(p1[0] - fp2[0]) < 0.1 &&
  1760. fabs(p1[1] - fp2[1]) < 0.1 &&
  1761. fabs(p1[2] - fp2[2]) < 0.1)
  1762. {
  1763. // memcpy(w.points, facet->points, facet->numpoints * sizeof(vec3_t));
  1764. // w.numpoints = facet->numpoints;
  1765. // DebugNet_DrawWinding(&w, 1);
  1766. *sNum = i;
  1767. *fNum = j;
  1768. *point = k;
  1769. return qtrue;
  1770. }
  1771. }
  1772. /*
  1773. else if (fabs(p1[0] - fp1[0]) < 0.1 &&
  1774. fabs(p1[1] - fp1[1]) < 0.1 &&
  1775. fabs(p1[2] - fp1[2]) < 0.1)
  1776. {
  1777. fp2 = facet->points[(k+1) % facet->numpoints];
  1778. if (fabs(p2[0] - fp2[0]) < 0.1 &&
  1779. fabs(p2[1] - fp2[1]) < 0.1 &&
  1780. fabs(p2[2] - fp2[2]) < 0.1)
  1781. {
  1782. // memcpy(w.points, facet->points, facet->numpoints * sizeof(vec3_t));
  1783. // w.numpoints = facet->numpoints;
  1784. // DebugNet_DrawWinding(&w, 1);
  1785. *sNum = i;
  1786. *fNum = j;
  1787. *point = k;
  1788. return qtrue;
  1789. }
  1790. }
  1791. //*/
  1792. }
  1793. }
  1794. }
  1795. return qfalse;
  1796. }
  1797. /*
  1798. =============
  1799. VL_SmoothenLightmapEdges
  1800. this code is used to smoothen lightmaps across surface edges
  1801. =============
  1802. */
  1803. void VL_SmoothenLightmapEdges(void)
  1804. {
  1805. int i, j, k, coords1[2][2];
  1806. float coords2[2][2];
  1807. int x1, y1, xinc1, yinc1, k1, k2;
  1808. float x2, y2, xinc2, yinc2, length;
  1809. int surfaceNum, facetNum, point;
  1810. lsurfaceTest_t *test;
  1811. lFacet_t *facet1, *facet2;
  1812. dsurface_t *ds1, *ds2;
  1813. float *p[2], s, t, *color1, *color2;
  1814. vec3_t dir, cross;
  1815. for ( i = 0 ; i < numDrawSurfaces ; i++ )
  1816. {
  1817. test = lsurfaceTest[ i ];
  1818. if (!test)
  1819. continue;
  1820. if (test->trisoup)// || test->patch)
  1821. continue;
  1822. ds1 = &drawSurfaces[i];
  1823. if ( ds1->lightmapNum < 0 )
  1824. continue;
  1825. for (j = 0; j < test->numFacets; j++)
  1826. {
  1827. facet1 = &test->facets[j];
  1828. //
  1829. for (k = 0; k < facet1->numpoints; k++)
  1830. {
  1831. p[0] = facet1->points[k];
  1832. p[1] = facet1->points[(k+1)%facet1->numpoints];
  1833. //
  1834. coords1[0][0] = facet1->lightmapCoords[k][0] * LIGHTMAP_SIZE;
  1835. coords1[0][1] = facet1->lightmapCoords[k][1] * LIGHTMAP_SIZE;
  1836. coords1[1][0] = facet1->lightmapCoords[(k+1)%facet1->numpoints][0] * LIGHTMAP_SIZE;
  1837. coords1[1][1] = facet1->lightmapCoords[(k+1)%facet1->numpoints][1] * LIGHTMAP_SIZE;
  1838. if (coords1[0][0] >= LIGHTMAP_SIZE)
  1839. coords1[0][0] = LIGHTMAP_SIZE-1;
  1840. if (coords1[0][1] >= LIGHTMAP_SIZE)
  1841. coords1[0][1] = LIGHTMAP_SIZE-1;
  1842. if (coords1[1][0] >= LIGHTMAP_SIZE)
  1843. coords1[1][0] = LIGHTMAP_SIZE-1;
  1844. if (coords1[1][1] >= LIGHTMAP_SIZE)
  1845. coords1[1][1] = LIGHTMAP_SIZE-1;
  1846. // try one row or column further because on flat faces the lightmap can
  1847. // extend beyond the edge
  1848. VectorSubtract(p[1], p[0], dir);
  1849. VectorNormalize(dir, dir);
  1850. CrossProduct(dir, facet1->plane.normal, cross);
  1851. //
  1852. if (coords1[0][0] - coords1[1][0] == 0)
  1853. {
  1854. s = DotProduct( cross, facet1->lightmapMatrix[0] );
  1855. coords1[0][0] += s < 0 ? 1 : -1;
  1856. coords1[1][0] += s < 0 ? 1 : -1;
  1857. if (coords1[0][0] < ds1->lightmapX || coords1[0][0] >= ds1->lightmapX + ds1->lightmapWidth)
  1858. {
  1859. coords1[0][0] += s < 0 ? -1 : 1;
  1860. coords1[1][0] += s < 0 ? -1 : 1;
  1861. }
  1862. length = fabs(coords1[1][1] - coords1[0][1]);
  1863. }
  1864. else if (coords1[0][1] - coords1[1][1] == 0)
  1865. {
  1866. t = DotProduct( cross, facet1->lightmapMatrix[1] );
  1867. coords1[0][1] += t < 0 ? 1 : -1;
  1868. coords1[1][1] += t < 0 ? 1 : -1;
  1869. if (coords1[0][1] < ds1->lightmapY || coords1[0][1] >= ds1->lightmapY + ds1->lightmapHeight)
  1870. {
  1871. coords1[0][1] += t < 0 ? -1 : 1;
  1872. coords1[1][1] += t < 0 ? -1 : 1;
  1873. }
  1874. length = fabs(coords1[1][0] - coords1[0][0]);
  1875. }
  1876. else
  1877. {
  1878. //the edge is not parallell to one of the lightmap axis
  1879. continue;
  1880. }
  1881. //
  1882. x1 = coords1[0][0];
  1883. y1 = coords1[0][1];
  1884. xinc1 = coords1[1][0] - coords1[0][0];
  1885. if (xinc1 < 0) xinc1 = -1;
  1886. if (xinc1 > 0) xinc1 = 1;
  1887. yinc1 = coords1[1][1] - coords1[0][1];
  1888. if (yinc1 < 0) yinc1 = -1;
  1889. if (yinc1 > 0) yinc1 = 1;
  1890. // the edge should be parallell to one of the lightmap axis
  1891. if (xinc1 != 0 && yinc1 != 0)
  1892. continue;
  1893. //
  1894. if (!VL_FindAdjacentSurface(i, j, p[0], p[1], &surfaceNum, &facetNum, &point))
  1895. continue;
  1896. //
  1897. ds2 = &drawSurfaces[surfaceNum];
  1898. facet2 = &lsurfaceTest[surfaceNum]->facets[facetNum];
  1899. coords2[0][0] = facet2->lightmapCoords[(point+1)%facet2->numpoints][0] * LIGHTMAP_SIZE;
  1900. coords2[0][1] = facet2->lightmapCoords[(point+1)%facet2->numpoints][1] * LIGHTMAP_SIZE;
  1901. coords2[1][0] = facet2->lightmapCoords[point][0] * LIGHTMAP_SIZE;
  1902. coords2[1][1] = facet2->lightmapCoords[point][1] * LIGHTMAP_SIZE;
  1903. if (coords2[0][0] >= LIGHTMAP_SIZE)
  1904. coords2[0][0] = LIGHTMAP_SIZE-1;
  1905. if (coords2[0][1] >= LIGHTMAP_SIZE)
  1906. coords2[0][1] = LIGHTMAP_SIZE-1;
  1907. if (coords2[1][0] >= LIGHTMAP_SIZE)
  1908. coords2[1][0] = LIGHTMAP_SIZE-1;
  1909. if (coords2[1][1] >= LIGHTMAP_SIZE)
  1910. coords2[1][1] = LIGHTMAP_SIZE-1;
  1911. //
  1912. x2 = coords2[0][0];
  1913. y2 = coords2[0][1];
  1914. xinc2 = coords2[1][0] - coords2[0][0];
  1915. if (length)
  1916. xinc2 = xinc2 / length;
  1917. yinc2 = coords2[1][1] - coords2[0][1];
  1918. if (length)
  1919. yinc2 = yinc2 / length;
  1920. // the edge should be parallell to one of the lightmap axis
  1921. if ((int) xinc2 != 0 && (int) yinc2 != 0)
  1922. continue;
  1923. //
  1924. while(1)
  1925. {
  1926. k1 = ( ds1->lightmapNum * LIGHTMAP_HEIGHT + y1) * LIGHTMAP_WIDTH + x1;
  1927. k2 = ( ds2->lightmapNum * LIGHTMAP_HEIGHT + ((int) y2)) * LIGHTMAP_WIDTH + ((int) x2);
  1928. color1 = lightFloats + k1*3;
  1929. color2 = lightFloats + k2*3;
  1930. if (lightmappixelarea[k1] < 0.01)
  1931. {
  1932. color1[0] = color2[0];
  1933. color1[1] = color2[1];
  1934. color1[2] = color2[2];
  1935. }
  1936. else
  1937. {
  1938. color1[0] = (float) color2[0] * 0.7 + (float) color1[0] * 0.3;
  1939. color1[1] = (float) color2[1] * 0.7 + (float) color1[1] * 0.3;
  1940. color1[2] = (float) color2[2] * 0.7 + (float) color1[2] * 0.3;
  1941. }
  1942. //
  1943. if (x1 == coords1[1][0] &&
  1944. y1 == coords1[1][1])
  1945. break;
  1946. x1 += xinc1;
  1947. y1 += yinc1;
  1948. x2 += xinc2;
  1949. y2 += yinc2;
  1950. if (x2 < ds2->lightmapX)
  1951. x2 = ds2->lightmapX;
  1952. if (x2 >= ds2->lightmapX + ds2->lightmapWidth)
  1953. x2 = ds2->lightmapX + ds2->lightmapWidth-1;
  1954. if (y2 < ds2->lightmapY)
  1955. y2 = ds2->lightmapY;
  1956. if (y2 >= ds2->lightmapY + ds2->lightmapHeight)
  1957. y2 = ds2->lightmapY + ds2->lightmapHeight-1;
  1958. }
  1959. }
  1960. }
  1961. }
  1962. }
  1963. /*
  1964. =============
  1965. VL_FixLightmapEdges
  1966. =============
  1967. */
  1968. void VL_FixLightmapEdges(void)
  1969. {
  1970. int i, j, x, y, k, foundvalue, height, width, index;
  1971. int pos, top, bottom;
  1972. dsurface_t *ds;
  1973. lsurfaceTest_t *test;
  1974. float color[3];
  1975. float *ptr;
  1976. byte filled[(LIGHTMAP_SIZE+1) * (LIGHTMAP_SIZE+1) / 8];
  1977. float lightmap_edge_epsilon;
  1978. lightmap_edge_epsilon = 0.1 * samplesize;
  1979. for ( i = 0 ; i < numDrawSurfaces ; i++ )
  1980. {
  1981. test = lsurfaceTest[ i ];
  1982. if (!test)
  1983. continue;
  1984. ds = &drawSurfaces[ i ];
  1985. if ( ds->lightmapNum < 0 )
  1986. continue;
  1987. if (ds->surfaceType == MST_PATCH)
  1988. {
  1989. height = ds->lightmapHeight - 1;
  1990. width = ds->lightmapWidth - 1;
  1991. }
  1992. else
  1993. {
  1994. height = ds->lightmapHeight;
  1995. width = ds->lightmapWidth;
  1996. }
  1997. memset(filled, 0, sizeof(filled));
  1998. // printf("\n");
  1999. for (x = 0; x < width; x++)
  2000. {
  2001. for (y = 0; y < height; y++)
  2002. {
  2003. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2004. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2005. if (lightmappixelarea[k] > lightmap_edge_epsilon)
  2006. {
  2007. index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2008. filled[index >> 3] |= 1 << (index & 7);
  2009. // printf("*");
  2010. }
  2011. // else
  2012. // printf("_");
  2013. }
  2014. // printf("\n");
  2015. }
  2016. for (y = 0; y < height; y++)
  2017. {
  2018. pos = -2;
  2019. for (x = 0; x < width; x++)
  2020. {
  2021. index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2022. if (pos == -2)
  2023. {
  2024. if (filled[index >> 3] & (1 << (index & 7)))
  2025. pos = -1;
  2026. }
  2027. else if (pos == -1)
  2028. {
  2029. if (!(filled[index >> 3] & (1 << (index & 7))))
  2030. pos = x - 1;
  2031. }
  2032. else
  2033. {
  2034. if (filled[index >> 3] & (1 << (index & 7)))
  2035. {
  2036. bottom = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2037. * LIGHTMAP_WIDTH + ds->lightmapX + pos;
  2038. top = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2039. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2040. for (j = 0; j < (x - pos + 1) / 2; j++)
  2041. {
  2042. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2043. * LIGHTMAP_WIDTH + ds->lightmapX + pos + j + 1;
  2044. index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + pos + j + 1;
  2045. filled[index >> 3] |= 1 << (index & 7);
  2046. (lightFloats + k*3)[0] = (lightFloats + top*3)[0];
  2047. (lightFloats + k*3)[1] = (lightFloats + top*3)[1];
  2048. (lightFloats + k*3)[2] = (lightFloats + top*3)[2];
  2049. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2050. * LIGHTMAP_WIDTH + ds->lightmapX + x - j - 1;
  2051. index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x - j - 1;
  2052. filled[index >> 3] |= 1 << (index & 7);
  2053. (lightFloats + k*3)[0] = (lightFloats + bottom*3)[0];
  2054. (lightFloats + k*3)[1] = (lightFloats + bottom*3)[1];
  2055. (lightFloats + k*3)[2] = (lightFloats + bottom*3)[2];
  2056. }
  2057. pos = -1;
  2058. }
  2059. }
  2060. }
  2061. }
  2062. for (x = 0; x < width; x++)
  2063. {
  2064. pos = -2;
  2065. for (y = 0; y < height; y++)
  2066. {
  2067. index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2068. if (pos == -2)
  2069. {
  2070. if (filled[index >> 3] & (1 << (index & 7)))
  2071. pos = -1;
  2072. }
  2073. else if (pos == -1)
  2074. {
  2075. if (!(filled[index >> 3] & (1 << (index & 7))))
  2076. pos = y - 1;
  2077. }
  2078. else
  2079. {
  2080. if (filled[index >> 3] & (1 << (index & 7)))
  2081. {
  2082. bottom = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + pos)
  2083. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2084. top = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2085. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2086. for (j = 0; j < (y - pos + 1) / 2; j++)
  2087. {
  2088. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + pos + j + 1)
  2089. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2090. index = (ds->lightmapY + pos + j + 1) * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2091. filled[index >> 3] |= 1 << (index & 7);
  2092. (lightFloats + k*3)[0] = (lightFloats + top*3)[0];
  2093. (lightFloats + k*3)[1] = (lightFloats + top*3)[1];
  2094. (lightFloats + k*3)[2] = (lightFloats + top*3)[2];
  2095. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y - j - 1)
  2096. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2097. index = (ds->lightmapY + y - j - 1) * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2098. filled[index >> 3] |= 1 << (index & 7);
  2099. (lightFloats + k*3)[0] = (lightFloats + bottom*3)[0];
  2100. (lightFloats + k*3)[1] = (lightFloats + bottom*3)[1];
  2101. (lightFloats + k*3)[2] = (lightFloats + bottom*3)[2];
  2102. }
  2103. pos = -1;
  2104. }
  2105. }
  2106. }
  2107. }
  2108. for (y = 0; y < height; y++)
  2109. {
  2110. foundvalue = qfalse;
  2111. for (x = 0; x < width; x++)
  2112. {
  2113. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2114. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2115. index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2116. if (foundvalue)
  2117. {
  2118. if (filled[index >> 3] & (1 << (index & 7)))
  2119. {
  2120. ptr = lightFloats + k*3;
  2121. color[0] = ptr[0];
  2122. color[1] = ptr[1];
  2123. color[2] = ptr[2];
  2124. }
  2125. else
  2126. {
  2127. ptr = lightFloats + k*3;
  2128. ptr[0] = color[0];
  2129. ptr[1] = color[1];
  2130. ptr[2] = color[2];
  2131. filled[index >> 3] |= 1 << (index & 7);
  2132. }
  2133. }
  2134. else
  2135. {
  2136. if (filled[index >> 3] & (1 << (index & 7)))
  2137. {
  2138. ptr = lightFloats + k*3;
  2139. color[0] = ptr[0];
  2140. color[1] = ptr[1];
  2141. color[2] = ptr[2];
  2142. foundvalue = qtrue;
  2143. }
  2144. }
  2145. }
  2146. foundvalue = qfalse;
  2147. for (x = width-1; x >= 0; x--)
  2148. {
  2149. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2150. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2151. index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2152. if (foundvalue)
  2153. {
  2154. if (filled[index >> 3] & (1 << (index & 7)))
  2155. {
  2156. ptr = lightFloats + k*3;
  2157. color[0] = ptr[0];
  2158. color[1] = ptr[1];
  2159. color[2] = ptr[2];
  2160. }
  2161. else
  2162. {
  2163. ptr = lightFloats + k*3;
  2164. ptr[0] = color[0];
  2165. ptr[1] = color[1];
  2166. ptr[2] = color[2];
  2167. filled[index >> 3] |= 1 << (index & 7);
  2168. }
  2169. }
  2170. else
  2171. {
  2172. if (filled[index >> 3] & (1 << (index & 7)))
  2173. {
  2174. ptr = lightFloats + k*3;
  2175. color[0] = ptr[0];
  2176. color[1] = ptr[1];
  2177. color[2] = ptr[2];
  2178. foundvalue = qtrue;
  2179. }
  2180. }
  2181. }
  2182. }
  2183. for (x = 0; x < width; x++)
  2184. {
  2185. foundvalue = qfalse;
  2186. for (y = 0; y < height; y++)
  2187. {
  2188. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2189. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2190. index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2191. if (foundvalue)
  2192. {
  2193. if (filled[index >> 3] & (1 << (index & 7)))
  2194. {
  2195. ptr = lightFloats + k*3;
  2196. color[0] = ptr[0];
  2197. color[1] = ptr[1];
  2198. color[2] = ptr[2];
  2199. }
  2200. else
  2201. {
  2202. ptr = lightFloats + k*3;
  2203. ptr[0] = color[0];
  2204. ptr[1] = color[1];
  2205. ptr[2] = color[2];
  2206. filled[index >> 3] |= 1 << (index & 7);
  2207. }
  2208. }
  2209. else
  2210. {
  2211. if (filled[index >> 3] & (1 << (index & 7)))
  2212. {
  2213. ptr = lightFloats + k*3;
  2214. color[0] = ptr[0];
  2215. color[1] = ptr[1];
  2216. color[2] = ptr[2];
  2217. foundvalue = qtrue;
  2218. }
  2219. }
  2220. }
  2221. foundvalue = qfalse;
  2222. for (y = height-1; y >= 0; y--)
  2223. {
  2224. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2225. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2226. index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2227. if (foundvalue)
  2228. {
  2229. if (filled[index >> 3] & (1 << (index & 7)))
  2230. {
  2231. ptr = lightFloats + k*3;
  2232. color[0] = ptr[0];
  2233. color[1] = ptr[1];
  2234. color[2] = ptr[2];
  2235. }
  2236. else
  2237. {
  2238. ptr = lightFloats + k*3;
  2239. ptr[0] = color[0];
  2240. ptr[1] = color[1];
  2241. ptr[2] = color[2];
  2242. filled[index >> 3] |= 1 << (index & 7);
  2243. }
  2244. }
  2245. else
  2246. {
  2247. if (filled[index >> 3] & (1 << (index & 7)))
  2248. {
  2249. ptr = lightFloats + k*3;
  2250. color[0] = ptr[0];
  2251. color[1] = ptr[1];
  2252. color[2] = ptr[2];
  2253. foundvalue = qtrue;
  2254. }
  2255. }
  2256. }
  2257. }
  2258. if (ds->surfaceType == MST_PATCH)
  2259. {
  2260. x = ds->lightmapWidth-1;
  2261. for (y = 0; y < ds->lightmapHeight; y++)
  2262. {
  2263. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2264. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2265. ptr = lightFloats + k*3;
  2266. ptr[0] = (lightFloats + (k-1)*3)[0];
  2267. ptr[1] = (lightFloats + (k-1)*3)[1];
  2268. ptr[2] = (lightFloats + (k-1)*3)[2];
  2269. }
  2270. y = ds->lightmapHeight-1;
  2271. for (x = 0; x < ds->lightmapWidth; x++)
  2272. {
  2273. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2274. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2275. ptr = lightFloats + k*3;
  2276. ptr[0] = (lightFloats + (k-LIGHTMAP_WIDTH)*3)[0];
  2277. ptr[1] = (lightFloats + (k-LIGHTMAP_WIDTH)*3)[1];
  2278. ptr[2] = (lightFloats + (k-LIGHTMAP_WIDTH)*3)[2];
  2279. }
  2280. }
  2281. /*
  2282. //colored debug edges
  2283. if (ds->surfaceType == MST_PATCH)
  2284. {
  2285. x = ds->lightmapWidth-1;
  2286. for (y = 0; y < ds->lightmapHeight; y++)
  2287. {
  2288. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2289. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2290. ptr = lightFloats + k*3;
  2291. ptr[0] = 255;
  2292. ptr[1] = 0;
  2293. ptr[2] = 0;
  2294. }
  2295. y = ds->lightmapHeight-1;
  2296. for (x = 0; x < ds->lightmapWidth; x++)
  2297. {
  2298. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2299. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2300. ptr = lightFloats + k*3;
  2301. ptr[0] = 0;
  2302. ptr[1] = 255;
  2303. ptr[2] = 0;
  2304. }
  2305. }
  2306. //*/
  2307. }
  2308. //
  2309. VL_SmoothenLightmapEdges();
  2310. }
  2311. /*
  2312. =============
  2313. VL_ShiftPatchLightmaps
  2314. =============
  2315. */
  2316. void VL_ShiftPatchLightmaps(void)
  2317. {
  2318. int i, j, x, y, k;
  2319. drawVert_t *verts;
  2320. dsurface_t *ds;
  2321. lsurfaceTest_t *test;
  2322. float *ptr;
  2323. for ( i = 0 ; i < numDrawSurfaces ; i++ )
  2324. {
  2325. test = lsurfaceTest[ i ];
  2326. if (!test)
  2327. continue;
  2328. ds = &drawSurfaces[ i ];
  2329. if ( ds->lightmapNum < 0 )
  2330. continue;
  2331. if (ds->surfaceType != MST_PATCH)
  2332. continue;
  2333. for (x = ds->lightmapWidth; x > 0; x--)
  2334. {
  2335. for (y = 0; y <= ds->lightmapHeight; y++)
  2336. {
  2337. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2338. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2339. ptr = lightFloats + k*3;
  2340. ptr[0] = (lightFloats + (k-1)*3)[0];
  2341. ptr[1] = (lightFloats + (k-1)*3)[1];
  2342. ptr[2] = (lightFloats + (k-1)*3)[2];
  2343. }
  2344. }
  2345. for (y = ds->lightmapHeight; y > 0; y--)
  2346. {
  2347. for (x = 0; x <= ds->lightmapWidth; x++)
  2348. {
  2349. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2350. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2351. ptr = lightFloats + k*3;
  2352. ptr[0] = (lightFloats + (k-LIGHTMAP_WIDTH)*3)[0];
  2353. ptr[1] = (lightFloats + (k-LIGHTMAP_WIDTH)*3)[1];
  2354. ptr[2] = (lightFloats + (k-LIGHTMAP_WIDTH)*3)[2];
  2355. }
  2356. }
  2357. verts = &drawVerts[ ds->firstVert ];
  2358. for ( j = 0 ; j < ds->patchHeight * ds->patchWidth; j++ )
  2359. {
  2360. verts[j].lightmap[0] += 0.5 / LIGHTMAP_WIDTH;
  2361. verts[j].lightmap[1] += 0.5 / LIGHTMAP_HEIGHT;
  2362. }
  2363. ds->lightmapHeight++;
  2364. ds->lightmapWidth++;
  2365. }
  2366. }
  2367. /*
  2368. =============
  2369. VL_StoreLightmap
  2370. =============
  2371. */
  2372. void VL_StoreLightmap(void)
  2373. {
  2374. int i, x, y, k;
  2375. dsurface_t *ds;
  2376. lsurfaceTest_t *test;
  2377. float *src;
  2378. byte *dst;
  2379. _printf("storing lightmaps...\n");
  2380. //fix lightmap edges before storing them
  2381. VL_FixLightmapEdges();
  2382. //
  2383. #ifdef LIGHTMAP_PATCHSHIFT
  2384. VL_ShiftPatchLightmaps();
  2385. #endif
  2386. //
  2387. for ( i = 0 ; i < numDrawSurfaces ; i++ )
  2388. {
  2389. test = lsurfaceTest[ i ];
  2390. if (!test)
  2391. continue;
  2392. ds = &drawSurfaces[ i ];
  2393. if ( ds->lightmapNum < 0 )
  2394. continue;
  2395. for (y = 0; y < ds->lightmapHeight; y++)
  2396. {
  2397. for (x = 0; x < ds->lightmapWidth; x++)
  2398. {
  2399. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  2400. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  2401. VectorAdd((lightFloats + k*3), lightAmbientColor, (lightFloats + k*3));
  2402. src = &lightFloats[k*3];
  2403. dst = lightBytes + k*3;
  2404. ColorToBytes(src, dst);
  2405. }
  2406. }
  2407. }
  2408. }
  2409. /*
  2410. =============
  2411. PointInLeafnum
  2412. =============
  2413. */
  2414. int PointInLeafnum(vec3_t point)
  2415. {
  2416. int nodenum;
  2417. vec_t dist;
  2418. dnode_t *node;
  2419. dplane_t *plane;
  2420. nodenum = 0;
  2421. while (nodenum >= 0)
  2422. {
  2423. node = &dnodes[nodenum];
  2424. plane = &dplanes[node->planeNum];
  2425. dist = DotProduct (point, plane->normal) - plane->dist;
  2426. if (dist > 0)
  2427. nodenum = node->children[0];
  2428. else
  2429. nodenum = node->children[1];
  2430. }
  2431. return -nodenum - 1;
  2432. }
  2433. /*
  2434. =============
  2435. VL_PointInLeafnum_r
  2436. =============
  2437. */
  2438. int VL_PointInLeafnum_r(vec3_t point, int nodenum)
  2439. {
  2440. int leafnum;
  2441. vec_t dist;
  2442. dnode_t *node;
  2443. dplane_t *plane;
  2444. while (nodenum >= 0)
  2445. {
  2446. node = &dnodes[nodenum];
  2447. plane = &dplanes[node->planeNum];
  2448. dist = DotProduct (point, plane->normal) - plane->dist;
  2449. if (dist > 0.1)
  2450. {
  2451. nodenum = node->children[0];
  2452. }
  2453. else if (dist < -0.1)
  2454. {
  2455. nodenum = node->children[1];
  2456. }
  2457. else
  2458. {
  2459. leafnum = VL_PointInLeafnum_r(point, node->children[0]);
  2460. if (dleafs[leafnum].cluster != -1)
  2461. return leafnum;
  2462. nodenum = node->children[1];
  2463. }
  2464. }
  2465. leafnum = -nodenum - 1;
  2466. return leafnum;
  2467. }
  2468. /*
  2469. =============
  2470. VL_PointInLeafnum
  2471. =============
  2472. */
  2473. int VL_PointInLeafnum(vec3_t point)
  2474. {
  2475. return VL_PointInLeafnum_r(point, 0);
  2476. }
  2477. /*
  2478. =============
  2479. VL_LightLeafnum
  2480. =============
  2481. */
  2482. int VL_LightLeafnum(vec3_t point)
  2483. {
  2484. /*
  2485. int leafnum;
  2486. dleaf_t *leaf;
  2487. float x, y, z;
  2488. vec3_t test;
  2489. leafnum = VL_PointInLeafnum(point);
  2490. leaf = &dleafs[leafnum];
  2491. if (leaf->cluster != -1)
  2492. return leafnum;
  2493. for (z = 1; z >= -1; z -= 1)
  2494. {
  2495. for (x = 1; x >= -1; x -= 1)
  2496. {
  2497. for (y = 1; y >= -1; y -= 1)
  2498. {
  2499. VectorCopy(point, test);
  2500. test[0] += x;
  2501. test[1] += y;
  2502. test[2] += z;
  2503. leafnum = VL_PointInLeafnum(test);
  2504. leaf = &dleafs[leafnum];
  2505. if (leaf->cluster != -1)
  2506. {
  2507. VectorCopy(test, point);
  2508. return leafnum;
  2509. }
  2510. }
  2511. }
  2512. }
  2513. return leafnum;
  2514. */
  2515. return VL_PointInLeafnum(point);
  2516. }
  2517. //#define LIGHTPOLYS
  2518. #ifdef LIGHTPOLYS
  2519. winding_t *lightwindings[MAX_MAP_DRAW_SURFS];
  2520. int numlightwindings;
  2521. /*
  2522. =============
  2523. VL_DrawLightWindings
  2524. =============
  2525. */
  2526. void VL_DrawLightWindings(void)
  2527. {
  2528. int i;
  2529. for (i = 0; i < numlightwindings; i++)
  2530. {
  2531. #ifdef DEBUGNET
  2532. DebugNet_DrawWinding(lightwindings[i], 1);
  2533. #endif
  2534. }
  2535. }
  2536. /*
  2537. =============
  2538. VL_LightSurfaceWithVolume
  2539. =============
  2540. */
  2541. void VL_LightSurfaceWithVolume(int surfaceNum, int facetNum, vlight_t *light, lightvolume_t *volume)
  2542. {
  2543. winding_t *w;
  2544. lsurfaceTest_t *test;
  2545. lFacet_t *facet;
  2546. int i;
  2547. test = lsurfaceTest[ surfaceNum ];
  2548. facet = &test->facets[ facetNum ];
  2549. //
  2550. w = (winding_t *) malloc(sizeof(winding_t));
  2551. memcpy(w->points, facet->points, sizeof(vec3_t) * facet->numpoints);
  2552. w->numpoints = facet->numpoints;
  2553. for (i = 0; i < volume->numplanes; i++)
  2554. {
  2555. //if totally on the back
  2556. if (VL_ChopWinding(w, &volume->planes[i], 0.01) == SIDE_BACK)
  2557. return;
  2558. }
  2559. lightwindings[numlightwindings] = w;
  2560. numlightwindings++;
  2561. if (numlightwindings >= MAX_MAP_DRAW_SURFS)
  2562. Error("MAX_LIGHTWINDINGS");
  2563. }
  2564. #else
  2565. /*
  2566. =============
  2567. VL_LightSurfaceWithVolume
  2568. =============
  2569. */
  2570. /*
  2571. int VL_PointInsideLightVolume(vec3_t point, lightvolume_t *volume)
  2572. {
  2573. int i;
  2574. float d;
  2575. for (i = 0; i < volume->numplanes; i++)
  2576. {
  2577. d = DotProduct(volume->planes[i].normal, point) - volume->planes[i].dist;
  2578. if (d < 0) return qfalse;
  2579. }
  2580. return qtrue;
  2581. }
  2582. void VL_LightSurfaceWithVolume( int surfaceNum, int facetNum, vlight_t *light, lightvolume_t *volume )
  2583. {
  2584. dsurface_t *ds;
  2585. int i, j, k;
  2586. int numPositions;
  2587. vec3_t base, normal, color;
  2588. int sampleWidth, sampleHeight;
  2589. vec3_t lightmapOrigin, lightmapVecs[2], dir;
  2590. unsigned char *ptr;
  2591. float add, dist, angle;
  2592. mesh_t * mesh;
  2593. ds = &drawSurfaces[surfaceNum];
  2594. // vertex-lit triangle model
  2595. if ( ds->surfaceType == MST_TRIANGLE_SOUP ) {
  2596. return;
  2597. }
  2598. if ( ds->lightmapNum < 0 ) {
  2599. return; // doesn't need lighting
  2600. }
  2601. if ( ds->surfaceType == MST_PATCH ) {
  2602. mesh = lsurfaceTest[surfaceNum]->detailMesh;
  2603. } else {
  2604. VectorCopy( ds->lightmapVecs[2], normal );
  2605. VectorCopy( ds->lightmapOrigin, lightmapOrigin );
  2606. VectorCopy( ds->lightmapVecs[0], lightmapVecs[0] );
  2607. VectorCopy( ds->lightmapVecs[1], lightmapVecs[1] );
  2608. }
  2609. sampleWidth = ds->lightmapWidth;
  2610. sampleHeight = ds->lightmapHeight;
  2611. //calculate lightmap
  2612. for ( i = 0 ; i < sampleWidth; i++ ) {
  2613. for ( j = 0 ; j < sampleHeight; j++ ) {
  2614. if ( ds->patchWidth ) {
  2615. numPositions = 9;
  2616. VectorCopy( mesh->verts[j*mesh->width+i].normal, normal );
  2617. // VectorNormalize( normal, normal );
  2618. // push off of the curve a bit
  2619. VectorMA( mesh->verts[j*mesh->width+i].xyz, 1, normal, base );
  2620. // MakeNormalVectors( normal, lightmapVecs[0], lightmapVecs[1] );
  2621. } else {
  2622. numPositions = 9;
  2623. for ( k = 0 ; k < 3 ; k++ ) {
  2624. base[k] = lightmapOrigin[k] + normal[k]
  2625. + ((float) i) * lightmapVecs[0][k]
  2626. + ((float) j) * lightmapVecs[1][k];
  2627. }
  2628. }
  2629. VectorAdd( base, surfaceOrigin[ surfaceNum ], base );
  2630. VectorSubtract(base, light->origin, dir);
  2631. dist = VectorNormalize(dir, dir);
  2632. if ( dist < 16 ) {
  2633. dist = 16;
  2634. }
  2635. angle = 1;//DotProduct( normal, dir ); //1;
  2636. if (angle > 1)
  2637. angle = 1;
  2638. if ( light->atten_disttype == LDAT_LINEAR ) {
  2639. add = angle * light->photons * lightLinearScale - dist;
  2640. if ( add < 0 ) {
  2641. add = 0;
  2642. }
  2643. } else {
  2644. add = light->photons / ( dist * dist ) * angle;
  2645. }
  2646. if (add <= 1.0)
  2647. continue;
  2648. if (VL_PointInsideLightVolume(base, volume))
  2649. {
  2650. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + j)
  2651. * LIGHTMAP_WIDTH + ds->lightmapX + i;
  2652. ptr = lightBytes + k*3;
  2653. color[0] = (float) ptr[0] + add * light->color[0];
  2654. color[1] = (float) ptr[1] + add * light->color[1];
  2655. color[2] = (float) ptr[2] + add * light->color[2];
  2656. ColorToBytes(color, ptr);
  2657. }
  2658. }
  2659. }
  2660. }
  2661. */
  2662. /*
  2663. =============
  2664. VL_GetFilter
  2665. FIXME: don't use a lightmap pixel origin but use the four corner points
  2666. to map part of a translucent surface onto the lightmap pixel
  2667. =============
  2668. */
  2669. void VL_GetFilter(vlight_t *light, lightvolume_t *volume, vec3_t lmp, vec3_t filter)
  2670. {
  2671. lFacet_t *facet;
  2672. lsurfaceTest_t *test;
  2673. float d, d1, d2, frac, s, t, ns;
  2674. int i, j, is, it, b;
  2675. int x, y, u, v, numsamples, radius, color[4], largest;
  2676. byte *image;
  2677. vec3_t point, origin, total;
  2678. VectorSet(filter, 1, 1, 1);
  2679. if (noalphashading)
  2680. return;
  2681. if (volume->numtransFacets <= 0)
  2682. return;
  2683. if (light->type == LIGHT_SURFACEDIRECTED)
  2684. {
  2685. // project the light map pixel origin onto the area light source plane
  2686. d = DotProduct(lmp, light->normal) - DotProduct(light->normal, light->w.points[0]);
  2687. VectorMA(lmp, -d, light->normal, origin);
  2688. }
  2689. else
  2690. {
  2691. VectorCopy(light->origin, origin);
  2692. }
  2693. for (i = 0; i < volume->numtransFacets; i++)
  2694. {
  2695. test = lsurfaceTest[ volume->transSurfaces[i] ];
  2696. facet = &test->facets[ volume->transFacets[i] ];
  2697. // if this surface does not cast an alpha shadow
  2698. if ( !(test->shader->surfaceFlags & SURF_ALPHASHADOW) )
  2699. continue;
  2700. // if there are no texture pixel available
  2701. if ( !test->shader->pixels ) {
  2702. continue;
  2703. }
  2704. //
  2705. d1 = DotProduct( origin, facet->plane.normal) - facet->plane.dist;
  2706. d2 = DotProduct( lmp, facet->plane.normal ) - facet->plane.dist;
  2707. // this should never happen because the light volume went through the facet
  2708. if ( ( d1 < 0 ) == ( d2 < 0 ) ) {
  2709. continue;
  2710. }
  2711. // calculate the crossing point
  2712. frac = d1 / ( d1 - d2 );
  2713. for ( j = 0 ; j < 3 ; j++ ) {
  2714. point[j] = origin[j] + frac * ( lmp[j] - origin[j] );
  2715. }
  2716. s = DotProduct( point, facet->textureMatrix[0] ) + facet->textureMatrix[0][3];
  2717. t = DotProduct( point, facet->textureMatrix[1] ) + facet->textureMatrix[1][3];
  2718. if (s < 0)
  2719. s = 0;
  2720. if (t < 0)
  2721. t = 0;
  2722. s = s - floor( s );
  2723. t = t - floor( t );
  2724. is = s * test->shader->width;
  2725. it = t * test->shader->height;
  2726. //if old style alpha shading
  2727. if (nocolorshading) {
  2728. image = test->shader->pixels + 4 * ( it * test->shader->width + is );
  2729. // alpha filter
  2730. b = image[3];
  2731. // alpha test makes this a binary option
  2732. b = b < 128 ? 0 : 255;
  2733. filter[0] = filter[0] * (255-b) / 255;
  2734. filter[1] = filter[1] * (255-b) / 255;
  2735. filter[2] = filter[2] * (255-b) / 255;
  2736. }
  2737. else {
  2738. VectorClear(total);
  2739. numsamples = 0;
  2740. radius = 2;
  2741. for ( u = -radius; u <= radius; u++ )
  2742. {
  2743. x = is + u;
  2744. if ( x < 0 || x >= test->shader->width)
  2745. continue;
  2746. for ( v = -radius; v <= radius; v++ )
  2747. {
  2748. y = it + v;
  2749. if ( y < 0 || y >= test->shader->height)
  2750. continue;
  2751. image = test->shader->pixels + 4 * ( y * test->shader->width + x );
  2752. color[0] = image[0];
  2753. color[1] = image[1];
  2754. color[2] = image[2];
  2755. largest = 0;
  2756. for (j = 0; j < 3; j++)
  2757. if (image[j] > largest)
  2758. largest = image[j];
  2759. if (largest <= 0 || image[3] == 0) {
  2760. color[0] = 255;
  2761. color[1] = 255;
  2762. color[2] = 255;
  2763. largest = 255;
  2764. }
  2765. total[0] += ((float) color[0]/largest) * (255-image[3]) / 255.0;
  2766. total[1] += ((float) color[1]/largest) * (255-image[3]) / 255.0;
  2767. total[2] += ((float) color[2]/largest) * (255-image[3]) / 255.0;
  2768. numsamples++;
  2769. }
  2770. }
  2771. ns = numsamples;
  2772. //
  2773. filter[0] *= total[0] / ns;
  2774. filter[1] *= total[1] / ns;
  2775. filter[2] *= total[2] / ns;
  2776. }
  2777. }
  2778. }
  2779. /*
  2780. =============
  2781. VL_LightSurfaceWithVolume
  2782. =============
  2783. */
  2784. void VL_LightSurfaceWithVolume( int surfaceNum, int facetNum, vlight_t *light, lightvolume_t *volume )
  2785. {
  2786. int i;
  2787. dsurface_t *ds;
  2788. lFacet_t *facet;
  2789. lsurfaceTest_t *test;
  2790. winding_t w;
  2791. vec3_t base, dir, delta, normal, filter, origin;
  2792. int min_x[LIGHTMAP_SIZE+2], max_x[LIGHTMAP_SIZE+2];
  2793. int min_y, max_y, k, x, y, n;
  2794. float *color, distscale;
  2795. float d, add, angle, dist, area, insidearea, coords[MAX_POINTS_ON_WINDING+1][2];
  2796. mesh_t *mesh;
  2797. byte polygonedges[(LIGHTMAP_SIZE+1) * (LIGHTMAP_SIZE+1) / 8];
  2798. ds = &drawSurfaces[surfaceNum];
  2799. // vertex-lit triangle model
  2800. if ( ds->surfaceType == MST_TRIANGLE_SOUP ) {
  2801. return;
  2802. }
  2803. if ( ds->lightmapNum < 0 ) {
  2804. return; // doesn't need lighting
  2805. }
  2806. test = lsurfaceTest[ surfaceNum ];
  2807. facet = &test->facets[ facetNum ];
  2808. if (defaulttracelight && !test->always_vlight)
  2809. return;
  2810. if (test->always_tracelight)
  2811. return;
  2812. memcpy(w.points, facet->points, sizeof(vec3_t) * facet->numpoints);
  2813. w.numpoints = facet->numpoints;
  2814. for (i = 0; i < volume->numplanes; i++)
  2815. {
  2816. //if totally on the back
  2817. if (VL_ChopWinding(&w, &volume->planes[i], 0.01) == SIDE_BACK)
  2818. return;
  2819. }
  2820. // only one thread at a time may write to the lightmap of this surface
  2821. MutexLock(test->mutex);
  2822. test->numvolumes++;
  2823. if (ds->surfaceType == MST_PATCH)
  2824. {
  2825. // FIXME: reduce size and don't mark all as edge
  2826. min_y = ds->lightmapY + facet->y;
  2827. max_y = ds->lightmapY + facet->y + facet->height - 1;
  2828. for (y = min_y; y <= max_y; y++)
  2829. {
  2830. min_x[y] = ds->lightmapX + facet->x;
  2831. max_x[y] = ds->lightmapX + facet->x + facet->width - 1;
  2832. for (x = min_x[y]; x <= max_x[y]; x++)
  2833. {
  2834. n = y * LIGHTMAP_SIZE + x;
  2835. polygonedges[n >> 3] |= 1 << (n & 7);
  2836. }
  2837. }
  2838. }
  2839. else
  2840. {
  2841. for (i = 0; i < w.numpoints; i++)
  2842. {
  2843. float s, t;
  2844. if (i >= MAX_POINTS_ON_WINDING)
  2845. _printf("coords overflow\n");
  2846. if (ds->surfaceType != MST_PATCH)
  2847. {
  2848. VectorSubtract(w.points[i], facet->mins, delta);
  2849. s = DotProduct( delta, facet->lightmapMatrix[0] ) + ds->lightmapX + 0.5;
  2850. t = DotProduct( delta, facet->lightmapMatrix[1] ) + ds->lightmapY + 0.5;
  2851. if (s >= LIGHTMAP_SIZE)
  2852. s = LIGHTMAP_SIZE - 0.5;
  2853. if (s < 0)
  2854. s = 0;
  2855. if (t >= LIGHTMAP_SIZE)
  2856. t = LIGHTMAP_SIZE - 0.5;
  2857. if (t < 0)
  2858. t = 0;
  2859. coords[i][0] = s;
  2860. coords[i][1] = t;
  2861. }
  2862. else
  2863. {
  2864. s = DotProduct( w.points[i], facet->lightmapMatrix[0] ) + facet->lightmapMatrix[0][3];
  2865. t = DotProduct( w.points[i], facet->lightmapMatrix[1] ) + facet->lightmapMatrix[1][3];
  2866. s = s - floor( s );
  2867. t = t - floor( t );
  2868. coords[i][0] = ds->lightmapX + s * LIGHTMAP_SIZE;// + 0.5;
  2869. coords[i][1] = ds->lightmapY + t * LIGHTMAP_SIZE;// + 0.5;
  2870. if (coords[i][0] >= LIGHTMAP_SIZE)
  2871. coords[i][0] -= LIGHTMAP_SIZE;
  2872. if (coords[i][1] >= LIGHTMAP_SIZE)
  2873. coords[i][1] -= LIGHTMAP_SIZE;
  2874. if (coords[i][0] < ds->lightmapX)
  2875. coords[i][0] = ds->lightmapX;
  2876. if (coords[i][1] < ds->lightmapY)
  2877. coords[i][1] = ds->lightmapY;
  2878. }
  2879. x = coords[i][0];
  2880. y = coords[i][1];
  2881. if (x < ds->lightmapX || x >= LIGHTMAP_SIZE)
  2882. _printf("VL_LightSurfaceWithVolume: x outside lightmap\n");
  2883. if (y < ds->lightmapY || y >= LIGHTMAP_SIZE)
  2884. _printf("VL_LightSurfaceWithVolume: y outside lightmap\n");
  2885. }
  2886. coords[i][0] = coords[0][0];
  2887. coords[i][1] = coords[0][1];
  2888. //
  2889. min_y = LIGHTMAP_SIZE;
  2890. max_y = 0;
  2891. for (i = 0; i < LIGHTMAP_SIZE; i++)
  2892. {
  2893. min_x[i] = LIGHTMAP_SIZE;
  2894. max_x[i] = 0;
  2895. }
  2896. memset(polygonedges, 0, sizeof(polygonedges));
  2897. // scan convert the polygon onto the lightmap
  2898. // for each edge it marks *every* lightmap pixel the edge goes through
  2899. // so no brasenham and no scan conversion used for texture mapping but
  2900. // more something like ray casting
  2901. // this is necesary because we need all lightmap pixels totally or partly
  2902. // inside the light volume. these lightmap pixels are only lit for the part
  2903. // that they are inside the light volume.
  2904. for (i = 0; i < w.numpoints; i++)
  2905. {
  2906. float xf, yf, dx, dy, xstep, ystep, xfrac, yfrac;
  2907. int xinc, yinc;
  2908. xf = coords[i][0];
  2909. yf = coords[i][1];
  2910. dx = coords[i+1][0] - xf;
  2911. dy = coords[i+1][1] - yf;
  2912. //
  2913. x = (int) xf;
  2914. y = (int) yf;
  2915. //
  2916. if (y < min_y)
  2917. min_y = y;
  2918. if (y > max_y)
  2919. max_y = y;
  2920. //
  2921. if (fabs(dx) > fabs(dy))
  2922. {
  2923. if (dx > 0)
  2924. {
  2925. // y fraction at integer x below fractional x
  2926. yfrac = yf + (floor(xf) - xf) * dy / dx;
  2927. xinc = 1;
  2928. }
  2929. else if (dx < 0)
  2930. {
  2931. // y fraction at integer x above fractional x
  2932. yfrac = yf + (floor(xf) + 1 - xf) * dy / dx;
  2933. xinc = -1;
  2934. }
  2935. else
  2936. {
  2937. yfrac = yf;
  2938. xinc = 0;
  2939. }
  2940. // step in y direction per 1 unit in x direction
  2941. if (dx)
  2942. ystep = dy / fabs(dx);
  2943. else
  2944. ystep = 0;
  2945. while(1)
  2946. {
  2947. if (x < ds->lightmapX || x >= LIGHTMAP_SIZE)
  2948. _printf("VL_LightSurfaceWithVolume: x outside lightmap\n");
  2949. if (y < ds->lightmapY || y >= LIGHTMAP_SIZE)
  2950. _printf("VL_LightSurfaceWithVolume: y outside lightmap\n");
  2951. //
  2952. n = y * LIGHTMAP_SIZE + x;
  2953. polygonedges[n >> 3] |= 1 << (n & 7);
  2954. if (x < min_x[y])
  2955. min_x[y] = x;
  2956. if (x > max_x[y])
  2957. max_x[y] = x;
  2958. if (x == (int) coords[i+1][0])
  2959. break;
  2960. yfrac += ystep;
  2961. if (dy > 0)
  2962. {
  2963. if (yfrac > (float) y + 1)
  2964. {
  2965. y += 1;
  2966. //
  2967. n = y * LIGHTMAP_SIZE + x;
  2968. polygonedges[n >> 3] |= 1 << (n & 7);
  2969. if (x < min_x[y])
  2970. min_x[y] = x;
  2971. if (x > max_x[y])
  2972. max_x[y] = x;
  2973. }
  2974. }
  2975. else
  2976. {
  2977. if (yfrac < (float) y)
  2978. {
  2979. y -= 1;
  2980. //
  2981. n = y * LIGHTMAP_SIZE + x;
  2982. polygonedges[n >> 3] |= 1 << (n & 7);
  2983. if (x < min_x[y])
  2984. min_x[y] = x;
  2985. if (x > max_x[y])
  2986. max_x[y] = x;
  2987. }
  2988. }
  2989. x += xinc;
  2990. }
  2991. }
  2992. else
  2993. {
  2994. if (dy > 0)
  2995. {
  2996. //x fraction at integer y below fractional y
  2997. xfrac = xf + (floor(yf) - yf) * dx / dy;
  2998. yinc = 1;
  2999. }
  3000. else if (dy < 0)
  3001. {
  3002. //x fraction at integer y above fractional y
  3003. xfrac = xf + (floor(yf) + 1 - yf) * dx / dy;
  3004. yinc = -1;
  3005. }
  3006. else
  3007. {
  3008. xfrac = xf;
  3009. yinc = 0;
  3010. }
  3011. // step in x direction per 1 unit in y direction
  3012. if (dy)
  3013. xstep = dx / fabs(dy);
  3014. else
  3015. xstep = 0;
  3016. while(1)
  3017. {
  3018. if (x < ds->lightmapX || x >= LIGHTMAP_SIZE)
  3019. _printf("VL_LightSurfaceWithVolume: x outside lightmap\n");
  3020. if (y < ds->lightmapY || y >= LIGHTMAP_SIZE)
  3021. _printf("VL_LightSurfaceWithVolume: y outside lightmap\n");
  3022. //
  3023. n = y * LIGHTMAP_SIZE + x;
  3024. polygonedges[n >> 3] |= 1 << (n & 7);
  3025. if (x < min_x[y])
  3026. min_x[y] = x;
  3027. if (x > max_x[y])
  3028. max_x[y] = x;
  3029. if (y == (int) coords[i+1][1])
  3030. break;
  3031. xfrac += xstep;
  3032. if (dx > 0)
  3033. {
  3034. if (xfrac > (float) x + 1)
  3035. {
  3036. x += 1;
  3037. //
  3038. n = y * LIGHTMAP_SIZE + x;
  3039. polygonedges[n >> 3] |= 1 << (n & 7);
  3040. if (x < min_x[y])
  3041. min_x[y] = x;
  3042. if (x > max_x[y])
  3043. max_x[y] = x;
  3044. }
  3045. }
  3046. else
  3047. {
  3048. if (xfrac < (float) x)
  3049. {
  3050. x -= 1;
  3051. //
  3052. n = y * LIGHTMAP_SIZE + x;
  3053. polygonedges[n >> 3] |= 1 << (n & 7);
  3054. if (x < min_x[y])
  3055. min_x[y] = x;
  3056. if (x > max_x[y])
  3057. max_x[y] = x;
  3058. }
  3059. }
  3060. y += yinc;
  3061. }
  3062. }
  3063. }
  3064. }
  3065. // map light onto the lightmap
  3066. for (y = min_y; y <= max_y; y++)
  3067. {
  3068. for (x = min_x[y]; x <= max_x[y]; x++)
  3069. {
  3070. if (ds->surfaceType == MST_PATCH)
  3071. {
  3072. mesh = test->detailMesh;
  3073. VectorCopy( mesh->verts[(y-ds->lightmapY)*mesh->width+x-ds->lightmapX].xyz, base);
  3074. VectorCopy( mesh->verts[(y-ds->lightmapY)*mesh->width+x-ds->lightmapX].normal, normal);
  3075. //VectorCopy(facet->plane.normal, normal);
  3076. }
  3077. else
  3078. {
  3079. VectorMA(ds->lightmapOrigin, (float) x - ds->lightmapX, ds->lightmapVecs[0], base);
  3080. VectorMA(base, (float) y - ds->lightmapY, ds->lightmapVecs[1], base);
  3081. VectorCopy(facet->plane.normal, normal);
  3082. }
  3083. if (light->type == LIGHT_POINTSPOT)
  3084. {
  3085. float distByNormal;
  3086. vec3_t pointAtDist;
  3087. float radiusAtDist;
  3088. float sampleRadius;
  3089. vec3_t distToSample;
  3090. float coneScale;
  3091. VectorSubtract( light->origin, base, dir );
  3092. distByNormal = -DotProduct( dir, light->normal );
  3093. if ( distByNormal < 0 ) {
  3094. continue;
  3095. }
  3096. VectorMA( light->origin, distByNormal, light->normal, pointAtDist );
  3097. radiusAtDist = light->radiusByDist * distByNormal;
  3098. VectorSubtract( base, pointAtDist, distToSample );
  3099. sampleRadius = VectorLength( distToSample );
  3100. if ( sampleRadius >= radiusAtDist ) {
  3101. continue; // outside the cone
  3102. }
  3103. if ( sampleRadius <= radiusAtDist - 32 ) {
  3104. coneScale = 1.0; // fully inside
  3105. } else {
  3106. coneScale = ( radiusAtDist - sampleRadius ) / 32.0;
  3107. }
  3108. dist = VectorNormalize( dir, dir );
  3109. // clamp the distance to prevent super hot spots
  3110. if ( dist < 16 ) {
  3111. dist = 16;
  3112. }
  3113. angle = DotProduct( normal, dir );
  3114. if (angle > 1)
  3115. angle = 1;
  3116. if (angle > 0) {
  3117. if ( light->atten_angletype == LAAT_QUADRATIC ) {
  3118. angle = 1 - angle;
  3119. angle *= angle;
  3120. angle = 1 - angle;
  3121. }
  3122. else if ( light->atten_angletype == LAAT_DOUBLEQUADRATIC ) {
  3123. angle = 1 - angle;
  3124. angle *= angle * angle;
  3125. angle = 1 - angle;
  3126. }
  3127. }
  3128. if (light->atten_anglescale > 0) {
  3129. angle /= light->atten_anglescale;
  3130. if (angle > 1)
  3131. angle = 1;
  3132. }
  3133. if (light->atten_distscale > 0) {
  3134. distscale = light->atten_distscale;
  3135. }
  3136. else {
  3137. distscale = 1;
  3138. }
  3139. //
  3140. if ( light->atten_disttype == LDAT_NOSCALE ) {
  3141. add = angle * coneScale;
  3142. }
  3143. else if ( light->atten_disttype == LDAT_LINEAR ) {
  3144. add = angle * light->photons * lightLinearScale * coneScale - dist * distscale;
  3145. if ( add < 0 ) {
  3146. add = 0;
  3147. }
  3148. }
  3149. else {
  3150. add = light->photons / ( dist * dist * distscale) * angle * coneScale;
  3151. }
  3152. if (add <= 1.0)
  3153. continue;
  3154. }
  3155. else if (light->type == LIGHT_POINTFAKESURFACE)
  3156. {
  3157. // calculate the contribution
  3158. add = PointToPolygonFormFactor( base, normal, &light->w );
  3159. if ( add <= 0 ) {
  3160. if ( light->twosided ) {
  3161. add = -add;
  3162. } else {
  3163. continue;
  3164. }
  3165. }
  3166. }
  3167. else if (light->type == LIGHT_SURFACEDIRECTED)
  3168. {
  3169. //VectorCopy(light->normal, dir);
  3170. //VectorInverse(dir);
  3171. // project the light map pixel origin onto the area light source plane
  3172. d = DotProduct(base, light->normal) - DotProduct(light->normal, light->w.points[0]);
  3173. VectorMA(base, -d, light->normal, origin);
  3174. VectorSubtract(origin, base, dir);
  3175. dist = VectorNormalize(dir, dir);
  3176. if ( dist < 16 ) {
  3177. dist = 16;
  3178. }
  3179. //
  3180. angle = DotProduct( normal, dir );
  3181. if (angle > 1)
  3182. angle = 1;
  3183. if (angle > 0) {
  3184. if ( light->atten_angletype == LAAT_QUADRATIC ) {
  3185. angle = 1 - angle;
  3186. angle *= angle;
  3187. angle = 1 - angle;
  3188. }
  3189. else if ( light->atten_angletype == LAAT_DOUBLEQUADRATIC ) {
  3190. angle = 1 - angle;
  3191. angle *= angle * angle;
  3192. angle = 1 - angle;
  3193. }
  3194. }
  3195. if (light->atten_anglescale > 0) {
  3196. angle /= light->atten_anglescale;
  3197. if (angle > 1)
  3198. angle = 1;
  3199. }
  3200. if (light->atten_distscale > 0) {
  3201. distscale = light->atten_distscale;
  3202. }
  3203. else {
  3204. distscale = 1;
  3205. }
  3206. if ( light->atten_disttype == LDAT_NOSCALE ) {
  3207. add = angle;
  3208. }
  3209. else if ( light->atten_disttype == LDAT_LINEAR ) {
  3210. add = angle * light->photons * lightLinearScale - dist * distscale;
  3211. if ( add < 0 ) {
  3212. add = 0;
  3213. }
  3214. } else { //default quadratic
  3215. add = light->photons / ( dist * dist * distscale) * angle;
  3216. }
  3217. if (add <= 0)
  3218. continue;
  3219. }
  3220. else //normal radial point light
  3221. {
  3222. VectorSubtract(light->origin, base, dir);
  3223. dist = VectorNormalize(dir, dir);
  3224. if ( dist < 16 ) {
  3225. dist = 16;
  3226. }
  3227. angle = DotProduct( normal, dir );
  3228. if (angle > 1)
  3229. angle = 1;
  3230. if (angle > 0) {
  3231. if ( light->atten_angletype == LAAT_QUADRATIC ) {
  3232. angle = 1 - angle;
  3233. angle *= angle;
  3234. angle = 1 - angle;
  3235. }
  3236. else if ( light->atten_angletype == LAAT_DOUBLEQUADRATIC ) {
  3237. angle = 1 - angle;
  3238. angle *= angle * angle;
  3239. angle = 1 - angle;
  3240. }
  3241. }
  3242. if (light->atten_anglescale > 0) {
  3243. angle /= light->atten_anglescale;
  3244. if (angle > 1)
  3245. angle = 1;
  3246. }
  3247. if (light->atten_distscale > 0) {
  3248. distscale = light->atten_distscale;
  3249. }
  3250. else {
  3251. distscale = 1;
  3252. }
  3253. if ( light->atten_disttype == LDAT_NOSCALE ) {
  3254. add = angle;
  3255. }
  3256. else if ( light->atten_disttype == LDAT_LINEAR ) {
  3257. add = angle * light->photons * lightLinearScale - dist * distscale;
  3258. if ( add < 0 ) {
  3259. add = 0;
  3260. }
  3261. } else {
  3262. add = light->photons / ( dist * dist * distscale) * angle;
  3263. }
  3264. if (add <= 1.0)
  3265. continue;
  3266. }
  3267. //
  3268. k = (ds->lightmapNum * LIGHTMAP_HEIGHT + y) * LIGHTMAP_WIDTH + x;
  3269. //if on one of the edges
  3270. n = y * LIGHTMAP_SIZE + x;
  3271. if ((polygonedges[n >> 3] & (1 << (n & 7)) ))
  3272. {
  3273. // multiply 'add' by the relative area being lit of the total visible lightmap pixel area
  3274. //
  3275. // first create a winding for the lightmap pixel
  3276. if (ds->surfaceType == MST_PATCH)
  3277. {
  3278. mesh = test->detailMesh;
  3279. if (y-ds->lightmapY >= mesh->height-1)
  3280. _printf("y outside mesh\n");
  3281. if (x-ds->lightmapX >= mesh->width-1)
  3282. _printf("x outside mesh\n");
  3283. VectorCopy( mesh->verts[(y-ds->lightmapY)*mesh->width+x-ds->lightmapX].xyz, w.points[0]);
  3284. VectorCopy( mesh->verts[(y+1-ds->lightmapY)*mesh->width+x-ds->lightmapX].xyz, w.points[1]);
  3285. VectorCopy( mesh->verts[(y+1-ds->lightmapY)*mesh->width+x+1-ds->lightmapX].xyz, w.points[2]);
  3286. VectorCopy( mesh->verts[(y-ds->lightmapY)*mesh->width+x+1-ds->lightmapX].xyz, w.points[3]);
  3287. w.numpoints = 4;
  3288. }
  3289. else
  3290. {
  3291. VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT - ds->lightmapX, ds->lightmapVecs[0], w.points[0]);
  3292. VectorMA(w.points[0], (float) y - LIGHTMAP_PIXELSHIFT - ds->lightmapY, ds->lightmapVecs[1], w.points[0]);
  3293. VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT - ds->lightmapX, ds->lightmapVecs[0], w.points[1]);
  3294. VectorMA(w.points[1], (float) y - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapY, ds->lightmapVecs[1], w.points[1]);
  3295. VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapX, ds->lightmapVecs[0], w.points[2]);
  3296. VectorMA(w.points[2], (float) y - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapY, ds->lightmapVecs[1], w.points[2]);
  3297. VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapX, ds->lightmapVecs[0], w.points[3]);
  3298. VectorMA(w.points[3], (float) y - LIGHTMAP_PIXELSHIFT - ds->lightmapY, ds->lightmapVecs[1], w.points[3]);
  3299. w.numpoints = 4;
  3300. }
  3301. //
  3302. // take the visible area of the lightmap pixel into account
  3303. //
  3304. //area = WindingArea(&w);
  3305. area = lightmappixelarea[k];
  3306. if (area <= 0)
  3307. continue;
  3308. // chop the lightmap pixel winding with the light volume
  3309. for (i = 0; i < volume->numplanes; i++)
  3310. {
  3311. //if totally on the back
  3312. if (VL_ChopWinding(&w, &volume->planes[i], 0) == SIDE_BACK)
  3313. break;
  3314. }
  3315. // if the lightmap pixel is partly inside the light volume
  3316. if (i >= volume->numplanes)
  3317. {
  3318. insidearea = WindingArea(&w);
  3319. if (insidearea <= 0)
  3320. i = 0;
  3321. add = add * insidearea / area;
  3322. }
  3323. else
  3324. {
  3325. //DebugNet_DrawWinding(&w, 2);
  3326. continue; // this shouldn't happen
  3327. }
  3328. }
  3329. // get the light filter from all the translucent surfaces the light volume went through
  3330. VL_GetFilter(light, volume, base, filter);
  3331. //
  3332. color = &lightFloats[k*3];
  3333. color[0] += add * light->color[0] * filter[0];
  3334. color[1] += add * light->color[1] * filter[1];
  3335. color[2] += add * light->color[2] * filter[2];
  3336. }
  3337. }
  3338. MutexUnlock(test->mutex);
  3339. }
  3340. #endif
  3341. /*
  3342. =============
  3343. VL_SplitLightVolume
  3344. =============
  3345. */
  3346. int VL_SplitLightVolume(lightvolume_t *volume, lightvolume_t *back, plane_t *split, float epsilon)
  3347. {
  3348. lightvolume_t f, b;
  3349. vec_t dists[128];
  3350. int sides[128];
  3351. int counts[3];
  3352. vec_t dot;
  3353. int i, j;
  3354. vec_t *p1, *p2;
  3355. vec3_t mid;
  3356. counts[0] = counts[1] = counts[2] = 0;
  3357. // determine sides for each point
  3358. for (i = 0; i < volume->numplanes; i++)
  3359. {
  3360. dot = DotProduct (volume->points[i], split->normal);
  3361. dot -= split->dist;
  3362. dists[i] = dot;
  3363. if (dot > epsilon)
  3364. sides[i] = SIDE_FRONT;
  3365. else if (dot < -epsilon)
  3366. sides[i] = SIDE_BACK;
  3367. else
  3368. {
  3369. sides[i] = SIDE_ON;
  3370. }
  3371. counts[sides[i]]++;
  3372. }
  3373. if (!counts[1])
  3374. return 0; // completely on front side
  3375. if (!counts[0])
  3376. return 1; // completely on back side
  3377. sides[i] = sides[0];
  3378. dists[i] = dists[0];
  3379. f.numplanes = 0;
  3380. b.numplanes = 0;
  3381. for (i = 0; i < volume->numplanes; i++)
  3382. {
  3383. p1 = volume->points[i];
  3384. if (f.numplanes >= MAX_POINTS_ON_FIXED_WINDING)
  3385. {
  3386. _printf("WARNING: VL_SplitLightVolume -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
  3387. return 0; // can't chop -- fall back to original
  3388. }
  3389. if (b.numplanes >= MAX_POINTS_ON_FIXED_WINDING)
  3390. {
  3391. _printf("WARNING: VL_SplitLightVolume -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
  3392. return 0; // can't chop -- fall back to original
  3393. }
  3394. if (sides[i] == SIDE_ON)
  3395. {
  3396. VectorCopy(p1, f.points[f.numplanes]);
  3397. VectorCopy(p1, b.points[b.numplanes]);
  3398. if (sides[i+1] == SIDE_BACK)
  3399. {
  3400. f.planes[f.numplanes] = *split;
  3401. b.planes[b.numplanes] = volume->planes[i];
  3402. }
  3403. else if (sides[i+1] == SIDE_FRONT)
  3404. {
  3405. f.planes[f.numplanes] = volume->planes[i];
  3406. b.planes[b.numplanes] = *split;
  3407. VectorInverse(b.planes[b.numplanes].normal);
  3408. b.planes[b.numplanes].dist = -b.planes[b.numplanes].dist;
  3409. }
  3410. else //this shouldn't happen
  3411. {
  3412. f.planes[f.numplanes] = *split;
  3413. b.planes[b.numplanes] = *split;
  3414. VectorInverse(b.planes[b.numplanes].normal);
  3415. b.planes[b.numplanes].dist = -b.planes[b.numplanes].dist;
  3416. }
  3417. f.numplanes++;
  3418. b.numplanes++;
  3419. continue;
  3420. }
  3421. if (sides[i] == SIDE_FRONT)
  3422. {
  3423. VectorCopy (p1, f.points[f.numplanes]);
  3424. f.planes[f.numplanes] = volume->planes[i];
  3425. f.numplanes++;
  3426. }
  3427. if (sides[i] == SIDE_BACK)
  3428. {
  3429. VectorCopy (p1, b.points[b.numplanes]);
  3430. b.planes[b.numplanes] = volume->planes[i];
  3431. b.numplanes++;
  3432. }
  3433. if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
  3434. continue;
  3435. if (f.numplanes >= MAX_POINTS_ON_FIXED_WINDING)
  3436. {
  3437. _printf("WARNING: VL_SplitLightVolume -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
  3438. return 0; // can't chop -- fall back to original
  3439. }
  3440. if (b.numplanes >= MAX_POINTS_ON_FIXED_WINDING)
  3441. {
  3442. _printf("WARNING: VL_SplitLightVolume -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
  3443. return 0; // can't chop -- fall back to original
  3444. }
  3445. // generate a split point
  3446. p2 = volume->points[(i+1)%volume->numplanes];
  3447. dot = dists[i] / (dists[i]-dists[i+1]);
  3448. for (j=0 ; j<3 ; j++)
  3449. { // avoid round off error when possible
  3450. if (split->normal[j] == 1)
  3451. mid[j] = split->dist;
  3452. else if (split->normal[j] == -1)
  3453. mid[j] = -split->dist;
  3454. else
  3455. mid[j] = p1[j] + dot*(p2[j]-p1[j]);
  3456. }
  3457. VectorCopy (mid, f.points[f.numplanes]);
  3458. VectorCopy(mid, b.points[b.numplanes]);
  3459. if (sides[i+1] == SIDE_BACK)
  3460. {
  3461. f.planes[f.numplanes] = *split;
  3462. b.planes[b.numplanes] = volume->planes[i];
  3463. }
  3464. else
  3465. {
  3466. f.planes[f.numplanes] = volume->planes[i];
  3467. b.planes[b.numplanes] = *split;
  3468. VectorInverse(b.planes[b.numplanes].normal);
  3469. b.planes[b.numplanes].dist = -b.planes[b.numplanes].dist;
  3470. }
  3471. f.numplanes++;
  3472. b.numplanes++;
  3473. }
  3474. memcpy(volume->points, f.points, sizeof(vec3_t) * f.numplanes);
  3475. memcpy(volume->planes, f.planes, sizeof(plane_t) * f.numplanes);
  3476. volume->numplanes = f.numplanes;
  3477. memcpy(back->points, b.points, sizeof(vec3_t) * b.numplanes);
  3478. memcpy(back->planes, b.planes, sizeof(plane_t) * b.numplanes);
  3479. back->numplanes = b.numplanes;
  3480. return 2;
  3481. }
  3482. /*
  3483. =============
  3484. VL_PlaneForEdgeToWinding
  3485. =============
  3486. */
  3487. void VL_PlaneForEdgeToWinding(vec3_t p1, vec3_t p2, winding_t *w, int windingonfront, plane_t *plane)
  3488. {
  3489. int i, j;
  3490. float length, d;
  3491. vec3_t v1, v2;
  3492. VectorSubtract(p2, p1, v1);
  3493. for (i = 0; i < w->numpoints; i++)
  3494. {
  3495. VectorSubtract (w->points[i], p1, v2);
  3496. plane->normal[0] = v1[1]*v2[2] - v1[2]*v2[1];
  3497. plane->normal[1] = v1[2]*v2[0] - v1[0]*v2[2];
  3498. plane->normal[2] = v1[0]*v2[1] - v1[1]*v2[0];
  3499. // if points don't make a valid plane, skip it
  3500. length = plane->normal[0] * plane->normal[0]
  3501. + plane->normal[1] * plane->normal[1]
  3502. + plane->normal[2] * plane->normal[2];
  3503. if (length < ON_EPSILON)
  3504. continue;
  3505. length = 1/sqrt(length);
  3506. plane->normal[0] *= length;
  3507. plane->normal[1] *= length;
  3508. plane->normal[2] *= length;
  3509. plane->dist = DotProduct (w->points[i], plane->normal);
  3510. //
  3511. for (j = 0; j < w->numpoints; j++)
  3512. {
  3513. if (j == i)
  3514. continue;
  3515. d = DotProduct(w->points[j], plane->normal) - plane->dist;
  3516. if (windingonfront)
  3517. {
  3518. if (d < -ON_EPSILON)
  3519. break;
  3520. }
  3521. else
  3522. {
  3523. if (d > ON_EPSILON)
  3524. break;
  3525. }
  3526. }
  3527. if (j >= w->numpoints)
  3528. return;
  3529. }
  3530. }
  3531. /*
  3532. =============
  3533. VL_R_CastLightAtSurface
  3534. =============
  3535. */
  3536. void VL_R_FloodLight(vlight_t *light, lightvolume_t *volume, int cluster, int firstportal);
  3537. void VL_R_CastLightAtSurface(vlight_t *light, lightvolume_t *volume)
  3538. {
  3539. lsurfaceTest_t *test;
  3540. int i, n;
  3541. // light the surface with this volume
  3542. VL_LightSurfaceWithVolume(volume->surfaceNum, volume->facetNum, light, volume);
  3543. //
  3544. test = lsurfaceTest[ volume->surfaceNum ];
  3545. // if this is not a translucent surface
  3546. if ( !(test->shader->surfaceFlags & SURF_ALPHASHADOW) && !(test->shader->contents & CONTENTS_TRANSLUCENT))
  3547. return;
  3548. //
  3549. if (volume->numtransFacets >= MAX_TRANSLUCENTFACETS)
  3550. Error("a light valume went through more than %d translucent facets", MAX_TRANSLUCENTFACETS);
  3551. //add this translucent surface to the list
  3552. volume->transSurfaces[volume->numtransFacets] = volume->surfaceNum;
  3553. volume->transFacets[volume->numtransFacets] = volume->facetNum;
  3554. volume->numtransFacets++;
  3555. //clear the tested facets except the translucent ones
  3556. memset(volume->facetTested, 0, sizeof(volume->facetTested));
  3557. for (i = 0; i < volume->numtransFacets; i++)
  3558. {
  3559. test = lsurfaceTest[ volume->transSurfaces[i] ];
  3560. n = test->facets[volume->transFacets[i]].num;
  3561. volume->facetTested[n >> 3] |= 1 << (n & 7);
  3562. }
  3563. memset(volume->clusterTested, 0, sizeof(volume->clusterTested));
  3564. volume->endplane = volume->farplane;
  3565. volume->surfaceNum = -1;
  3566. volume->facetNum = 0;
  3567. VL_R_FloodLight(light, volume, volume->cluster, 0);
  3568. if (volume->surfaceNum >= 0)
  3569. {
  3570. VL_R_CastLightAtSurface(light, volume);
  3571. }
  3572. }
  3573. /*
  3574. =============
  3575. VL_R_SplitLightVolume
  3576. =============
  3577. */
  3578. int numvolumes = 0;
  3579. int VL_R_SplitLightVolume(vlight_t *light, lightvolume_t *volume, plane_t *split, int cluster, int firstportal)
  3580. {
  3581. lightvolume_t back;
  3582. int res;
  3583. //
  3584. res = VL_SplitLightVolume(volume, &back, split, 0.1);
  3585. // if the volume was split
  3586. if (res == 2)
  3587. {
  3588. memcpy(back.clusterTested, volume->clusterTested, sizeof(back.clusterTested));
  3589. memcpy(back.facetTested, volume->facetTested, sizeof(back.facetTested));
  3590. back.num = numvolumes++;
  3591. back.endplane = volume->endplane;
  3592. back.surfaceNum = volume->surfaceNum;
  3593. back.facetNum = volume->facetNum;
  3594. back.type = volume->type;
  3595. back.cluster = volume->cluster;
  3596. back.farplane = volume->farplane;
  3597. if (volume->numtransFacets > 0)
  3598. {
  3599. memcpy(back.transFacets, volume->transFacets, sizeof(back.transFacets));
  3600. memcpy(back.transSurfaces, volume->transSurfaces, sizeof(back.transSurfaces));
  3601. }
  3602. back.numtransFacets = volume->numtransFacets;
  3603. //
  3604. // flood the volume at the back of the split plane
  3605. VL_R_FloodLight(light, &back, cluster, firstportal);
  3606. // if the back volume hit a surface
  3607. if (back.surfaceNum >= 0)
  3608. {
  3609. VL_R_CastLightAtSurface(light, &back);
  3610. }
  3611. }
  3612. return res;
  3613. }
  3614. /*
  3615. =============
  3616. VL_R_FloodLight
  3617. =============
  3618. */
  3619. void VL_R_FloodLight(vlight_t *light, lightvolume_t *volume, int cluster, int firstportal)
  3620. {
  3621. int i, j, k, res, surfaceNum, backfaceculled, testculled;
  3622. float d;
  3623. winding_t winding, tmpwinding;
  3624. lleaf_t *leaf;
  3625. lportal_t *p;
  3626. lsurfaceTest_t *test;
  3627. lFacet_t *facet;
  3628. vec3_t dir1, dir2;
  3629. plane_t plane;
  3630. // DebugNet_RemoveAllPolys();
  3631. // VL_DrawLightVolume(light, volume);
  3632. // if the first portal is not zero then we've checked all occluders in this leaf already
  3633. if (firstportal == 0)
  3634. {
  3635. // check all potential occluders in this leaf
  3636. for (i = 0; i < leafs[cluster].numSurfaces; i++)
  3637. {
  3638. surfaceNum = clustersurfaces[leafs[cluster].firstSurface + i];
  3639. //
  3640. test = lsurfaceTest[ surfaceNum ];
  3641. if ( !test )
  3642. continue;
  3643. //
  3644. testculled = qfalse;
  3645. // use surface as an occluder
  3646. for (j = 0; j < test->numFacets; j++)
  3647. {
  3648. // use each facet as an occluder
  3649. facet = &test->facets[j];
  3650. //
  3651. // memcpy(winding.points, facet->points, sizeof(vec3_t) * facet->numpoints);
  3652. // winding.numpoints = facet->numpoints;
  3653. // DebugNet_DrawWinding(&winding, 5);
  3654. //
  3655. // if the facet was tested already
  3656. if ( volume->facetTested[facet->num >> 3] & (1 << (facet->num & 7)) )
  3657. continue;
  3658. volume->facetTested[facet->num >> 3] |= 1 << (facet->num & 7);
  3659. // backface culling for planar surfaces
  3660. backfaceculled = qfalse;
  3661. if (!test->patch && !test->trisoup)
  3662. {
  3663. if (volume->type == VOLUME_NORMAL)
  3664. {
  3665. // facet backface culling
  3666. d = DotProduct(light->origin, facet->plane.normal) - facet->plane.dist;
  3667. if (d < 0)
  3668. {
  3669. // NOTE: this doesn't work too great because of sometimes very bad tesselation
  3670. // of surfaces that are supposed to be flat
  3671. // FIXME: to work around this problem we should make sure that all facets
  3672. // created from planar surfaces use the lightmapVecs normal vector
  3673. /*
  3674. if ( !test->shader->twoSided )
  3675. {
  3676. // skip all other facets of this surface as well because they are in the same plane
  3677. for (k = 0; k < test->numFacets; k++)
  3678. {
  3679. facet = &test->facets[k];
  3680. volume->facetTested[facet->num >> 3] |= 1 << (facet->num & 7);
  3681. }
  3682. }*/
  3683. backfaceculled = qtrue;
  3684. }
  3685. }
  3686. else
  3687. {
  3688. // FIXME: if all light source winding points are at the back of the facet
  3689. // plane then backfaceculled = qtrue
  3690. }
  3691. }
  3692. else // backface culling per facet for patches and triangle soups
  3693. {
  3694. if (volume->type == VOLUME_NORMAL)
  3695. {
  3696. // facet backface culling
  3697. d = DotProduct(light->origin, facet->plane.normal) - facet->plane.dist;
  3698. if (d < 0)
  3699. backfaceculled = qtrue;
  3700. }
  3701. else
  3702. {
  3703. // FIXME: if all light source winding points are at the back of the facet
  3704. // plane then backfaceculled = qtrue
  3705. }
  3706. }
  3707. /* chopping does this already
  3708. // check if this facet is totally or partly in front of the volume end plane
  3709. for (k = 0; k < facet->numpoints; k++)
  3710. {
  3711. d = DotProduct(volume->endplane.normal, facet->points[k]) - volume->endplane.dist;
  3712. if (d > ON_EPSILON)
  3713. break;
  3714. }
  3715. // if this facet is outside the light volume
  3716. if (k >= facet->numpoints)
  3717. continue;
  3718. */
  3719. //
  3720. if (backfaceculled)
  3721. {
  3722. // if the facet is not two sided
  3723. if ( !nobackfaceculling && !test->shader->twoSided )
  3724. continue;
  3725. // flip the winding
  3726. for (k = 0; k < facet->numpoints; k++)
  3727. VectorCopy(facet->points[k], winding.points[facet->numpoints - k - 1]);
  3728. winding.numpoints = facet->numpoints;
  3729. }
  3730. else
  3731. {
  3732. memcpy(winding.points, facet->points, sizeof(vec3_t) * facet->numpoints);
  3733. winding.numpoints = facet->numpoints;
  3734. }
  3735. //
  3736. if (!testculled)
  3737. {
  3738. testculled = qtrue;
  3739. // fast check if the surface sphere is totally behind the volume end plane
  3740. d = DotProduct(volume->endplane.normal, test->origin) - volume->endplane.dist;
  3741. if (d < -test->radius)
  3742. {
  3743. for (k = 0; k < test->numFacets; k++)
  3744. {
  3745. facet = &test->facets[k];
  3746. volume->facetTested[facet->num >> 3] |= 1 << (facet->num & 7);
  3747. }
  3748. break;
  3749. }
  3750. for (k = 0; k < volume->numplanes; k++)
  3751. {
  3752. d = DotProduct(volume->planes[k].normal, test->origin) - volume->planes[k].dist;
  3753. if (d < - test->radius)
  3754. {
  3755. for (k = 0; k < test->numFacets; k++)
  3756. {
  3757. facet = &test->facets[k];
  3758. volume->facetTested[facet->num >> 3] |= 1 << (facet->num & 7);
  3759. }
  3760. break;
  3761. }
  3762. }
  3763. if (k < volume->numplanes)
  3764. break;
  3765. }
  3766. //NOTE: we have to chop the facet winding with the volume end plane because
  3767. // the faces in Q3 are not stitched together nicely
  3768. res = VL_ChopWinding(&winding, &volume->endplane, 0.01);
  3769. // if the facet is on or at the back of the volume end plane
  3770. if (res == SIDE_BACK || res == SIDE_ON)
  3771. continue;
  3772. // check if the facet winding is totally or partly inside the light volume
  3773. memcpy(&tmpwinding, &winding, sizeof(winding_t));
  3774. for (k = 0; k < volume->numplanes; k++)
  3775. {
  3776. res = VL_ChopWinding(&tmpwinding, &volume->planes[k], 0.01);
  3777. if (res == SIDE_BACK || res == SIDE_ON)
  3778. break;
  3779. }
  3780. // if no part of the light volume is occluded by this facet
  3781. if (k < volume->numplanes)
  3782. continue;
  3783. //
  3784. for (k = 0; k < winding.numpoints; k++)
  3785. {
  3786. if (volume->type == VOLUME_DIRECTED)
  3787. {
  3788. VectorSubtract(winding.points[(k+1) % winding.numpoints], winding.points[k], dir1);
  3789. CrossProduct(light->normal, dir1, plane.normal);
  3790. VectorNormalize(plane.normal, plane.normal);
  3791. plane.dist = DotProduct(plane.normal, winding.points[k]);
  3792. }
  3793. else
  3794. {
  3795. VectorSubtract(winding.points[(k+1) % winding.numpoints], winding.points[k], dir1);
  3796. VectorSubtract(light->origin, winding.points[k], dir2);
  3797. CrossProduct(dir1, dir2, plane.normal);
  3798. VectorNormalize(plane.normal, plane.normal);
  3799. plane.dist = DotProduct(plane.normal, winding.points[k]);
  3800. }
  3801. res = VL_R_SplitLightVolume(light, volume, &plane, cluster, 0);
  3802. if (res == 1)
  3803. break; //the facet wasn't really inside the volume
  3804. }
  3805. if (k >= winding.numpoints)
  3806. {
  3807. volume->endplane = facet->plane;
  3808. if (backfaceculled)
  3809. {
  3810. VectorInverse(volume->endplane.normal);
  3811. volume->endplane.dist = -volume->endplane.dist;
  3812. }
  3813. volume->surfaceNum = surfaceNum;
  3814. volume->facetNum = j;
  3815. }
  3816. }
  3817. }
  3818. }
  3819. // we've tested all occluders in this cluster
  3820. volume->clusterTested[cluster >> 3] |= 1 << (cluster & 7);
  3821. // flood light through the portals of the current leaf
  3822. leaf = &leafs[cluster];
  3823. for (i = firstportal; i < leaf->numportals; i++)
  3824. {
  3825. p = leaf->portals[i];
  3826. //
  3827. // memcpy(&winding, p->winding, sizeof(winding_t));
  3828. // DebugNet_DrawWinding(&winding, 5);
  3829. // if already flooded into the cluster this portal leads to
  3830. if ( volume->clusterTested[p->leaf >> 3] & (1 << (p->leaf & 7)) )
  3831. continue;
  3832. //
  3833. if (volume->type == VOLUME_NORMAL)
  3834. {
  3835. // portal backface culling
  3836. d = DotProduct(light->origin, p->plane.normal) - p->plane.dist;
  3837. if (d > 0) // portal plane normal points into neighbour cluster
  3838. continue;
  3839. }
  3840. else
  3841. {
  3842. // FIXME: if all light source winding points are at the back of this portal
  3843. // plane then there's no need to flood through
  3844. }
  3845. // check if this portal is totally or partly in front of the volume end plane
  3846. // fast check with portal sphere
  3847. d = DotProduct(volume->endplane.normal, p->origin) - volume->endplane.dist;
  3848. if (d < -p->radius)
  3849. continue;
  3850. for (j = 0; j < p->winding->numpoints; j++)
  3851. {
  3852. d = DotProduct(volume->endplane.normal, p->winding->points[j]) - volume->endplane.dist;
  3853. if (d > -0.01)
  3854. break;
  3855. }
  3856. // if this portal is totally behind the light volume end plane
  3857. if (j >= p->winding->numpoints)
  3858. continue;
  3859. //distance from point light to portal
  3860. d = DotProduct(p->plane.normal, light->origin) - p->plane.dist;
  3861. // only check if a point light is Not *on* the portal
  3862. if (volume->type != VOLUME_NORMAL || fabs(d) > 0.1)
  3863. {
  3864. // check if the portal is partly or totally inside the light volume
  3865. memcpy(&winding, p->winding, sizeof(winding_t));
  3866. for (j = 0; j < volume->numplanes; j++)
  3867. {
  3868. res = VL_ChopWinding(&winding, &volume->planes[j], 0.01);
  3869. if (res == SIDE_BACK || res == SIDE_ON)
  3870. break;
  3871. }
  3872. // if the light volume does not go through this portal at all
  3873. if (j < volume->numplanes)
  3874. continue;
  3875. }
  3876. // chop the light volume with the portal
  3877. for (k = 0; k < p->winding->numpoints; k++)
  3878. {
  3879. if (volume->type == VOLUME_DIRECTED)
  3880. {
  3881. VectorSubtract(p->winding->points[(k+1) % p->winding->numpoints], p->winding->points[k], dir1);
  3882. CrossProduct(light->normal, dir1, plane.normal);
  3883. VectorNormalize(plane.normal, plane.normal);
  3884. plane.dist = DotProduct(plane.normal, p->winding->points[k]);
  3885. }
  3886. else
  3887. {
  3888. VectorSubtract(p->winding->points[(k+1) % p->winding->numpoints], p->winding->points[k], dir1);
  3889. VectorSubtract(light->origin, p->winding->points[k], dir2);
  3890. CrossProduct(dir1, dir2, plane.normal);
  3891. VectorNormalize(plane.normal, plane.normal);
  3892. plane.dist = DotProduct(plane.normal, p->winding->points[k]);
  3893. }
  3894. res = VL_R_SplitLightVolume(light, volume, &plane, cluster, i+1);
  3895. if (res == 1)
  3896. break; //volume didn't really go through the portal
  3897. }
  3898. // if the light volume went through the portal
  3899. if (k >= p->winding->numpoints)
  3900. {
  3901. // flood through the portal
  3902. VL_R_FloodLight(light, volume, p->leaf, 0);
  3903. }
  3904. }
  3905. }
  3906. /*
  3907. =============
  3908. VL_R_FloodAreaSpotLight
  3909. =============
  3910. */
  3911. void VL_FloodAreaSpotLight(vlight_t *light, winding_t *w, int leafnum)
  3912. {
  3913. }
  3914. /*
  3915. =============
  3916. VL_R_SubdivideAreaSpotLight
  3917. =============
  3918. */
  3919. void VL_R_SubdivideAreaSpotLight(vlight_t *light, int nodenum, winding_t *w)
  3920. {
  3921. int leafnum, res;
  3922. dnode_t *node;
  3923. dplane_t *plane;
  3924. winding_t back;
  3925. plane_t split;
  3926. while(nodenum >= 0)
  3927. {
  3928. node = &dnodes[nodenum];
  3929. plane = &dplanes[node->planeNum];
  3930. VectorCopy(plane->normal, split.normal);
  3931. split.dist = plane->dist;
  3932. res = VL_SplitWinding (w, &back, &split, 0.1);
  3933. if (res == SIDE_FRONT)
  3934. {
  3935. nodenum = node->children[0];
  3936. }
  3937. else if (res == SIDE_BACK)
  3938. {
  3939. nodenum = node->children[1];
  3940. }
  3941. else if (res == SIDE_ON)
  3942. {
  3943. memcpy(&back, w, sizeof(winding_t));
  3944. VL_R_SubdivideAreaSpotLight(light, node->children[1], &back);
  3945. nodenum = node->children[0];
  3946. }
  3947. else
  3948. {
  3949. VL_R_SubdivideAreaSpotLight(light, node->children[1], &back);
  3950. nodenum = node->children[0];
  3951. }
  3952. }
  3953. leafnum = -nodenum - 1;
  3954. if (dleafs[leafnum].cluster != -1)
  3955. {
  3956. VL_FloodAreaSpotLight(light, w, leafnum);
  3957. }
  3958. }
  3959. /*
  3960. =============
  3961. VL_R_FloodRadialAreaLight
  3962. =============
  3963. */
  3964. void VL_FloodRadialAreaLight(vlight_t *light, winding_t *w, int leafnum)
  3965. {
  3966. }
  3967. /*
  3968. =============
  3969. VL_R_SubdivideRadialAreaLight
  3970. =============
  3971. */
  3972. void VL_R_SubdivideRadialAreaLight(vlight_t *light, int nodenum, winding_t *w)
  3973. {
  3974. int leafnum, res;
  3975. dnode_t *node;
  3976. dplane_t *plane;
  3977. winding_t back;
  3978. plane_t split;
  3979. while(nodenum >= 0)
  3980. {
  3981. node = &dnodes[nodenum];
  3982. plane = &dplanes[node->planeNum];
  3983. VectorCopy(plane->normal, split.normal);
  3984. split.dist = plane->dist;
  3985. res = VL_SplitWinding (w, &back, &split, 0.1);
  3986. if (res == SIDE_FRONT)
  3987. {
  3988. nodenum = node->children[0];
  3989. }
  3990. else if (res == SIDE_BACK)
  3991. {
  3992. nodenum = node->children[1];
  3993. }
  3994. else if (res == SIDE_ON)
  3995. {
  3996. memcpy(&back, w, sizeof(winding_t));
  3997. VL_R_SubdivideRadialAreaLight(light, node->children[1], &back);
  3998. nodenum = node->children[0];
  3999. }
  4000. else
  4001. {
  4002. VL_R_SubdivideRadialAreaLight(light, node->children[1], &back);
  4003. nodenum = node->children[0];
  4004. }
  4005. }
  4006. leafnum = -nodenum - 1;
  4007. if (dleafs[leafnum].cluster != -1)
  4008. {
  4009. VL_FloodRadialAreaLight(light, w, leafnum);
  4010. }
  4011. }
  4012. /*
  4013. =============
  4014. VL_R_FloodDirectedLight
  4015. =============
  4016. */
  4017. void VL_FloodDirectedLight(vlight_t *light, winding_t *w, int leafnum)
  4018. {
  4019. int i;
  4020. float dist;
  4021. lightvolume_t volume;
  4022. vec3_t dir;
  4023. if (light->atten_disttype == LDAT_NOSCALE)
  4024. {
  4025. // light travels without decrease in intensity over distance
  4026. dist = MAX_WORLD_COORD;
  4027. }
  4028. else
  4029. {
  4030. if ( light->atten_disttype == LDAT_LINEAR )
  4031. dist = light->photons * lightLinearScale;
  4032. else
  4033. dist = sqrt(light->photons);
  4034. }
  4035. memset(&volume, 0, sizeof(lightvolume_t));
  4036. for (i = 0; i < w->numpoints; i++)
  4037. {
  4038. VectorMA(w->points[i], dist, light->normal, volume.points[i]);
  4039. VectorSubtract(w->points[(i+1)%w->numpoints], w->points[i], dir);
  4040. CrossProduct(light->normal, dir, volume.planes[i].normal);
  4041. VectorNormalize(volume.planes[i].normal, volume.planes[i].normal);
  4042. volume.planes[i].dist = DotProduct(volume.planes[i].normal, w->points[i]);
  4043. }
  4044. volume.numplanes = w->numpoints;
  4045. VectorCopy(light->normal, volume.endplane.normal);
  4046. VectorInverse(volume.endplane.normal);
  4047. volume.endplane.dist = DotProduct(volume.endplane.normal, volume.points[0]);
  4048. volume.farplane = volume.endplane;
  4049. volume.surfaceNum = -1;
  4050. volume.type = VOLUME_DIRECTED;
  4051. volume.cluster = dleafs[leafnum].cluster;
  4052. VL_R_FloodLight(light, &volume, volume.cluster, 0);
  4053. if (volume.surfaceNum >= 0)
  4054. {
  4055. VL_R_CastLightAtSurface(light, &volume);
  4056. }
  4057. }
  4058. /*
  4059. =============
  4060. VL_R_SubdivideDirectedAreaLight
  4061. =============
  4062. */
  4063. void VL_R_SubdivideDirectedAreaLight(vlight_t *light, int nodenum, winding_t *w)
  4064. {
  4065. int leafnum, res;
  4066. dnode_t *node;
  4067. dplane_t *plane;
  4068. winding_t back;
  4069. plane_t split;
  4070. while(nodenum >= 0)
  4071. {
  4072. node = &dnodes[nodenum];
  4073. plane = &dplanes[node->planeNum];
  4074. VectorCopy(plane->normal, split.normal);
  4075. split.dist = plane->dist;
  4076. res = VL_SplitWinding (w, &back, &split, 0.1);
  4077. if (res == SIDE_FRONT)
  4078. {
  4079. nodenum = node->children[0];
  4080. }
  4081. else if (res == SIDE_BACK)
  4082. {
  4083. nodenum = node->children[1];
  4084. }
  4085. else if (res == SIDE_ON)
  4086. {
  4087. memcpy(&back, w, sizeof(winding_t));
  4088. VL_R_SubdivideDirectedAreaLight(light, node->children[1], &back);
  4089. nodenum = node->children[0];
  4090. }
  4091. else
  4092. {
  4093. VL_R_SubdivideDirectedAreaLight(light, node->children[1], &back);
  4094. nodenum = node->children[0];
  4095. }
  4096. }
  4097. leafnum = -nodenum - 1;
  4098. if (dleafs[leafnum].cluster != -1)
  4099. {
  4100. VL_FloodDirectedLight(light, w, leafnum);
  4101. }
  4102. }
  4103. /*
  4104. =============
  4105. VL_FloodLight
  4106. =============
  4107. */
  4108. void VL_FloodLight(vlight_t *light)
  4109. {
  4110. lightvolume_t volume;
  4111. dleaf_t *leaf;
  4112. int leafnum, i, j, k, dir[2][4] = {{1, 1, -1, -1}, {1, -1, -1, 1}};
  4113. float a, step, dist, radius, windingdist;
  4114. vec3_t vec, r, p, temp;
  4115. winding_t winding;
  4116. switch(light->type)
  4117. {
  4118. case LIGHT_POINTRADIAL:
  4119. {
  4120. // source is a point
  4121. // light radiates in all directions
  4122. // creates sharp shadows
  4123. //
  4124. // create 6 volumes shining in the axis directions
  4125. // what about: 4 tetrahedrons instead?
  4126. //
  4127. if ( light->atten_disttype == LDAT_LINEAR )
  4128. dist = light->photons * lightLinearScale;
  4129. else
  4130. dist = sqrt(light->photons);
  4131. //always put the winding at a large distance to avoid epsilon issues
  4132. windingdist = MAX_WORLD_COORD;
  4133. if (dist > windingdist)
  4134. windingdist = dist;
  4135. //
  4136. leafnum = VL_LightLeafnum(light->origin);
  4137. leaf = &dleafs[leafnum];
  4138. if (leaf->cluster == -1)
  4139. {
  4140. light->insolid = qtrue;
  4141. break;
  4142. }
  4143. // for each axis
  4144. for (i = 0; i < 3; i++)
  4145. {
  4146. // for both directions on the axis
  4147. for (j = -1; j <= 1; j += 2)
  4148. {
  4149. memset(&volume, 0, sizeof(lightvolume_t));
  4150. volume.numplanes = 0;
  4151. for (k = 0; k < 4; k ++)
  4152. {
  4153. volume.points[volume.numplanes][i] = light->origin[i] + j * windingdist;
  4154. volume.points[volume.numplanes][(i+1)%3] = light->origin[(i+1)%3] + dir[0][k] * windingdist;
  4155. volume.points[volume.numplanes][(i+2)%3] = light->origin[(i+2)%3] + dir[1][k] * windingdist;
  4156. volume.numplanes++;
  4157. }
  4158. if (j >= 0)
  4159. {
  4160. VectorCopy(volume.points[0], temp);
  4161. VectorCopy(volume.points[2], volume.points[0]);
  4162. VectorCopy(temp, volume.points[2]);
  4163. }
  4164. for (k = 0; k < volume.numplanes; k++)
  4165. {
  4166. VL_PlaneFromPoints(&volume.planes[k], light->origin, volume.points[(k+1)%volume.numplanes], volume.points[k]);
  4167. }
  4168. VectorCopy(light->origin, temp);
  4169. temp[i] += (float) j * dist;
  4170. VectorClear(volume.endplane.normal);
  4171. volume.endplane.normal[i] = -j;
  4172. volume.endplane.dist = DotProduct(volume.endplane.normal, temp); //DotProduct(volume.endplane.normal, volume.points[0]);
  4173. volume.farplane = volume.endplane;
  4174. volume.cluster = leaf->cluster;
  4175. volume.surfaceNum = -1;
  4176. volume.type = VOLUME_NORMAL;
  4177. //
  4178. memset(volume.facetTested, 0, sizeof(volume.facetTested));
  4179. memset(volume.clusterTested, 0, sizeof(volume.clusterTested));
  4180. VL_R_FloodLight(light, &volume, leaf->cluster, 0);
  4181. if (volume.surfaceNum >= 0)
  4182. {
  4183. VL_R_CastLightAtSurface(light, &volume);
  4184. }
  4185. }
  4186. }
  4187. break;
  4188. }
  4189. case LIGHT_POINTSPOT:
  4190. {
  4191. // source is a point
  4192. // light is targetted
  4193. // creates sharp shadows
  4194. //
  4195. // what about using brushes to shape spot lights? that'd be pretty cool
  4196. //
  4197. if ( light->atten_disttype == LDAT_LINEAR )
  4198. dist = light->photons * lightLinearScale;
  4199. else
  4200. dist = sqrt(light->photons);
  4201. dist *= 2;
  4202. //
  4203. windingdist = 4096;
  4204. if (dist > windingdist)
  4205. windingdist = dist;
  4206. //take 8 times the cone radius because the spotlight also lights outside the cone
  4207. radius = 8 * windingdist * light->radiusByDist;
  4208. //
  4209. memset(&volume, 0, sizeof(lightvolume_t));
  4210. leafnum = VL_LightLeafnum(light->origin);
  4211. leaf = &dleafs[leafnum];
  4212. if (leaf->cluster == -1)
  4213. {
  4214. light->insolid = qtrue;
  4215. break;
  4216. }
  4217. //
  4218. VectorClear(vec);
  4219. for (i = 0; i < 3; i++)
  4220. {
  4221. if (light->normal[i] > -0.9 && light->normal[i] < 0.9)
  4222. {
  4223. vec[i] = 1;
  4224. break;
  4225. }
  4226. }
  4227. CrossProduct(light->normal, vec, r);
  4228. VectorScale(r, radius, p);
  4229. volume.numplanes = 0;
  4230. step = 45;
  4231. for (a = step / 2; a < 360 + step / 2; a += step)
  4232. {
  4233. RotatePointAroundVector(volume.points[volume.numplanes], light->normal, p, a);
  4234. VectorAdd(light->origin, volume.points[volume.numplanes], volume.points[volume.numplanes]);
  4235. VectorMA(volume.points[volume.numplanes], windingdist, light->normal, volume.points[volume.numplanes]);
  4236. volume.numplanes++;
  4237. }
  4238. for (i = 0; i < volume.numplanes; i++)
  4239. {
  4240. VL_PlaneFromPoints(&volume.planes[i], light->origin, volume.points[(i+1)%volume.numplanes], volume.points[i]);
  4241. }
  4242. VectorMA(light->origin, dist, light->normal, temp);
  4243. VectorCopy(light->normal, volume.endplane.normal);
  4244. VectorInverse(volume.endplane.normal);
  4245. volume.endplane.dist = DotProduct(volume.endplane.normal, temp);//DotProduct(volume.endplane.normal, volume.points[0]);
  4246. volume.farplane = volume.endplane;
  4247. volume.cluster = leaf->cluster;
  4248. volume.surfaceNum = -1;
  4249. volume.type = VOLUME_NORMAL;
  4250. //
  4251. memset(volume.facetTested, 0, sizeof(volume.facetTested));
  4252. memset(volume.clusterTested, 0, sizeof(volume.clusterTested));
  4253. VL_R_FloodLight(light, &volume, leaf->cluster, 0);
  4254. if (volume.surfaceNum >= 0)
  4255. {
  4256. VL_R_CastLightAtSurface(light, &volume);
  4257. }
  4258. break;
  4259. }
  4260. case LIGHT_POINTFAKESURFACE:
  4261. {
  4262. float value;
  4263. int n, axis;
  4264. vec3_t v, vecs[2];
  4265. if ( light->atten_disttype == LDAT_LINEAR )
  4266. dist = light->photons * lightLinearScale;
  4267. else
  4268. dist = sqrt(light->photons);
  4269. //always put the winding at a large distance to avoid epsilon issues
  4270. windingdist = 4096;
  4271. if (dist > windingdist)
  4272. windingdist = dist;
  4273. //
  4274. VectorMA(light->origin, 0.1, light->normal, light->origin);
  4275. //
  4276. leafnum = VL_LightLeafnum(light->origin);
  4277. leaf = &dleafs[leafnum];
  4278. if (leaf->cluster == -1)
  4279. {
  4280. light->insolid = qtrue;
  4281. break;
  4282. }
  4283. value = 0;
  4284. for (i = 0; i < 3; i++)
  4285. {
  4286. if (fabs(light->normal[i]) > value)
  4287. {
  4288. value = fabs(light->normal[i]);
  4289. axis = i;
  4290. }
  4291. }
  4292. for (i = 0; i < 2; i++)
  4293. {
  4294. VectorClear(v);
  4295. v[(axis + 1 + i) % 3] = 1;
  4296. CrossProduct(light->normal, v, vecs[i]);
  4297. }
  4298. //cast 4 volumes at the front of the surface
  4299. for (i = -1; i <= 1; i += 2)
  4300. {
  4301. for (j = -1; j <= 1; j += 2)
  4302. {
  4303. for (n = 0; n < 2; n++)
  4304. {
  4305. memset(&volume, 0, sizeof(lightvolume_t));
  4306. volume.numplanes = 3;
  4307. VectorMA(light->origin, i * windingdist, vecs[0], volume.points[(i == j) == n]);
  4308. VectorMA(light->origin, j * windingdist, vecs[1], volume.points[(i != j) == n]);
  4309. VectorMA(light->origin, windingdist, light->normal, volume.points[2]);
  4310. for (k = 0; k < volume.numplanes; k++)
  4311. {
  4312. VL_PlaneFromPoints(&volume.planes[k], light->origin, volume.points[(k+1)%volume.numplanes], volume.points[k]);
  4313. }
  4314. VL_PlaneFromPoints(&volume.endplane, volume.points[0], volume.points[1], volume.points[2]);
  4315. VectorMA(light->origin, dist, light->normal, temp);
  4316. volume.endplane.dist = DotProduct(volume.endplane.normal, temp);
  4317. if (DotProduct(light->origin, volume.endplane.normal) - volume.endplane.dist > 0)
  4318. break;
  4319. }
  4320. volume.farplane = volume.endplane;
  4321. volume.cluster = leaf->cluster;
  4322. volume.surfaceNum = -1;
  4323. volume.type = VOLUME_NORMAL;
  4324. //
  4325. memset(volume.facetTested, 0, sizeof(volume.facetTested));
  4326. memset(volume.clusterTested, 0, sizeof(volume.clusterTested));
  4327. VL_R_FloodLight(light, &volume, leaf->cluster, 0);
  4328. if (volume.surfaceNum >= 0)
  4329. {
  4330. VL_R_CastLightAtSurface(light, &volume);
  4331. }
  4332. }
  4333. }
  4334. break;
  4335. }
  4336. case LIGHT_SURFACEDIRECTED:
  4337. {
  4338. // source is an area defined by a winding
  4339. // the light is unidirectional
  4340. // creates sharp shadows
  4341. // for instance sun light or laser light
  4342. //
  4343. memcpy(&winding, &light->w, sizeof(winding_t));
  4344. VL_R_SubdivideDirectedAreaLight(light, 0, &winding);
  4345. break;
  4346. }
  4347. case LIGHT_SURFACERADIAL:
  4348. {
  4349. // source is an area defined by a winding
  4350. // the light radiates in all directions at the front of the winding plane
  4351. //
  4352. memcpy(&winding, &light->w, sizeof(winding_t));
  4353. VL_R_SubdivideRadialAreaLight(light, 0, &winding);
  4354. break;
  4355. }
  4356. case LIGHT_SURFACESPOT:
  4357. {
  4358. // source is an area defined by a winding
  4359. // light is targetted but not unidirectional
  4360. //
  4361. memcpy(&winding, &light->w, sizeof(winding_t));
  4362. VL_R_SubdivideAreaSpotLight(light, 0, &winding);
  4363. break;
  4364. }
  4365. }
  4366. }
  4367. /*
  4368. =============
  4369. VL_FloodLightThread
  4370. =============
  4371. */
  4372. void VL_FloodLightThread(int num)
  4373. {
  4374. VL_FloodLight(vlights[num]);
  4375. }
  4376. /*
  4377. =============
  4378. VL_TestLightLeafs
  4379. =============
  4380. */
  4381. void VL_TestLightLeafs(void)
  4382. {
  4383. int leafnum, i;
  4384. vlight_t *light;
  4385. dleaf_t *leaf;
  4386. for (i = 0; i < numvlights; i++)
  4387. {
  4388. light = vlights[i];
  4389. if (light->type != LIGHT_POINTRADIAL &&
  4390. light->type != LIGHT_POINTSPOT)
  4391. continue;
  4392. leafnum = VL_LightLeafnum(light->origin);
  4393. leaf = &dleafs[leafnum];
  4394. if (leaf->cluster == -1)
  4395. if (light->type == LIGHT_POINTRADIAL)
  4396. qprintf("light in solid at %1.1f %1.1f %1.1f\n", light->origin[0], light->origin[1], light->origin[2]);
  4397. else if (light->type == LIGHT_POINTSPOT)
  4398. qprintf("spot light in solid at %1.1f %1.1f %1.1f\n", light->origin[0], light->origin[1], light->origin[2]);
  4399. }
  4400. }
  4401. /*
  4402. =============
  4403. VL_DoForcedTraceLight
  4404. =============
  4405. */
  4406. // from light.c
  4407. void TraceLtm( int num );
  4408. void VL_DoForcedTraceLight(int num)
  4409. {
  4410. dsurface_t *ds;
  4411. shaderInfo_t *si;
  4412. ds = &drawSurfaces[num];
  4413. if ( ds->surfaceType == MST_TRIANGLE_SOUP )
  4414. return;
  4415. if ( ds->lightmapNum < 0 )
  4416. return;
  4417. // always light entity surfaces with the old light algorithm
  4418. if ( !entitySurface[num] )
  4419. {
  4420. si = ShaderInfoForShader( dshaders[ ds->shaderNum].shader );
  4421. if (defaulttracelight)
  4422. {
  4423. if (si->forceVLight)
  4424. return;
  4425. }
  4426. else
  4427. {
  4428. if (!si->forceTraceLight)
  4429. return;
  4430. }
  4431. }
  4432. TraceLtm(num);
  4433. }
  4434. /*
  4435. =============
  4436. VL_DoForcedTraceLightSurfaces
  4437. =============
  4438. */
  4439. void VL_DoForcedTraceLightSurfaces(void)
  4440. {
  4441. _printf( "forced trace light\n" );
  4442. RunThreadsOnIndividual( numDrawSurfaces, qtrue, VL_DoForcedTraceLight );
  4443. }
  4444. float *oldLightFloats;
  4445. /*
  4446. =============
  4447. VL_SurfaceRadiosity
  4448. =============
  4449. */
  4450. void VL_SurfaceRadiosity( int num ) {
  4451. dsurface_t *ds;
  4452. mesh_t *mesh;
  4453. shaderInfo_t *si;
  4454. lsurfaceTest_t *test;
  4455. int x, y, k;
  4456. vec3_t base, normal;
  4457. float *color, area;
  4458. vlight_t vlight;
  4459. ds = &drawSurfaces[num];
  4460. if ( ds->lightmapNum < 0 ) {
  4461. return; // doesn't have a lightmap
  4462. }
  4463. // vertex-lit triangle model
  4464. if ( ds->surfaceType == MST_TRIANGLE_SOUP ) {
  4465. return;
  4466. }
  4467. si = ShaderInfoForShader( dshaders[ ds->shaderNum].shader );
  4468. test = lsurfaceTest[ num ];
  4469. if (!test) {
  4470. return;
  4471. }
  4472. for (x = 0; x < ds->lightmapWidth; x++) {
  4473. for (y = 0; y < ds->lightmapHeight; y++) {
  4474. //
  4475. k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
  4476. * LIGHTMAP_WIDTH + ds->lightmapX + x;
  4477. area = lightmappixelarea[k];
  4478. if (area <= 0)
  4479. continue;
  4480. //
  4481. if (ds->surfaceType == MST_PATCH)
  4482. {
  4483. mesh = test->detailMesh;
  4484. VectorCopy( mesh->verts[y*mesh->width+x].xyz, base);
  4485. VectorCopy( mesh->verts[y*mesh->width+x].normal, normal);
  4486. }
  4487. else
  4488. {
  4489. VectorMA(ds->lightmapOrigin, (float) x, ds->lightmapVecs[0], base);
  4490. VectorMA(base, (float) y, ds->lightmapVecs[1], base);
  4491. VectorCopy(test->facets[0].plane.normal, normal);
  4492. }
  4493. // create ligth from base
  4494. memset(&vlight, 0, sizeof(vlight_t));
  4495. color = &oldLightFloats[k*3];
  4496. // a few units away from the surface
  4497. VectorMA(base, 5, normal, vlight.origin);
  4498. ColorNormalize(color, vlight.color);
  4499. // ok this is crap
  4500. vlight.photons = VectorLength(color) * 0.05 * lightPointScale / (area * radiosity_scale);
  4501. // what about using a front facing light only ?
  4502. vlight.type = LIGHT_POINTRADIAL;
  4503. // flood the light from this lightmap pixel
  4504. VL_FloodLight(&vlight);
  4505. // only one thread at a time may write to the lightmap of this surface
  4506. MutexLock(test->mutex);
  4507. // don't light the lightmap pixel itself
  4508. lightFloats[k*3] = oldLightFloats[k*3];
  4509. lightFloats[k*3+1] = oldLightFloats[k*3+1];
  4510. lightFloats[k*3+2] = oldLightFloats[k*3+2];
  4511. //
  4512. MutexUnlock(test->mutex);
  4513. }
  4514. }
  4515. }
  4516. /*
  4517. =============
  4518. VL_Radiosity
  4519. this aint working real well but it's fun to play with.
  4520. =============
  4521. */
  4522. void VL_Radiosity(void) {
  4523. oldLightFloats = lightFloats;
  4524. lightFloats = (float *) malloc(numLightBytes * sizeof(float));
  4525. memcpy(lightFloats, oldLightFloats, numLightBytes * sizeof(float));
  4526. _printf("%7i surfaces\n", numDrawSurfaces);
  4527. RunThreadsOnIndividual( numDrawSurfaces, qtrue, VL_SurfaceRadiosity );
  4528. free(oldLightFloats);
  4529. }
  4530. /*
  4531. =============
  4532. VL_LightWorld
  4533. =============
  4534. */
  4535. void VL_LightWorld(void)
  4536. {
  4537. int i, numcastedvolumes, numvlightsinsolid;
  4538. float f;
  4539. // find the optional world ambient
  4540. GetVectorForKey( &entities[0], "_color", lightAmbientColor );
  4541. f = FloatForKey( &entities[0], "ambient" );
  4542. VectorScale( lightAmbientColor, f, lightAmbientColor );
  4543. /*
  4544. _printf("\r%6d lights out of %d", 0, numvlights);
  4545. for (i = 0; i < numvlights; i++)
  4546. {
  4547. _printf("\r%6d", i);
  4548. VL_FloodLight(vlights[i]);
  4549. }
  4550. _printf("\r%6d lights out of %d\n", i, numvlights);
  4551. */
  4552. _printf("%7i lights\n", numvlights);
  4553. RunThreadsOnIndividual( numvlights, qtrue, VL_FloodLightThread );
  4554. numcastedvolumes = 0;
  4555. for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
  4556. if (lsurfaceTest[i])
  4557. numcastedvolumes += lsurfaceTest[i]->numvolumes;
  4558. }
  4559. _printf("%7i light volumes casted\n", numcastedvolumes);
  4560. numvlightsinsolid = 0;
  4561. for (i = 0; i < numvlights; i++)
  4562. {
  4563. if (vlights[i]->insolid)
  4564. numvlightsinsolid++;
  4565. }
  4566. _printf("%7i lights in solid\n", numvlightsinsolid);
  4567. //
  4568. radiosity_scale = 1;
  4569. for (i = 0; i < radiosity; i++) {
  4570. VL_Radiosity();
  4571. radiosity_scale <<= 1;
  4572. }
  4573. //
  4574. VL_StoreLightmap();
  4575. // redo surfaces with the old light algorithm when needed
  4576. VL_DoForcedTraceLightSurfaces();
  4577. }
  4578. /*
  4579. =============
  4580. VL_CreateEntityLights
  4581. =============
  4582. */
  4583. entity_t *FindTargetEntity( const char *target );
  4584. void VL_CreateEntityLights (void)
  4585. {
  4586. int i, c_entityLights;
  4587. vlight_t *dl;
  4588. entity_t *e, *e2;
  4589. const char *name;
  4590. const char *target;
  4591. vec3_t dest;
  4592. const char *_color;
  4593. float intensity;
  4594. int spawnflags;
  4595. //
  4596. c_entityLights = 0;
  4597. _printf("Creating entity lights...\n");
  4598. //
  4599. for ( i = 0 ; i < num_entities ; i++ ) {
  4600. e = &entities[i];
  4601. name = ValueForKey (e, "classname");
  4602. if (strncmp (name, "light", 5))
  4603. continue;
  4604. dl = malloc(sizeof(*dl));
  4605. memset (dl, 0, sizeof(*dl));
  4606. spawnflags = FloatForKey (e, "spawnflags");
  4607. if ( spawnflags & 1 ) {
  4608. dl->atten_disttype = LDAT_LINEAR;
  4609. }
  4610. if ( spawnflags & 2 ) {
  4611. dl->atten_disttype = LDAT_NOSCALE;
  4612. }
  4613. if ( spawnflags & 4 ) {
  4614. dl->atten_angletype = LAAT_QUADRATIC;
  4615. }
  4616. if ( spawnflags & 8 ) {
  4617. dl->atten_angletype = LAAT_DOUBLEQUADRATIC;
  4618. }
  4619. dl->atten_distscale = FloatForKey(e, "atten_distscale");
  4620. dl->atten_anglescale = FloatForKey(e, "atten_anglescale");
  4621. GetVectorForKey (e, "origin", dl->origin);
  4622. dl->style = FloatForKey (e, "_style");
  4623. if (!dl->style)
  4624. dl->style = FloatForKey (e, "style");
  4625. if (dl->style < 0)
  4626. dl->style = 0;
  4627. intensity = FloatForKey (e, "light");
  4628. if (!intensity)
  4629. intensity = FloatForKey (e, "_light");
  4630. if (!intensity)
  4631. intensity = 300;
  4632. _color = ValueForKey (e, "_color");
  4633. if (_color && _color[0])
  4634. {
  4635. sscanf (_color, "%f %f %f", &dl->color[0],&dl->color[1],&dl->color[2]);
  4636. ColorNormalize (dl->color, dl->color);
  4637. }
  4638. else
  4639. dl->color[0] = dl->color[1] = dl->color[2] = 1.0;
  4640. intensity = intensity * lightPointScale;
  4641. dl->photons = intensity;
  4642. dl->type = LIGHT_POINTRADIAL;
  4643. // lights with a target will be spotlights
  4644. target = ValueForKey (e, "target");
  4645. if ( target[0] ) {
  4646. float radius;
  4647. float dist;
  4648. e2 = FindTargetEntity (target);
  4649. if (!e2) {
  4650. _printf ("WARNING: light at (%i %i %i) has missing target\n",
  4651. (int)dl->origin[0], (int)dl->origin[1], (int)dl->origin[2]);
  4652. } else {
  4653. GetVectorForKey (e2, "origin", dest);
  4654. VectorSubtract (dest, dl->origin, dl->normal);
  4655. dist = VectorNormalize (dl->normal, dl->normal);
  4656. radius = FloatForKey (e, "radius");
  4657. if ( !radius ) {
  4658. radius = 64;
  4659. }
  4660. if ( !dist ) {
  4661. dist = 64;
  4662. }
  4663. dl->radiusByDist = (radius + 16) / dist;
  4664. dl->type = LIGHT_POINTSPOT;
  4665. }
  4666. }
  4667. vlights[numvlights++] = dl;
  4668. c_entityLights++;
  4669. }
  4670. _printf("%7i entity lights\n", c_entityLights);
  4671. }
  4672. /*
  4673. ==================
  4674. VL_SubdivideAreaLight
  4675. ==================
  4676. */
  4677. void VL_SubdivideAreaLight( shaderInfo_t *ls, winding_t *w, vec3_t normal,
  4678. float areaSubdivide, qboolean backsplash ) {
  4679. float area, value, intensity;
  4680. vlight_t *dl, *dl2;
  4681. vec3_t mins, maxs;
  4682. int axis;
  4683. winding_t *front, *back;
  4684. vec3_t planeNormal;
  4685. float planeDist;
  4686. if ( !w ) {
  4687. return;
  4688. }
  4689. WindingBounds( w, mins, maxs );
  4690. // check for subdivision
  4691. for ( axis = 0 ; axis < 3 ; axis++ ) {
  4692. if ( maxs[axis] - mins[axis] > areaSubdivide ) {
  4693. VectorClear( planeNormal );
  4694. planeNormal[axis] = 1;
  4695. planeDist = ( maxs[axis] + mins[axis] ) * 0.5;
  4696. ClipWindingEpsilon ( w, planeNormal, planeDist, ON_EPSILON, &front, &back );
  4697. VL_SubdivideAreaLight( ls, front, normal, areaSubdivide, qfalse );
  4698. VL_SubdivideAreaLight( ls, back, normal, areaSubdivide, qfalse );
  4699. FreeWinding( w );
  4700. return;
  4701. }
  4702. }
  4703. // create a light from this
  4704. area = WindingArea (w);
  4705. if ( area <= 0 || area > 20000000 ) {
  4706. return;
  4707. }
  4708. dl = malloc(sizeof(*dl));
  4709. memset (dl, 0, sizeof(*dl));
  4710. dl->type = LIGHT_POINTFAKESURFACE;
  4711. WindingCenter( w, dl->origin );
  4712. memcpy(dl->w.points, w->points, sizeof(vec3_t) * w->numpoints);
  4713. dl->w.numpoints = w->numpoints;
  4714. VectorCopy ( normal, dl->normal);
  4715. VectorCopy ( normal, dl->plane);
  4716. dl->plane[3] = DotProduct( dl->origin, normal );
  4717. value = ls->value;
  4718. intensity = value * area * lightAreaScale;
  4719. VectorAdd( dl->origin, dl->normal, dl->origin );
  4720. VectorCopy( ls->color, dl->color );
  4721. dl->photons = intensity;
  4722. // emitColor is irrespective of the area
  4723. VectorScale( ls->color, value*lightFormFactorValueScale*lightAreaScale, dl->emitColor );
  4724. //
  4725. VectorCopy(dl->emitColor, dl->color);
  4726. dl->si = ls;
  4727. if ( ls->contents & CONTENTS_FOG ) {
  4728. dl->twosided = qtrue;
  4729. }
  4730. vlights[numvlights++] = dl;
  4731. // optionally create a point backsplash light
  4732. if ( backsplash && ls->backsplashFraction > 0 ) {
  4733. dl2 = malloc(sizeof(*dl));
  4734. memset (dl2, 0, sizeof(*dl2));
  4735. dl2->type = LIGHT_POINTRADIAL;
  4736. VectorMA( dl->origin, ls->backsplashDistance, normal, dl2->origin );
  4737. VectorCopy( ls->color, dl2->color );
  4738. dl2->photons = dl->photons * ls->backsplashFraction;
  4739. dl2->si = ls;
  4740. vlights[numvlights++] = dl2;
  4741. }
  4742. }
  4743. /*
  4744. ==================
  4745. VL_CreateFakeSurfaceLights
  4746. ==================
  4747. */
  4748. void VL_CreateFakeSurfaceLights( void ) {
  4749. int i, j, side;
  4750. dsurface_t *ds;
  4751. shaderInfo_t *ls;
  4752. winding_t *w;
  4753. lFacet_t *f;
  4754. vlight_t *dl;
  4755. vec3_t origin;
  4756. drawVert_t *dv;
  4757. int c_surfaceLights;
  4758. float lightSubdivide;
  4759. vec3_t normal;
  4760. c_surfaceLights = 0;
  4761. _printf ("Creating surface lights...\n");
  4762. for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
  4763. // see if this surface is light emiting
  4764. ds = &drawSurfaces[i];
  4765. ls = ShaderInfoForShader( dshaders[ ds->shaderNum].shader );
  4766. if ( ls->value == 0 ) {
  4767. continue;
  4768. }
  4769. // determine how much we need to chop up the surface
  4770. if ( ls->lightSubdivide ) {
  4771. lightSubdivide = ls->lightSubdivide;
  4772. } else {
  4773. lightSubdivide = lightDefaultSubdivide;
  4774. }
  4775. c_surfaceLights++;
  4776. // an autosprite shader will become
  4777. // a point light instead of an area light
  4778. if ( ls->autosprite ) {
  4779. // autosprite geometry should only have four vertexes
  4780. if ( lsurfaceTest[i] ) {
  4781. // curve or misc_model
  4782. f = lsurfaceTest[i]->facets;
  4783. if ( lsurfaceTest[i]->numFacets != 1 || f->numpoints != 4 ) {
  4784. _printf( "WARNING: surface at (%i %i %i) has autosprite shader but isn't a quad\n",
  4785. (int)f->points[0], (int)f->points[1], (int)f->points[2] );
  4786. }
  4787. VectorAdd( f->points[0], f->points[1], origin );
  4788. VectorAdd( f->points[2], origin, origin );
  4789. VectorAdd( f->points[3], origin, origin );
  4790. VectorScale( origin, 0.25, origin );
  4791. } else {
  4792. // normal polygon
  4793. dv = &drawVerts[ ds->firstVert ];
  4794. if ( ds->numVerts != 4 ) {
  4795. _printf( "WARNING: surface at (%i %i %i) has autosprite shader but %i verts\n",
  4796. (int)dv->xyz[0], (int)dv->xyz[1], (int)dv->xyz[2] );
  4797. continue;
  4798. }
  4799. VectorAdd( dv[0].xyz, dv[1].xyz, origin );
  4800. VectorAdd( dv[2].xyz, origin, origin );
  4801. VectorAdd( dv[3].xyz, origin, origin );
  4802. VectorScale( origin, 0.25, origin );
  4803. }
  4804. dl = malloc(sizeof(*dl));
  4805. memset (dl, 0, sizeof(*dl));
  4806. VectorCopy( origin, dl->origin );
  4807. VectorCopy( ls->color, dl->color );
  4808. dl->photons = ls->value * lightPointScale;
  4809. dl->type = LIGHT_POINTRADIAL;
  4810. vlights[numvlights++] = dl;
  4811. continue;
  4812. }
  4813. // possibly create for both sides of the polygon
  4814. for ( side = 0 ; side <= ls->twoSided ; side++ ) {
  4815. // create area lights
  4816. if ( lsurfaceTest[i] ) {
  4817. // curve or misc_model
  4818. for ( j = 0 ; j < lsurfaceTest[i]->numFacets ; j++ ) {
  4819. f = lsurfaceTest[i]->facets + j;
  4820. w = AllocWinding( f->numpoints );
  4821. w->numpoints = f->numpoints;
  4822. memcpy( w->points, f->points, f->numpoints * 12 );
  4823. VectorCopy( f->plane.normal, normal );
  4824. if ( side ) {
  4825. winding_t *t;
  4826. t = w;
  4827. w = ReverseWinding( t );
  4828. FreeWinding( t );
  4829. VectorSubtract( vec3_origin, normal, normal );
  4830. }
  4831. VL_SubdivideAreaLight( ls, w, normal, lightSubdivide, qtrue );
  4832. }
  4833. } else {
  4834. // normal polygon
  4835. w = AllocWinding( ds->numVerts );
  4836. w->numpoints = ds->numVerts;
  4837. for ( j = 0 ; j < ds->numVerts ; j++ ) {
  4838. VectorCopy( drawVerts[ds->firstVert+j].xyz, w->points[j] );
  4839. }
  4840. VectorCopy( ds->lightmapVecs[2], normal );
  4841. if ( side ) {
  4842. winding_t *t;
  4843. t = w;
  4844. w = ReverseWinding( t );
  4845. FreeWinding( t );
  4846. VectorSubtract( vec3_origin, normal, normal );
  4847. }
  4848. VL_SubdivideAreaLight( ls, w, normal, lightSubdivide, qtrue );
  4849. }
  4850. }
  4851. }
  4852. _printf( "%7i light emitting surfaces\n", c_surfaceLights );
  4853. }
  4854. /*
  4855. ==================
  4856. VL_WindingForBrushSide
  4857. ==================
  4858. */
  4859. winding_t *VL_WindingForBrushSide(dbrush_t *brush, int side, winding_t *w)
  4860. {
  4861. int i, res;
  4862. winding_t *tmpw;
  4863. plane_t plane;
  4864. VectorCopy(dplanes[ dbrushsides[ brush->firstSide + side ].planeNum ].normal, plane.normal);
  4865. VectorInverse(plane.normal);
  4866. plane.dist = -dplanes[ dbrushsides[ brush->firstSide + side ].planeNum ].dist;
  4867. tmpw = BaseWindingForPlane( plane.normal, plane.dist );
  4868. memcpy(w->points, tmpw->points, sizeof(vec3_t) * tmpw->numpoints);
  4869. w->numpoints = tmpw->numpoints;
  4870. for (i = 0; i < brush->numSides; i++)
  4871. {
  4872. if (i == side)
  4873. continue;
  4874. VectorCopy(dplanes[ dbrushsides[ brush->firstSide + i ].planeNum ].normal, plane.normal);
  4875. VectorInverse(plane.normal);
  4876. plane.dist = -dplanes[ dbrushsides[ brush->firstSide + i ].planeNum ].dist;
  4877. res = VL_ChopWinding(w, &plane, 0.1);
  4878. if (res == SIDE_BACK)
  4879. return NULL;
  4880. }
  4881. return w;
  4882. }
  4883. /*
  4884. ==================
  4885. VL_CreateSkyLights
  4886. ==================
  4887. */
  4888. void VL_CreateSkyLights(void)
  4889. {
  4890. int i, j, c_skyLights;
  4891. dbrush_t *b;
  4892. shaderInfo_t *si;
  4893. dbrushside_t *s;
  4894. vlight_t *dl;
  4895. vec3_t sunColor, sunDir = { 0.45, 0.3, 0.9 };
  4896. float d;
  4897. VectorNormalize(sunDir, sunDir);
  4898. VectorInverse(sunDir);
  4899. c_skyLights = 0;
  4900. _printf("Creating sky lights...\n");
  4901. // find the sky shader
  4902. for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
  4903. si = ShaderInfoForShader( dshaders[ drawSurfaces[i].shaderNum ].shader );
  4904. if ( si->surfaceFlags & SURF_SKY ) {
  4905. VectorCopy( si->sunLight, sunColor );
  4906. VectorCopy( si->sunDirection, sunDir );
  4907. VectorInverse(sunDir);
  4908. break;
  4909. }
  4910. }
  4911. // find the brushes
  4912. for ( i = 0 ; i < numbrushes ; i++ ) {
  4913. b = &dbrushes[i];
  4914. for ( j = 0 ; j < b->numSides ; j++ ) {
  4915. s = &dbrushsides[ b->firstSide + j ];
  4916. if ( dshaders[ s->shaderNum ].surfaceFlags & SURF_SKY ) {
  4917. //if this surface doesn't face in the same direction as the sun
  4918. d = DotProduct(dplanes[ s->planeNum ].normal, sunDir);
  4919. if (d <= 0)
  4920. continue;
  4921. //
  4922. dl = malloc(sizeof(*dl));
  4923. memset (dl, 0, sizeof(*dl));
  4924. VectorCopy(sunColor, dl->color);
  4925. VectorCopy(sunDir, dl->normal);
  4926. VectorCopy(dplanes[ s->planeNum ].normal, dl->plane);
  4927. dl->plane[3] = dplanes[ s->planeNum ].dist;
  4928. dl->type = LIGHT_SURFACEDIRECTED;
  4929. dl->atten_disttype = LDAT_NOSCALE;
  4930. VL_WindingForBrushSide(b, j, &dl->w);
  4931. // DebugNet_DrawWinding(&dl->w, 2);
  4932. //
  4933. vlights[numvlights++] = dl;
  4934. c_skyLights++;
  4935. }
  4936. }
  4937. }
  4938. _printf("%7i light emitting sky surfaces\n", c_skyLights);
  4939. }
  4940. /*
  4941. ==================
  4942. VL_SetPortalSphere
  4943. ==================
  4944. */
  4945. void VL_SetPortalSphere (lportal_t *p)
  4946. {
  4947. int i;
  4948. vec3_t total, dist;
  4949. winding_t *w;
  4950. float r, bestr;
  4951. w = p->winding;
  4952. VectorCopy (vec3_origin, total);
  4953. for (i=0 ; i<w->numpoints ; i++)
  4954. {
  4955. VectorAdd (total, w->points[i], total);
  4956. }
  4957. for (i=0 ; i<3 ; i++)
  4958. total[i] /= w->numpoints;
  4959. bestr = 0;
  4960. for (i=0 ; i<w->numpoints ; i++)
  4961. {
  4962. VectorSubtract (w->points[i], total, dist);
  4963. r = VectorLength (dist);
  4964. if (r > bestr)
  4965. bestr = r;
  4966. }
  4967. VectorCopy (total, p->origin);
  4968. p->radius = bestr;
  4969. }
  4970. /*
  4971. ==================
  4972. VL_PlaneFromWinding
  4973. ==================
  4974. */
  4975. void VL_PlaneFromWinding (winding_t *w, plane_t *plane)
  4976. {
  4977. vec3_t v1, v2;
  4978. //calc plane
  4979. VectorSubtract (w->points[2], w->points[1], v1);
  4980. VectorSubtract (w->points[0], w->points[1], v2);
  4981. CrossProduct (v2, v1, plane->normal);
  4982. VectorNormalize (plane->normal, plane->normal);
  4983. plane->dist = DotProduct (w->points[0], plane->normal);
  4984. }
  4985. /*
  4986. ==================
  4987. VL_AllocWinding
  4988. ==================
  4989. */
  4990. winding_t *VL_AllocWinding (int points)
  4991. {
  4992. winding_t *w;
  4993. int size;
  4994. if (points > MAX_POINTS_ON_WINDING)
  4995. Error ("NewWinding: %i points", points);
  4996. size = (int)((winding_t *)0)->points[points];
  4997. w = malloc (size);
  4998. memset (w, 0, size);
  4999. return w;
  5000. }
  5001. /*
  5002. ============
  5003. VL_LoadPortals
  5004. ============
  5005. */
  5006. void VL_LoadPortals (char *name)
  5007. {
  5008. int i, j, hint;
  5009. lportal_t *p;
  5010. lleaf_t *l;
  5011. char magic[80];
  5012. FILE *f;
  5013. int numpoints;
  5014. winding_t *w;
  5015. int leafnums[2];
  5016. plane_t plane;
  5017. //
  5018. if (!strcmp(name,"-"))
  5019. f = stdin;
  5020. else
  5021. {
  5022. f = fopen(name, "r");
  5023. if (!f)
  5024. Error ("LoadPortals: couldn't read %s\n",name);
  5025. }
  5026. if (fscanf (f,"%79s\n%i\n%i\n%i\n",magic, &portalclusters, &numportals, &numfaces) != 4)
  5027. Error ("LoadPortals: failed to read header");
  5028. if (strcmp(magic, PORTALFILE))
  5029. Error ("LoadPortals: not a portal file");
  5030. _printf ("%6i portalclusters\n", portalclusters);
  5031. _printf ("%6i numportals\n", numportals);
  5032. _printf ("%6i numfaces\n", numfaces);
  5033. if (portalclusters >= MAX_CLUSTERS)
  5034. Error ("more than %d clusters in portal file\n", MAX_CLUSTERS);
  5035. // each file portal is split into two memory portals
  5036. portals = malloc(2*numportals*sizeof(lportal_t));
  5037. memset (portals, 0, 2*numportals*sizeof(lportal_t));
  5038. leafs = malloc(portalclusters*sizeof(lleaf_t));
  5039. memset (leafs, 0, portalclusters*sizeof(lleaf_t));
  5040. for (i=0, p=portals ; i<numportals ; i++)
  5041. {
  5042. if (fscanf (f, "%i %i %i ", &numpoints, &leafnums[0], &leafnums[1]) != 3)
  5043. Error ("LoadPortals: reading portal %i", i);
  5044. if (numpoints > MAX_POINTS_ON_WINDING)
  5045. Error ("LoadPortals: portal %i has too many points", i);
  5046. if ( (unsigned)leafnums[0] > portalclusters
  5047. || (unsigned)leafnums[1] > portalclusters)
  5048. Error ("LoadPortals: reading portal %i", i);
  5049. if (fscanf (f, "%i ", &hint) != 1)
  5050. Error ("LoadPortals: reading hint state");
  5051. w = p->winding = VL_AllocWinding (numpoints);
  5052. w->numpoints = numpoints;
  5053. for (j=0 ; j<numpoints ; j++)
  5054. {
  5055. double v[3];
  5056. int k;
  5057. // scanf into double, then assign to vec_t
  5058. // so we don't care what size vec_t is
  5059. if (fscanf (f, "(%lf %lf %lf ) "
  5060. , &v[0], &v[1], &v[2]) != 3)
  5061. Error ("LoadPortals: reading portal %i", i);
  5062. for (k=0 ; k<3 ; k++)
  5063. w->points[j][k] = v[k];
  5064. }
  5065. fscanf (f, "\n");
  5066. // calc plane
  5067. VL_PlaneFromWinding (w, &plane);
  5068. // create forward portal
  5069. l = &leafs[leafnums[0]];
  5070. if (l->numportals == MAX_PORTALS_ON_LEAF)
  5071. Error ("Leaf with too many portals");
  5072. l->portals[l->numportals] = p;
  5073. l->numportals++;
  5074. p->winding = w;
  5075. VectorSubtract (vec3_origin, plane.normal, p->plane.normal);
  5076. p->plane.dist = -plane.dist;
  5077. p->leaf = leafnums[1];
  5078. VL_SetPortalSphere (p);
  5079. p++;
  5080. // create backwards portal
  5081. l = &leafs[leafnums[1]];
  5082. if (l->numportals == MAX_PORTALS_ON_LEAF)
  5083. Error ("Leaf with too many portals");
  5084. l->portals[l->numportals] = p;
  5085. l->numportals++;
  5086. p->winding = VL_AllocWinding(w->numpoints);
  5087. p->winding->numpoints = w->numpoints;
  5088. for (j=0 ; j<w->numpoints ; j++)
  5089. {
  5090. VectorCopy (w->points[w->numpoints-1-j], p->winding->points[j]);
  5091. }
  5092. p->plane = plane;
  5093. p->leaf = leafnums[0];
  5094. VL_SetPortalSphere (p);
  5095. p++;
  5096. }
  5097. fclose (f);
  5098. }
  5099. /*
  5100. ============
  5101. VLightMain
  5102. ============
  5103. */
  5104. int VLightMain (int argc, char **argv) {
  5105. int i;
  5106. double start, end;
  5107. const char *value;
  5108. _printf ("----- VLighting ----\n");
  5109. for (i=1 ; i<argc ; i++) {
  5110. if (!strcmp(argv[i],"-v")) {
  5111. verbose = qtrue;
  5112. } else if (!strcmp(argv[i],"-threads")) {
  5113. numthreads = atoi (argv[i+1]);
  5114. _printf("num threads = %d\n", numthreads);
  5115. i++;
  5116. } else if (!strcmp(argv[i],"-area")) {
  5117. lightAreaScale *= atof(argv[i+1]);
  5118. _printf ("area light scaling at %f\n", lightAreaScale);
  5119. i++;
  5120. } else if (!strcmp(argv[i],"-point")) {
  5121. lightPointScale *= atof(argv[i+1]);
  5122. _printf ("point light scaling at %f\n", lightPointScale);
  5123. i++;
  5124. } else if (!strcmp(argv[i], "-samplesize")) {
  5125. samplesize = atoi(argv[i+1]);
  5126. if (samplesize < 1) samplesize = 1;
  5127. i++;
  5128. _printf("lightmap sample size is %dx%d units\n", samplesize, samplesize);
  5129. } else if (!strcmp(argv[i], "-novertex")) {
  5130. novertexlighting = qtrue;
  5131. _printf("no vertex lighting = true\n");
  5132. } else if (!strcmp(argv[i], "-nogrid")) {
  5133. nogridlighting = qtrue;
  5134. _printf("no grid lighting = true\n");
  5135. } else if (!strcmp(argv[i], "-nostitching")) {
  5136. nostitching = qtrue;
  5137. _printf("no stitching = true\n");
  5138. } else if (!strcmp(argv[i], "-noalphashading")) {
  5139. noalphashading = qtrue;
  5140. _printf("no alpha shading = true\n");
  5141. } else if (!strcmp(argv[i], "-nocolorshading")) {
  5142. nocolorshading = qtrue;
  5143. _printf("old style alpha shading = true\n");
  5144. } else if (!strcmp(argv[i], "-nobackfaceculling")) {
  5145. nobackfaceculling = qtrue;
  5146. _printf("no backface culling = true\n");
  5147. } else if (!strcmp(argv[i], "-tracelight")) {
  5148. defaulttracelight = qtrue;
  5149. _printf("default trace light = true\n");
  5150. } else if (!strcmp(argv[i], "-radiosity")) {
  5151. radiosity = atoi(argv[i+1]);
  5152. _printf("radiosity = %d\n", radiosity);
  5153. i++;
  5154. } else {
  5155. break;
  5156. }
  5157. }
  5158. ThreadSetDefault ();
  5159. if (i != argc - 1) {
  5160. _printf("usage: q3map -vlight [-<switch> [-<switch> ...]] <mapname>\n"
  5161. "\n"
  5162. "Switches:\n"
  5163. " v = verbose output\n"
  5164. " threads <X> = set number of threads to X\n"
  5165. " area <V> = set the area light scale to V\n"
  5166. " point <W> = set the point light scale to W\n"
  5167. " novertex = don't calculate vertex lighting\n"
  5168. " nogrid = don't calculate light grid for dynamic model lighting\n"
  5169. " nostitching = no polygon stitching before lighting\n"
  5170. " noalphashading = don't use alpha shading\n"
  5171. " nocolorshading = don't use color alpha shading\n"
  5172. " tracelight = use old light algorithm by default\n"
  5173. " samplesize <N> = set the lightmap pixel size to NxN units\n");
  5174. exit(0);
  5175. }
  5176. SetQdirFromPath (argv[i]);
  5177. #ifdef _WIN32
  5178. InitPakFile(gamedir, NULL);
  5179. #endif
  5180. strcpy (source, ExpandArg(argv[i]));
  5181. StripExtension (source);
  5182. DefaultExtension (source, ".bsp");
  5183. LoadShaderInfo();
  5184. _printf ("reading %s\n", source);
  5185. LoadBSPFile (source);
  5186. ParseEntities();
  5187. value = ValueForKey( &entities[0], "gridsize" );
  5188. if (strlen(value)) {
  5189. sscanf( value, "%f %f %f", &gridSize[0], &gridSize[1], &gridSize[2] );
  5190. _printf("grid size = {%1.1f, %1.1f, %1.1f}\n", gridSize[0], gridSize[1], gridSize[2]);
  5191. }
  5192. CountLightmaps();
  5193. StripExtension (source);
  5194. DefaultExtension (source, ".prt");
  5195. VL_LoadPortals(source);
  5196. // set surfaceOrigin
  5197. SetEntityOrigins();
  5198. // grid and vertex lighting
  5199. GridAndVertexLighting();
  5200. #ifdef DEBUGNET
  5201. DebugNet_Setup();
  5202. #endif
  5203. start = clock();
  5204. lightFloats = (float *) malloc(numLightBytes * sizeof(float));
  5205. memset(lightFloats, 0, numLightBytes * sizeof(float));
  5206. VL_InitSurfacesForTesting();
  5207. VL_CalcVisibleLightmapPixelArea();
  5208. numvlights = 0;
  5209. VL_CreateEntityLights();
  5210. VL_CreateFakeSurfaceLights();
  5211. VL_CreateSkyLights();
  5212. VL_TestLightLeafs();
  5213. VL_LightWorld();
  5214. #ifndef LIGHTPOLYS
  5215. StripExtension (source);
  5216. DefaultExtension (source, ".bsp");
  5217. _printf ("writing %s\n", source);
  5218. WriteBSPFile (source);
  5219. #endif
  5220. end = clock();
  5221. _printf ("%5.2f seconds elapsed\n", (end-start) / CLK_TCK);
  5222. #ifdef LIGHTPOLYS
  5223. VL_DrawLightWindings();
  5224. #endif
  5225. #ifdef DEBUGNET
  5226. DebugNet_Shutdown();
  5227. #endif
  5228. return 0;
  5229. }