soundv.c 145 KB

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