Brush.cpp 105 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "stdafx.h"
  19. #include <assert.h>
  20. #include "qe3.h"
  21. #include "winding.h"
  22. // globals
  23. int g_nBrushId = 0;
  24. const char* Brush_Name(brush_t *b)
  25. {
  26. static char cBuff[1024];
  27. b->numberId = g_nBrushId++;
  28. if (g_qeglobals.m_bBrushPrimitMode)
  29. {
  30. sprintf(cBuff, "Brush %i", b->numberId);
  31. Brush_SetEpair(b, "Name", cBuff);
  32. }
  33. return cBuff;
  34. }
  35. brush_t *Brush_Alloc()
  36. {
  37. brush_t *b = (brush_t*)qmalloc(sizeof(brush_t));
  38. return b;
  39. }
  40. void PrintWinding (winding_t *w)
  41. {
  42. int i;
  43. printf ("-------------\n");
  44. for (i=0 ; i<w->numpoints ; i++)
  45. printf ("(%5.2f, %5.2f, %5.2f)\n", w->points[i][0]
  46. , w->points[i][1], w->points[i][2]);
  47. }
  48. void PrintPlane (plane_t *p)
  49. {
  50. printf ("(%5.2f, %5.2f, %5.2f) : %5.2f\n", p->normal[0], p->normal[1],
  51. p->normal[2], p->dist);
  52. }
  53. void PrintVector (vec3_t v)
  54. {
  55. printf ("(%5.2f, %5.2f, %5.2f)\n", v[0], v[1], v[2]);
  56. }
  57. /*
  58. =============================================================================
  59. TEXTURE COORDINATES
  60. =============================================================================
  61. */
  62. /*
  63. ==================
  64. textureAxisFromPlane
  65. ==================
  66. */
  67. vec3_t baseaxis[18] =
  68. {
  69. {0,0,1}, {1,0,0}, {0,-1,0}, // floor
  70. {0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling
  71. {1,0,0}, {0,1,0}, {0,0,-1}, // west wall
  72. {-1,0,0}, {0,1,0}, {0,0,-1}, // east wall
  73. {0,1,0}, {1,0,0}, {0,0,-1}, // south wall
  74. {0,-1,0}, {1,0,0}, {0,0,-1} // north wall
  75. };
  76. void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv)
  77. {
  78. int bestaxis;
  79. float dot,best;
  80. int i;
  81. best = 0;
  82. bestaxis = 0;
  83. for (i=0 ; i<6 ; i++)
  84. {
  85. dot = DotProduct (pln->normal, baseaxis[i*3]);
  86. if (dot > best)
  87. {
  88. best = dot;
  89. bestaxis = i;
  90. }
  91. }
  92. VectorCopy (baseaxis[bestaxis*3+1], xv);
  93. VectorCopy (baseaxis[bestaxis*3+2], yv);
  94. }
  95. float lightaxis[3] = {0.6, 0.8, 1.0};
  96. /*
  97. ================
  98. SetShadeForPlane
  99. Light different planes differently to
  100. improve recognition
  101. ================
  102. */
  103. float SetShadeForPlane (plane_t *p)
  104. {
  105. int i;
  106. float f;
  107. // axial plane
  108. for (i=0 ; i<3 ; i++)
  109. if (fabs(p->normal[i]) > 0.9)
  110. {
  111. f = lightaxis[i];
  112. return f;
  113. }
  114. // between two axial planes
  115. for (i=0 ; i<3 ; i++)
  116. if (fabs(p->normal[i]) < 0.1)
  117. {
  118. f = (lightaxis[(i+1)%3] + lightaxis[(i+2)%3])/2;
  119. return f;
  120. }
  121. // other
  122. f= (lightaxis[0] + lightaxis[1] + lightaxis[2]) / 3;
  123. return f;
  124. }
  125. vec3_t vecs[2];
  126. float shift[2];
  127. /*
  128. ================
  129. Face_Alloc
  130. ================
  131. */
  132. face_t *Face_Alloc( void )
  133. {
  134. face_t *f = (face_t*)qmalloc( sizeof( *f ) );
  135. if (g_qeglobals.bSurfacePropertiesPlugin)
  136. f->pData = static_cast<void *>( g_SurfaceTable.m_pfnTexdefAlloc( f ) );
  137. return f;
  138. }
  139. /*
  140. ================
  141. Face_Free
  142. ================
  143. */
  144. void Face_Free( face_t *f )
  145. {
  146. assert( f != 0 );
  147. if ( f->face_winding )
  148. {
  149. free( f->face_winding );
  150. f->face_winding = 0;
  151. }
  152. if (g_qeglobals.bSurfacePropertiesPlugin)
  153. {
  154. #ifdef _DEBUG
  155. if ( !f->pData )
  156. {
  157. Sys_Printf("WARNING: unexpected IPluginTexdef is NULL in Face_Free\n");
  158. }
  159. else
  160. #endif
  161. GETPLUGINTEXDEF(f)->DecRef();
  162. }
  163. f->texdef.~texdef_t();;
  164. free( f );
  165. }
  166. /*
  167. ================
  168. Face_Clone
  169. ================
  170. */
  171. face_t *Face_Clone (face_t *f)
  172. {
  173. face_t *n;
  174. n = Face_Alloc();
  175. n->texdef = f->texdef;
  176. memcpy (n->planepts, f->planepts, sizeof(n->planepts));
  177. // all other fields are derived, and will be set by Brush_Build
  178. return n;
  179. }
  180. /*
  181. ================
  182. Face_FullClone
  183. makes an exact copy of the face
  184. ================
  185. */
  186. face_t *Face_FullClone (face_t *f)
  187. {
  188. face_t *n;
  189. n = Face_Alloc();
  190. n->texdef = f->texdef;
  191. memcpy(n->planepts, f->planepts, sizeof(n->planepts));
  192. memcpy(&n->plane, &f->plane, sizeof(plane_t));
  193. if (f->face_winding)
  194. n->face_winding = Winding_Clone(f->face_winding);
  195. else
  196. n->face_winding = NULL;
  197. n->d_texture = Texture_ForName( n->texdef.name );
  198. return n;
  199. }
  200. /*
  201. ================
  202. Clamp
  203. ================
  204. */
  205. void Clamp(float& f, int nClamp)
  206. {
  207. float fFrac = f - static_cast<int>(f);
  208. f = static_cast<int>(f) % nClamp;
  209. f += fFrac;
  210. }
  211. /*
  212. ================
  213. Face_MoveTexture
  214. ================
  215. */
  216. void Face_MoveTexture(face_t *f, vec3_t delta)
  217. {
  218. vec3_t vX, vY;
  219. /*
  220. #ifdef _DEBUG
  221. if (g_PrefsDlg.m_bBrushPrimitMode)
  222. Sys_Printf("Warning : Face_MoveTexture not done in brush primitive mode\n");
  223. #endif
  224. */
  225. if (g_qeglobals.m_bBrushPrimitMode)
  226. Face_MoveTexture_BrushPrimit( f, delta );
  227. else
  228. {
  229. TextureAxisFromPlane(&f->plane, vX, vY);
  230. vec3_t vDP, vShift;
  231. vDP[0] = DotProduct(delta, vX);
  232. vDP[1] = DotProduct(delta, vY);
  233. double fAngle = f->texdef.rotate / 180 * Q_PI;
  234. double c = cos(fAngle);
  235. double s = sin(fAngle);
  236. vShift[0] = vDP[0] * c - vDP[1] * s;
  237. vShift[1] = vDP[0] * s + vDP[1] * c;
  238. if (!f->texdef.scale[0])
  239. f->texdef.scale[0] = 1;
  240. if (!f->texdef.scale[1])
  241. f->texdef.scale[1] = 1;
  242. f->texdef.shift[0] -= vShift[0] / f->texdef.scale[0];
  243. f->texdef.shift[1] -= vShift[1] / f->texdef.scale[1];
  244. // clamp the shifts
  245. Clamp(f->texdef.shift[0], f->d_texture->width);
  246. Clamp(f->texdef.shift[1], f->d_texture->height);
  247. }
  248. }
  249. /*
  250. ================
  251. Face_SetColor
  252. ================
  253. */
  254. void Face_SetColor (brush_t *b, face_t *f, float fCurveColor)
  255. {
  256. float shade;
  257. qtexture_t *q;
  258. q = f->d_texture;
  259. // set shading for face
  260. shade = SetShadeForPlane (&f->plane);
  261. if (g_pParentWnd->GetCamera()->Camera().draw_mode == cd_texture && !b->owner->eclass->fixedsize)
  262. {
  263. //if (b->curveBrush)
  264. // shade = fCurveColor;
  265. f->d_color[0] =
  266. f->d_color[1] =
  267. f->d_color[2] = shade;
  268. }
  269. else
  270. {
  271. f->d_color[0] = shade*q->color[0];
  272. f->d_color[1] = shade*q->color[1];
  273. f->d_color[2] = shade*q->color[2];
  274. }
  275. }
  276. /*
  277. ================
  278. Face_TextureVectors
  279. TTimo: NOTE: this is never to get called while in brush primitives mode
  280. ================
  281. */
  282. void Face_TextureVectors (face_t *f, float STfromXYZ[2][4])
  283. {
  284. vec3_t pvecs[2];
  285. int sv, tv;
  286. float ang, sinv, cosv;
  287. float ns, nt;
  288. int i,j;
  289. qtexture_t *q;
  290. texdef_t *td;
  291. #ifdef _DEBUG
  292. //++timo when playing with patches, this sometimes get called and the Warning is displayed
  293. // find some way out ..
  294. if (g_qeglobals.m_bBrushPrimitMode && !g_qeglobals.bNeedConvert)
  295. Sys_Printf("Warning : illegal call of Face_TextureVectors in brush primitive mode\n");
  296. #endif
  297. td = &f->texdef;
  298. q = f->d_texture;
  299. memset (STfromXYZ, 0, 8*sizeof(float));
  300. if (!td->scale[0])
  301. td->scale[0] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1;
  302. if (!td->scale[1])
  303. td->scale[1] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1;
  304. // get natural texture axis
  305. TextureAxisFromPlane(&f->plane, pvecs[0], pvecs[1]);
  306. // rotate axis
  307. if (td->rotate == 0)
  308. { sinv = 0 ; cosv = 1; }
  309. else if (td->rotate == 90)
  310. { sinv = 1 ; cosv = 0; }
  311. else if (td->rotate == 180)
  312. { sinv = 0 ; cosv = -1; }
  313. else if (td->rotate == 270)
  314. { sinv = -1 ; cosv = 0; }
  315. else
  316. {
  317. ang = td->rotate / 180 * Q_PI;
  318. sinv = sin(ang);
  319. cosv = cos(ang);
  320. }
  321. if (pvecs[0][0])
  322. sv = 0;
  323. else if (pvecs[0][1])
  324. sv = 1;
  325. else
  326. sv = 2;
  327. if (pvecs[1][0])
  328. tv = 0;
  329. else if (pvecs[1][1])
  330. tv = 1;
  331. else
  332. tv = 2;
  333. for (i=0 ; i<2 ; i++) {
  334. ns = cosv * pvecs[i][sv] - sinv * pvecs[i][tv];
  335. nt = sinv * pvecs[i][sv] + cosv * pvecs[i][tv];
  336. STfromXYZ[i][sv] = ns;
  337. STfromXYZ[i][tv] = nt;
  338. }
  339. // scale
  340. for (i=0 ; i<2 ; i++)
  341. for (j=0 ; j<3 ; j++)
  342. STfromXYZ[i][j] = STfromXYZ[i][j] / td->scale[i];
  343. // shift
  344. STfromXYZ[0][3] = td->shift[0];
  345. STfromXYZ[1][3] = td->shift[1];
  346. for (j=0 ; j<4 ; j++) {
  347. STfromXYZ[0][j] /= q->width;
  348. STfromXYZ[1][j] /= q->height;
  349. }
  350. }
  351. /*
  352. ================
  353. Face_MakePlane
  354. ================
  355. */
  356. void Face_MakePlane (face_t *f)
  357. {
  358. int j;
  359. vec3_t t1, t2, t3;
  360. // convert to a vector / dist plane
  361. for (j=0 ; j<3 ; j++)
  362. {
  363. t1[j] = f->planepts[0][j] - f->planepts[1][j];
  364. t2[j] = f->planepts[2][j] - f->planepts[1][j];
  365. t3[j] = f->planepts[1][j];
  366. }
  367. CrossProduct(t1,t2, f->plane.normal);
  368. if (VectorCompare (f->plane.normal, vec3_origin))
  369. printf ("WARNING: brush plane with no normal\n");
  370. VectorNormalize (f->plane.normal);
  371. f->plane.dist = DotProduct (t3, f->plane.normal);
  372. }
  373. /*
  374. ================
  375. EmitTextureCoordinates
  376. ================
  377. */
  378. void EmitTextureCoordinates ( float *xyzst, qtexture_t *q, face_t *f)
  379. {
  380. float STfromXYZ[2][4];
  381. Face_TextureVectors (f, STfromXYZ);
  382. xyzst[3] = DotProduct (xyzst, STfromXYZ[0]) + STfromXYZ[0][3];
  383. xyzst[4] = DotProduct (xyzst, STfromXYZ[1]) + STfromXYZ[1][3];
  384. }
  385. //==========================================================================
  386. /*
  387. ================
  388. Brush_MakeFacePlanes
  389. ================
  390. */
  391. void Brush_MakeFacePlanes (brush_t *b)
  392. {
  393. face_t *f;
  394. for (f=b->brush_faces ; f ; f=f->next)
  395. {
  396. Face_MakePlane (f);
  397. }
  398. }
  399. /*
  400. ================
  401. DrawBrushEntityName
  402. ================
  403. */
  404. void DrawBrushEntityName (brush_t *b)
  405. {
  406. char *name;
  407. //float a, s, c;
  408. //vec3_t mid;
  409. //int i;
  410. if (!b->owner)
  411. return; // during contruction
  412. if (b->owner == world_entity)
  413. return;
  414. if (b != b->owner->brushes.onext)
  415. return; // not key brush
  416. // MERGEME
  417. #if 0
  418. if (!(g_qeglobals.d_savedinfo.exclude & EXCLUDE_ANGLES))
  419. {
  420. // draw the angle pointer
  421. a = FloatForKey (b->owner, "angle");
  422. if (a)
  423. {
  424. s = sin (a/180*Q_PI);
  425. c = cos (a/180*Q_PI);
  426. for (i=0 ; i<3 ; i++)
  427. mid[i] = (b->mins[i] + b->maxs[i])*0.5;
  428. qglBegin (GL_LINE_STRIP);
  429. qglVertex3fv (mid);
  430. mid[0] += c*8;
  431. mid[1] += s*8;
  432. mid[2] += s*8;
  433. qglVertex3fv (mid);
  434. mid[0] -= c*4;
  435. mid[1] -= s*4;
  436. mid[2] -= s*4;
  437. mid[0] -= s*4;
  438. mid[1] += c*4;
  439. mid[2] += c*4;
  440. qglVertex3fv (mid);
  441. mid[0] += c*4;
  442. mid[1] += s*4;
  443. mid[2] += s*4;
  444. mid[0] += s*4;
  445. mid[1] -= c*4;
  446. mid[2] -= c*4;
  447. qglVertex3fv (mid);
  448. mid[0] -= c*4;
  449. mid[1] -= s*4;
  450. mid[2] -= s*4;
  451. mid[0] += s*4;
  452. mid[1] -= c*4;
  453. mid[2] -= c*4;
  454. qglVertex3fv (mid);
  455. qglEnd ();
  456. }
  457. }
  458. #endif
  459. if (g_qeglobals.d_savedinfo.show_names)
  460. {
  461. name = ValueForKey (b->owner, "classname");
  462. qglRasterPos3f (b->mins[0]+4, b->mins[1]+4, b->mins[2]+4);
  463. qglCallLists (strlen(name), GL_UNSIGNED_BYTE, name);
  464. }
  465. }
  466. /*
  467. =================
  468. Brush_MakeFaceWinding
  469. returns the visible polygon on a face
  470. =================
  471. */
  472. winding_t *Brush_MakeFaceWinding (brush_t *b, face_t *face)
  473. {
  474. winding_t *w;
  475. face_t *clip;
  476. plane_t plane;
  477. qboolean past;
  478. // get a poly that covers an effectively infinite area
  479. w = Winding_BaseForPlane (&face->plane);
  480. // chop the poly by all of the other faces
  481. past = false;
  482. for (clip = b->brush_faces ; clip && w ; clip=clip->next)
  483. {
  484. if (clip == face)
  485. {
  486. past = true;
  487. continue;
  488. }
  489. if (DotProduct (face->plane.normal, clip->plane.normal) > 0.999
  490. && fabs(face->plane.dist - clip->plane.dist) < 0.01 )
  491. { // identical plane, use the later one
  492. if (past)
  493. {
  494. free (w);
  495. return NULL;
  496. }
  497. continue;
  498. }
  499. // flip the plane, because we want to keep the back side
  500. VectorSubtract (vec3_origin,clip->plane.normal, plane.normal);
  501. plane.dist = -clip->plane.dist;
  502. w = Winding_Clip (w, &plane, false);
  503. if (!w)
  504. return w;
  505. }
  506. if (w->numpoints < 3)
  507. {
  508. free(w);
  509. w = NULL;
  510. }
  511. if (!w)
  512. printf ("unused plane\n");
  513. return w;
  514. }
  515. /*
  516. =================
  517. Brush_SnapPlanepts
  518. =================
  519. */
  520. void Brush_SnapPlanepts (brush_t *b)
  521. {
  522. int i, j;
  523. face_t *f;
  524. if (g_PrefsDlg.m_bNoClamp)
  525. return;
  526. for (f=b->brush_faces ; f; f=f->next)
  527. for (i=0 ; i<3 ; i++)
  528. for (j=0 ; j<3 ; j++)
  529. f->planepts[i][j] = floor (f->planepts[i][j] + 0.5);
  530. }
  531. /*
  532. ** Brush_Build
  533. **
  534. ** Builds a brush rendering data and also sets the min/max bounds
  535. */
  536. // TTimo
  537. // added a bConvert flag to convert between old and new brush texture formats
  538. // TTimo
  539. // brush grouping: update the group treeview if necessary
  540. void Brush_Build( brush_t *b, bool bSnap, bool bMarkMap, bool bConvert )
  541. {
  542. bool bLocalConvert;
  543. #ifdef _DEBUG
  544. if (!g_qeglobals.m_bBrushPrimitMode && bConvert)
  545. Sys_Printf("Warning : conversion from brush primitive to old brush format not implemented\n");
  546. #endif
  547. // if bConvert is set and g_qeglobals.bNeedConvert is not, that just means we need convert for this brush only
  548. if (bConvert && !g_qeglobals.bNeedConvert)
  549. {
  550. bLocalConvert = true;
  551. g_qeglobals.bNeedConvert = true;
  552. }
  553. /*
  554. ** build the windings and generate the bounding box
  555. */
  556. Brush_BuildWindings(b, bSnap);
  557. Patch_BuildPoints (b);
  558. /*
  559. ** move the points and edges if in select mode
  560. */
  561. if (g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_edge)
  562. SetupVertexSelection ();
  563. if (b->itemOwner == NULL)
  564. Group_AddToProperGroup(b);
  565. if (bMarkMap)
  566. {
  567. Sys_MarkMapModified();
  568. }
  569. if (bLocalConvert)
  570. g_qeglobals.bNeedConvert = false;
  571. }
  572. /*
  573. ==============
  574. Brush_SplitBrushByFace
  575. The incoming brush is NOT freed.
  576. The incoming face is NOT left referenced.
  577. ==============
  578. */
  579. void Brush_SplitBrushByFace (brush_t *in, face_t *f, brush_t **front, brush_t **back)
  580. {
  581. brush_t *b;
  582. face_t *nf;
  583. vec3_t temp;
  584. b = Brush_Clone (in);
  585. nf = Face_Clone (f);
  586. nf->texdef = b->brush_faces->texdef;
  587. nf->next = b->brush_faces;
  588. b->brush_faces = nf;
  589. Brush_Build( b );
  590. Brush_RemoveEmptyFaces ( b );
  591. if ( !b->brush_faces )
  592. { // completely clipped away
  593. Brush_Free (b);
  594. *back = NULL;
  595. }
  596. else
  597. {
  598. Entity_LinkBrush (in->owner, b);
  599. *back = b;
  600. }
  601. b = Brush_Clone (in);
  602. nf = Face_Clone (f);
  603. // swap the plane winding
  604. VectorCopy (nf->planepts[0], temp);
  605. VectorCopy (nf->planepts[1], nf->planepts[0]);
  606. VectorCopy (temp, nf->planepts[1]);
  607. nf->texdef = b->brush_faces->texdef;
  608. nf->next = b->brush_faces;
  609. b->brush_faces = nf;
  610. Brush_Build( b );
  611. Brush_RemoveEmptyFaces ( b );
  612. if ( !b->brush_faces )
  613. { // completely clipped away
  614. Brush_Free (b);
  615. *front = NULL;
  616. }
  617. else
  618. {
  619. Entity_LinkBrush (in->owner, b);
  620. *front = b;
  621. }
  622. }
  623. /*
  624. =================
  625. Brush_BestSplitFace
  626. returns the best face to split the brush with.
  627. return NULL if the brush is convex
  628. =================
  629. */
  630. face_t *Brush_BestSplitFace(brush_t *b)
  631. {
  632. face_t *face, *f, *bestface;
  633. winding_t *front, *back;
  634. int splits, tinywindings, value, bestvalue;
  635. bestvalue = 999999;
  636. bestface = NULL;
  637. for (face = b->brush_faces; face; face = face->next)
  638. {
  639. splits = 0;
  640. tinywindings = 0;
  641. for (f = b->brush_faces; f; f = f->next)
  642. {
  643. if (f == face) continue;
  644. //
  645. Winding_SplitEpsilon(f->face_winding, face->plane.normal, face->plane.dist, 0.1, &front, &back);
  646. if (!front)
  647. {
  648. Winding_Free(back);
  649. }
  650. else if (!back)
  651. {
  652. Winding_Free(front);
  653. }
  654. else
  655. {
  656. splits++;
  657. if (Winding_IsTiny(front)) tinywindings++;
  658. if (Winding_IsTiny(back)) tinywindings++;
  659. }
  660. }
  661. if (splits)
  662. {
  663. value = splits + 50 * tinywindings;
  664. if (value < bestvalue)
  665. {
  666. bestvalue = value;
  667. bestface = face;
  668. }
  669. }
  670. }
  671. return bestface;
  672. }
  673. /*
  674. =================
  675. Brush_MakeConvexBrushes
  676. MrE FIXME: this doesn't work because the old
  677. Brush_SplitBrushByFace is used
  678. Turns the brush into a minimal number of convex brushes.
  679. If the input brush is convex then it will be returned.
  680. Otherwise the input brush will be freed.
  681. NOTE: the input brush should have windings for the faces.
  682. =================
  683. */
  684. brush_t *Brush_MakeConvexBrushes(brush_t *b)
  685. {
  686. brush_t *front, *back, *end;
  687. face_t *face;
  688. b->next = NULL;
  689. face = Brush_BestSplitFace(b);
  690. if (!face) return b;
  691. Brush_SplitBrushByFace(b, face, &front, &back);
  692. //this should never happen
  693. if (!front && !back) return b;
  694. Brush_Free(b);
  695. if (!front)
  696. return Brush_MakeConvexBrushes(back);
  697. b = Brush_MakeConvexBrushes(front);
  698. if (back)
  699. {
  700. for (end = b; end->next; end = end->next);
  701. end->next = Brush_MakeConvexBrushes(back);
  702. }
  703. return b;
  704. }
  705. /*
  706. =================
  707. Brush_Convex
  708. =================
  709. */
  710. int Brush_Convex(brush_t *b)
  711. {
  712. face_t *face1, *face2;
  713. for (face1 = b->brush_faces; face1; face1 = face1->next)
  714. {
  715. if (!face1->face_winding) continue;
  716. for (face2 = b->brush_faces; face2; face2 = face2->next)
  717. {
  718. if (face1 == face2) continue;
  719. if (!face2->face_winding) continue;
  720. if (Winding_PlanesConcave(face1->face_winding, face2->face_winding,
  721. face1->plane.normal, face2->plane.normal,
  722. face1->plane.dist, face2->plane.dist))
  723. {
  724. return false;
  725. }
  726. }
  727. }
  728. return true;
  729. }
  730. /*
  731. =================
  732. Brush_MoveVertexes_old1
  733. - The input brush must have face windings.
  734. - The input brush must be a brush with faces that do not intersect.
  735. - The input brush does not have to be convex.
  736. - The vertex will not be moved if the movement either causes the
  737. brush to have faces that intersect or causes the brush to be
  738. flipped inside out.
  739. (For instance a tetrahedron can easily be flipped inside out
  740. without having faces that intersect.)
  741. - The created brush does not have to be convex.
  742. - Returns true if the vertex movement is performed.
  743. =================
  744. */
  745. #define MAX_MOVE_FACES 64
  746. #define INTERSECT_EPSILON 0.1
  747. #define POINT_EPSILON 0.3
  748. int Brush_MoveVertex_old1(brush_t *b, vec3_t vertex, vec3_t delta, vec3_t end, bool bSnap)
  749. {
  750. face_t *f, *face, *newface, *lastface, *nextface;
  751. face_t *movefaces[MAX_MOVE_FACES];
  752. int movefacepoints[MAX_MOVE_FACES];
  753. winding_t *w, tmpw;
  754. int i, j, k, nummovefaces, result;
  755. float dot;
  756. result = false;
  757. //
  758. tmpw.numpoints = 3;
  759. tmpw.maxpoints = 3;
  760. VectorAdd(vertex, delta, end);
  761. //snap or not?
  762. if (bSnap)
  763. for (i = 0; i < 3; i++)
  764. end[i] = floor(end[i] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
  765. //chop off triangles from all brush faces that use the to be moved vertex
  766. //store pointers to these chopped off triangles in movefaces[]
  767. nummovefaces = 0;
  768. for (face = b->brush_faces; face; face = face->next)
  769. {
  770. w = face->face_winding;
  771. if (!w) continue;
  772. for (i = 0; i < w->numpoints; i++)
  773. {
  774. if (Point_Equal(w->points[i], vertex, POINT_EPSILON))
  775. {
  776. if (face->face_winding->numpoints <= 3)
  777. {
  778. movefacepoints[nummovefaces] = i;
  779. movefaces[nummovefaces++] = face;
  780. break;
  781. }
  782. dot = DotProduct(end, face->plane.normal) - face->plane.dist;
  783. //if the end point is in front of the face plane
  784. if (dot > 0.1)
  785. {
  786. //fanout triangle subdivision
  787. for (k = i; k < i + w->numpoints-3; k++)
  788. {
  789. VectorCopy(w->points[i], tmpw.points[0]);
  790. VectorCopy(w->points[(k+1) % w->numpoints], tmpw.points[1]);
  791. VectorCopy(w->points[(k+2) % w->numpoints], tmpw.points[2]);
  792. //
  793. newface = Face_Clone(face);
  794. //get the original
  795. for (f = face; f->original; f = f->original) ;
  796. newface->original = f;
  797. //store the new winding
  798. if (newface->face_winding) Winding_Free(newface->face_winding);
  799. newface->face_winding = Winding_Clone(&tmpw);
  800. //get the texture
  801. newface->d_texture = Texture_ForName( newface->texdef.name );
  802. //add the face to the brush
  803. newface->next = b->brush_faces;
  804. b->brush_faces = newface;
  805. //add this new triangle to the move faces
  806. movefacepoints[nummovefaces] = 0;
  807. movefaces[nummovefaces++] = newface;
  808. }
  809. //give the original face a new winding
  810. VectorCopy(w->points[(i-2+w->numpoints) % w->numpoints], tmpw.points[0]);
  811. VectorCopy(w->points[(i-1+w->numpoints) % w->numpoints], tmpw.points[1]);
  812. VectorCopy(w->points[i], tmpw.points[2]);
  813. Winding_Free(face->face_winding);
  814. face->face_winding = Winding_Clone(&tmpw);
  815. //add the original face to the move faces
  816. movefacepoints[nummovefaces] = 2;
  817. movefaces[nummovefaces++] = face;
  818. }
  819. else
  820. {
  821. //chop a triangle off the face
  822. VectorCopy(w->points[(i-1+w->numpoints) % w->numpoints], tmpw.points[0]);
  823. VectorCopy(w->points[i], tmpw.points[1]);
  824. VectorCopy(w->points[(i+1) % w->numpoints], tmpw.points[2]);
  825. //remove the point from the face winding
  826. Winding_RemovePoint(w, i);
  827. //get texture crap right
  828. Face_SetColor(b, face, 1.0);
  829. for (j = 0; j < w->numpoints; j++)
  830. EmitTextureCoordinates(w->points[j], face->d_texture, face);
  831. //make a triangle face
  832. newface = Face_Clone(face);
  833. //get the original
  834. for (f = face; f->original; f = f->original) ;
  835. newface->original = f;
  836. //store the new winding
  837. if (newface->face_winding) Winding_Free(newface->face_winding);
  838. newface->face_winding = Winding_Clone(&tmpw);
  839. //get the texture
  840. newface->d_texture = Texture_ForName( newface->texdef.name );
  841. //add the face to the brush
  842. newface->next = b->brush_faces;
  843. b->brush_faces = newface;
  844. //
  845. movefacepoints[nummovefaces] = 1;
  846. movefaces[nummovefaces++] = newface;
  847. }
  848. break;
  849. }
  850. }
  851. }
  852. //now movefaces contains pointers to triangle faces that
  853. //contain the to be moved vertex
  854. //check if the move is valid
  855. int l;
  856. vec3_t p1, p2;
  857. winding_t *w2;
  858. plane_t plane;
  859. face = NULL;
  860. VectorCopy(vertex, tmpw.points[1]);
  861. VectorCopy(end, tmpw.points[2]);
  862. for (face = b->brush_faces; face; face = face->next)
  863. {
  864. for (i = 0; i < nummovefaces; i++)
  865. {
  866. if (face == movefaces[i])
  867. break;
  868. }
  869. if (i < nummovefaces)
  870. continue;
  871. //the delta vector may not intersect with any of the not move faces
  872. if (Winding_VectorIntersect(face->face_winding, &face->plane, vertex, end, INTERSECT_EPSILON))
  873. break;
  874. //if the end point of the to be moved vertex is near this not move face
  875. if (abs(DotProduct(face->plane.normal, end) - face->plane.dist) < 0.5)
  876. {
  877. //the end point may not be inside or very close to the not move face winding
  878. if (Winding_PointInside(face->face_winding, &face->plane, end, 0.5))
  879. break;
  880. }
  881. for (i = 0; i < nummovefaces; i++)
  882. {
  883. w = movefaces[i]->face_winding;
  884. j = movefacepoints[i];
  885. for (k = -1; k <= 1; k += 2)
  886. {
  887. //check if the new edge will not intersect with the not move face
  888. VectorCopy(w->points[(j + k + w->numpoints) % w->numpoints], tmpw.points[0]);
  889. if (Winding_VectorIntersect(face->face_winding, &face->plane, tmpw.points[0], end, INTERSECT_EPSILON))
  890. {
  891. //ok the new edge instersects with the not move face
  892. //we can't perform the vertex movement
  893. //break;
  894. }
  895. //check if the not move face intersects the "movement winding"
  896. Winding_Plane(&tmpw, plane.normal, &plane.dist);
  897. w2 = face->face_winding;
  898. for (l = 0; l < w2->numpoints; l++)
  899. {
  900. VectorCopy(w2->points[l], p1);
  901. if (Point_Equal(p1, tmpw.points[0], POINT_EPSILON)) continue;
  902. VectorCopy(w2->points[(l+1) % w2->numpoints], p2);
  903. if (Point_Equal(p2, tmpw.points[0], POINT_EPSILON)) continue;
  904. if (Winding_VectorIntersect(&tmpw, &plane, p1, p2, INTERSECT_EPSILON))
  905. break;
  906. }
  907. if (l < w2->numpoints)
  908. {
  909. //ok this not move face intersects the "movement winding"
  910. //we can't perform the vertex movement
  911. break;
  912. }
  913. }
  914. if (k <= 1) break;
  915. }
  916. if (i < nummovefaces)
  917. break;
  918. }
  919. if (!face)
  920. {
  921. //ok the move was valid
  922. //now move all the vertexes of the movefaces
  923. for (i = 0; i < nummovefaces; i++)
  924. {
  925. VectorCopy(end, movefaces[i]->face_winding->points[movefacepoints[i]]);
  926. //create new face plane
  927. for (j = 0; j < 3; j++)
  928. {
  929. VectorCopy(movefaces[i]->face_winding->points[j], movefaces[i]->planepts[j]);
  930. }
  931. Face_MakePlane(movefaces[i]);
  932. }
  933. result = true;
  934. }
  935. //get texture crap right
  936. for (i = 0; i < nummovefaces; i++)
  937. {
  938. Face_SetColor(b, movefaces[i], 1.0);
  939. for (j = 0; j < movefaces[i]->face_winding->numpoints; j++)
  940. EmitTextureCoordinates(movefaces[i]->face_winding->points[j], movefaces[i]->d_texture, movefaces[i]);
  941. }
  942. //now try to merge faces with their original faces
  943. lastface = NULL;
  944. for (face = b->brush_faces; face; face = nextface)
  945. {
  946. nextface = face->next;
  947. if (!face->original)
  948. {
  949. lastface = face;
  950. continue;
  951. }
  952. if (!Plane_Equal(&face->plane, &face->original->plane, false))
  953. {
  954. lastface = face;
  955. continue;
  956. }
  957. w = Winding_TryMerge(face->face_winding, face->original->face_winding, face->plane.normal, true);
  958. if (!w)
  959. {
  960. lastface = face;
  961. continue;
  962. }
  963. Winding_Free(face->original->face_winding);
  964. face->original->face_winding = w;
  965. //get texture crap right
  966. Face_SetColor(b, face->original, 1.0);
  967. for (j = 0; j < face->original->face_winding->numpoints; j++)
  968. EmitTextureCoordinates(face->original->face_winding->points[j], face->original->d_texture, face->original);
  969. //remove the face that was merged with the original
  970. if (lastface) lastface->next = face->next;
  971. else b->brush_faces = face->next;
  972. Face_Free(face);
  973. }
  974. return result;
  975. }
  976. /*
  977. =================
  978. Brush_MoveVertexes_old2
  979. - The input brush must be convex
  980. - The input brush must have face windings.
  981. - The output brush will be convex.
  982. - Returns true if the vertex movement is performed.
  983. =================
  984. */
  985. #define MAX_MOVE_FACES 64
  986. #define INTERSECT_EPSILON 0.1
  987. #define POINT_EPSILON 0.3
  988. int Brush_MoveVertex_old2(brush_t *b, vec3_t vertex, vec3_t delta, vec3_t end, bool bSnap)
  989. {
  990. face_t *f, *face, *newface, *lastface, *nextface;
  991. face_t *movefaces[MAX_MOVE_FACES];
  992. int movefacepoints[MAX_MOVE_FACES];
  993. winding_t *w, tmpw;
  994. int i, j, k, nummovefaces, result;
  995. float dot;
  996. result = true;
  997. //
  998. tmpw.numpoints = 3;
  999. tmpw.maxpoints = 3;
  1000. VectorAdd(vertex, delta, end);
  1001. //snap or not?
  1002. if (bSnap)
  1003. for (i = 0; i < 3; i++)
  1004. end[i] = floor(end[i] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
  1005. //chop off triangles from all brush faces that use the to be moved vertex
  1006. //store pointers to these chopped off triangles in movefaces[]
  1007. nummovefaces = 0;
  1008. for (face = b->brush_faces; face; face = face->next)
  1009. {
  1010. w = face->face_winding;
  1011. if (!w) continue;
  1012. for (i = 0; i < w->numpoints; i++)
  1013. {
  1014. if (Point_Equal(w->points[i], vertex, POINT_EPSILON))
  1015. {
  1016. if (face->face_winding->numpoints <= 3)
  1017. {
  1018. movefacepoints[nummovefaces] = i;
  1019. movefaces[nummovefaces++] = face;
  1020. break;
  1021. }
  1022. dot = DotProduct(end, face->plane.normal) - face->plane.dist;
  1023. //if the end point is in front of the face plane
  1024. if (dot > 0.1)
  1025. {
  1026. //fanout triangle subdivision
  1027. for (k = i; k < i + w->numpoints-3; k++)
  1028. {
  1029. VectorCopy(w->points[i], tmpw.points[0]);
  1030. VectorCopy(w->points[(k+1) % w->numpoints], tmpw.points[1]);
  1031. VectorCopy(w->points[(k+2) % w->numpoints], tmpw.points[2]);
  1032. //
  1033. newface = Face_Clone(face);
  1034. //get the original
  1035. for (f = face; f->original; f = f->original) ;
  1036. newface->original = f;
  1037. //store the new winding
  1038. if (newface->face_winding) Winding_Free(newface->face_winding);
  1039. newface->face_winding = Winding_Clone(&tmpw);
  1040. //get the texture
  1041. newface->d_texture = Texture_ForName( newface->texdef.name );
  1042. //add the face to the brush
  1043. newface->next = b->brush_faces;
  1044. b->brush_faces = newface;
  1045. //add this new triangle to the move faces
  1046. movefacepoints[nummovefaces] = 0;
  1047. movefaces[nummovefaces++] = newface;
  1048. }
  1049. //give the original face a new winding
  1050. VectorCopy(w->points[(i-2+w->numpoints) % w->numpoints], tmpw.points[0]);
  1051. VectorCopy(w->points[(i-1+w->numpoints) % w->numpoints], tmpw.points[1]);
  1052. VectorCopy(w->points[i], tmpw.points[2]);
  1053. Winding_Free(face->face_winding);
  1054. face->face_winding = Winding_Clone(&tmpw);
  1055. //add the original face to the move faces
  1056. movefacepoints[nummovefaces] = 2;
  1057. movefaces[nummovefaces++] = face;
  1058. }
  1059. else
  1060. {
  1061. //chop a triangle off the face
  1062. VectorCopy(w->points[(i-1+w->numpoints) % w->numpoints], tmpw.points[0]);
  1063. VectorCopy(w->points[i], tmpw.points[1]);
  1064. VectorCopy(w->points[(i+1) % w->numpoints], tmpw.points[2]);
  1065. //remove the point from the face winding
  1066. Winding_RemovePoint(w, i);
  1067. //get texture crap right
  1068. Face_SetColor(b, face, 1.0);
  1069. for (j = 0; j < w->numpoints; j++)
  1070. EmitTextureCoordinates(w->points[j], face->d_texture, face);
  1071. //make a triangle face
  1072. newface = Face_Clone(face);
  1073. //get the original
  1074. for (f = face; f->original; f = f->original) ;
  1075. newface->original = f;
  1076. //store the new winding
  1077. if (newface->face_winding) Winding_Free(newface->face_winding);
  1078. newface->face_winding = Winding_Clone(&tmpw);
  1079. //get the texture
  1080. newface->d_texture = Texture_ForName( newface->texdef.name );
  1081. //add the face to the brush
  1082. newface->next = b->brush_faces;
  1083. b->brush_faces = newface;
  1084. //
  1085. movefacepoints[nummovefaces] = 1;
  1086. movefaces[nummovefaces++] = newface;
  1087. }
  1088. break;
  1089. }
  1090. }
  1091. }
  1092. //now movefaces contains pointers to triangle faces that
  1093. //contain the to be moved vertex
  1094. //move the vertex
  1095. for (i = 0; i < nummovefaces; i++)
  1096. {
  1097. //move vertex to end position
  1098. VectorCopy(end, movefaces[i]->face_winding->points[movefacepoints[i]]);
  1099. //create new face plane
  1100. for (j = 0; j < 3; j++)
  1101. {
  1102. VectorCopy(movefaces[i]->face_winding->points[j], movefaces[i]->planepts[j]);
  1103. }
  1104. Face_MakePlane(movefaces[i]);
  1105. }
  1106. //if the brush is no longer convex
  1107. if (!Brush_Convex(b))
  1108. {
  1109. for (i = 0; i < nummovefaces; i++)
  1110. {
  1111. //move the vertex back to the initial position
  1112. VectorCopy(vertex, movefaces[i]->face_winding->points[movefacepoints[i]]);
  1113. //create new face plane
  1114. for (j = 0; j < 3; j++)
  1115. {
  1116. VectorCopy(movefaces[i]->face_winding->points[j], movefaces[i]->planepts[j]);
  1117. }
  1118. Face_MakePlane(movefaces[i]);
  1119. }
  1120. result = false;
  1121. }
  1122. //get texture crap right
  1123. for (i = 0; i < nummovefaces; i++)
  1124. {
  1125. Face_SetColor(b, movefaces[i], 1.0);
  1126. for (j = 0; j < movefaces[i]->face_winding->numpoints; j++)
  1127. EmitTextureCoordinates(movefaces[i]->face_winding->points[j], movefaces[i]->d_texture, movefaces[i]);
  1128. }
  1129. //now try to merge faces with their original faces
  1130. lastface = NULL;
  1131. for (face = b->brush_faces; face; face = nextface)
  1132. {
  1133. nextface = face->next;
  1134. if (!face->original)
  1135. {
  1136. lastface = face;
  1137. continue;
  1138. }
  1139. if (!Plane_Equal(&face->plane, &face->original->plane, false))
  1140. {
  1141. lastface = face;
  1142. continue;
  1143. }
  1144. w = Winding_TryMerge(face->face_winding, face->original->face_winding, face->plane.normal, true);
  1145. if (!w)
  1146. {
  1147. lastface = face;
  1148. continue;
  1149. }
  1150. Winding_Free(face->original->face_winding);
  1151. face->original->face_winding = w;
  1152. //get texture crap right
  1153. Face_SetColor(b, face->original, 1.0);
  1154. for (j = 0; j < face->original->face_winding->numpoints; j++)
  1155. EmitTextureCoordinates(face->original->face_winding->points[j], face->original->d_texture, face->original);
  1156. //remove the face that was merged with the original
  1157. if (lastface) lastface->next = face->next;
  1158. else b->brush_faces = face->next;
  1159. Face_Free(face);
  1160. }
  1161. return result;
  1162. }
  1163. /*
  1164. =================
  1165. Brush_MoveVertexes
  1166. - The input brush must be convex
  1167. - The input brush must have face windings.
  1168. - The output brush will be convex.
  1169. - Returns true if the WHOLE vertex movement is performed.
  1170. =================
  1171. */
  1172. #define MAX_MOVE_FACES 64
  1173. int Brush_MoveVertex(brush_t *b, vec3_t vertex, vec3_t delta, vec3_t end, bool bSnap)
  1174. {
  1175. face_t *f, *face, *newface, *lastface, *nextface;
  1176. face_t *movefaces[MAX_MOVE_FACES];
  1177. int movefacepoints[MAX_MOVE_FACES];
  1178. winding_t *w, tmpw;
  1179. vec3_t start, mid;
  1180. plane_t plane;
  1181. int i, j, k, nummovefaces, result, done;
  1182. float dot, front, back, frac, smallestfrac;
  1183. result = true;
  1184. //
  1185. tmpw.numpoints = 3;
  1186. tmpw.maxpoints = 3;
  1187. VectorCopy(vertex, start);
  1188. VectorAdd(vertex, delta, end);
  1189. //snap or not?
  1190. if (bSnap)
  1191. for (i = 0; i < 3; i++)
  1192. end[i] = floor(end[i] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
  1193. //
  1194. VectorCopy(end, mid);
  1195. //if the start and end are the same
  1196. if (Point_Equal(start, end, 0.3)) return false;
  1197. //the end point may not be the same as another vertex
  1198. for (face = b->brush_faces; face; face = face->next)
  1199. {
  1200. w = face->face_winding;
  1201. if (!w) continue;
  1202. for (i = 0; i < w->numpoints; i++)
  1203. {
  1204. if (Point_Equal(w->points[i], end, 0.3))
  1205. {
  1206. VectorCopy(vertex, end);
  1207. return false;
  1208. }
  1209. }
  1210. }
  1211. //
  1212. done = false;
  1213. while(!done)
  1214. {
  1215. //chop off triangles from all brush faces that use the to be moved vertex
  1216. //store pointers to these chopped off triangles in movefaces[]
  1217. nummovefaces = 0;
  1218. for (face = b->brush_faces; face; face = face->next)
  1219. {
  1220. w = face->face_winding;
  1221. if (!w) continue;
  1222. for (i = 0; i < w->numpoints; i++)
  1223. {
  1224. if (Point_Equal(w->points[i], start, 0.2))
  1225. {
  1226. if (face->face_winding->numpoints <= 3)
  1227. {
  1228. movefacepoints[nummovefaces] = i;
  1229. movefaces[nummovefaces++] = face;
  1230. break;
  1231. }
  1232. dot = DotProduct(end, face->plane.normal) - face->plane.dist;
  1233. //if the end point is in front of the face plane
  1234. if (dot > 0.1)
  1235. {
  1236. //fanout triangle subdivision
  1237. for (k = i; k < i + w->numpoints-3; k++)
  1238. {
  1239. VectorCopy(w->points[i], tmpw.points[0]);
  1240. VectorCopy(w->points[(k+1) % w->numpoints], tmpw.points[1]);
  1241. VectorCopy(w->points[(k+2) % w->numpoints], tmpw.points[2]);
  1242. //
  1243. newface = Face_Clone(face);
  1244. //get the original
  1245. for (f = face; f->original; f = f->original) ;
  1246. newface->original = f;
  1247. //store the new winding
  1248. if (newface->face_winding) Winding_Free(newface->face_winding);
  1249. newface->face_winding = Winding_Clone(&tmpw);
  1250. //get the texture
  1251. newface->d_texture = Texture_ForName( newface->texdef.name );
  1252. //add the face to the brush
  1253. newface->next = b->brush_faces;
  1254. b->brush_faces = newface;
  1255. //add this new triangle to the move faces
  1256. movefacepoints[nummovefaces] = 0;
  1257. movefaces[nummovefaces++] = newface;
  1258. }
  1259. //give the original face a new winding
  1260. VectorCopy(w->points[(i-2+w->numpoints) % w->numpoints], tmpw.points[0]);
  1261. VectorCopy(w->points[(i-1+w->numpoints) % w->numpoints], tmpw.points[1]);
  1262. VectorCopy(w->points[i], tmpw.points[2]);
  1263. Winding_Free(face->face_winding);
  1264. face->face_winding = Winding_Clone(&tmpw);
  1265. //add the original face to the move faces
  1266. movefacepoints[nummovefaces] = 2;
  1267. movefaces[nummovefaces++] = face;
  1268. }
  1269. else
  1270. {
  1271. //chop a triangle off the face
  1272. VectorCopy(w->points[(i-1+w->numpoints) % w->numpoints], tmpw.points[0]);
  1273. VectorCopy(w->points[i], tmpw.points[1]);
  1274. VectorCopy(w->points[(i+1) % w->numpoints], tmpw.points[2]);
  1275. //remove the point from the face winding
  1276. Winding_RemovePoint(w, i);
  1277. //get texture crap right
  1278. Face_SetColor(b, face, 1.0);
  1279. for (j = 0; j < w->numpoints; j++)
  1280. EmitTextureCoordinates(w->points[j], face->d_texture, face);
  1281. //make a triangle face
  1282. newface = Face_Clone(face);
  1283. //get the original
  1284. for (f = face; f->original; f = f->original) ;
  1285. newface->original = f;
  1286. //store the new winding
  1287. if (newface->face_winding) Winding_Free(newface->face_winding);
  1288. newface->face_winding = Winding_Clone(&tmpw);
  1289. //get the texture
  1290. newface->d_texture = Texture_ForName( newface->texdef.name );
  1291. //add the face to the brush
  1292. newface->next = b->brush_faces;
  1293. b->brush_faces = newface;
  1294. //
  1295. movefacepoints[nummovefaces] = 1;
  1296. movefaces[nummovefaces++] = newface;
  1297. }
  1298. break;
  1299. }
  1300. }
  1301. }
  1302. //now movefaces contains pointers to triangle faces that
  1303. //contain the to be moved vertex
  1304. //
  1305. done = true;
  1306. VectorCopy(end, mid);
  1307. smallestfrac = 1;
  1308. for (face = b->brush_faces; face; face = face->next)
  1309. {
  1310. //check if there is a move face that has this face as the original
  1311. for (i = 0; i < nummovefaces; i++)
  1312. {
  1313. if (movefaces[i]->original == face) break;
  1314. }
  1315. if (i >= nummovefaces) continue;
  1316. //check if the original is not a move face itself
  1317. for (j = 0; j < nummovefaces; j++)
  1318. {
  1319. if (face == movefaces[j]) break;
  1320. }
  1321. //if the original is not a move face itself
  1322. if (j >= nummovefaces)
  1323. {
  1324. memcpy(&plane, &movefaces[i]->original->plane, sizeof(plane_t));
  1325. }
  1326. else
  1327. {
  1328. k = movefacepoints[j];
  1329. w = movefaces[j]->face_winding;
  1330. VectorCopy(w->points[(k+1)%w->numpoints], tmpw.points[0]);
  1331. VectorCopy(w->points[(k+2)%w->numpoints], tmpw.points[1]);
  1332. //
  1333. k = movefacepoints[i];
  1334. w = movefaces[i]->face_winding;
  1335. VectorCopy(w->points[(k+1)%w->numpoints], tmpw.points[2]);
  1336. if (!Plane_FromPoints(tmpw.points[0], tmpw.points[1], tmpw.points[2], &plane))
  1337. {
  1338. VectorCopy(w->points[(k+2)%w->numpoints], tmpw.points[2]);
  1339. if (!Plane_FromPoints(tmpw.points[0], tmpw.points[1], tmpw.points[2], &plane))
  1340. //this should never happen otherwise the face merge did a crappy job a previous pass
  1341. continue;
  1342. }
  1343. }
  1344. //now we've got the plane to check agains
  1345. front = DotProduct(start, plane.normal) - plane.dist;
  1346. back = DotProduct(end, plane.normal) - plane.dist;
  1347. //if the whole move is at one side of the plane
  1348. if (front < 0.01 && back < 0.01) continue;
  1349. if (front > -0.01 && back > -0.01) continue;
  1350. //if there's no movement orthogonal to this plane at all
  1351. if (fabs(front-back) < 0.001) continue;
  1352. //ok first only move till the plane is hit
  1353. frac = front/(front-back);
  1354. if (frac < smallestfrac)
  1355. {
  1356. mid[0] = start[0] + (end[0] - start[0]) * frac;
  1357. mid[1] = start[1] + (end[1] - start[1]) * frac;
  1358. mid[2] = start[2] + (end[2] - start[2]) * frac;
  1359. smallestfrac = frac;
  1360. }
  1361. //
  1362. done = false;
  1363. }
  1364. //move the vertex
  1365. for (i = 0; i < nummovefaces; i++)
  1366. {
  1367. //move vertex to end position
  1368. VectorCopy(mid, movefaces[i]->face_winding->points[movefacepoints[i]]);
  1369. //create new face plane
  1370. for (j = 0; j < 3; j++)
  1371. {
  1372. VectorCopy(movefaces[i]->face_winding->points[j], movefaces[i]->planepts[j]);
  1373. }
  1374. Face_MakePlane(movefaces[i]);
  1375. if (VectorLength(movefaces[i]->plane.normal) < 0.1)
  1376. result = false;
  1377. }
  1378. //if the brush is no longer convex
  1379. if (!result || !Brush_Convex(b))
  1380. {
  1381. for (i = 0; i < nummovefaces; i++)
  1382. {
  1383. //move the vertex back to the initial position
  1384. VectorCopy(start, movefaces[i]->face_winding->points[movefacepoints[i]]);
  1385. //create new face plane
  1386. for (j = 0; j < 3; j++)
  1387. {
  1388. VectorCopy(movefaces[i]->face_winding->points[j], movefaces[i]->planepts[j]);
  1389. }
  1390. Face_MakePlane(movefaces[i]);
  1391. }
  1392. result = false;
  1393. VectorCopy(start, end);
  1394. done = true;
  1395. }
  1396. else
  1397. {
  1398. VectorCopy(mid, start);
  1399. }
  1400. //get texture crap right
  1401. for (i = 0; i < nummovefaces; i++)
  1402. {
  1403. Face_SetColor(b, movefaces[i], 1.0);
  1404. for (j = 0; j < movefaces[i]->face_winding->numpoints; j++)
  1405. EmitTextureCoordinates(movefaces[i]->face_winding->points[j], movefaces[i]->d_texture, movefaces[i]);
  1406. }
  1407. //now try to merge faces with their original faces
  1408. lastface = NULL;
  1409. for (face = b->brush_faces; face; face = nextface)
  1410. {
  1411. nextface = face->next;
  1412. if (!face->original)
  1413. {
  1414. lastface = face;
  1415. continue;
  1416. }
  1417. if (!Plane_Equal(&face->plane, &face->original->plane, false))
  1418. {
  1419. lastface = face;
  1420. continue;
  1421. }
  1422. w = Winding_TryMerge(face->face_winding, face->original->face_winding, face->plane.normal, true);
  1423. if (!w)
  1424. {
  1425. lastface = face;
  1426. continue;
  1427. }
  1428. Winding_Free(face->original->face_winding);
  1429. face->original->face_winding = w;
  1430. //get texture crap right
  1431. Face_SetColor(b, face->original, 1.0);
  1432. for (j = 0; j < face->original->face_winding->numpoints; j++)
  1433. EmitTextureCoordinates(face->original->face_winding->points[j], face->original->d_texture, face->original);
  1434. //remove the face that was merged with the original
  1435. if (lastface) lastface->next = face->next;
  1436. else b->brush_faces = face->next;
  1437. Face_Free(face);
  1438. }
  1439. }
  1440. return result;
  1441. }
  1442. /*
  1443. =================
  1444. Brush_InsertVertexBetween
  1445. =================
  1446. */
  1447. int Brush_InsertVertexBetween(brush_t *b, vec3_t p1, vec3_t p2)
  1448. {
  1449. face_t *face;
  1450. winding_t *w, *neww;
  1451. vec3_t point;
  1452. int i, insert;
  1453. if (Point_Equal(p1, p2, 0.4))
  1454. return false;
  1455. VectorAdd(p1, p2, point);
  1456. VectorScale(point, 0.5, point);
  1457. insert = false;
  1458. //the end point may not be the same as another vertex
  1459. for (face = b->brush_faces; face; face = face->next)
  1460. {
  1461. w = face->face_winding;
  1462. if (!w) continue;
  1463. neww = NULL;
  1464. for (i = 0; i < w->numpoints; i++)
  1465. {
  1466. if (!Point_Equal(w->points[i], p1, 0.1))
  1467. continue;
  1468. if (Point_Equal(w->points[(i+1) % w->numpoints], p2, 0.1))
  1469. {
  1470. neww = Winding_InsertPoint(w, point, (i+1) % w->numpoints);
  1471. break;
  1472. }
  1473. else if (Point_Equal(w->points[(i-1+w->numpoints) % w->numpoints], p2, 0.3))
  1474. {
  1475. neww = Winding_InsertPoint(w, point, i);
  1476. break;
  1477. }
  1478. }
  1479. if (neww)
  1480. {
  1481. Winding_Free(face->face_winding);
  1482. face->face_winding = neww;
  1483. insert = true;
  1484. }
  1485. }
  1486. return insert;
  1487. }
  1488. /*
  1489. =================
  1490. Brush_ResetFaceOriginals
  1491. =================
  1492. */
  1493. void Brush_ResetFaceOriginals(brush_t *b)
  1494. {
  1495. face_t *face;
  1496. for (face = b->brush_faces; face; face = face->next)
  1497. {
  1498. face->original = NULL;
  1499. }
  1500. }
  1501. /*
  1502. =================
  1503. Brush_Parse
  1504. The brush is NOT linked to any list
  1505. =================
  1506. */
  1507. //++timo FIXME: when using old brush primitives, the test loop for "Brush" and "patchDef2" "patchDef3" is ran
  1508. // before each face parsing. It works, but it's a performance hit
  1509. brush_t *Brush_Parse (void)
  1510. {
  1511. brush_t *b;
  1512. face_t *f;
  1513. int i,j;
  1514. g_qeglobals.d_parsed_brushes++;
  1515. b = Brush_Alloc();
  1516. do
  1517. {
  1518. if (!GetToken (true))
  1519. break;
  1520. if (!strcmp (token, "}") )
  1521. break;
  1522. // handle "Brush" primitive
  1523. if (strcmpi(token, "brushDef") == 0)
  1524. {
  1525. // Timo parsing new brush format
  1526. g_qeglobals.bPrimitBrushes=true;
  1527. // check the map is not mixing the two kinds of brushes
  1528. if (g_qeglobals.m_bBrushPrimitMode)
  1529. {
  1530. if (g_qeglobals.bOldBrushes)
  1531. Sys_Printf("Warning : old brushes and brush primitive in the same file are not allowed ( Brush_Parse )\n");
  1532. }
  1533. //++Timo write new brush primitive -> old conversion code for Q3->Q2 conversions ?
  1534. else
  1535. Sys_Printf("Warning : conversion code from brush primitive not done ( Brush_Parse )\n");
  1536. BrushPrimit_Parse(b);
  1537. if (b == NULL)
  1538. {
  1539. Warning ("parsing brush primitive");
  1540. return NULL;
  1541. }
  1542. else
  1543. {
  1544. continue;
  1545. }
  1546. }
  1547. if ( strcmpi( token, "terrainDef" ) == 0 )
  1548. {
  1549. free (b);
  1550. b = Terrain_Parse();
  1551. if (b == NULL)
  1552. {
  1553. Warning ("parsing terrain/brush");
  1554. return NULL;
  1555. }
  1556. else
  1557. {
  1558. continue;
  1559. }
  1560. }
  1561. if (strcmpi(token, "patchDef2") == 0 || strcmpi(token, "patchDef3") == 0)
  1562. {
  1563. free (b);
  1564. // double string compare but will go away soon
  1565. b = Patch_Parse(strcmpi(token, "patchDef2") == 0);
  1566. if (b == NULL)
  1567. {
  1568. Warning ("parsing patch/brush");
  1569. return NULL;
  1570. }
  1571. else
  1572. {
  1573. continue;
  1574. }
  1575. // handle inline patch
  1576. }
  1577. else
  1578. {
  1579. // Timo parsing old brush format
  1580. g_qeglobals.bOldBrushes=true;
  1581. if (g_qeglobals.m_bBrushPrimitMode)
  1582. {
  1583. // check the map is not mixing the two kinds of brushes
  1584. if (g_qeglobals.bPrimitBrushes)
  1585. Sys_Printf("Warning : old brushes and brush primitive in the same file are not allowed ( Brush_Parse )\n");
  1586. // set the "need" conversion flag
  1587. g_qeglobals.bNeedConvert=true;
  1588. }
  1589. f = Face_Alloc();
  1590. // add the brush to the end of the chain, so
  1591. // loading and saving a map doesn't reverse the order
  1592. f->next = NULL;
  1593. if (!b->brush_faces)
  1594. {
  1595. b->brush_faces = f;
  1596. }
  1597. else
  1598. {
  1599. face_t *scan;
  1600. for (scan=b->brush_faces ; scan->next ; scan=scan->next)
  1601. ;
  1602. scan->next = f;
  1603. }
  1604. // read the three point plane definition
  1605. for (i=0 ; i<3 ; i++)
  1606. {
  1607. if (i != 0)
  1608. GetToken (true);
  1609. if (strcmp (token, "(") )
  1610. {
  1611. Warning ("parsing brush");
  1612. return NULL;
  1613. }
  1614. for (j=0 ; j<3 ; j++)
  1615. {
  1616. GetToken (false);
  1617. f->planepts[i][j] = atof(token);
  1618. }
  1619. GetToken (false);
  1620. if (strcmp (token, ")") )
  1621. {
  1622. Warning ("parsing brush");
  1623. return NULL;
  1624. }
  1625. }
  1626. }
  1627. // Timo
  1628. // if we have a surface plugin, we'll call the plugin parsing
  1629. if (g_qeglobals.bSurfacePropertiesPlugin)
  1630. {
  1631. GETPLUGINTEXDEF(f)->ParseTexdef();
  1632. }
  1633. else
  1634. {
  1635. // read the texturedef
  1636. GetToken (false);
  1637. f->texdef.SetName(token);
  1638. if (token[0] == '(')
  1639. {
  1640. int i = 32;
  1641. }
  1642. GetToken (false);
  1643. f->texdef.shift[0] = atoi(token);
  1644. GetToken (false);
  1645. f->texdef.shift[1] = atoi(token);
  1646. GetToken (false);
  1647. f->texdef.rotate = atoi(token);
  1648. GetToken (false);
  1649. f->texdef.scale[0] = atof(token);
  1650. GetToken (false);
  1651. f->texdef.scale[1] = atof(token);
  1652. // the flags and value field aren't necessarily present
  1653. f->d_texture = Texture_ForName( f->texdef.name );
  1654. f->texdef.flags = f->d_texture->flags;
  1655. f->texdef.value = f->d_texture->value;
  1656. f->texdef.contents = f->d_texture->contents;
  1657. if (TokenAvailable ())
  1658. {
  1659. GetToken (false);
  1660. f->texdef.contents = atoi(token);
  1661. GetToken (false);
  1662. f->texdef.flags = atoi(token);
  1663. GetToken (false);
  1664. f->texdef.value = atoi(token);
  1665. }
  1666. }
  1667. } while (1);
  1668. return b;
  1669. }
  1670. /*
  1671. =================
  1672. QERApp_MapPrintf_FILE
  1673. callback for surface properties plugin
  1674. must fit a PFN_QERAPP_MAPPRINTF ( see isurfaceplugin.h )
  1675. =================
  1676. */
  1677. // carefully initialize !
  1678. FILE * g_File;
  1679. void WINAPI QERApp_MapPrintf_FILE( char *text, ... )
  1680. {
  1681. va_list argptr;
  1682. char buf[32768];
  1683. va_start (argptr,text);
  1684. vsprintf (buf, text,argptr);
  1685. va_end (argptr);
  1686. fprintf( g_File, buf );
  1687. }
  1688. /*
  1689. ==============
  1690. Brush_SetEpair
  1691. sets an epair for the given brush
  1692. ==============
  1693. */
  1694. void Brush_SetEpair(brush_t *b, const char *pKey, const char *pValue)
  1695. {
  1696. if (g_qeglobals.m_bBrushPrimitMode)
  1697. {
  1698. if (b->patchBrush)
  1699. {
  1700. Patch_SetEpair(b->pPatch, pKey, pValue);
  1701. }
  1702. else if (b->terrainBrush)
  1703. {
  1704. Terrain_SetEpair(b->pTerrain, pKey, pValue);
  1705. }
  1706. else
  1707. {
  1708. SetKeyValue(b->epairs, pKey, pValue);
  1709. }
  1710. }
  1711. else
  1712. {
  1713. Sys_Printf("Can only set key/values in Brush primitive mode\n");
  1714. }
  1715. }
  1716. /*
  1717. =================
  1718. Brush_GetKeyValue
  1719. =================
  1720. */
  1721. const char* Brush_GetKeyValue(brush_t *b, const char *pKey)
  1722. {
  1723. if (g_qeglobals.m_bBrushPrimitMode)
  1724. {
  1725. if (b->patchBrush)
  1726. {
  1727. return Patch_GetKeyValue(b->pPatch, pKey);
  1728. }
  1729. else if (b->terrainBrush)
  1730. {
  1731. return Terrain_GetKeyValue(b->pTerrain, pKey);
  1732. }
  1733. else
  1734. {
  1735. return ValueForKey(b->epairs, pKey);
  1736. }
  1737. }
  1738. else
  1739. {
  1740. Sys_Printf("Can only set brush/patch key/values in Brush primitive mode\n");
  1741. }
  1742. return "";
  1743. }
  1744. /*
  1745. =================
  1746. Brush_Write
  1747. save all brushes as Brush primitive format
  1748. =================
  1749. */
  1750. void Brush_Write (brush_t *b, FILE *f)
  1751. {
  1752. epair_t *ep;
  1753. face_t *fa;
  1754. char *pname;
  1755. int i;
  1756. if (b->patchBrush)
  1757. {
  1758. Patch_Write(b->pPatch, f);
  1759. return;
  1760. }
  1761. if ( b->pTerrain )
  1762. {
  1763. Terrain_Write(b->pTerrain, f);
  1764. return;
  1765. }
  1766. if (g_qeglobals.m_bBrushPrimitMode)
  1767. {
  1768. // save brush primitive format
  1769. fprintf (f, "{\nbrushDef\n{\n");
  1770. // brush epairs
  1771. if (b->epairs)
  1772. for (ep = b->epairs ; ep ; ep=ep->next)
  1773. fprintf (f, "\"%s\" \"%s\"\n", ep->key, ep->value);
  1774. for (fa=b->brush_faces ; fa ; fa=fa->next)
  1775. {
  1776. // save planepts
  1777. for (i=0 ; i<3 ; i++)
  1778. {
  1779. fprintf(f, "( ");
  1780. for (int j = 0; j < 3; j++)
  1781. if (fa->planepts[i][j] == static_cast<int>(fa->planepts[i][j]))
  1782. fprintf(f, "%i ", static_cast<int>(fa->planepts[i][j]));
  1783. else
  1784. fprintf(f, "%f ", fa->planepts[i][j]);
  1785. fprintf(f, ") ");
  1786. }
  1787. // save texture coordinates
  1788. fprintf(f,"( ( ");
  1789. for (i=0 ; i<3 ; i++)
  1790. if (fa->brushprimit_texdef.coords[0][i] == static_cast<int>(fa->brushprimit_texdef.coords[0][i]))
  1791. fprintf(f,"%i ",static_cast<int>(fa->brushprimit_texdef.coords[0][i]));
  1792. else
  1793. fprintf(f,"%f ",fa->brushprimit_texdef.coords[0][i]);
  1794. fprintf(f,") ( ");
  1795. for (i=0 ; i<3 ; i++)
  1796. if (fa->brushprimit_texdef.coords[1][i] == static_cast<int>(fa->brushprimit_texdef.coords[1][i]))
  1797. fprintf(f,"%i ",static_cast<int>(fa->brushprimit_texdef.coords[1][i]));
  1798. else
  1799. fprintf(f,"%f ",fa->brushprimit_texdef.coords[1][i]);
  1800. fprintf(f,") ) ");
  1801. // save texture attribs
  1802. //++timo surface properties plugin not implemented for brush primitives
  1803. if (g_qeglobals.bSurfacePropertiesPlugin)
  1804. Sys_Printf("WARNING: surface properties plugin not supported with brush primitives (yet)\n");
  1805. char *pName = strlen(fa->texdef.name) > 0 ? fa->texdef.name : "unnamed";
  1806. fprintf(f, "%s ", pName );
  1807. fprintf(f, "%i %i %i\n", fa->texdef.contents, fa->texdef.flags, fa->texdef.value);
  1808. }
  1809. fprintf (f, "}\n}\n");
  1810. }
  1811. else
  1812. {
  1813. fprintf (f, "{\n");
  1814. for (fa=b->brush_faces ; fa ; fa=fa->next)
  1815. {
  1816. for (i=0 ; i<3 ; i++)
  1817. {
  1818. fprintf(f, "( ");
  1819. for (int j = 0; j < 3; j++)
  1820. {
  1821. if (fa->planepts[i][j] == static_cast<int>(fa->planepts[i][j]))
  1822. fprintf(f, "%i ", static_cast<int>(fa->planepts[i][j]));
  1823. else
  1824. fprintf(f, "%f ", fa->planepts[i][j]);
  1825. }
  1826. fprintf(f, ") ");
  1827. }
  1828. if (g_qeglobals.bSurfacePropertiesPlugin)
  1829. {
  1830. g_File = f;
  1831. #ifdef _DEBUG
  1832. if (!fa->pData)
  1833. Sys_Printf("ERROR: unexpected IPluginTexdef* is NULL in Brush_Write\n");
  1834. else
  1835. #endif
  1836. GETPLUGINTEXDEF(fa)->WriteTexdef( QERApp_MapPrintf_FILE );
  1837. }
  1838. else
  1839. {
  1840. pname = fa->texdef.name;
  1841. if (pname[0] == 0)
  1842. pname = "unnamed";
  1843. fprintf (f, "%s %i %i %i ", pname,
  1844. (int)fa->texdef.shift[0], (int)fa->texdef.shift[1],
  1845. (int)fa->texdef.rotate);
  1846. if (fa->texdef.scale[0] == (int)fa->texdef.scale[0])
  1847. fprintf (f, "%i ", (int)fa->texdef.scale[0]);
  1848. else
  1849. fprintf (f, "%f ", (float)fa->texdef.scale[0]);
  1850. if (fa->texdef.scale[1] == (int)fa->texdef.scale[1])
  1851. fprintf (f, "%i", (int)fa->texdef.scale[1]);
  1852. else
  1853. fprintf (f, "%f", (float)fa->texdef.scale[1]);
  1854. fprintf (f, " %i %i %i", fa->texdef.contents, fa->texdef.flags, fa->texdef.value);
  1855. }
  1856. fprintf (f, "\n");
  1857. }
  1858. fprintf (f, "}\n");
  1859. }
  1860. }
  1861. /*
  1862. =================
  1863. QERApp_MapPrintf_MEMFILE
  1864. callback for surface properties plugin
  1865. must fit a PFN_QERAPP_MAPPRINTF ( see isurfaceplugin.h )
  1866. =================
  1867. */
  1868. // carefully initialize !
  1869. CMemFile * g_pMemFile;
  1870. void WINAPI QERApp_MapPrintf_MEMFILE( char *text, ... )
  1871. {
  1872. va_list argptr;
  1873. char buf[32768];
  1874. va_start (argptr,text);
  1875. vsprintf (buf, text,argptr);
  1876. va_end (argptr);
  1877. MemFile_fprintf( g_pMemFile, buf );
  1878. }
  1879. /*
  1880. =================
  1881. Brush_Write to a CMemFile*
  1882. save all brushes as Brush primitive format
  1883. =================
  1884. */
  1885. void Brush_Write (brush_t *b, CMemFile *pMemFile)
  1886. {
  1887. epair_t *ep;
  1888. face_t *fa;
  1889. char *pname;
  1890. int i;
  1891. if (b->patchBrush)
  1892. {
  1893. Patch_Write(b->pPatch, pMemFile);
  1894. return;
  1895. }
  1896. if (b->terrainBrush)
  1897. {
  1898. Terrain_Write(b->pTerrain, pMemFile);
  1899. return;
  1900. }
  1901. //++timo NOTE: it's not very difficult to add since the surface properties plugin
  1902. // writes throught a printf-style function prototype
  1903. if (g_qeglobals.bSurfacePropertiesPlugin)
  1904. {
  1905. Sys_Printf("WARNING: Brush_Write to a CMemFile and Surface Properties plugin not done\n");
  1906. }
  1907. if (g_qeglobals.m_bBrushPrimitMode)
  1908. {
  1909. // brush primitive format
  1910. MemFile_fprintf (pMemFile, "{\nBrushDef\n{\n");
  1911. // brush epairs
  1912. if (b->epairs)
  1913. for( ep = b->epairs ; ep ; ep=ep->next )
  1914. MemFile_fprintf (pMemFile, "\"%s\" \"%s\"\n", ep->key, ep->value );
  1915. for (fa=b->brush_faces ; fa ; fa=fa->next)
  1916. {
  1917. // save planepts
  1918. for (i=0 ; i<3 ; i++)
  1919. {
  1920. MemFile_fprintf(pMemFile, "( ");
  1921. for (int j = 0; j < 3; j++)
  1922. if (fa->planepts[i][j] == static_cast<int>(fa->planepts[i][j]))
  1923. MemFile_fprintf(pMemFile, "%i ", static_cast<int>(fa->planepts[i][j]));
  1924. else
  1925. MemFile_fprintf(pMemFile, "%f ", fa->planepts[i][j]);
  1926. MemFile_fprintf(pMemFile, ") ");
  1927. }
  1928. // save texture coordinates
  1929. MemFile_fprintf(pMemFile,"( ( ");
  1930. for (i=0 ; i<3 ; i++)
  1931. if (fa->brushprimit_texdef.coords[0][i] == static_cast<int>(fa->brushprimit_texdef.coords[0][i]))
  1932. MemFile_fprintf(pMemFile,"%i ",static_cast<int>(fa->brushprimit_texdef.coords[0][i]));
  1933. else
  1934. MemFile_fprintf(pMemFile,"%f ",fa->brushprimit_texdef.coords[0][i]);
  1935. MemFile_fprintf(pMemFile,") ( ");
  1936. for (i=0 ; i<3 ; i++)
  1937. if (fa->brushprimit_texdef.coords[1][i] == static_cast<int>(fa->brushprimit_texdef.coords[1][i]))
  1938. MemFile_fprintf(pMemFile,"%i ",static_cast<int>(fa->brushprimit_texdef.coords[1][i]));
  1939. else
  1940. MemFile_fprintf(pMemFile,"%f ",fa->brushprimit_texdef.coords[1][i]);
  1941. MemFile_fprintf(pMemFile,") ) ");
  1942. // save texture attribs
  1943. char *pName = strlen(fa->texdef.name) > 0 ? fa->texdef.name : "unnamed";
  1944. MemFile_fprintf(pMemFile, "%s ", pName);
  1945. MemFile_fprintf(pMemFile, "%i %i %i\n", fa->texdef.contents, fa->texdef.flags, fa->texdef.value);
  1946. }
  1947. MemFile_fprintf (pMemFile, "}\n}\n");
  1948. }
  1949. else
  1950. {
  1951. // old brushes format
  1952. // also handle surface properties plugin
  1953. MemFile_fprintf (pMemFile, "{\n");
  1954. for (fa=b->brush_faces ; fa ; fa=fa->next)
  1955. {
  1956. for (i=0 ; i<3 ; i++)
  1957. {
  1958. MemFile_fprintf(pMemFile, "( ");
  1959. for (int j = 0; j < 3; j++)
  1960. {
  1961. if (fa->planepts[i][j] == static_cast<int>(fa->planepts[i][j]))
  1962. MemFile_fprintf(pMemFile, "%i ", static_cast<int>(fa->planepts[i][j]));
  1963. else
  1964. MemFile_fprintf(pMemFile, "%f ", fa->planepts[i][j]);
  1965. }
  1966. MemFile_fprintf(pMemFile, ") ");
  1967. }
  1968. if (g_qeglobals.bSurfacePropertiesPlugin)
  1969. {
  1970. g_pMemFile = pMemFile;
  1971. #ifdef _DEBUG
  1972. if (!fa->pData)
  1973. Sys_Printf("ERROR: unexpected IPluginTexdef* is NULL in Brush_Write\n");
  1974. else
  1975. #endif
  1976. GETPLUGINTEXDEF(fa)->WriteTexdef( QERApp_MapPrintf_MEMFILE );
  1977. }
  1978. else
  1979. {
  1980. pname = fa->texdef.name;
  1981. if (pname[0] == 0)
  1982. pname = "unnamed";
  1983. MemFile_fprintf (pMemFile, "%s %i %i %i ", pname,
  1984. (int)fa->texdef.shift[0], (int)fa->texdef.shift[1],
  1985. (int)fa->texdef.rotate);
  1986. if (fa->texdef.scale[0] == (int)fa->texdef.scale[0])
  1987. MemFile_fprintf (pMemFile, "%i ", (int)fa->texdef.scale[0]);
  1988. else
  1989. MemFile_fprintf (pMemFile, "%f ", (float)fa->texdef.scale[0]);
  1990. if (fa->texdef.scale[1] == (int)fa->texdef.scale[1])
  1991. MemFile_fprintf (pMemFile, "%i", (int)fa->texdef.scale[1]);
  1992. else
  1993. MemFile_fprintf (pMemFile, "%f", (float)fa->texdef.scale[1]);
  1994. MemFile_fprintf (pMemFile, " %i %i %i", fa->texdef.contents, fa->texdef.flags, fa->texdef.value);
  1995. }
  1996. MemFile_fprintf (pMemFile, "\n");
  1997. }
  1998. MemFile_fprintf (pMemFile, "}\n");
  1999. }
  2000. }
  2001. /*
  2002. =============
  2003. Brush_Create
  2004. Create non-textured blocks for entities
  2005. The brush is NOT linked to any list
  2006. =============
  2007. */
  2008. brush_t *Brush_Create (vec3_t mins, vec3_t maxs, texdef_t *texdef)
  2009. {
  2010. int i, j;
  2011. vec3_t pts[4][2];
  2012. face_t *f;
  2013. brush_t *b;
  2014. // brush primitive mode : convert texdef to brushprimit_texdef ?
  2015. // most of the time texdef is empty
  2016. if (g_qeglobals.m_bBrushPrimitMode)
  2017. {
  2018. // check texdef is empty .. if there are cases it's not we need to write some conversion code
  2019. if (texdef->shift[0]!=0 || texdef->shift[1]!=0 || texdef->scale[0]!=0 || texdef->scale[1]!=0 || texdef->rotate!=0)
  2020. Sys_Printf("Warning : non-zero texdef detected in Brush_Create .. need brush primitive conversion\n");
  2021. }
  2022. for (i=0 ; i<3 ; i++)
  2023. {
  2024. if (maxs[i] < mins[i])
  2025. Error ("Brush_InitSolid: backwards");
  2026. }
  2027. b = Brush_Alloc();
  2028. pts[0][0][0] = mins[0];
  2029. pts[0][0][1] = mins[1];
  2030. pts[1][0][0] = mins[0];
  2031. pts[1][0][1] = maxs[1];
  2032. pts[2][0][0] = maxs[0];
  2033. pts[2][0][1] = maxs[1];
  2034. pts[3][0][0] = maxs[0];
  2035. pts[3][0][1] = mins[1];
  2036. for (i=0 ; i<4 ; i++)
  2037. {
  2038. pts[i][0][2] = mins[2];
  2039. pts[i][1][0] = pts[i][0][0];
  2040. pts[i][1][1] = pts[i][0][1];
  2041. pts[i][1][2] = maxs[2];
  2042. }
  2043. for (i=0 ; i<4 ; i++)
  2044. {
  2045. f = Face_Alloc();
  2046. f->texdef = *texdef;
  2047. f->texdef.flags &= ~SURF_KEEP;
  2048. f->texdef.contents &= ~CONTENTS_KEEP;
  2049. f->next = b->brush_faces;
  2050. b->brush_faces = f;
  2051. j = (i+1)%4;
  2052. VectorCopy (pts[j][1], f->planepts[0]);
  2053. VectorCopy (pts[i][1], f->planepts[1]);
  2054. VectorCopy (pts[i][0], f->planepts[2]);
  2055. }
  2056. f = Face_Alloc();
  2057. f->texdef = *texdef;
  2058. f->texdef.flags &= ~SURF_KEEP;
  2059. f->texdef.contents &= ~CONTENTS_KEEP;
  2060. f->next = b->brush_faces;
  2061. b->brush_faces = f;
  2062. VectorCopy (pts[0][1], f->planepts[0]);
  2063. VectorCopy (pts[1][1], f->planepts[1]);
  2064. VectorCopy (pts[2][1], f->planepts[2]);
  2065. f = Face_Alloc();
  2066. f->texdef = *texdef;
  2067. f->texdef.flags &= ~SURF_KEEP;
  2068. f->texdef.contents &= ~CONTENTS_KEEP;
  2069. f->next = b->brush_faces;
  2070. b->brush_faces = f;
  2071. VectorCopy (pts[2][0], f->planepts[0]);
  2072. VectorCopy (pts[1][0], f->planepts[1]);
  2073. VectorCopy (pts[0][0], f->planepts[2]);
  2074. return b;
  2075. }
  2076. /*
  2077. =============
  2078. Brush_CreatePyramid
  2079. Create non-textured pyramid for light entities
  2080. The brush is NOT linked to any list
  2081. =============
  2082. */
  2083. brush_t *Brush_CreatePyramid (vec3_t mins, vec3_t maxs, texdef_t *texdef)
  2084. {
  2085. //++timo handle new brush primitive ? return here ??
  2086. return Brush_Create(mins, maxs, texdef);
  2087. for (int i=0 ; i<3 ; i++)
  2088. if (maxs[i] < mins[i])
  2089. Error ("Brush_InitSolid: backwards");
  2090. brush_t* b = Brush_Alloc();
  2091. vec3_t corners[4];
  2092. float fMid = Q_rint(mins[2] + (Q_rint((maxs[2] - mins[2]) / 2)));
  2093. corners[0][0] = mins[0];
  2094. corners[0][1] = mins[1];
  2095. corners[0][2] = fMid;
  2096. corners[1][0] = mins[0];
  2097. corners[1][1] = maxs[1];
  2098. corners[1][2] = fMid;
  2099. corners[2][0] = maxs[0];
  2100. corners[2][1] = maxs[1];
  2101. corners[2][2] = fMid;
  2102. corners[3][0] = maxs[0];
  2103. corners[3][1] = mins[1];
  2104. corners[3][2] = fMid;
  2105. vec3_t top, bottom;
  2106. top[0] = Q_rint(mins[0] + ((maxs[0] - mins[0]) / 2));
  2107. top[1] = Q_rint(mins[1] + ((maxs[1] - mins[1]) / 2));
  2108. top[2] = Q_rint(maxs[2]);
  2109. VectorCopy(top, bottom);
  2110. bottom[2] = mins[2];
  2111. // sides
  2112. for (i = 0; i < 4; i++)
  2113. {
  2114. face_t* f = Face_Alloc();
  2115. f->texdef = *texdef;
  2116. f->texdef.flags &= ~SURF_KEEP;
  2117. f->texdef.contents &= ~CONTENTS_KEEP;
  2118. f->next = b->brush_faces;
  2119. b->brush_faces = f;
  2120. int j = (i+1)%4;
  2121. VectorCopy (top, f->planepts[0]);
  2122. VectorCopy (corners[i], f->planepts[1]);
  2123. VectorCopy(corners[j], f->planepts[2]);
  2124. f = Face_Alloc();
  2125. f->texdef = *texdef;
  2126. f->texdef.flags &= ~SURF_KEEP;
  2127. f->texdef.contents &= ~CONTENTS_KEEP;
  2128. f->next = b->brush_faces;
  2129. b->brush_faces = f;
  2130. VectorCopy (bottom, f->planepts[2]);
  2131. VectorCopy (corners[i], f->planepts[1]);
  2132. VectorCopy(corners[j], f->planepts[0]);
  2133. }
  2134. return b;
  2135. }
  2136. /*
  2137. =============
  2138. Brush_MakeSided
  2139. Makes the current brush have the given number of 2d sides
  2140. =============
  2141. */
  2142. void Brush_MakeSided (int sides)
  2143. {
  2144. int i, axis;
  2145. vec3_t mins, maxs;
  2146. brush_t *b;
  2147. texdef_t *texdef;
  2148. face_t *f;
  2149. vec3_t mid;
  2150. float width;
  2151. float sv, cv;
  2152. if (sides < 3)
  2153. {
  2154. Sys_Status ("Bad sides number", 0);
  2155. return;
  2156. }
  2157. if (sides >= MAX_POINTS_ON_WINDING-4)
  2158. {
  2159. Sys_Printf("too many sides.\n");
  2160. return;
  2161. }
  2162. if (!QE_SingleBrush ())
  2163. {
  2164. Sys_Status ("Must have a single brush selected", 0 );
  2165. return;
  2166. }
  2167. b = selected_brushes.next;
  2168. VectorCopy (b->mins, mins);
  2169. VectorCopy (b->maxs, maxs);
  2170. texdef = &g_qeglobals.d_texturewin.texdef;
  2171. Brush_Free (b);
  2172. if (g_pParentWnd->ActiveXY())
  2173. {
  2174. switch(g_pParentWnd->ActiveXY()->GetViewType())
  2175. {
  2176. case XY: axis = 2; break;
  2177. case XZ: axis = 1; break;
  2178. case YZ: axis = 0; break;
  2179. }
  2180. }
  2181. else
  2182. {
  2183. axis = 2;
  2184. }
  2185. // find center of brush
  2186. width = 8;
  2187. for (i = 0; i < 3; i++)
  2188. {
  2189. mid[i] = (maxs[i] + mins[i]) * 0.5;
  2190. if (i == axis) continue;
  2191. if ((maxs[i] - mins[i]) * 0.5 > width)
  2192. width = (maxs[i] - mins[i]) * 0.5;
  2193. }
  2194. b = Brush_Alloc();
  2195. // create top face
  2196. f = Face_Alloc();
  2197. f->texdef = *texdef;
  2198. f->next = b->brush_faces;
  2199. b->brush_faces = f;
  2200. f->planepts[2][(axis+1)%3] = mins[(axis+1)%3]; f->planepts[2][(axis+2)%3] = mins[(axis+2)%3]; f->planepts[2][axis] = maxs[axis];
  2201. f->planepts[1][(axis+1)%3] = maxs[(axis+1)%3]; f->planepts[1][(axis+2)%3] = mins[(axis+2)%3]; f->planepts[1][axis] = maxs[axis];
  2202. f->planepts[0][(axis+1)%3] = maxs[(axis+1)%3]; f->planepts[0][(axis+2)%3] = maxs[(axis+2)%3]; f->planepts[0][axis] = maxs[axis];
  2203. // create bottom face
  2204. f = Face_Alloc();
  2205. f->texdef = *texdef;
  2206. f->next = b->brush_faces;
  2207. b->brush_faces = f;
  2208. f->planepts[0][(axis+1)%3] = mins[(axis+1)%3]; f->planepts[0][(axis+2)%3] = mins[(axis+2)%3]; f->planepts[0][axis] = mins[axis];
  2209. f->planepts[1][(axis+1)%3] = maxs[(axis+1)%3]; f->planepts[1][(axis+2)%3] = mins[(axis+2)%3]; f->planepts[1][axis] = mins[axis];
  2210. f->planepts[2][(axis+1)%3] = maxs[(axis+1)%3]; f->planepts[2][(axis+2)%3] = maxs[(axis+2)%3]; f->planepts[2][axis] = mins[axis];
  2211. for (i=0 ; i<sides ; i++)
  2212. {
  2213. f = Face_Alloc();
  2214. f->texdef = *texdef;
  2215. f->next = b->brush_faces;
  2216. b->brush_faces = f;
  2217. sv = sin (i*3.14159265*2/sides);
  2218. cv = cos (i*3.14159265*2/sides);
  2219. f->planepts[0][(axis+1)%3] = floor(mid[(axis+1)%3]+width*cv+0.5);
  2220. f->planepts[0][(axis+2)%3] = floor(mid[(axis+2)%3]+width*sv+0.5);
  2221. f->planepts[0][axis] = mins[axis];
  2222. f->planepts[1][(axis+1)%3] = f->planepts[0][(axis+1)%3];
  2223. f->planepts[1][(axis+2)%3] = f->planepts[0][(axis+2)%3];
  2224. f->planepts[1][axis] = maxs[axis];
  2225. f->planepts[2][(axis+1)%3] = floor(f->planepts[0][(axis+1)%3] - width*sv + 0.5);
  2226. f->planepts[2][(axis+2)%3] = floor(f->planepts[0][(axis+2)%3] + width*cv + 0.5);
  2227. f->planepts[2][axis] = maxs[axis];
  2228. }
  2229. Brush_AddToList (b, &selected_brushes);
  2230. Entity_LinkBrush (world_entity, b);
  2231. Brush_Build( b );
  2232. Sys_UpdateWindows (W_ALL);
  2233. }
  2234. /*
  2235. =============
  2236. Brush_Free
  2237. Frees the brush with all of its faces and display list.
  2238. Unlinks the brush from whichever chain it is in.
  2239. Decrements the owner entity's brushcount.
  2240. Removes owner entity if this was the last brush
  2241. unless owner is the world.
  2242. Removes from groups
  2243. =============
  2244. */
  2245. void Brush_Free (brush_t *b, bool bRemoveNode)
  2246. {
  2247. face_t *f, *next;
  2248. epair_t *ep, *enext;
  2249. // remove from group
  2250. if (bRemoveNode)
  2251. Group_RemoveBrush(b);
  2252. // free the patch if it's there
  2253. if (b->patchBrush)
  2254. {
  2255. Patch_Delete(b->pPatch);
  2256. }
  2257. if( b->terrainBrush )
  2258. {
  2259. Terrain_Delete( b->pTerrain );
  2260. }
  2261. // free faces
  2262. for (f=b->brush_faces ; f ; f=next)
  2263. {
  2264. next = f->next;
  2265. Face_Free( f );
  2266. }
  2267. //Timo : free brush epairs
  2268. for (ep = b->epairs ; ep ; ep=enext )
  2269. {
  2270. enext = ep->next;
  2271. free (ep->key);
  2272. free (ep->value);
  2273. free (ep);
  2274. }
  2275. // unlink from active/selected list
  2276. if (b->next)
  2277. Brush_RemoveFromList (b);
  2278. // unlink from entity list
  2279. if (b->onext)
  2280. Entity_UnlinkBrush (b);
  2281. free (b);
  2282. }
  2283. /*
  2284. =============
  2285. Face_MemorySize
  2286. =============
  2287. */
  2288. int Face_MemorySize(face_t *f )
  2289. {
  2290. int size = 0;
  2291. if (f->face_winding)
  2292. {
  2293. size += _msize(f->face_winding);
  2294. }
  2295. //f->texdef.~texdef_t();;
  2296. size += _msize(f);
  2297. return size;
  2298. }
  2299. /*
  2300. =============
  2301. Brush_MemorySize
  2302. =============
  2303. */
  2304. int Brush_MemorySize(brush_t *b)
  2305. {
  2306. face_t *f;
  2307. epair_t *ep;
  2308. int size = 0;
  2309. //
  2310. if (b->patchBrush)
  2311. {
  2312. size += Patch_MemorySize(b->pPatch);
  2313. }
  2314. if (b->terrainBrush)
  2315. {
  2316. size += Terrain_MemorySize(b->pTerrain);
  2317. }
  2318. //
  2319. for (f = b->brush_faces; f; f = f->next)
  2320. {
  2321. size += Face_MemorySize(f);
  2322. }
  2323. //
  2324. for (ep = b->epairs; ep; ep = ep->next )
  2325. {
  2326. size += _msize(ep->key);
  2327. size += _msize(ep->value);
  2328. size += _msize(ep);
  2329. }
  2330. size += _msize(b);
  2331. return size;
  2332. }
  2333. /*
  2334. ============
  2335. Brush_Clone
  2336. Does NOT add the new brush to any lists
  2337. ============
  2338. */
  2339. brush_t *Brush_Clone (brush_t *b)
  2340. {
  2341. brush_t *n = NULL;
  2342. face_t *f, *nf;
  2343. if (b->patchBrush)
  2344. {
  2345. patchMesh_t *p = Patch_Duplicate(b->pPatch);
  2346. Brush_RemoveFromList(p->pSymbiot);
  2347. Entity_UnlinkBrush(p->pSymbiot);
  2348. n = p->pSymbiot;
  2349. }
  2350. else if (b->terrainBrush)
  2351. {
  2352. terrainMesh_t *p = Terrain_Duplicate(b->pTerrain);
  2353. Brush_RemoveFromList(p->pSymbiot);
  2354. Entity_UnlinkBrush(p->pSymbiot);
  2355. n = p->pSymbiot;
  2356. }
  2357. else
  2358. {
  2359. n = Brush_Alloc();
  2360. n->numberId = g_nBrushId++;
  2361. n->owner = b->owner;
  2362. for (f=b->brush_faces ; f ; f=f->next)
  2363. {
  2364. nf = Face_Clone( f );
  2365. nf->next = n->brush_faces;
  2366. n->brush_faces = nf;
  2367. }
  2368. }
  2369. return n;
  2370. }
  2371. /*
  2372. ============
  2373. Brush_Clone
  2374. Does NOT add the new brush to any lists
  2375. ============
  2376. */
  2377. brush_t *Brush_FullClone(brush_t *b)
  2378. {
  2379. brush_t *n = NULL;
  2380. face_t *f, *nf, *f2, *nf2;
  2381. int j;
  2382. if (b->patchBrush)
  2383. {
  2384. patchMesh_t *p = Patch_Duplicate(b->pPatch);
  2385. Brush_RemoveFromList(p->pSymbiot);
  2386. Entity_UnlinkBrush(p->pSymbiot);
  2387. n = p->pSymbiot;
  2388. n->owner = b->owner;
  2389. Brush_Build(n);
  2390. }
  2391. else if (b->terrainBrush)
  2392. {
  2393. terrainMesh_t *p = Terrain_Duplicate(b->pTerrain);
  2394. Brush_RemoveFromList(p->pSymbiot);
  2395. Entity_UnlinkBrush(p->pSymbiot);
  2396. n = p->pSymbiot;
  2397. n->owner = b->owner;
  2398. Brush_Build(n);
  2399. }
  2400. else
  2401. {
  2402. n = Brush_Alloc();
  2403. n->numberId = g_nBrushId++;
  2404. n->owner = b->owner;
  2405. VectorCopy(b->mins, n->mins);
  2406. VectorCopy(b->maxs, n->maxs);
  2407. //
  2408. for (f = b->brush_faces; f; f = f->next)
  2409. {
  2410. if (f->original) continue;
  2411. nf = Face_FullClone(f);
  2412. nf->next = n->brush_faces;
  2413. n->brush_faces = nf;
  2414. //copy all faces that have the original set to this face
  2415. for (f2 = b->brush_faces; f2; f2 = f2->next)
  2416. {
  2417. if (f2->original == f)
  2418. {
  2419. nf2 = Face_FullClone(f2);
  2420. nf2->next = n->brush_faces;
  2421. n->brush_faces = nf2;
  2422. //set original
  2423. nf2->original = nf;
  2424. }
  2425. }
  2426. }
  2427. for (nf = n->brush_faces; nf; nf = nf->next)
  2428. {
  2429. Face_SetColor(n, nf, 1.0);
  2430. if (nf->face_winding)
  2431. {
  2432. if (g_qeglobals.m_bBrushPrimitMode)
  2433. EmitBrushPrimitTextureCoordinates(nf,nf->face_winding);
  2434. else
  2435. {
  2436. for (j = 0; j < nf->face_winding->numpoints; j++)
  2437. EmitTextureCoordinates(nf->face_winding->points[j], nf->d_texture, nf);
  2438. }
  2439. }
  2440. }
  2441. }
  2442. return n;
  2443. }
  2444. /*
  2445. ==============
  2446. Brush_Ray
  2447. Itersects a ray with a brush
  2448. Returns the face hit and the distance along the ray the intersection occured at
  2449. Returns NULL and 0 if not hit at all
  2450. ==============
  2451. */
  2452. face_t *Brush_Ray (vec3_t origin, vec3_t dir, brush_t *b, float *dist)
  2453. {
  2454. face_t *f, *firstface;
  2455. vec3_t p1, p2;
  2456. float frac, d1, d2;
  2457. int i;
  2458. VectorCopy (origin, p1);
  2459. for (i=0 ; i<3 ; i++)
  2460. p2[i] = p1[i] + dir[i]*16384;
  2461. for (f=b->brush_faces ; f ; f=f->next)
  2462. {
  2463. d1 = DotProduct (p1, f->plane.normal) - f->plane.dist;
  2464. d2 = DotProduct (p2, f->plane.normal) - f->plane.dist;
  2465. if (d1 >= 0 && d2 >= 0)
  2466. {
  2467. *dist = 0;
  2468. return NULL; // ray is on front side of face
  2469. }
  2470. if (d1 <=0 && d2 <= 0)
  2471. continue;
  2472. // clip the ray to the plane
  2473. frac = d1 / (d1 - d2);
  2474. if (d1 > 0)
  2475. {
  2476. firstface = f;
  2477. for (i=0 ; i<3 ; i++)
  2478. p1[i] = p1[i] + frac *(p2[i] - p1[i]);
  2479. }
  2480. else
  2481. {
  2482. for (i=0 ; i<3 ; i++)
  2483. p2[i] = p1[i] + frac *(p2[i] - p1[i]);
  2484. }
  2485. }
  2486. // find distance p1 is along dir
  2487. VectorSubtract (p1, origin, p1);
  2488. d1 = DotProduct (p1, dir);
  2489. *dist = d1;
  2490. return firstface;
  2491. }
  2492. //PGM
  2493. face_t *Brush_Point (vec3_t origin, brush_t *b)
  2494. {
  2495. face_t *f;
  2496. float d1;
  2497. for (f=b->brush_faces ; f ; f=f->next)
  2498. {
  2499. d1 = DotProduct (origin, f->plane.normal) - f->plane.dist;
  2500. if (d1 > 0)
  2501. {
  2502. return NULL; // point is on front side of face
  2503. }
  2504. }
  2505. return b->brush_faces;
  2506. }
  2507. //PGM
  2508. void Brush_AddToList (brush_t *b, brush_t *list)
  2509. {
  2510. if (b->next || b->prev)
  2511. Error ("Brush_AddToList: allready linked");
  2512. if (list == &selected_brushes || list == &active_brushes)
  2513. {
  2514. if (b->patchBrush && list == &selected_brushes)
  2515. {
  2516. Patch_Select(b->pPatch);
  2517. }
  2518. if (b->terrainBrush && list == &selected_brushes) {
  2519. Terrain_Select(b->pTerrain);
  2520. }
  2521. }
  2522. b->next = list->next;
  2523. list->next->prev = b;
  2524. list->next = b;
  2525. b->prev = list;
  2526. // TTimo messaging
  2527. DispatchRadiantMsg( RADIANT_SELECTION );
  2528. }
  2529. void Brush_RemoveFromList (brush_t *b)
  2530. {
  2531. if (!b->next || !b->prev)
  2532. Error ("Brush_RemoveFromList: not linked");
  2533. if (b->patchBrush)
  2534. {
  2535. Patch_Deselect(b->pPatch);
  2536. //Patch_Deselect(b->nPatchID);
  2537. }
  2538. if (b->terrainBrush)
  2539. {
  2540. Terrain_Deselect(b->pTerrain);
  2541. }
  2542. b->next->prev = b->prev;
  2543. b->prev->next = b->next;
  2544. b->next = b->prev = NULL;
  2545. }
  2546. /*
  2547. ===============
  2548. SetFaceTexdef
  2549. Doesn't set the curve flags
  2550. NOTE : ( TTimo )
  2551. never trust f->d_texture here, f->texdef and f->d_texture are out of sync when called by Brush_SetTexture
  2552. use Texture_ForName() to find the right shader
  2553. FIXME : send the right shader ( qtexture_t * ) in the parameters ?
  2554. TTimo: surface plugin, added an IPluginTexdef* parameter
  2555. if not NULL, get ->Copy() of it into the face ( and remember to hook )
  2556. if NULL, ask for a default
  2557. ===============
  2558. */
  2559. void SetFaceTexdef (brush_t *b, face_t *f, texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale, IPluginTexdef* pPlugTexdef) {
  2560. int oldFlags;
  2561. int oldContents;
  2562. face_t *tf;
  2563. oldFlags = f->texdef.flags;
  2564. oldContents = f->texdef.contents;
  2565. if (g_qeglobals.m_bBrushPrimitMode)
  2566. {
  2567. f->texdef = *texdef;
  2568. ConvertTexMatWithQTexture( brushprimit_texdef, NULL, &f->brushprimit_texdef, Texture_ForName( f->texdef.name ) );
  2569. }
  2570. else
  2571. if (bFitScale)
  2572. {
  2573. f->texdef = *texdef;
  2574. // fit the scaling of the texture on the actual plane
  2575. vec3_t p1,p2,p3; // absolute coordinates
  2576. // compute absolute coordinates
  2577. ComputeAbsolute(f,p1,p2,p3);
  2578. // compute the scale
  2579. vec3_t vx,vy;
  2580. VectorSubtract(p2,p1,vx);
  2581. VectorNormalize(vx);
  2582. VectorSubtract(p3,p1,vy);
  2583. VectorNormalize(vy);
  2584. // assign scale
  2585. VectorScale(vx,texdef->scale[0],vx);
  2586. VectorScale(vy,texdef->scale[1],vy);
  2587. VectorAdd(p1,vx,p2);
  2588. VectorAdd(p1,vy,p3);
  2589. // compute back shift scale rot
  2590. AbsoluteToLocal(f->plane,f,p1,p2,p3);
  2591. }
  2592. else
  2593. f->texdef = *texdef;
  2594. f->texdef.flags = (f->texdef.flags & ~SURF_KEEP) | (oldFlags & SURF_KEEP);
  2595. f->texdef.contents = (f->texdef.contents & ~CONTENTS_KEEP) | (oldContents & CONTENTS_KEEP);
  2596. // surface plugin
  2597. if (g_qeglobals.bSurfacePropertiesPlugin)
  2598. {
  2599. #ifdef _DEBUG
  2600. if (!f->pData)
  2601. Sys_Printf("ERROR: unexpected IPluginTexdef* is NULL in SetFaceTexdef\n");
  2602. else
  2603. #endif
  2604. GETPLUGINTEXDEF(f)->DecRef();
  2605. IPluginTexdef *pTexdef = NULL;
  2606. if ( pPlugTexdef )
  2607. {
  2608. pTexdef = pPlugTexdef->Copy();
  2609. pTexdef->Hook( f );
  2610. }
  2611. else
  2612. pTexdef = g_SurfaceTable.m_pfnTexdefAlloc( f );
  2613. f->pData = pTexdef;
  2614. }
  2615. // if this is a curve face, set all other curve faces to the same texdef
  2616. if (f->texdef.flags & SURF_CURVE)
  2617. {
  2618. for (tf = b->brush_faces ; tf ; tf = tf->next)
  2619. {
  2620. if (tf->texdef.flags & SURF_CURVE)
  2621. tf->texdef = f->texdef;
  2622. }
  2623. }
  2624. }
  2625. void Brush_SetTexture (brush_t *b, texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale, IPluginTexdef* pTexdef)
  2626. {
  2627. for (face_t* f = b->brush_faces ; f ; f = f->next)
  2628. {
  2629. SetFaceTexdef (b, f, texdef, brushprimit_texdef, bFitScale, pTexdef);
  2630. }
  2631. Brush_Build( b );
  2632. if (b->patchBrush)
  2633. {
  2634. //++timo clean
  2635. // Sys_Printf("WARNING: Brush_SetTexture needs surface plugin code for patches\n");
  2636. Patch_SetTexture(b->pPatch, texdef, pTexdef );
  2637. }
  2638. if (b->terrainBrush)
  2639. {
  2640. Terrain_SetTexture(b->pTerrain, texdef);
  2641. }
  2642. }
  2643. qboolean ClipLineToFace (vec3_t p1, vec3_t p2, face_t *f)
  2644. {
  2645. float d1, d2, fr;
  2646. int i;
  2647. float *v;
  2648. d1 = DotProduct (p1, f->plane.normal) - f->plane.dist;
  2649. d2 = DotProduct (p2, f->plane.normal) - f->plane.dist;
  2650. if (d1 >= 0 && d2 >= 0)
  2651. return false; // totally outside
  2652. if (d1 <= 0 && d2 <= 0)
  2653. return true; // totally inside
  2654. fr = d1 / (d1 - d2);
  2655. if (d1 > 0)
  2656. v = p1;
  2657. else
  2658. v = p2;
  2659. for (i=0 ; i<3 ; i++)
  2660. v[i] = p1[i] + fr*(p2[i] - p1[i]);
  2661. return true;
  2662. }
  2663. int AddPlanept (float *f)
  2664. {
  2665. int i;
  2666. for (i=0 ; i<g_qeglobals.d_num_move_points ; i++)
  2667. if (g_qeglobals.d_move_points[i] == f)
  2668. return 0;
  2669. g_qeglobals.d_move_points[g_qeglobals.d_num_move_points++] = f;
  2670. return 1;
  2671. }
  2672. /*
  2673. ==============
  2674. Brush_SelectFaceForDragging
  2675. Adds the faces planepts to move_points, and
  2676. rotates and adds the planepts of adjacent face if shear is set
  2677. ==============
  2678. */
  2679. void Brush_SelectFaceForDragging (brush_t *b, face_t *f, qboolean shear)
  2680. {
  2681. int i;
  2682. face_t *f2;
  2683. winding_t *w;
  2684. float d;
  2685. brush_t *b2;
  2686. int c;
  2687. if (b->owner->eclass->fixedsize)
  2688. return;
  2689. c = 0;
  2690. for (i=0 ; i<3 ; i++)
  2691. c += AddPlanept (f->planepts[i]);
  2692. if (c == 0)
  2693. return; // allready completely added
  2694. // select all points on this plane in all brushes the selection
  2695. for (b2=selected_brushes.next ; b2 != &selected_brushes ; b2 = b2->next)
  2696. {
  2697. if (b2 == b)
  2698. continue;
  2699. for (f2=b2->brush_faces ; f2 ; f2=f2->next)
  2700. {
  2701. for (i=0 ; i<3 ; i++)
  2702. if (fabs(DotProduct(f2->planepts[i], f->plane.normal)
  2703. -f->plane.dist) > ON_EPSILON)
  2704. break;
  2705. if (i==3)
  2706. { // move this face as well
  2707. Brush_SelectFaceForDragging (b2, f2, shear);
  2708. break;
  2709. }
  2710. }
  2711. }
  2712. // if shearing, take all the planes adjacent to
  2713. // selected faces and rotate their points so the
  2714. // edge clipped by a selcted face has two of the points
  2715. if (!shear)
  2716. return;
  2717. for (f2=b->brush_faces ; f2 ; f2=f2->next)
  2718. {
  2719. if (f2 == f)
  2720. continue;
  2721. w = Brush_MakeFaceWinding (b, f2);
  2722. if (!w)
  2723. continue;
  2724. // any points on f will become new control points
  2725. for (i=0 ; i<w->numpoints ; i++)
  2726. {
  2727. d = DotProduct (w->points[i], f->plane.normal)
  2728. - f->plane.dist;
  2729. if (d > -ON_EPSILON && d < ON_EPSILON)
  2730. break;
  2731. }
  2732. //
  2733. // if none of the points were on the plane,
  2734. // leave it alone
  2735. //
  2736. if (i != w->numpoints)
  2737. {
  2738. if (i == 0)
  2739. { // see if the first clockwise point was the
  2740. // last point on the winding
  2741. d = DotProduct (w->points[w->numpoints-1]
  2742. , f->plane.normal) - f->plane.dist;
  2743. if (d > -ON_EPSILON && d < ON_EPSILON)
  2744. i = w->numpoints - 1;
  2745. }
  2746. AddPlanept (f2->planepts[0]);
  2747. VectorCopy (w->points[i], f2->planepts[0]);
  2748. if (++i == w->numpoints)
  2749. i = 0;
  2750. // see if the next point is also on the plane
  2751. d = DotProduct (w->points[i]
  2752. , f->plane.normal) - f->plane.dist;
  2753. if (d > -ON_EPSILON && d < ON_EPSILON)
  2754. AddPlanept (f2->planepts[1]);
  2755. VectorCopy (w->points[i], f2->planepts[1]);
  2756. if (++i == w->numpoints)
  2757. i = 0;
  2758. // the third point is never on the plane
  2759. VectorCopy (w->points[i], f2->planepts[2]);
  2760. }
  2761. free(w);
  2762. }
  2763. }
  2764. /*
  2765. ==============
  2766. Brush_SideSelect
  2767. The mouse click did not hit the brush, so grab one or more side
  2768. planes for dragging
  2769. ==============
  2770. */
  2771. void Brush_SideSelect (brush_t *b, vec3_t origin, vec3_t dir
  2772. , qboolean shear)
  2773. {
  2774. face_t *f, *f2;
  2775. vec3_t p1, p2;
  2776. //if (b->patchBrush)
  2777. // return;
  2778. //Patch_SideSelect(b->nPatchID, origin, dir);
  2779. for (f=b->brush_faces ; f ; f=f->next)
  2780. {
  2781. VectorCopy (origin, p1);
  2782. VectorMA (origin, 16384, dir, p2);
  2783. for (f2=b->brush_faces ; f2 ; f2=f2->next)
  2784. {
  2785. if (f2 == f)
  2786. continue;
  2787. ClipLineToFace (p1, p2, f2);
  2788. }
  2789. if (f2)
  2790. continue;
  2791. if (VectorCompare (p1, origin))
  2792. continue;
  2793. if (ClipLineToFace (p1, p2, f))
  2794. continue;
  2795. Brush_SelectFaceForDragging (b, f, shear);
  2796. }
  2797. }
  2798. void Brush_BuildWindings( brush_t *b, bool bSnap )
  2799. {
  2800. winding_t *w;
  2801. face_t *face;
  2802. vec_t v;
  2803. if (bSnap)
  2804. Brush_SnapPlanepts( b );
  2805. // clear the mins/maxs bounds
  2806. b->mins[0] = b->mins[1] = b->mins[2] = 99999;
  2807. b->maxs[0] = b->maxs[1] = b->maxs[2] = -99999;
  2808. Brush_MakeFacePlanes (b);
  2809. face = b->brush_faces;
  2810. float fCurveColor = 1.0;
  2811. for ( ; face ; face=face->next)
  2812. {
  2813. int i, j;
  2814. free(face->face_winding);
  2815. w = face->face_winding = Brush_MakeFaceWinding (b, face);
  2816. face->d_texture = Texture_ForName( face->texdef.name );
  2817. if (!w)
  2818. continue;
  2819. for (i=0 ; i<w->numpoints ; i++)
  2820. {
  2821. // add to bounding box
  2822. for (j=0 ; j<3 ; j++)
  2823. {
  2824. v = w->points[i][j];
  2825. if (v > b->maxs[j])
  2826. b->maxs[j] = v;
  2827. if (v < b->mins[j])
  2828. b->mins[j] = v;
  2829. }
  2830. }
  2831. // setup s and t vectors, and set color
  2832. //if (!g_PrefsDlg.m_bGLLighting)
  2833. //{
  2834. Face_SetColor (b, face, fCurveColor);
  2835. //}
  2836. fCurveColor -= .10;
  2837. if (fCurveColor <= 0)
  2838. fCurveColor = 1.0;
  2839. // computing ST coordinates for the windings
  2840. if (g_qeglobals.m_bBrushPrimitMode)
  2841. {
  2842. if (g_qeglobals.bNeedConvert)
  2843. {
  2844. // we have parsed old brushes format and need conversion
  2845. // convert old brush texture representation to new format
  2846. FaceToBrushPrimitFace(face);
  2847. #ifdef _DEBUG
  2848. // use old texture coordinates code to check against
  2849. for (i=0 ; i<w->numpoints ; i++)
  2850. EmitTextureCoordinates( w->points[i], face->d_texture, face);
  2851. #endif
  2852. }
  2853. // use new texture representation to compute texture coordinates
  2854. // in debug mode we will check against old code and warn if there are differences
  2855. EmitBrushPrimitTextureCoordinates(face,w);
  2856. }
  2857. else
  2858. {
  2859. for (i=0 ; i<w->numpoints ; i++)
  2860. EmitTextureCoordinates( w->points[i], face->d_texture, face);
  2861. }
  2862. }
  2863. }
  2864. /*
  2865. ==================
  2866. Brush_RemoveEmptyFaces
  2867. Frees any overconstraining faces
  2868. ==================
  2869. */
  2870. void Brush_RemoveEmptyFaces ( brush_t *b )
  2871. {
  2872. face_t *f, *next;
  2873. f = b->brush_faces;
  2874. b->brush_faces = NULL;
  2875. for ( ; f ; f=next)
  2876. {
  2877. next = f->next;
  2878. if (!f->face_winding)
  2879. Face_Free (f);
  2880. else
  2881. {
  2882. f->next = b->brush_faces;
  2883. b->brush_faces = f;
  2884. }
  2885. }
  2886. }
  2887. void Brush_SnapToGrid(brush_t *pb)
  2888. {
  2889. for (face_t *f = pb->brush_faces ; f; f = f->next)
  2890. {
  2891. for (int i = 0 ;i < 3 ;i++)
  2892. {
  2893. for (int j = 0 ;j < 3 ; j++)
  2894. {
  2895. f->planepts[i][j] = floor (f->planepts[i][j] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
  2896. }
  2897. }
  2898. }
  2899. Brush_Build(pb);
  2900. }
  2901. void Brush_Rotate(brush_t *b, vec3_t vAngle, vec3_t vOrigin, bool bBuild)
  2902. {
  2903. for (face_t* f=b->brush_faces ; f ; f=f->next)
  2904. {
  2905. for (int i=0 ; i<3 ; i++)
  2906. {
  2907. VectorRotate(f->planepts[i], vAngle, vOrigin, f->planepts[i]);
  2908. }
  2909. }
  2910. if (bBuild)
  2911. {
  2912. Brush_Build(b, false, false);
  2913. }
  2914. }
  2915. void Brush_Center(brush_t *b, vec3_t vNewCenter)
  2916. {
  2917. vec3_t vMid;
  2918. // get center of the brush
  2919. for (int j = 0; j < 3; j++)
  2920. {
  2921. vMid[j] = b->mins[j] + abs((b->maxs[j] - b->mins[j]) * 0.5);
  2922. }
  2923. // calc distance between centers
  2924. VectorSubtract(vNewCenter, vMid, vMid);
  2925. Brush_Move(b, vMid, true);
  2926. }
  2927. // only designed for fixed size entity brushes
  2928. void Brush_Resize(brush_t *b, vec3_t vMin, vec3_t vMax)
  2929. {
  2930. brush_t *b2 = Brush_Create(vMin, vMax, &b->brush_faces->texdef);
  2931. face_t *next;
  2932. for (face_t *f=b->brush_faces ; f ; f=next)
  2933. {
  2934. next = f->next;
  2935. Face_Free( f );
  2936. }
  2937. b->brush_faces = b2->brush_faces;
  2938. // unlink from active/selected list
  2939. if (b2->next)
  2940. Brush_RemoveFromList (b2);
  2941. free(b2);
  2942. Brush_Build(b, true);
  2943. }
  2944. eclass_t* HasModel(brush_t *b)
  2945. {
  2946. vec3_t vMin, vMax;
  2947. vMin[0] = vMin[1] = vMin[2] = 9999;
  2948. vMax[0] = vMax[1] = vMax[2] = -9999;
  2949. if (b->owner->md3Class != NULL)
  2950. {
  2951. return b->owner->md3Class;
  2952. }
  2953. if (Eclass_hasModel(b->owner->eclass, vMin, vMax))
  2954. {
  2955. return b->owner->eclass;
  2956. }
  2957. eclass_t *e = NULL;
  2958. // FIXME: entity needs to track whether a cache hit failed and not ask again
  2959. if (b->owner->eclass->nShowFlags & ECLASS_MISCMODEL)
  2960. {
  2961. char *pModel = ValueForKey(b->owner, "model");
  2962. if (pModel != NULL && strlen(pModel) > 0)
  2963. {
  2964. e = GetCachedModel(b->owner, pModel, vMin, vMax);
  2965. if (e != NULL)
  2966. {
  2967. // we need to scale the brush to the proper size based on the model load
  2968. // recreate brush just like in load/save
  2969. VectorAdd (vMin, b->owner->origin, vMin);
  2970. VectorAdd (vMax, b->owner->origin, vMax);
  2971. Brush_Resize(b, vMin, vMax);
  2972. /*
  2973. //
  2974. vec3_t vTemp, vTemp2;
  2975. VectorSubtract(b->maxs, b->mins, vTemp);
  2976. VectorSubtract(vMax, vMin, vTemp2);
  2977. for (int i = 0; i < 3; i++)
  2978. {
  2979. if (vTemp[i] != 0)
  2980. {
  2981. vTemp2[i] /= vTemp[i];
  2982. }
  2983. }
  2984. vec3_t vMid, vMid2;
  2985. vMid[0] = vMid[1] = vMid[2] = 0.0;
  2986. vMid2[0] = vMid2[1] = vMid2[2] = 0.0;
  2987. for (int j = 0; j < 3; j++)
  2988. {
  2989. vMid2[j] = b->mins[j] + abs((b->maxs[j] - b->mins[j]) * 0.5);
  2990. }
  2991. //VectorSubtract(vMid2, vMid, vMid2);
  2992. for (face_t* f=b->brush_faces ; f ; f=f->next)
  2993. {
  2994. for (int i=0 ; i<3 ; i++)
  2995. {
  2996. // scale
  2997. VectorSubtract(f->planepts[i], vMid2, f->planepts[i]);
  2998. f->planepts[i][0] *= vTemp2[0];
  2999. f->planepts[i][1] *= vTemp2[1];
  3000. f->planepts[i][2] *= vTemp2[2];
  3001. VectorAdd(f->planepts[i], vMid2, f->planepts[i]);
  3002. }
  3003. }
  3004. //Brush_Center(b, b->owner->origin);
  3005. //Brush_SnapToGrid(b);
  3006. /*
  3007. float a = FloatForKey (b->owner, "angle");
  3008. if (a)
  3009. {
  3010. vec3_t vAngle;
  3011. vAngle[0] = vAngle[1] = 0;
  3012. vAngle[2] = a;
  3013. Brush_Rotate(b, vAngle, b->owner->origin);
  3014. }
  3015. else
  3016. {
  3017. Brush_Build(b, true);
  3018. */
  3019. // }
  3020. b->bModelFailed = false;
  3021. }
  3022. else
  3023. {
  3024. b->bModelFailed = true;
  3025. }
  3026. }
  3027. }
  3028. return e;
  3029. }
  3030. static bool g_bInPaintedModel = false;
  3031. static bool g_bDoIt = false;
  3032. bool PaintedModel(brush_t *b, bool bOkToTexture)
  3033. {
  3034. if (g_bInPaintedModel)
  3035. {
  3036. return true;
  3037. }
  3038. if (g_PrefsDlg.m_nEntityShowState == ENTITY_BOX || b->bModelFailed)
  3039. {
  3040. return false;
  3041. }
  3042. else if (!IsBrushSelected(b) && (g_PrefsDlg.m_nEntityShowState & ENTITY_SELECTED_ONLY))
  3043. {
  3044. return false;
  3045. }
  3046. g_bInPaintedModel = true;
  3047. bool bReturn = false;
  3048. eclass_t *pEclass = HasModel(b);
  3049. if (pEclass)
  3050. {
  3051. qglPushAttrib(GL_ALL_ATTRIB_BITS);
  3052. entitymodel *model = pEclass->model;
  3053. float a = FloatForKey (b->owner, "angle");
  3054. while (model != NULL)
  3055. {
  3056. if (bOkToTexture == false || g_PrefsDlg.m_nEntityShowState & ENTITY_WIREFRAME || model->nTextureBind == -1) // skinned
  3057. {
  3058. qglDisable( GL_CULL_FACE );
  3059. qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
  3060. qglDisable(GL_TEXTURE_2D);
  3061. qglColor3fv(pEclass->color);
  3062. }
  3063. else
  3064. {
  3065. qglColor3f(1, 1, 1);
  3066. qglEnable(GL_TEXTURE_2D);
  3067. qglBindTexture( GL_TEXTURE_2D, model->nTextureBind );
  3068. }
  3069. vec3_t v;
  3070. int i,j;
  3071. VectorAdd(b->maxs, b->mins, v);
  3072. VectorScale(v, 0.5, v);
  3073. VectorCopy(b->owner->origin, v);
  3074. //for (i = 0; i < 3; i++)
  3075. //{
  3076. // v[i] -= (pEclass->mins[i] - b->mins[i]);
  3077. //}
  3078. //if (model->nModelPosition)
  3079. //{
  3080. //v[2] = b->mins[2] - (pEclass->mins[2]);
  3081. //}
  3082. float s, c;
  3083. if (a)
  3084. {
  3085. s = sin (a/180*Q_PI);
  3086. c = cos (a/180*Q_PI);
  3087. }
  3088. vec3_t vSin;
  3089. vec3_t vCos;
  3090. VectorClear(vSin);
  3091. VectorClear(vCos);
  3092. for ( j = 0; j < 3; j++)
  3093. {
  3094. if (b->owner->vRotation[j])
  3095. {
  3096. vSin[j] = sin(b->owner->vRotation[j]/180*Q_PI);
  3097. vCos[j] = cos(b->owner->vRotation[j]/180*Q_PI);
  3098. }
  3099. }
  3100. qglBegin (GL_TRIANGLES);
  3101. vec5_t vTest[3];
  3102. for (i = 0; i < model->nTriCount; i++)
  3103. {
  3104. for (j = 0; j < 3; j++)
  3105. {
  3106. #if 1
  3107. float x = model->pTriList[i].v[j][0] + v[0];
  3108. float y = model->pTriList[i].v[j][1] + v[1];
  3109. if (a)
  3110. {
  3111. float x2 = (((x - v[0]) * c) - ((y - v[1]) * s)) + v[0];
  3112. float y2 = (((x - v[0]) * s) + ((y - v[1]) * c)) + v[1];
  3113. x = x2;
  3114. y = y2;
  3115. }
  3116. //qglTexCoord2f (pEclass->pTriList[i].st[j][0] / pEclass->nSkinWidth, pEclass->pTriList[i].st[j][1] / pEclass->nSkinHeight);
  3117. qglTexCoord2f (model->pTriList[i].st[j][0], model->pTriList[i].st[j][1]);
  3118. qglVertex3f(x, y, model->pTriList[i].v[j][2] + v[2]);
  3119. #else
  3120. float x = model->pTriList[i].v[j][0] + v[0];
  3121. float y = model->pTriList[i].v[j][1] + v[1];
  3122. float z = model->pTriList[i].v[j][2] + v[2];
  3123. if (b->owner->vRotation[0])
  3124. {
  3125. float y2 = (((y - v[1]) * vCos[0]) - ((z - v[2]) * vSin[0])) + v[1];
  3126. float z2 = (((y - v[1]) * vSin[0]) + ((z - v[2]) * vCos[0])) + v[2];
  3127. y = y2;
  3128. z = z2;
  3129. }
  3130. if (b->owner->vRotation[1])
  3131. {
  3132. float z2 = (((z - v[2]) * vCos[1]) - ((x - v[0]) * vSin[1])) + v[2];
  3133. float x2 = (((z - v[2]) * vSin[1]) + ((x - v[0]) * vCos[1])) + v[0];
  3134. x = x2;
  3135. z = z2;
  3136. }
  3137. if (b->owner->vRotation[2])
  3138. {
  3139. float x2 = (((x - v[0]) * vCos[2]) - ((y - v[1]) * vSin[2])) + v[0];
  3140. float y2 = (((x - v[0]) * vSin[2]) + ((y - v[1]) * vCos[2])) + v[1];
  3141. x = x2;
  3142. y = y2;
  3143. }
  3144. qglTexCoord2f (model->pTriList[i].st[j][0], model->pTriList[i].st[j][1]);
  3145. qglVertex3f(x, y, z);
  3146. #endif
  3147. if (g_bDoIt)
  3148. {
  3149. vTest[j][0] = x;
  3150. vTest[j][1] = y;
  3151. vTest[j][2] = model->pTriList[i].v[j][2] + v[2];
  3152. vTest[j][3] = model->pTriList[i].st[j][0];
  3153. vTest[j][4] = model->pTriList[i].st[j][1];
  3154. }
  3155. }
  3156. if (g_bDoIt)
  3157. {
  3158. Patch_FromTriangle(vTest[0], vTest[1], vTest[2]);
  3159. }
  3160. }
  3161. qglEnd();
  3162. if (g_PrefsDlg.m_nEntityShowState & ENTITY_WIREFRAME) // skinned
  3163. {
  3164. qglEnable(GL_CULL_FACE );
  3165. qglEnable(GL_TEXTURE_2D);
  3166. qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  3167. }
  3168. else
  3169. {
  3170. qglDisable(GL_TEXTURE_2D);
  3171. }
  3172. model = model->pNext;
  3173. }
  3174. if (g_bDoIt)
  3175. {
  3176. g_bDoIt = false;
  3177. }
  3178. vec3_t vColor;
  3179. VectorScale(pEclass->color, 0.50, vColor);
  3180. vec3_t vCenter, vMin, vMax;
  3181. VectorCopy(b->owner->origin, vCenter);
  3182. qglColor3fv(vColor);
  3183. qglPointSize(4);
  3184. qglBegin(GL_POINTS);
  3185. qglVertex3fv(b->owner->origin);
  3186. qglEnd();
  3187. qglBegin(GL_LINES);
  3188. vCenter[0] -= 8;
  3189. qglVertex3fv(vCenter);
  3190. vCenter[0] += 16;
  3191. qglVertex3fv(vCenter);
  3192. vCenter[0] -= 8;
  3193. vCenter[1] -= 8;
  3194. qglVertex3fv(vCenter);
  3195. vCenter[1] += 16;
  3196. qglVertex3fv(vCenter);
  3197. vCenter[1] -= 8;
  3198. vCenter[2] -= 8;
  3199. qglVertex3fv(vCenter);
  3200. vCenter[2] += 16;
  3201. qglVertex3fv(vCenter);
  3202. vCenter[2] -= 8;
  3203. qglEnd();
  3204. VectorCopy(vCenter, vMin);
  3205. VectorCopy(vCenter, vMax);
  3206. vMin[0] -= 4;
  3207. vMin[1] -= 4;
  3208. vMin[2] -= 4;
  3209. vMax[0] += 4;
  3210. vMax[1] += 4;
  3211. vMax[2] += 4;
  3212. qglBegin(GL_LINE_LOOP);
  3213. qglVertex3f(vMin[0],vMin[1],vMin[2]);
  3214. qglVertex3f(vMax[0],vMin[1],vMin[2]);
  3215. qglVertex3f(vMax[0],vMax[1],vMin[2]);
  3216. qglVertex3f(vMin[0],vMax[1],vMin[2]);
  3217. qglEnd();
  3218. qglBegin(GL_LINE_LOOP);
  3219. qglVertex3f(vMin[0],vMin[1],vMax[2]);
  3220. qglVertex3f(vMax[0],vMin[1],vMax[2]);
  3221. qglVertex3f(vMax[0],vMax[1],vMax[2]);
  3222. qglVertex3f(vMin[0],vMax[1],vMax[2]);
  3223. qglEnd();
  3224. qglBegin(GL_LINES);
  3225. qglVertex3f(vMin[0],vMin[1],vMin[2]);
  3226. qglVertex3f(vMin[0],vMin[1],vMax[2]);
  3227. qglVertex3f(vMin[0],vMax[1],vMax[2]);
  3228. qglVertex3f(vMin[0],vMax[1],vMin[2]);
  3229. qglVertex3f(vMax[0],vMin[1],vMin[2]);
  3230. qglVertex3f(vMax[0],vMin[1],vMax[2]);
  3231. qglVertex3f(vMax[0],vMax[1],vMax[2]);
  3232. qglVertex3f(vMax[0],vMax[1],vMin[2]);
  3233. qglEnd();
  3234. if (g_PrefsDlg.m_nEntityShowState & ENTITY_BOXED)
  3235. {
  3236. qglColor3fv(pEclass->color);
  3237. vec3_t mins, maxs;
  3238. VectorCopy(b->mins, mins);
  3239. VectorCopy(b->maxs, maxs);
  3240. /*
  3241. if (a)
  3242. {
  3243. vec3_t vAngle;
  3244. vAngle[0] = vAngle[1] = 0;
  3245. vAngle[2] = a;
  3246. VectorRotate(mins, vAngle, b->owner->origin, mins);
  3247. VectorRotate(maxs, vAngle, b->owner->origin, maxs);
  3248. }
  3249. */
  3250. qglBegin(GL_LINE_LOOP);
  3251. qglVertex3f(mins[0],mins[1],mins[2]);
  3252. qglVertex3f(maxs[0],mins[1],mins[2]);
  3253. qglVertex3f(maxs[0],maxs[1],mins[2]);
  3254. qglVertex3f(mins[0],maxs[1],mins[2]);
  3255. qglEnd();
  3256. qglBegin(GL_LINE_LOOP);
  3257. qglVertex3f(mins[0],mins[1],maxs[2]);
  3258. qglVertex3f(maxs[0],mins[1],maxs[2]);
  3259. qglVertex3f(maxs[0],maxs[1],maxs[2]);
  3260. qglVertex3f(mins[0],maxs[1],maxs[2]);
  3261. qglEnd();
  3262. qglBegin(GL_LINES);
  3263. qglVertex3f(mins[0],mins[1],mins[2]);
  3264. qglVertex3f(mins[0],mins[1],maxs[2]);
  3265. qglVertex3f(mins[0],maxs[1],maxs[2]);
  3266. qglVertex3f(mins[0],maxs[1],mins[2]);
  3267. qglVertex3f(maxs[0],mins[1],mins[2]);
  3268. qglVertex3f(maxs[0],mins[1],maxs[2]);
  3269. qglVertex3f(maxs[0],maxs[1],maxs[2]);
  3270. qglVertex3f(maxs[0],maxs[1],mins[2]);
  3271. qglEnd();
  3272. }
  3273. qglPopAttrib();
  3274. bReturn = true;
  3275. }
  3276. else
  3277. {
  3278. b->bModelFailed = true;
  3279. }
  3280. g_bInPaintedModel = false;
  3281. return bReturn;
  3282. }
  3283. /*
  3284. //++timo moved out to mahlib.h
  3285. //++timo remove
  3286. void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
  3287. {
  3288. float angle;
  3289. static float sr, sp, sy, cr, cp, cy;
  3290. // static to help MS compiler fp bugs
  3291. angle = angles[YAW] * Q_PI / 180;
  3292. sy = sin(angle);
  3293. cy = cos(angle);
  3294. angle = angles[PITCH] * Q_PI / 180;
  3295. sp = sin(angle);
  3296. cp = cos(angle);
  3297. angle = angles[ROLL] * Q_PI / 180;
  3298. sr = sin(angle);
  3299. cr = cos(angle);
  3300. if (forward)
  3301. {
  3302. forward[0] = cp*cy;
  3303. forward[1] = cp*sy;
  3304. forward[2] = -sp;
  3305. }
  3306. if (right)
  3307. {
  3308. right[0] = (-1*sr*sp*cy+-1*cr*-sy);
  3309. right[1] = (-1*sr*sp*sy+-1*cr*cy);
  3310. right[2] = -1*sr*cp;
  3311. }
  3312. if (up)
  3313. {
  3314. up[0] = (cr*sp*cy+-sr*-sy);
  3315. up[1] = (cr*sp*sy+-sr*cy);
  3316. up[2] = cr*cp;
  3317. }
  3318. }
  3319. */
  3320. void FacingVectors (entity_t *e, vec3_t forward, vec3_t right, vec3_t up)
  3321. {
  3322. int angleVal;
  3323. vec3_t angles;
  3324. angleVal = IntForKey(e, "angle");
  3325. if (angleVal == -1) // up
  3326. {
  3327. VectorSet(angles, 270, 0, 0);
  3328. }
  3329. else if(angleVal == -2) // down
  3330. {
  3331. VectorSet(angles, 90, 0, 0);
  3332. }
  3333. else
  3334. {
  3335. VectorSet(angles, 0, angleVal, 0);
  3336. }
  3337. AngleVectors(angles, forward, right, up);
  3338. }
  3339. void Brush_DrawFacingAngle (brush_t *b, entity_t *e)
  3340. {
  3341. vec3_t forward, right, up;
  3342. vec3_t endpoint, tip1, tip2;
  3343. vec3_t start;
  3344. float dist;
  3345. VectorAdd(e->brushes.onext->mins, e->brushes.onext->maxs, start);
  3346. VectorScale(start, 0.5, start);
  3347. dist = (b->maxs[0] - start[0]) * 2.5;
  3348. FacingVectors (e, forward, right, up);
  3349. VectorMA (start, dist, forward, endpoint);
  3350. dist = (b->maxs[0] - start[0]) * 0.5;
  3351. VectorMA (endpoint, -dist, forward, tip1);
  3352. VectorMA (tip1, -dist, up, tip1);
  3353. VectorMA (tip1, 2*dist, up, tip2);
  3354. qglColor4f (1, 1, 1, 1);
  3355. qglLineWidth (4);
  3356. qglBegin (GL_LINES);
  3357. qglVertex3fv (start);
  3358. qglVertex3fv (endpoint);
  3359. qglVertex3fv (endpoint);
  3360. qglVertex3fv (tip1);
  3361. qglVertex3fv (endpoint);
  3362. qglVertex3fv (tip2);
  3363. qglEnd ();
  3364. qglLineWidth (1);
  3365. }
  3366. void DrawLight(brush_t *b)
  3367. {
  3368. vec3_t vTriColor;
  3369. bool bTriPaint = false;
  3370. vTriColor[0] = vTriColor[2] = 1.0;
  3371. vTriColor[1] = 1.0;
  3372. bTriPaint = true;
  3373. CString strColor = ValueForKey(b->owner, "_color");
  3374. if (strColor.GetLength() > 0)
  3375. {
  3376. float fR, fG, fB;
  3377. int n = sscanf(strColor,"%f %f %f", &fR, &fG, &fB);
  3378. if (n == 3)
  3379. {
  3380. vTriColor[0] = fR;
  3381. vTriColor[1] = fG;
  3382. vTriColor[2] = fB;
  3383. }
  3384. }
  3385. qglColor3f(vTriColor[0], vTriColor[1], vTriColor[2]);
  3386. vec3_t vCorners[4];
  3387. float fMid = b->mins[2] + (b->maxs[2] - b->mins[2]) / 2;
  3388. vCorners[0][0] = b->mins[0];
  3389. vCorners[0][1] = b->mins[1];
  3390. vCorners[0][2] = fMid;
  3391. vCorners[1][0] = b->mins[0];
  3392. vCorners[1][1] = b->maxs[1];
  3393. vCorners[1][2] = fMid;
  3394. vCorners[2][0] = b->maxs[0];
  3395. vCorners[2][1] = b->maxs[1];
  3396. vCorners[2][2] = fMid;
  3397. vCorners[3][0] = b->maxs[0];
  3398. vCorners[3][1] = b->mins[1];
  3399. vCorners[3][2] = fMid;
  3400. vec3_t vTop, vBottom;
  3401. vTop[0] = b->mins[0] + ((b->maxs[0] - b->mins[0]) / 2);
  3402. vTop[1] = b->mins[1] + ((b->maxs[1] - b->mins[1]) / 2);
  3403. vTop[2] = b->maxs[2];
  3404. VectorCopy(vTop, vBottom);
  3405. vBottom[2] = b->mins[2];
  3406. vec3_t vSave;
  3407. VectorCopy(vTriColor, vSave);
  3408. qglBegin(GL_TRIANGLE_FAN);
  3409. qglVertex3fv(vTop);
  3410. for (int i = 0; i <= 3; i++)
  3411. {
  3412. vTriColor[0] *= 0.95;
  3413. vTriColor[1] *= 0.95;
  3414. vTriColor[2] *= 0.95;
  3415. qglColor3f(vTriColor[0], vTriColor[1], vTriColor[2]);
  3416. qglVertex3fv(vCorners[i]);
  3417. }
  3418. qglVertex3fv(vCorners[0]);
  3419. qglEnd();
  3420. VectorCopy(vSave, vTriColor);
  3421. vTriColor[0] *= 0.95;
  3422. vTriColor[1] *= 0.95;
  3423. vTriColor[2] *= 0.95;
  3424. qglBegin(GL_TRIANGLE_FAN);
  3425. qglVertex3fv(vBottom);
  3426. qglVertex3fv(vCorners[0]);
  3427. for (i = 3; i >= 0; i--)
  3428. {
  3429. vTriColor[0] *= 0.95;
  3430. vTriColor[1] *= 0.95;
  3431. vTriColor[2] *= 0.95;
  3432. qglColor3f(vTriColor[0], vTriColor[1], vTriColor[2]);
  3433. qglVertex3fv(vCorners[i]);
  3434. }
  3435. qglEnd();
  3436. // check for DOOM lights
  3437. CString str = ValueForKey(b->owner, "light_right");
  3438. if (str.GetLength() > 0) {
  3439. vec3_t vRight, vUp, vTarget, vTemp;
  3440. GetVectorForKey (b->owner, "light_right", vRight);
  3441. GetVectorForKey (b->owner, "light_up", vUp);
  3442. GetVectorForKey (b->owner, "light_target", vTarget);
  3443. qglColor3f(0, 1, 0);
  3444. qglBegin(GL_LINE_LOOP);
  3445. VectorAdd(vTarget, b->owner->origin, vTemp);
  3446. VectorAdd(vTemp, vRight, vTemp);
  3447. VectorAdd(vTemp, vUp, vTemp);
  3448. qglVertex3fv(b->owner->origin);
  3449. qglVertex3fv(vTemp);
  3450. VectorAdd(vTarget, b->owner->origin, vTemp);
  3451. VectorAdd(vTemp, vUp, vTemp);
  3452. VectorSubtract(vTemp, vRight, vTemp);
  3453. qglVertex3fv(b->owner->origin);
  3454. qglVertex3fv(vTemp);
  3455. VectorAdd(vTarget, b->owner->origin, vTemp);
  3456. VectorAdd(vTemp, vRight, vTemp);
  3457. VectorSubtract(vTemp, vUp, vTemp);
  3458. qglVertex3fv(b->owner->origin);
  3459. qglVertex3fv(vTemp);
  3460. VectorAdd(vTarget, b->owner->origin, vTemp);
  3461. VectorSubtract(vTemp, vUp, vTemp);
  3462. VectorSubtract(vTemp, vRight, vTemp);
  3463. qglVertex3fv(b->owner->origin);
  3464. qglVertex3fv(vTemp);
  3465. qglEnd();
  3466. }
  3467. }
  3468. void Brush_Draw( brush_t *b )
  3469. {
  3470. face_t *face;
  3471. int i, order;
  3472. qtexture_t *prev = 0;
  3473. winding_t *w;
  3474. if ( b->owner && ( b->owner->eclass->nShowFlags & ECLASS_PLUGINENTITY ) )
  3475. {
  3476. b->owner->pPlugEnt->CamRender();
  3477. return;
  3478. }
  3479. // (TTimo) NOTE: added by build 173, I check after pPlugEnt so it doesn't interfere ?
  3480. if (b->hiddenBrush)
  3481. {
  3482. return;
  3483. }
  3484. if (b->patchBrush)
  3485. {
  3486. //Patch_DrawCam(b->nPatchID);
  3487. Patch_DrawCam(b->pPatch);
  3488. //if (!g_bPatchShowBounds)
  3489. return;
  3490. }
  3491. if (b->terrainBrush)
  3492. {
  3493. Terrain_DrawCam(b->pTerrain);
  3494. return;
  3495. }
  3496. int nDrawMode = g_pParentWnd->GetCamera()->Camera().draw_mode;
  3497. if (b->owner->eclass->fixedsize)
  3498. {
  3499. if (!(g_qeglobals.d_savedinfo.exclude & EXCLUDE_ANGLES) && (b->owner->eclass->nShowFlags & ECLASS_ANGLE))
  3500. {
  3501. Brush_DrawFacingAngle(b, b->owner);
  3502. }
  3503. if (g_PrefsDlg.m_bNewLightDraw && (b->owner->eclass->nShowFlags & ECLASS_LIGHT))
  3504. {
  3505. DrawLight(b);
  3506. return;
  3507. }
  3508. if (nDrawMode == cd_texture || nDrawMode == cd_light)
  3509. qglDisable (GL_TEXTURE_2D);
  3510. // if we are wireframing models
  3511. bool bp = (b->bModelFailed) ? false : PaintedModel(b, true);
  3512. if (nDrawMode == cd_texture || nDrawMode == cd_light)
  3513. qglEnable (GL_TEXTURE_2D);
  3514. if (bp)
  3515. return;
  3516. }
  3517. // guarantee the texture will be set first
  3518. prev = NULL;
  3519. for (face = b->brush_faces,order = 0 ; face ; face=face->next, order++)
  3520. {
  3521. w = face->face_winding;
  3522. if (!w)
  3523. {
  3524. continue; // freed face
  3525. }
  3526. if (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CAULK)
  3527. {
  3528. if (strstr(face->texdef.name, "caulk"))
  3529. {
  3530. continue;
  3531. }
  3532. }
  3533. #if 0
  3534. if (b->alphaBrush)
  3535. {
  3536. if (!(face->texdef.flags & SURF_ALPHA))
  3537. continue;
  3538. //--qglPushAttrib(GL_ALL_ATTRIB_BITS);
  3539. qglDisable(GL_CULL_FACE);
  3540. //--qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  3541. //--qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  3542. //--qglDisable(GL_DEPTH_TEST);
  3543. //--qglBlendFunc (GL_SRC_ALPHA, GL_DST_ALPHA);
  3544. //--qglEnable (GL_BLEND);
  3545. }
  3546. #endif
  3547. if ((nDrawMode == cd_texture || nDrawMode == cd_light) && face->d_texture != prev)
  3548. {
  3549. // set the texture for this face
  3550. prev = face->d_texture;
  3551. qglBindTexture( GL_TEXTURE_2D, face->d_texture->texture_number );
  3552. }
  3553. if (!b->patchBrush)
  3554. {
  3555. if (face->texdef.flags & SURF_TRANS33)
  3556. qglColor4f ( face->d_color[0], face->d_color[1], face->d_color[2], 0.33 );
  3557. else if ( face->texdef.flags & SURF_TRANS66)
  3558. qglColor4f ( face->d_color[0], face->d_color[1], face->d_color[2], 0.66 );
  3559. else
  3560. qglColor3fv( face->d_color );
  3561. }
  3562. else
  3563. {
  3564. qglColor4f ( face->d_color[0], face->d_color[1], face->d_color[2], 0.13 );
  3565. }
  3566. // shader drawing stuff
  3567. if (face->d_texture->bFromShader)
  3568. {
  3569. // setup shader drawing
  3570. qglColor4f ( face->d_color[0], face->d_color[1], face->d_color[2], face->d_texture->fTrans );
  3571. }
  3572. // draw the polygon
  3573. //if (nDrawMode == cd_light)
  3574. //{
  3575. if (g_PrefsDlg.m_bGLLighting)
  3576. {
  3577. qglNormal3fv(face->plane.normal);
  3578. }
  3579. //}
  3580. qglBegin(GL_POLYGON);
  3581. //if (nDrawMode == cd_light)
  3582. for (i=0 ; i<w->numpoints ; i++)
  3583. {
  3584. if (nDrawMode == cd_texture || nDrawMode == cd_light)
  3585. qglTexCoord2fv( &w->points[i][3] );
  3586. qglVertex3fv(w->points[i]);
  3587. }
  3588. qglEnd();
  3589. }
  3590. #if 0
  3591. if (b->alphaBrush)
  3592. {
  3593. //--qglPopAttrib();
  3594. qglEnable(GL_CULL_FACE);
  3595. //--qglDisable (GL_BLEND);
  3596. //--qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  3597. }
  3598. #endif
  3599. if (b->owner->eclass->fixedsize && (nDrawMode == cd_texture || nDrawMode == cd_light))
  3600. qglEnable (GL_TEXTURE_2D);
  3601. qglBindTexture( GL_TEXTURE_2D, 0 );
  3602. }
  3603. void Face_Draw( face_t *f )
  3604. {
  3605. int i;
  3606. if ( f->face_winding == 0 )
  3607. return;
  3608. qglBegin( GL_POLYGON );
  3609. for ( i = 0 ; i < f->face_winding->numpoints; i++)
  3610. qglVertex3fv( f->face_winding->points[i] );
  3611. qglEnd();
  3612. }
  3613. void Brush_DrawXY(brush_t *b, int nViewType)
  3614. {
  3615. face_t *face;
  3616. int order;
  3617. winding_t *w;
  3618. int i;
  3619. if (b->hiddenBrush)
  3620. {
  3621. return;
  3622. }
  3623. if (b->patchBrush)
  3624. {
  3625. //Patch_DrawXY(b->nPatchID);
  3626. Patch_DrawXY(b->pPatch);
  3627. if (!g_bPatchShowBounds)
  3628. return;
  3629. }
  3630. if (b->terrainBrush)
  3631. {
  3632. Terrain_DrawXY(b->pTerrain, b->owner);
  3633. }
  3634. if (b->owner->eclass->fixedsize)
  3635. {
  3636. if (g_PrefsDlg.m_bNewLightDraw && (b->owner->eclass->nShowFlags & ECLASS_LIGHT))
  3637. {
  3638. vec3_t vCorners[4];
  3639. float fMid = b->mins[2] + (b->maxs[2] - b->mins[2]) / 2;
  3640. vCorners[0][0] = b->mins[0];
  3641. vCorners[0][1] = b->mins[1];
  3642. vCorners[0][2] = fMid;
  3643. vCorners[1][0] = b->mins[0];
  3644. vCorners[1][1] = b->maxs[1];
  3645. vCorners[1][2] = fMid;
  3646. vCorners[2][0] = b->maxs[0];
  3647. vCorners[2][1] = b->maxs[1];
  3648. vCorners[2][2] = fMid;
  3649. vCorners[3][0] = b->maxs[0];
  3650. vCorners[3][1] = b->mins[1];
  3651. vCorners[3][2] = fMid;
  3652. vec3_t vTop, vBottom;
  3653. vTop[0] = b->mins[0] + ((b->maxs[0] - b->mins[0]) / 2);
  3654. vTop[1] = b->mins[1] + ((b->maxs[1] - b->mins[1]) / 2);
  3655. vTop[2] = b->maxs[2];
  3656. VectorCopy(vTop, vBottom);
  3657. vBottom[2] = b->mins[2];
  3658. qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
  3659. qglBegin(GL_TRIANGLE_FAN);
  3660. qglVertex3fv(vTop);
  3661. qglVertex3fv(vCorners[0]);
  3662. qglVertex3fv(vCorners[1]);
  3663. qglVertex3fv(vCorners[2]);
  3664. qglVertex3fv(vCorners[3]);
  3665. qglVertex3fv(vCorners[0]);
  3666. qglEnd();
  3667. qglBegin(GL_TRIANGLE_FAN);
  3668. qglVertex3fv(vBottom);
  3669. qglVertex3fv(vCorners[0]);
  3670. qglVertex3fv(vCorners[3]);
  3671. qglVertex3fv(vCorners[2]);
  3672. qglVertex3fv(vCorners[1]);
  3673. qglVertex3fv(vCorners[0]);
  3674. qglEnd();
  3675. DrawBrushEntityName (b);
  3676. return;
  3677. }
  3678. else if (b->owner->eclass->nShowFlags & ECLASS_MISCMODEL)
  3679. {
  3680. if (PaintedModel(b, false))
  3681. return;
  3682. }
  3683. }
  3684. for (face = b->brush_faces,order = 0 ; face ; face=face->next, order++)
  3685. {
  3686. // only draw polygons facing in a direction we care about
  3687. if (nViewType == XY)
  3688. {
  3689. if (face->plane.normal[2] <= 0)
  3690. continue;
  3691. }
  3692. else
  3693. {
  3694. if (nViewType == XZ)
  3695. {
  3696. if (face->plane.normal[1] <= 0)
  3697. continue;
  3698. }
  3699. else
  3700. {
  3701. if (face->plane.normal[0] <= 0)
  3702. continue;
  3703. }
  3704. }
  3705. w = face->face_winding;
  3706. if (!w)
  3707. continue;
  3708. //if (b->alphaBrush && !(face->texdef.flags & SURF_ALPHA))
  3709. // continue;
  3710. // draw the polygon
  3711. qglBegin(GL_LINE_LOOP);
  3712. for (i=0 ; i<w->numpoints ; i++)
  3713. qglVertex3fv(w->points[i]);
  3714. qglEnd();
  3715. }
  3716. DrawBrushEntityName (b);
  3717. }
  3718. /*
  3719. ============
  3720. Brush_Move
  3721. ============
  3722. */
  3723. void Brush_Move (brush_t *b, const vec3_t move, bool bSnap)
  3724. {
  3725. int i;
  3726. face_t *f;
  3727. for (f=b->brush_faces ; f ; f=f->next)
  3728. {
  3729. vec3_t vTemp;
  3730. VectorCopy(move, vTemp);
  3731. if (g_PrefsDlg.m_bTextureLock)
  3732. Face_MoveTexture(f, vTemp);
  3733. for (i=0 ; i<3 ; i++)
  3734. VectorAdd (f->planepts[i], move, f->planepts[i]);
  3735. }
  3736. Brush_Build( b, bSnap );
  3737. if (b->patchBrush)
  3738. {
  3739. //Patch_Move(b->nPatchID, move);
  3740. Patch_Move(b->pPatch, move);
  3741. }
  3742. if (b->terrainBrush)
  3743. {
  3744. Terrain_Move(b->pTerrain, move);
  3745. }
  3746. // PGM - keep the origin vector up to date on fixed size entities.
  3747. if(b->owner->eclass->fixedsize)
  3748. {
  3749. VectorAdd(b->owner->origin, move, b->owner->origin);
  3750. //VectorAdd(b->maxs, b->mins, b->owner->origin);
  3751. //VectorScale(b->owner->origin, 0.5, b->owner->origin);
  3752. }
  3753. }
  3754. void Brush_Print(brush_t* b)
  3755. {
  3756. int nFace = 0;
  3757. for (face_t* f = b->brush_faces ; f ; f=f->next)
  3758. {
  3759. Sys_Printf("Face %i\n", nFace++);
  3760. Sys_Printf("%f %f %f\n", f->planepts[0][0], f->planepts[0][1], f->planepts[0][2]);
  3761. Sys_Printf("%f %f %f\n", f->planepts[1][0], f->planepts[1][1], f->planepts[1][2]);
  3762. Sys_Printf("%f %f %f\n", f->planepts[2][0], f->planepts[2][1], f->planepts[2][2]);
  3763. }
  3764. }
  3765. /*
  3766. =============
  3767. Brush_MakeSided
  3768. Makes the current brushhave the given number of 2d sides and turns it into a cone
  3769. =============
  3770. */
  3771. void Brush_MakeSidedCone(int sides)
  3772. {
  3773. int i;
  3774. vec3_t mins, maxs;
  3775. brush_t *b;
  3776. texdef_t *texdef;
  3777. face_t *f;
  3778. vec3_t mid;
  3779. float width;
  3780. float sv, cv;
  3781. if (sides < 3)
  3782. {
  3783. Sys_Status ("Bad sides number", 0);
  3784. return;
  3785. }
  3786. if (!QE_SingleBrush ())
  3787. {
  3788. Sys_Status ("Must have a single brush selected", 0 );
  3789. return;
  3790. }
  3791. b = selected_brushes.next;
  3792. VectorCopy (b->mins, mins);
  3793. VectorCopy (b->maxs, maxs);
  3794. texdef = &g_qeglobals.d_texturewin.texdef;
  3795. Brush_Free (b);
  3796. // find center of brush
  3797. width = 8;
  3798. for (i=0 ; i<2 ; i++)
  3799. {
  3800. mid[i] = (maxs[i] + mins[i])*0.5;
  3801. if (maxs[i] - mins[i] > width)
  3802. width = maxs[i] - mins[i];
  3803. }
  3804. width /= 2;
  3805. b = Brush_Alloc();
  3806. // create bottom face
  3807. f = Face_Alloc();
  3808. f->texdef = *texdef;
  3809. f->next = b->brush_faces;
  3810. b->brush_faces = f;
  3811. f->planepts[0][0] = mins[0];f->planepts[0][1] = mins[1];f->planepts[0][2] = mins[2];
  3812. f->planepts[1][0] = maxs[0];f->planepts[1][1] = mins[1];f->planepts[1][2] = mins[2];
  3813. f->planepts[2][0] = maxs[0];f->planepts[2][1] = maxs[1];f->planepts[2][2] = mins[2];
  3814. for (i=0 ; i<sides ; i++)
  3815. {
  3816. f = Face_Alloc();
  3817. f->texdef = *texdef;
  3818. f->next = b->brush_faces;
  3819. b->brush_faces = f;
  3820. sv = sin (i*3.14159265*2/sides);
  3821. cv = cos (i*3.14159265*2/sides);
  3822. f->planepts[0][0] = floor(mid[0]+width*cv+0.5);
  3823. f->planepts[0][1] = floor(mid[1]+width*sv+0.5);
  3824. f->planepts[0][2] = mins[2];
  3825. f->planepts[1][0] = mid[0];
  3826. f->planepts[1][1] = mid[1];
  3827. f->planepts[1][2] = maxs[2];
  3828. f->planepts[2][0] = floor(f->planepts[0][0] - width * sv + 0.5);
  3829. f->planepts[2][1] = floor(f->planepts[0][1] + width * cv + 0.5);
  3830. f->planepts[2][2] = maxs[2];
  3831. }
  3832. Brush_AddToList (b, &selected_brushes);
  3833. Entity_LinkBrush (world_entity, b);
  3834. Brush_Build( b );
  3835. Sys_UpdateWindows (W_ALL);
  3836. }
  3837. /*
  3838. =============
  3839. Brush_MakeSided
  3840. Makes the current brushhave the given number of 2d sides and turns it into a sphere
  3841. =============
  3842. */
  3843. void Brush_MakeSidedSphere(int sides)
  3844. {
  3845. int i,j;
  3846. vec3_t mins, maxs;
  3847. brush_t *b;
  3848. texdef_t *texdef;
  3849. face_t *f;
  3850. vec3_t mid;
  3851. if (sides < 4)
  3852. {
  3853. Sys_Status ("Bad sides number", 0);
  3854. return;
  3855. }
  3856. if (!QE_SingleBrush ())
  3857. {
  3858. Sys_Status ("Must have a single brush selected", 0 );
  3859. return;
  3860. }
  3861. b = selected_brushes.next;
  3862. VectorCopy (b->mins, mins);
  3863. VectorCopy (b->maxs, maxs);
  3864. texdef = &g_qeglobals.d_texturewin.texdef;
  3865. Brush_Free (b);
  3866. // find center of brush
  3867. float radius = 8;
  3868. for (i=0 ; i<2 ; i++)
  3869. {
  3870. mid[i] = (maxs[i] + mins[i])*0.5;
  3871. if (maxs[i] - mins[i] > radius)
  3872. radius = maxs[i] - mins[i];
  3873. }
  3874. radius /= 2;
  3875. b = Brush_Alloc();
  3876. float dt = float(2 * Q_PI / sides);
  3877. float dp = float(Q_PI / sides);
  3878. float t,p;
  3879. for(i=0; i <= sides-1; i++)
  3880. {
  3881. for(j=0;j <= sides-2; j++)
  3882. {
  3883. t = i * dt;
  3884. p = float(j * dp - Q_PI / 2);
  3885. f = Face_Alloc();
  3886. f->texdef = *texdef;
  3887. f->next = b->brush_faces;
  3888. b->brush_faces = f;
  3889. VectorPolar(f->planepts[0], radius, t, p);
  3890. VectorPolar(f->planepts[1], radius, t, p + dp);
  3891. VectorPolar(f->planepts[2], radius, t + dt, p + dp);
  3892. for (int k = 0; k < 3; k++)
  3893. VectorAdd(f->planepts[k], mid, f->planepts[k]);
  3894. }
  3895. }
  3896. p = float((sides - 1) * dp - Q_PI / 2);
  3897. for(i = 0; i <= sides-1; i++)
  3898. {
  3899. t = i * dt;
  3900. f = Face_Alloc();
  3901. f->texdef = *texdef;
  3902. f->next = b->brush_faces;
  3903. b->brush_faces = f;
  3904. VectorPolar(f->planepts[0], radius, t, p);
  3905. VectorPolar(f->planepts[1], radius, t + dt, p + dp);
  3906. VectorPolar(f->planepts[2], radius, t + dt, p);
  3907. for (int k = 0; k < 3; k++)
  3908. VectorAdd(f->planepts[k], mid, f->planepts[k]);
  3909. }
  3910. Brush_AddToList (b, &selected_brushes);
  3911. Entity_LinkBrush (world_entity, b);
  3912. Brush_Build( b );
  3913. Sys_UpdateWindows (W_ALL);
  3914. }
  3915. void Face_FitTexture( face_t * face, int nHeight, int nWidth )
  3916. {
  3917. winding_t *w;
  3918. vec3_t mins,maxs;
  3919. int i;
  3920. float width, height, temp;
  3921. float rot_width, rot_height;
  3922. float cosv,sinv,ang;
  3923. float min_t, min_s, max_t, max_s;
  3924. float s,t;
  3925. vec3_t vecs[2];
  3926. vec3_t coords[4];
  3927. texdef_t *td;
  3928. if (nHeight < 1)
  3929. {
  3930. nHeight = 1;
  3931. }
  3932. if (nWidth < 1)
  3933. {
  3934. nWidth = 1;
  3935. }
  3936. ClearBounds (mins, maxs);
  3937. td = &face->texdef;
  3938. w = face->face_winding;
  3939. if (!w)
  3940. {
  3941. return;
  3942. }
  3943. for (i=0 ; i<w->numpoints ; i++)
  3944. {
  3945. AddPointToBounds( w->points[i], mins, maxs );
  3946. }
  3947. //
  3948. // get the current angle
  3949. //
  3950. ang = td->rotate / 180 * Q_PI;
  3951. sinv = sin(ang);
  3952. cosv = cos(ang);
  3953. // get natural texture axis
  3954. TextureAxisFromPlane(&face->plane, vecs[0], vecs[1]);
  3955. min_s = DotProduct( mins, vecs[0] );
  3956. min_t = DotProduct( mins, vecs[1] );
  3957. max_s = DotProduct( maxs, vecs[0] );
  3958. max_t = DotProduct( maxs, vecs[1] );
  3959. width = max_s - min_s;
  3960. height = max_t - min_t;
  3961. coords[0][0] = min_s;
  3962. coords[0][1] = min_t;
  3963. coords[1][0] = max_s;
  3964. coords[1][1] = min_t;
  3965. coords[2][0] = min_s;
  3966. coords[2][1] = max_t;
  3967. coords[3][0] = max_s;
  3968. coords[3][1] = max_t;
  3969. min_s = min_t = 99999;
  3970. max_s = max_t = -99999;
  3971. for (i=0; i<4; i++)
  3972. {
  3973. s = cosv * coords[i][0] - sinv * coords[i][1];
  3974. t = sinv * coords[i][0] + cosv * coords[i][1];
  3975. if (i&1)
  3976. {
  3977. if (s > max_s)
  3978. {
  3979. max_s = s;
  3980. }
  3981. }
  3982. else
  3983. {
  3984. if (s < min_s)
  3985. {
  3986. min_s = s;
  3987. }
  3988. if (i<2)
  3989. {
  3990. if (t < min_t)
  3991. {
  3992. min_t = t;
  3993. }
  3994. }
  3995. else
  3996. {
  3997. if (t > max_t)
  3998. {
  3999. max_t = t;
  4000. }
  4001. }
  4002. }
  4003. }
  4004. rot_width = (max_s - min_s);
  4005. rot_height = (max_t - min_t);
  4006. td->scale[0] = -(rot_width/((float)(face->d_texture->width*nWidth)));
  4007. td->scale[1] = -(rot_height/((float)(face->d_texture->height*nHeight)));
  4008. td->shift[0] = min_s/td->scale[0];
  4009. temp = (int)(td->shift[0] / (face->d_texture->width*nWidth));
  4010. temp = (temp+1)*face->d_texture->width*nWidth;
  4011. td->shift[0] = (int)(temp - td->shift[0])%(face->d_texture->width*nWidth);
  4012. td->shift[1] = min_t/td->scale[1];
  4013. temp = (int)(td->shift[1] / (face->d_texture->height*nHeight));
  4014. temp = (temp+1)*(face->d_texture->height*nHeight);
  4015. td->shift[1] = (int)(temp - td->shift[1])%(face->d_texture->height*nHeight);
  4016. }
  4017. void Brush_FitTexture( brush_t *b, int nHeight, int nWidth )
  4018. {
  4019. face_t *face;
  4020. for (face = b->brush_faces ; face ; face=face->next)
  4021. {
  4022. Face_FitTexture( face, nHeight, nWidth );
  4023. }
  4024. }